#!/bin/sh
#
# Create the source file containing the individual programs
#
cat >loadMusicUSB.cbl <<!EOF!
      ******************************************************************
      * Author: Jay Moseley
      * Date: June 24, 2019
      * Purpose: Copy MP3 files from hard drive to USB for Passport.
      * Tectonics: cobc -x loadPassport.cbl
      ******************************************************************
       IDENTIFICATION DIVISION.
       PROGRAM-ID. loadPassport.

       ENVIRONMENT DIVISION.

       CONFIGURATION SECTION.
       REPOSITORY.
           FUNCTION ALL INTRINSIC.

       INPUT-OUTPUT SECTION.
       FILE-CONTROL.

           SELECT FOLDERS-FILE
               ASSIGN TO WS-FOLDERLIST-ID
               ORGANIZATION IS LINE SEQUENTIAL.

           SELECT MP3-TRACKLIST-FILE
               ASSIGN TO WS-TRACKLIST-ID
               ORGANIZATION IS LINE SEQUENTIAL.

           SELECT OPTIONAL LSOUTPUT-FILE
               ASSIGN TO TMPFILE
               ORGANIZATION IS LINE SEQUENTIAL.

       DATA DIVISION.
       FILE SECTION.

       FD  FOLDERS-FILE
           DATA RECORD IS FOLDERS-RECORD.
       01  FOLDERS-RECORD              PIC X(120).

       FD  MP3-TRACKLIST-FILE
           DATA RECORD IS TRACKLIST-RECORD.
       01  TRACKLIST-RECORD            PIC X(120).

       FD  LSOUTPUT-FILE
           DATA RECORD IS LSOUTPUT-RECORD.
       01  LSOUTPUT-RECORD             PIC X(120).

       WORKING-STORAGE SECTION.
       01  WS-WORK-FIELDS.
           02  WS-ARGN                 PIC 9(02).
           02  WS-ONE-DIRECTORY        PIC X(50) VALUE SPACES.
           02  WS-QUOTEMARK            PIC X VALUE '"'.
           02  WS-TARGET-BASE-PATH     PIC X(20) VALUE
               '/media/jay/PASSPORT/'.
           02  WS-FOLDERLIST-ID        PIC X(80) VALUE
               'folderlist.txt'.
           02  WS-TRACKLIST-ID         PIC X(80).
           02  WS-TEST-DIRECTORY       PIC X(50).
           02  WS-FILE-INFO            USAGE COMP.
               03  WS-FILE-SIZE        PIC 9(18).
               03  WS-FILE-MOD-DMY     PIC 9(08).
               03  WS-FILE-MOD-HMS     PIC 9(06).
               03  FILLER              PIC 9(02).
           02  WS-LS-COMMAND           PIC X(150).
           02  WS-CP-COMMAND           PIC X(240).
           02  WS-RM-COMMAND           PIC X(240).
           02  WS-RANDOM               PIC S9(5)V9(8).
           02  WS-RANDOM-I             PIC S9(5) COMP-3.
           02  WS-COUNT-TO-MOVE        PIC S9(4) COMP.
           02  WS-MP3-TABLE-LIMIT      USAGE INDEX VALUE +2000.
           02  WS-MP3LIST-TABLE.
               03  WS-MP3-TABLE-MAX    PIC S9(4) COMP.
               03  WS-MP3-TABLE-ENTRY  OCCURS 2000 TIMES
                                       INDEXED BY MP3-X.
                   05  WS-MP3-TE-ALLOC PIC 9(1).
                   05  WS-MP3-TE-NAME  PIC X(120).
           02  WS-STAT                 PIC S9(9).

       PROCEDURE DIVISION.

       MAIN-PROCEDURE.

      ******************************************************************
      * If an argument was supplied, retrieve it and save as the single
      * directory to process (will be verified before processing).
      ******************************************************************
           ACCEPT WS-ARGN FROM ARGUMENT-NUMBER.
           IF WS-ARGN = 1
             DISPLAY 1 UPON ARGUMENT-NUMBER
             ACCEPT WS-ONE-DIRECTORY FROM ARGUMENT-VALUE
           END-IF.

      ******************************************************************
      * Initialize random number generation from current date/time.
      ******************************************************************
           MOVE RANDOM(CURRENT-DATE(1:16))
             TO WS-RANDOM.

      ******************************************************************
      * Meta process to empty and remove any folders on the target that
      * are not listed in the 'folderlist.txt' file.
      ******************************************************************
           CALL 'cleanTarget'.

      ******************************************************************
      * If no argument supplied, process all folders in 'folderlist.txt'
      * file 
      *         /else/
      * attempt to process single folder named in supplied argument.
      ******************************************************************
           IF WS-ARGN = 0
             PERFORM PROCESS-FOLDERS-FILE
                THRU PROCESS-FOLDERS-FILE-EXIT
           ELSE
             DISPLAY 'Processing single requested folder: '
                     TRIM(WS-ONE-DIRECTORY)
               END-DISPLAY
             PERFORM PROCESS-SINGLE-REQUEST
                THRU PROCESS-SINGLE-REQUEST-EXIT
           END-IF.

           GOBACK.    

       PROCESS-SINGLE-REQUEST.

      ******************************************************************
      * Verify source folder specified as argument exists. If it doesn't
      * issue error message /else/ process folder.
      ******************************************************************
           MOVE WS-ONE-DIRECTORY TO WS-TEST-DIRECTORY.
           IF TRIM(REVERSE(WS-TEST-DIRECTORY)) (1:1) NOT = '/'
             MOVE CONCATENATE(TRIM(WS-TEST-DIRECTORY),
                              '/')
               TO WS-TEST-DIRECTORY
           END-IF.

           CALL "CBL_CHECK_FILE_EXIST" USING WS-TEST-DIRECTORY,
                                             WS-FILE-INFO.

           IF RETURN-CODE = 35
             DISPLAY 'Specified source directory: '
                     TRIM(WS-ONE-DIRECTORY)
                     ', does not exist. '
             DISPLAY 'Terminating with no action.'
               END-DISPLAY
           ELSE
             MOVE WS-ONE-DIRECTORY TO FOLDERS-RECORD
             PERFORM PROCESS-SINGLE-FOLDER
                THRU PROCESS-SINGLE-FOLDER-EXIT
           END-IF.

       PROCESS-SINGLE-REQUEST-EXIT.
           EXIT.

       PROCESS-FOLDERS-FILE.

      ******************************************************************
      * Read list of source folders from 'folderlist.txt' file and 
      * process each folder.
      ******************************************************************
           DISPLAY 'Processing folderlist.txt contents.'
             END-DISPLAY.
           OPEN INPUT FOLDERS-FILE.
           PERFORM FOREVER
             READ FOLDERS-FILE
               AT END
                 EXIT PERFORM
               NOT AT END
                 DISPLAY 'From folderlist.txt: ' 
                         TRIM(FOLDERS-RECORD)
                   END-DISPLAY
                 PERFORM PROCESS-SINGLE-FOLDER
                    THRU PROCESS-SINGLE-FOLDER-EXIT
             END-READ
           END-PERFORM.
           CLOSE FOLDERS-FILE.

       PROCESS-FOLDERS-FILE-EXIT.
           EXIT.

       PROCESS-SINGLE-FOLDER.

      ******************************************************************
      * If target folder exists, delete the contents and remove it.
      ******************************************************************
           MOVE CONCATENATE(WS-TARGET-BASE-PATH,
                            TRIM(FOLDERS-RECORD))
             TO WS-TEST-DIRECTORY.

           CALL "CBL_CHECK_FILE_EXIST" USING WS-TEST-DIRECTORY,
                                             WS-FILE-INFO.

           IF RETURN-CODE = 0
             MOVE CONCATENATE('rm -r -v ',
                              WS-QUOTEMARK,
                              TRIM(WS-TEST-DIRECTORY),
                              WS-QUOTEMARK)
               TO WS-RM-COMMAND
             CALL 'SYSTEM'
               USING TRIM(WS-RM-COMMAND TRAILING)
               RETURNING WS-STAT
             END-CALL

      ******************************************************************
      * If 'playorder.txt' file exists in source folder, use it to copy
      * files from source folder to target folder /else/ acquire list
      * of all mp3 files in source folder and copy them to target folder
      * in random order.
      ******************************************************************
           MOVE CONCATENATE(TRIM(FOLDERS-RECORD),
                            '/playorder.txt')
             TO WS-TRACKLIST-ID.
           CALL "CBL_CHECK_FILE_EXIST" USING WS-TRACKLIST-ID,
                                             WS-FILE-INFO.
           IF RETURN-CODE = 0
             PERFORM PROCESS-PLAYORDER-LIST
                THRU PROCESS-PLAYORDER-LIST-EXIT
           ELSE
             PERFORM RANDOMIZE-ALL-MP3S
                THRU RANDOMIZE-ALL-MP3S-EXIT
           END-IF.

       PROCESS-SINGLE-FOLDER-EXIT.
            EXIT.

       PROCESS-PLAYORDER-LIST.

      ******************************************************************
      * Create target folder.
      ******************************************************************
           DISPLAY 'Loading using playorder.txt.' END-DISPLAY.
           MOVE CONCATENATE('mkdir -v ',
                            WS-QUOTEMARK,
                            WS-TARGET-BASE-PATH,
                            TRIM(FOLDERS-RECORD)
                            WS-QUOTEMARK)
             TO WS-CP-COMMAND.
           CALL 'SYSTEM' USING TRIM(WS-CP-COMMAND TRAILING)
                RETURNING WS-STAT
           END-CALL.
                           
      ******************************************************************
      * Read list of mp3 files from 'playorder.txt' file and copy them
      * in that order to target folder.
      ******************************************************************
           OPEN INPUT MP3-TRACKLIST-FILE.
           PERFORM FOREVER
             READ MP3-TRACKLIST-FILE
               AT END
                 EXIT PERFORM
               NOT AT END
                 MOVE SPACES TO WS-CP-COMMAND
                 STRING 'cp -v '
                        WS-QUOTEMARK
                        TRIM(FOLDERS-RECORD)
                        '/'
                        TRIM(TRACKLIST-RECORD)
                        WS-QUOTEMARK
                        ' '
                        WS-QUOTEMARK
                        WS-TARGET-BASE-PATH
                        TRIM(FOLDERS-RECORD)
                        WS-QUOTEMARK
                   DELIMITED BY SIZE 
                   INTO WS-CP-COMMAND
                 END-STRING
                 CALL 'SYSTEM' USING TRIM(WS-CP-COMMAND TRAILING)
                      RETURNING WS-STAT
                 END-CALL
             END-READ
           END-PERFORM.
           CLOSE MP3-TRACKLIST-FILE.

       PROCESS-PLAYORDER-LIST-EXIT.
           EXIT.

       RANDOMIZE-ALL-MP3S.

      ******************************************************************
      * Acquire list of mp3 files in source folder. If no mp3 files
      * are found, issue error message and terminate.
      ******************************************************************
           DISPLAY 'Loading in random order.' END-DISPLAY.
           PERFORM ACQUIRE-MP3-LIST
              THRU ACQUIRE-MP3-LIST-EXIT.
           IF WS-MP3-TABLE-MAX = ZERO
             DISPLAY 'No MP3 files in ' TRIM(FOLDERS-RECORD)
             STOP RUN 99
           END-IF

      ******************************************************************
      * Create target folder.
      ******************************************************************
           MOVE CONCATENATE('mkdir -v ',
                            WS-QUOTEMARK,
                            WS-TARGET-BASE-PATH,
                            TRIM(FOLDERS-RECORD),
                            WS-QUOTEMARK)
             TO WS-CP-COMMAND.
           CALL 'SYSTEM' USING TRIM(WS-CP-COMMAND TRAILING)
                RETURNING WS-STAT
           END-CALL.

      ******************************************************************
      * Copy mp3 files in random order from source to target directory.
      ******************************************************************
           MOVE WS-MP3-TABLE-MAX TO WS-COUNT-TO-MOVE.
           PERFORM UNTIL WS-COUNT-TO-MOVE = 0
             MOVE RANDOM TO WS-RANDOM
             COMPUTE WS-RANDOM = (WS-RANDOM *
                                  WS-MP3-TABLE-MAX) + 1
             MOVE WS-RANDOM TO WS-RANDOM-I
             SET MP3-X TO WS-RANDOM-I
             IF WS-MP3-TE-ALLOC (MP3-X) = 0
               MOVE SPACES TO WS-CP-COMMAND
               STRING 'cp -v '
                      WS-QUOTEMARK
                      TRIM(WS-MP3-TE-NAME (MP3-X))
                      WS-QUOTEMARK
                      ' '
                      WS-QUOTEMARK
                      WS-TARGET-BASE-PATH
                      TRIM(FOLDERS-RECORD)
                      WS-QUOTEMARK
                 DELIMITED BY SIZE
                 INTO WS-CP-COMMAND
               END-STRING
               CALL 'SYSTEM' USING TRIM(WS-CP-COMMAND TRAILING)
                    RETURNING WS-STAT
               END-CALL
               MOVE 1 TO WS-MP3-TE-ALLOC (MP3-X)
               SUBTRACT 1 FROM WS-COUNT-TO-MOVE
             END-IF
           END-PERFORM.

       RANDOMIZE-ALL-MP3S-EXIT.
           EXIT.

       ACQUIRE-MP3-LIST.

      ******************************************************************
      * Use 'ls' command to acquire list of mp3 files in source folder.
      ******************************************************************
           CALL 'tmpnam' USING TMPFILE
                RETURNING WS-STAT
           END-CALL.
           MOVE SPACES TO WS-LS-COMMAND.
           STRING 'ls -1 '
                  WS-QUOTEMARK
                  TRIM(FOLDERS-RECORD)
                  WS-QUOTEMARK
                  '/*.mp3'
                  ' > '
             DELIMITED BY SIZE
             TMPFILE DELIMITED BY SPACE
             LOW-VALUES DELIMITED BY SIZE
             INTO WS-LS-COMMAND
           END-STRING.
           CALL 'SYSTEM' USING TRIM(WS-LS-COMMAND TRAILING)
                RETURNING WS-STAT
           END-CALL.

      ******************************************************************
      * Read output of 'ls' command to fill table with names of mp3 
      * files in source directory.
      ******************************************************************
           INITIALIZE WS-MP3LIST-TABLE.
           SET MP3-X TO +1.
           OPEN INPUT LSOUTPUT-FILE.
           PERFORM FOREVER
               READ LSOUTPUT-FILE
                   AT END
                       EXIT PERFORM
                   NOT AT END
                       MOVE TRIM(LSOUTPUT-RECORD)
                         TO WS-MP3-TE-NAME (MP3-X)
                       SET WS-MP3-TABLE-MAX TO MP3-X
                       SET MP3-X UP BY +1
                       IF MP3-X > WS-MP3-TABLE-LIMIT
                         DISPLAY 'Number of mp3 files in folder ('
                                 TRIM(FOLDERS-RECORD)
                                 ' exceeds MP3LIST-TABLE size!'
                         DISPLAY 'Execution will be terminated!'
                         END-DISPLAY
                         STOP RUN 99
                       END-IF
               END-READ
           END-PERFORM .
           CLOSE LSOUTPUT-FILE.
           CALL 'remove' USING TMPFILE 
                RETURNING WS-STAT
           END-CALL.

       ACQUIRE-MP3-LIST-EXIT.
           EXIT.

       END PROGRAM loadPassport.

      ******************************************************************
      * Author: Jay Moseley
      * Date: July 6, 2019
      * Purpose: Compare directories on target drive with list in
      *          folders file and delete those on target but not in
      *          file.
      * Tectonics: embedded in loadPassport.cbl
      ******************************************************************
       IDENTIFICATION DIVISION.
       PROGRAM-ID. cleanTarget.

       ENVIRONMENT DIVISION.

       CONFIGURATION SECTION.
       REPOSITORY.
           FUNCTION ALL INTRINSIC.

       INPUT-OUTPUT SECTION.
       FILE-CONTROL.

           SELECT FOLDERS-FILE
               ASSIGN TO WS-FOLDERLIST-ID
               ORGANIZATION IS LINE SEQUENTIAL.

           SELECT OPTIONAL LSOUTPUT-FILE
               ASSIGN TO TMPFILE
               ORGANIZATION IS LINE SEQUENTIAL.

       DATA DIVISION.
       FILE SECTION.

       FD  FOLDERS-FILE
           DATA RECORD IS FOLDERS-RECORD.
       01  FOLDERS-RECORD              PIC X(120).

       FD  LSOUTPUT-FILE
           DATA RECORD IS LSOUTPUT-RECORD.
       01  LSOUTPUT-RECORD             PIC X(120).

       WORKING-STORAGE SECTION.
       01  WS-WORK-FIELDS.
           02  WS-QUOTEMARK            PIC X VALUE '"'.
           02  WS-SOURCE-BASE-PATH     PIC X(45) VALUE
               '/home/jay/PhoenixW/Passport Music/Mirror USB/'.
           02  WS-TARGET-BASE-PATH     PIC X(20) VALUE
               '/media/jay/PASSPORT/'.
           02  WS-FOLDERLIST-ID        PIC X(80) VALUE
               'folderlist.txt'.
           02  WS-FILE-INFO            USAGE COMP.
               03  WS-FILE-SIZE        PIC 9(18).
               03  WS-FILE-MOD-DMY     PIC 9(08).
               03  WS-FILE-MOD-HMS     PIC 9(06).
               03  FILLER              PIC 9(02).
           02  WS-STAT                 PIC S9(9).
           02  WS-LS-COMMAND           PIC X(150).
           02  WS-FOLDER-LIST.
               03  WS-FOLDER-LIMIT     PIC S9(4) COMP VALUE +200.
               03  WS-FOLDER-MAX       PIC S9(4) COMP VALUE +0.
               03  WS-FOLDER-NAME      OCCURS 200 TIMES
                                       INDEXED BY WS-FOLDER-IX
                                       PIC X(120).
           02  WS-TARGET-FOUND-SW      PIC X.
               88  TARGET-FOLDER-FOUND        VALUE 'Y'.
               88  TARGET-FOLDER-NOT-FOUND    VALUE 'N'.
           02  WS-RM-COMMAND           PIC X(240).

       PROCEDURE DIVISION.

       MAIN-PROCEDURE.

      ******************************************************************
      * Verify 'folderlist.txt' file exists. If not, issue error message
      * /else/ process list of folders.
      ******************************************************************
           MOVE CONCATENATE(WS-SOURCE-BASE-PATH,
                            'folderlist.txt')
             TO WS-FOLDERLIST-ID.

           CALL "CBL_CHECK_FILE_EXIST" USING WS-FOLDERLIST-ID,
                                             WS-FILE-INFO.

           IF RETURN-CODE = 35
             DISPLAY 'Specified source directory: '
                     TRIM(WS-FOLDERLIST-ID)
                     ', does not exist. Terminating.'
             END-DISPLAY
           ELSE
             PERFORM LOAD-FOLDER-LIST
                THRU LOAD-FOLDER-LIST-EXIT
             IF WS-FOLDER-MAX > +0
               PERFORM EXAMINE-TARGET-FOLDERS
                  THRU EXAMINE-TARGET-FOLDERS-EXIT
             END-IF
           END-IF.

           GOBACK.    

       LOAD-FOLDER-LIST.

      ******************************************************************
      * Load contents of 'folderlist.txt' into table.
      ******************************************************************
           OPEN INPUT FOLDERS-FILE
           SET WS-FOLDER-IX TO +1.
           PERFORM FOREVER
             READ FOLDERS-FILE
               AT END
                 EXIT PERFORM
               NOT AT END
                 MOVE FOLDERS-RECORD TO WS-FOLDER-NAME (WS-FOLDER-IX)
                 SET WS-FOLDER-IX UP BY +1
                 IF WS-FOLDER-IX > WS-FOLDER-LIMIT
                   DISPLAY 'List of folders exceeds limit ('
                           WS-FOLDER-LIMIT
                           '). Execution will not continue!'
                   END-DISPLAY
                   STOP RUN 99
                 END-IF
             END-READ
           END-PERFORM.
           CLOSE FOLDERS-FILE.
           SET WS-FOLDER-MAX TO WS-FOLDER-IX.
           SUBTRACT 1 FROM WS-FOLDER-MAX.

       LOAD-FOLDER-LIST-EXIT.
           EXIT.

       EXAMINE-TARGET-FOLDERS.

      ******************************************************************
      * Use 'ls' command to acquire list of folders in target base path.
      ******************************************************************
           CALL 'tmpnam' USING TMPFILE
                RETURNING WS-STAT
           END-CALL.
           MOVE SPACES TO WS-LS-COMMAND.
           STRING 'ls -1 '
                  WS-TARGET-BASE-PATH
                  ' > '
             DELIMITED BY SIZE
             TMPFILE DELIMITED BY SPACE
             LOW-VALUES DELIMITED BY SIZE
             INTO WS-LS-COMMAND
           END-STRING.
           CALL 'SYSTEM' USING TRIM(WS-LS-COMMAND TRAILING)
                RETURNING WS-STAT
           END-CALL.

      ******************************************************************
      * Process list of target folders.
      ******************************************************************
           OPEN INPUT LSOUTPUT-FILE.
           PERFORM FOREVER
               READ LSOUTPUT-FILE
                   AT END
                       EXIT PERFORM
                   NOT AT END
                       PERFORM VALIDATE-FOLDER
                          THRU VALIDATE-FOLDER-EXIT
               END-READ
           END-PERFORM .
           CLOSE LSOUTPUT-FILE.
           CALL 'remove' USING TMPFILE 
                RETURNING WS-STAT
           END-CALL.

       EXAMINE-TARGET-FOLDERS-EXIT.
           EXIT.

       VALIDATE-FOLDER.

      ******************************************************************
      * Search folder list (from 'folderlist.txt' file) for folder in
      * target base path.  If found, do nothing, /else/ delete contents
      * of target folder, and remove folder.
      ******************************************************************
           SET TARGET-FOLDER-NOT-FOUND TO TRUE.
           PERFORM VARYING WS-FOLDER-IX
                   FROM +1 BY +1
                   UNTIL WS-FOLDER-IX > WS-FOLDER-MAX
             IF TRIM(LSOUTPUT-RECORD) = 
                TRIM(WS-FOLDER-NAME (WS-FOLDER-IX))
               SET TARGET-FOLDER-FOUND TO TRUE
               EXIT PERFORM
             END-IF
           END-PERFORM.

           IF TARGET-FOLDER-FOUND
             CONTINUE
           ELSE
             MOVE CONCATENATE('rm -r -v ',
                              WS-QUOTEMARK,
                              WS-TARGET-BASE-PATH,
                              TRIM(LSOUTPUT-RECORD),
                              WS-QUOTEMARK)
               TO WS-RM-COMMAND
             CALL 'SYSTEM'
               USING TRIM(WS-RM-COMMAND TRAILING)
               RETURNING WS-STAT
             END-CALL
         END-IF.

       VALIDATE-FOLDER-EXIT.
           EXIT.

       END PROGRAM cleanTarget.

!EOF!
# ------------------------------------------------------------------
#
# Compile the program
#
cobc -x loadMusicUSB.cbl
#
exit 0

