10    !===================================================================!
20    !   FILE_COPY REVISION 3.0                                          !
30    !                                                                   !
40    !   This program copies files from mass storage to mass storage.    !
50    !   On SRM the contents of a directory may be copied to another     !
60    !   device or another directory, but directories themselves (with   !
70    !   contents) will not be automatically copied.                     !
80    !                                                                   !
90    !   A find command has been added to find 'lost' files on SRM.      !
100   !   To use this command, Enter the source msus as :REMOTE and       !
110   !   use "/" or the directory name of a sub-tree (to confine the     !
120   !   search).                                                        !
130   !                                            Frank Mascarich        !
140   !                                            Piscataway AEO         !
150   !                                            sept 20 1984           !
160   !                                                                   !
170   !   NOTE !                                                          !
180   !   Modify the lines below for your installation.                   !
190   !
200   Spool_dir$="/Printer"
210   Spool_dev$=":REMOTE"
220   !===================================================================!
230   !
231   !
249!   RE-STORE"/HPDRAFT/FILE_COPY:REMOTE"
250!   RE-STORE"/UTILITIES/FILE_COPY:REMOTE"
270!   RE-STORE"FILE_COPY:,701"
290   !
300   !===================================================================!
310   !
320   COM /Defaults/ Source$[80],Destin$[80],Max_files,Loaded
330   COM /Files/ Err_flag,Files$(1:2000)[80],N_files,Picked(1:2000),Mode$[10]
340   DIM File_name$[20],Dir_path$[80]
350   Max_files=2000
360   Clear_screen
370   IF NOT Loaded THEN CALL Setup
380   LOOP
390     REDIM Files$(1:Max_files)
400     Header
410     Prompt("Copy, Purge, Quit, List, Find, Showtree, Help",Ans$)
411     DISP 
420     SELECT Ans$
430     CASE "C"  !...copy command selected.
440       Clear_screen
450       Mode$="Copy"
460       Show_mode
470       Get_source
480       Get_destin
490       Select_files
500       Copy_files
510       Clear_screen
520     CASE "P" !...purge command selected.
530       Clear_screen
540       Mode$="Purge"
550       Show_mode
560       Get_source
570       Select_files
580       Purge_files
590       Clear_screen
600     CASE "Q" !...quit this program.
610       Clear_screen
620       DISP "Program ended...."
630       STOP
640     CASE "L" !...list command selected.
650       Clear_screen
660       Mode$="List"
670       Show_mode
680       Get_source
690       Ls
700       Clear_screen
710     CASE "H" !...help command selected.
720       Mode$="Help"
730       Show_help
740     CASE "F" !...find command selected.
750       Mode$="Find"
760       Show_mode
770       Get_source
780       Find_file
790       Clear_screen
800     CASE "S" !...showtree command selected.
810       Mode$="Showtree"
820       Show_mode
830       Get_source
840       Showtree(Spool_dir$,Spool_dev$)
850       Clear_screen
860     CASE ELSE  !...illegal command attempted.
870       BEEP 1000,.025
880     END SELECT
890   END LOOP
900   END
910   !
920   !
930 Get_source:SUB Get_source
940     !...get the source msus for the pending mode.
950     COM /Defaults/ Source$[80],Destin$[80],Max_files,Loaded
960     COM /Files/ Err_flag,Files$(*),N_files,Picked(*),Mode$
970     DIM Dir_path$[80],Old_msus$[80]
980     !...save current msus and restore later.
990     Old_msus$=SYSTEM$("MSI")
1000    REPEAT
1010      Err_flag=0
1020      Prompt_str("Enter source MSUS:",Source$,"SHOW")
1021      DISP 
1030      IF POS(Source$,":REMOTE") AND POS(Source$,"/")<>1 THEN 
1040        !...source on srm with no directory path given, (get it.)
1050        Prompt_str("Enter remote directory path:",Dir_path$)
1051        DISP 
1060        IF Dir_path$="/" THEN Dir_path$=""
1070        Source$=Dir_path$&Source$
1080      END IF
1090      ON ERROR CALL Trap_error
1100      !...check entered msus by trying it out.
1110      IF Err_flag=0 THEN MASS STORAGE IS Source$
1120      OFF ERROR 
1130      IF Err_flag<>0 THEN 
1140        DISP "Error in MSUS"
1150        WAIT 1.5
1160      END IF
1170    UNTIL Err_flag=0
1180    Show_source
1190    !...restore msi to old msus.
1200    IF POS(Old_msus$,":REMOTE") THEN 
1210      MASS STORAGE IS ":REMOTE"
1220    ELSE
1230      MASS STORAGE IS Old_msus$
1240    END IF
1250  SUBEND
1260  !
1270  !
1280 Get_destin:SUB Get_destin
1290    !...get the destination msus for the pending command.
1300    COM /Defaults/ Source$[80],Destin$[80],Max_files,Loaded
1310    COM /Files/ Err_flag,Files$(*),N_files,Picked(*),Mode$
1320    DIM Dir_path$[80],Old_msus$[80]
1330    !...save the current msi to restore later.
1340    Old_msus$=SYSTEM$("MSI")
1350    REPEAT
1360      Err_flag=0
1370      Prompt_str("Enter Destination MSUS:",Destin$,"SHOW")
1371      DISP 
1380      IF POS(Destin$,":REMOTE") THEN 
1390        IF POS(Destin$,"/")=0 THEN 
1400          !...if on srm and no path entered then get one.
1410          Prompt_str("Enter remote directory path:",Dir_path$)
1411          DISP 
1420          IF Dir_path$="/" THEN Dir_path$=""
1430          Destin$=Dir_path$&Destin$
1440        END IF
1450      END IF
1460      ON ERROR CALL Trap_error
1470      !...test for valid msus by trying it out.
1480      IF Err_flag=0 THEN MASS STORAGE IS Destin$
1490      OFF ERROR 
1500      IF Err_flag<>0 THEN 
1510        DISP "Error in Destination MSUS"
1520        WAIT 1.5
1530      END IF
1540    UNTIL Err_flag=0
1550    Show_destin
1560    !...restore msi to original msus.
1570    IF POS(Old_msus$,":REMOTE") THEN 
1580      MASS STORAGE IS ":REMOTE"
1590    ELSE
1600      MASS STORAGE IS Old_msus$
1610    END IF
1620  SUBEND
1630  !
1640  !
1650 Select_files:SUB Select_files
1660    !...select the files to be operated on.
1670    COM /Defaults/ Source$[80],Destin$[80],Max_files,Loaded
1680    COM /Files/ Err_flag,Files$(*),N_files,Picked(*),Mode$
1690    DIM Line$[80],Errmess$[80]
1700    !...clear out the picked and files arrays. (selected = 1)
1710    FOR I=1 TO Max_files
1720      Picked(I)=0
1730      Files$(I)=""
1740    NEXT I
1750    ON ERROR GOTO Select_error
1760    DISP "Performing catalog of source directory..."
1770    CAT Source$ TO Files$(*);COUNT N_files,NO HEADER
1780    OFF ERROR 
1790    K=0
1800    IF N_files=0 THEN 
1810      DISP "No files on source"
1820      WAIT 1.5
1830      GOTO Sub_exit
1840    END IF
1850    !...redim files array for sorting.
1860    REDIM Files$(1:N_files)
1870    !...sort the files array.
1880    MAT SORT Files$(*)
1890    !...trim the array down to include only the filename and type.
1900    FOR I=1 TO N_files
1910      Files$(I)=Files$(I)[1,36]
1920    NEXT I
1930    !...Start marks the start index of the current screen.
1940    !...Last marks the end index of the current screen.
1950    Start=1
1960    IF N_files>18 THEN 
1970      Last=18
1980    ELSE
1990      Last=N_files
2000    END IF
2010    REPEAT
2020      !...set print position to top of screen.
2030      CONTROL 1,1;1
2040      Y=1
2050      !...list the current screen.
2060      FOR I=Start TO Last
2070        IF Picked(I) THEN 
2080          Line$="   *"&Files$(I)[1;16]&Files$(I)[32;36]
2090        ELSE
2100          Line$="    "&Files$(I)[1;16]&Files$(I)[32;36]
2110        END IF
2120        PRINT TABXY(1,Y);Line$;
2130        Y=Y+1
2140      NEXT I
2150      !...print blanks over any remaining lines.
2160      Left_over=18-(Last-Start)-1
2170      FOR I=1 TO Left_over
2180        PRINT TABXY(1,Y);RPT$(" ",29);
2190        Y=Y+1
2200      NEXT I
2210      !...get the select option from the user.
2220      Prompt("All, Select, Wildcard, Nextpage, Prevpage, Done, Help",Ans$)
2230      Char$=UPC$(Ans$)
2240      SELECT Char$
2250      CASE "S"
2260        !...select only files that the user flags.
2270        Char$=""
2280        K=0
2290        GOSUB Knob
2300        ON KBD GOSUB Kbd
2310        ON KNOB .30 GOSUB Knob
2320        REPEAT
2330          IF Char$="<cr>" THEN 
2340            IF Picked(Start+Line_no)=1 THEN 
2350              !...un-pick the selected file.
2360              Picked(Start+Line_no)=0
2370              PRINT TABXY(4,Line_no+1);" ";
2380              Char$=""
2390            ELSE  !...pick the selected file.
2400              !...put a marker next to the selected file.
2410              PRINT TABXY(4,Line_no+1);"*";
2420              Picked(Start+Line_no)=1
2430              Char$=""
2440            END IF
2450          END IF
2460        UNTIL Char$="W" OR Char$="N" OR Char$="P" OR Char$="H" OR Char$="D" OR Char$="A"
2470        PRINT TABXY(1,K+1);"   "
2480        OFF KBD
2490        OFF KNOB
2500      END SELECT
2510      SELECT Char$
2520      CASE "A"
2530        J=1
2540        !...Select all files on the current screen to be copied.
2550        FOR I=Start TO Last
2560          PRINT TABXY(4,J);"*";
2570          Picked(I)=NOT Picked(I)
2580          J=J+1
2590        NEXT I
2600      CASE "W"
2610        !...select files on all screens with a wildcard match.
2620        Prompt_str("Enter the search pattern, press <ENTER> ",Item$)
2630        IF Item$<>"" THEN 
2640          Get_match_type(Item$,Search_type$)
2650          Select_them(Item$,Search_type$)
2660        END IF
2670      CASE "N"
2680        !...page foward to the next screen.
2690        IF Start+18<N_files THEN 
2700          Start=Start+18
2710          Last=Last+18
2720          IF Last>N_files THEN 
2730            Last=N_files
2740          END IF
2750        END IF
2760      CASE "P"
2770        !...page back to the previous screen.
2780        IF Start>18 THEN 
2790          Last=Start-1
2800          Start=Start-18
2810        END IF
2820      CASE "D"
2830        !...set the done flag to exit this loop.
2840        Done=1
2850      CASE "H"
2860        !...show the help screen on select options.
2870        Show_help(2)
2880      END SELECT
2890    UNTIL Done
2900    SUBEXIT
2910 Knob:!
2920    !...move the selection arrow up and down.
2930    Y=KNOBX
2940    !...erase the current arrow.
2950    PRINT TABXY(1,K+1);"   ";
2960    IF Y>0 THEN K=K-1
2970    IF Y<0 THEN K=K+1
2980    IF K<0 THEN K=O
2990    IF K>Last-Start THEN K=Last-Start
3000    !...display the new arrow.
3010    PRINT TABXY(1,K+1);"==>";
3020    RETURN 
3030 Kbd:!
3040    Char$=UPC$(KBD$)
3050    SELECT Char$
3060    CASE "<cr>"
3070      !...enter pressed, get the current arrow position.
3080      STATUS 1,1;Line_no
3090      Line_no=Line_no-1
3100    CASE "ÿ^"
3110      !...uparrow key pressed, move the arrow up.
3120      PRINT TABXY(1,K+1);"   ";
3130      IF K>0 THEN K=K-1
3140      PRINT TABXY(1,K+1);"==>";
3150    CASE "ÿV"
3160      !...downarrow key pressed, move the arrow down.
3170      PRINT TABXY(1,K+1);"   ";
3180      IF K<Last-Start THEN K=K+1
3190      PRINT TABXY(1,K+1);"==>";
3200    END SELECT
3210    RETURN 
3220 Sub_exit:   !
3230    SUBEXIT
3240 Select_error:  !
3250    OFF ERROR 
3260    Errmess$=ERRM$
3270    Errmess$=Errmess$[POS(Errmess$,"  ")]
3280    DISP "Error no.";ERRN;" accessing source: ";Errmess$
3290    BEEP 1000,.025
3300    WAIT 1.5
3310  SUBEND
3320  !
3330  !
3340 Copy_files:SUB Copy_files
3350    !...copy selected files from source to destination.
3360    COM /Defaults/ Source$[80],Destin$[80],Max_files,Loaded
3370    COM /Files/ Err_flag,Files$(*),N_files,Picked(*),Mode$
3380    DIM From_file$[80],To_file$[80],File_type$[20],Line$[80]
3390    Err_flag=0
3400    Flag=0
3410    Start=1
3420    !...look to see if any files are selected.
3430    FOR I=1 TO N_files
3440      IF Picked(I)=1 THEN Flag=1
3450    NEXT I
3460    !...if not then exit the copy routine.
3470    IF Flag=0 THEN GOTO Copy_exit
3480    Prompt("Ready to copy  (Y/N)",Ans$)
3490    IF UPC$(Ans$)<>"Y" THEN GOTO Copy_exit
3500    I=1
3510    WHILE I<=N_files
3520      Next_page=NOT ((I-1) MOD 18)
3530      !...page thru to next screen when required.
3540      IF Next_page AND N_files<>I OR I=1 THEN 
3550        Last=Start+17
3560        IF Last>N_files THEN 
3570          Last=N_files
3580        END IF
3590        CONTROL 1,1;1
3600        Y=1
3610        FOR J=Start TO Last
3620          IF Picked(J) THEN 
3630            Line$="   *"&Files$(J)[1;16]&Files$(J)[32;36]
3640          ELSE
3650            Line$="    "&Files$(J)[1;16]&Files$(J)[32;36]
3660          END IF
3670          PRINT TABXY(1,Y);Line$;
3680          Y=Y+1
3690        NEXT J
3700        Left_over=18-(Last-Start)-1
3710        FOR J=1 TO Left_over
3720          PRINT TABXY(1,Y);RPT$(" ",29);
3730          Y=Y+1
3740        NEXT J
3750        Start=Start+18
3760      END IF
3770      !...copy the picked file.
3780      IF Picked(I)=1 THEN 
3790        Screen_y=(I MOD 18)
3800        IF Screen_y=0 THEN Screen_y=18
3810        !...move the marker by the filename being operated on.
3820        PRINT TABXY(1,Screen_y);"==>";
3830        File_type$=Files$(I)[32,36]
3840        File$=TRIM$(Files$(I)[1,21])
3850        !...check for srm at destination.
3860        IF POS(Destin$,":REMOTE") THEN 
3870          !...concatenate directory path.
3880          To_file$=Destin$[1,POS(Destin$,":REMOTE")-1]
3890          IF To_file$="/" THEN To_file$=""
3900          To_file$=To_file$&"/"&File$&":REMOTE"
3910        ELSE
3920          To_file$=File$&Destin$
3930        END IF
3940        !...check for srm at source
3950        IF POS(Source$,":REMOTE") THEN 
3960          !...concatenate directory path.
3970          From_file$=Source$[1,POS(Source$,":REMOTE")-1]
3980          IF From_file$="/" THEN From_file$=""
3990          From_file$=From_file$&"/"&File$&":REMOTE"
4000        ELSE
4010          From_file$=File$&Source$
4020        END IF
4030        DISP "Copying ";From_file$;" to ";To_file$
4040        ON ERROR CALL Trap_error
4050        !...copy from source to destination.
4060        IF Err_flag=0 THEN COPY From_file$ TO To_file$
4070        OFF ERROR 
4080        IF Err_flag<>0 THEN !...handle selected errors as fit.
4090          SELECT Err_flag
4100          CASE 53    !...bad file name.
4110            Err_flag=0
4120            DISP "Error, cannot copy file name: ";File$;" continuing..."
4130            WAIT 1.5
4140          CASE 54!...Duplicate file name
4150            Err_flag=0
4160            Prompt("Purge destination file "&To_file$&" (Y/N) ",Ans$)
4170            IF UPC$(Ans$)="Y" THEN 
4180              ON ERROR CALL Trap_error
4190              DISP "Purging file ";To_file$
4200              IF Err_flag=0 THEN PURGE To_file$
4210              WAIT .25
4220              OFF ERROR 
4230              IF Err_flag=0 THEN 
4240                I=I-1
4250              ELSE
4260                Err_flag=0
4270                DISP "Cannot purge ";To_file$;" Continuing..."
4280                WAIT 1
4290              END IF
4300            END IF
4310          CASE 64!...Disc full.
4320            Err_flag=0
4330            Prompt("Disc full, insert initialized media, Press <ENTER>",Ans$)
4340            I=I-1
4350          CASE 58    !...bad file type.
4360            Err_flag=0
4370            DISP "Can't copy file type ";File_type$;" Continuing..."
4380            WAIT 2
4390          CASE 80     !...Disk changed or not in drive
4400            Err_flag=0
4410            Prompt("Disc changed or not in drive, fix and press  <ENTER>",Ans$)
4420            I=I-1
4430          CASE ELSE
4440            Err_flag=0
4450            DISP "<ENTER> to cont... Copy aborted, ";ERRM$
4460            BEEP 1000,.025
4470            WAIT 5
4480            GOTO Copy_exit
4490          END SELECT
4500        END IF
4510        PRINT TABXY(1,Screen_y);"   ";
4520      END IF
4530      I=I+1
4540      IF I=1 THEN Start=1
4550    END WHILE
4560    !...allow user to purge all copied files from the source.
4570    Ans$="N"
4580    Prompt_str("Purge selected files from source (Y/N) ",Ans$,"SHOW")
4590    IF UPC$(Ans$)="Y" THEN 
4600      Mode$="Purge"
4610      Show_mode
4620      Purge_files
4630    END IF
4640 Copy_exit:!
4650  SUBEND
4660  !
4670  !
4680 Trap_error:SUB Trap_error
4690    COM /Defaults/ Source$[80],Destin$[80],Max_files,Loaded
4700    COM /Files/ Err_flag,Files$(*),N_files,Picked(*),Mode$
4710    Err_flag=ERRN
4720    BEEP 2000,.05
4730    BEEP 1000,.05
4740  SUBEND
4750  !
4760  !
4770 Purge_files:SUB Purge_files
4780    !...purge all selected files from the source directory.
4790    COM /Defaults/ Source$[80],Destin$[80],Max_files,Loaded
4800    COM /Files/ Err_flag,Files$(*),N_files,Picked(*),Mode$
4810    DIM Purge_file$[80],File$[20],Line$[80]
4820    Flag=0
4830    Start=1
4840    !...look for any selected files.
4850    FOR I=1 TO N_files
4860      IF Picked(I)=1 THEN Flag=1
4870    NEXT I
4880    !...if there are no files selected then quit.
4890    IF Flag<>1 THEN GOTO Purge_exit
4900    !...make sure user wants to proceed.
4910    Prompt("Ready to purge ? (Y/N) ",Ans$)
4920    IF UPC$(Ans$)<>"Y" THEN GOTO Purge_exit
4930    FOR I=1 TO N_files
4940      Next_page=NOT ((I-1) MOD 18)
4950      !...page thru the catalog as required.
4960      IF (Next_page AND N_files<>I) OR I=1 THEN 
4970        Last=Start+17
4980        IF Last>N_files THEN 
4990          Last=N_files
5000        END IF
5010        !...home cursor and list the next page.
5020        CONTROL 1,1;1
5030        Y=1
5040        FOR J=Start TO Last
5050          IF Picked(J) THEN 
5060            Line$="   *"&Files$(J)[1;16]&Files$(J)[32;36]
5070          ELSE
5080            Line$="    "&Files$(J)[1;16]&Files$(J)[32;36]
5090          END IF
5100          PRINT TABXY(1,Y);Line$;
5110          Y=Y+1
5120        NEXT J
5130        Left_over=18-(Last-Start)-1
5140        FOR J=1 TO Left_over
5150          PRINT TABXY(1,Y);RPT$(" ",29);
5160          Y=Y+1
5170        NEXT J
5180        Start=Start+18
5190        WAIT .2
5200      END IF
5210      !...purge selected files.
5220      IF Picked(I)=1 THEN 
5230        Screen_y=(I MOD 18)
5240        IF Screen_y=0 THEN Screen_y=18
5250        !...mark the file currently being purged.
5260        PRINT TABXY(1,Screen_y);"==>";
5270        File_type$=Files$(I)[32,36]
5280        File$=TRIM$(Files$(I)[1,16])
5290        !...check for srm source.
5300        IF POS(Source$,":REMOTE") THEN 
5310          !...concatenate directory path.
5320          Purge_file$=Source$[1,POS(Source$,":REMOTE")-1]
5330          IF Purge_file$="/" THEN Purge_file$=""
5340          Purge_file$=Purge_file$&"/"&File$&":REMOTE"
5350        ELSE
5360          Purge_file$=File$&Source$
5370        END IF
5380        DISP "Purging file ";Purge_file$
5390        IF POS(File_type$,"DIR")=0 THEN 
5400          ON ERROR CALL Trap_error
5410          IF Err_flag=0 THEN PURGE Purge_file$
5420          OFF ERROR 
5430          IF Err_flag<>0 THEN 
5440            Err_flag=0
5450            DISP "Cannot purge ";Purge_file$;" Continuing..."
5460            WAIT 1.5
5470          END IF
5480        ELSE
5490          DISP "Cannot purge directory ";File$;",  Continuing..."
5500          WAIT 1.5
5510        END IF
5520        !...erase marker.
5530        PRINT TABXY(1,Screen_y);"   ";
5540      END IF
5550    NEXT I
5560 Purge_exit:!
5570  SUBEND
5580  !
5590  !
5600 Prompt:SUB Prompt(Mess$,Ans$)
5610    !...get a one character response from the user.
5620    !...convert all alpha to upper case.
5630    DISP Mess$
5640    ON KNOB .1 GOTO Idle_wait
5650    ON KBD GOTO Identify
5660 Idle_wait:GOTO Idle_wait
5670 Identify: !
5680    Char$=KBD$
5690    Char$=UPC$(Char$)
5700    SELECT Char$
5710    CASE "A" TO "Z","a" TO "z"
5720      Ans$=UPC$(Char$)
5730      OUTPUT 2;"ÿ#";
5740    CASE ELSE
5750      OUTPUT 2;"ÿ#";
5760      Ans$=""
5770    END SELECT
5780    OFF KBD
5790    OFF KNOB
5800  SUBEND
5810    !
5820    !
5830 Setup:SUB Setup
5840    !...set defaults for un-initialized common.
5850    COM /Defaults/ Source$[80],Destin$[80],Max_files,Loaded
5860    COM /Files/ Err_flag,Files$(*),N_files,Picked(*),Mode$
5870    PRINT CHR$(12)
5880    !...use current msi for default source.
5890    Source$=SYSTEM$("MSI")
5900    IF POS(Source$,":REMOTE") THEN 
5910      Source$=Source$[1,POS(Source$,":REMOTE")+6]
5920    ELSE
5930      Source$=Source$[1,37]
5940    END IF
5950    !...set up default destination device here.
5960    Destin$=":,700"
5970    !...set flag so that we do not return here again.
5980    Loaded=1
5990  SUBEND
6000  !
6010  !
6020 Ls:SUB Ls
6030    !...print a catalog of the current mass storage dev., sort and column
6040    !...into 5 columns of 17 rows.
6050    COM /Defaults/ Source$[80],Destin$[80],Max_files,Loaded
6060    DIM Disc$(500)[80],Errmess$[80],Ans$[20],Match$[20]
6070    Prompt_str("Substring to match ?, <ENTER> for all files ",Ans$)
6080    Match$=Ans$
6090    Clear_screen
6100    DISP "Reading directory..."
6110    ON ERROR GOTO Ls_error
6120    CAT Source$ TO Disc$(*);COUNT Nfiles,NO HEADER
6130    OFF ERROR 
6140    !...redim disc$ for sort.
6150    REDIM Disc$(Nfiles)
6160    !..sort directory list.
6170    MAT SORT Disc$(*)
6180    DISP 
6190    !...set print position to line 2.
6200    CONTROL 1,1;2
6210    !...keep count of all displayed files.
6220    Cnt=0
6230    FOR I=1 TO Nfiles
6240      IF Cnt=85 THEN !...start a new screen.
6250        Prompt("more...   hit  <ENTER> ",Ans$)
6260        Clear_screen
6270        Cnt=0
6280      END IF
6290      IF (Cnt) MOD 17=0 THEN CONTROL 1,1;2  !...start a new column.
6300      CONTROL 1,0;16*(Cnt DIV 17)+1         !...place cursor on next row.
6310      IF Match$<>"" THEN !...show only files with substring matches.
6320        IF POS(Disc$(I),Match$) THEN 
6330          PRINT Disc$(I)[1,16]
6340          Cnt=Cnt+1
6350        END IF
6360      ELSE  !...show all files.
6370        PRINT Disc$(I)[1,16]
6380        Cnt=Cnt+1
6390      END IF
6400    NEXT I
6410    !...set column print position back to 1
6420    CONTROL 1,0;1
6430    Prompt("Press <ENTER> to continue...",Ans$)
6440    SUBEXIT
6450 Ls_error:   !
6460    OFF ERROR 
6470    Errmess$=ERRM$
6480    Errmess$=Errmess$[POS(Errmess$,"  ")]
6490    DISP "Error no.";ERRN;" accessing source: ";Errmess$
6500    BEEP 1000,.025
6510    WAIT 1.5
6520  SUBEND
6530  !
6540  !
6550 Get_match_type:SUB Get_match_type(Item$,Search_type$)
6560    !...obtain the match type from the string item$, trim wildcard chars.
6570    COM /Defaults/ Source$[80],Destin$[80],Max_files,Loaded
6580    COM /Files/ Err_flag,Files$(*),N_files,Picked(*),Mode$
6590    Item$=TRIM$(Item$)
6600    !
6610    !...check for no string entered.
6620    IF Item$="" THEN 
6630      Search_type$="NONE"
6640      GOTO Typed
6650    END IF
6660    !
6670    !...look for a single "*"
6680    IF Item$="*" THEN 
6690      Item$=""
6700      Search_type$="ALL"
6710      DISP "Selecting all files... "
6720      GOTO Typed
6730    END IF
6740    !
6750    !...look for imbedded string.
6760    IF Item$[1,1]="*" AND Item$[LEN(Item$),LEN(Item$)]="*" THEN 
6770      Search_type$="SUB_STR"
6780      Length=LEN(Item$)
6790      IF Length=1 THEN 
6800        Item$=""
6810      ELSE
6820        Item$=Item$[2,Length-1]
6830      END IF
6840      DISP "Selecting files with substring ";Item$;" ..."
6850      GOTO Typed
6860    END IF
6870    !
6880    !...look for trailing string match.
6890    IF Item$[1,1]="*" AND Item$[LEN(Item$),LEN(Item$)]<>"*" THEN 
6900      Search_type$="END_STR"
6910      Length=LEN(Item$)
6920      Item$=Item$[2,Length]
6930      DISP "Selecting files with substring ";Item$;" ..."
6940      GOTO Typed
6950    END IF
6960    !
6970    !...look for leading string match.
6980    IF Item$[1,1]<>"*" AND Item$[LEN(Item$),LEN(Item$)]="*" THEN 
6990      Search_type$="BEG_STR"
7000      Length=LEN(Item$)
7010      Item$=Item$[1,Length-1]
7020      DISP "Selecting files with substring ";Item$;" ..."
7030      GOTO Typed
7040    END IF
7050    !
7060    !...look for exact match (no wildcard).
7070    IF Item$[1,1]<>"*" AND Item$[LEN(Item$),LEN(Item$)]<>"*" THEN 
7080      Search_type$="MATCH"
7090      DISP "Selecting file ";Item$;" ..."
7100      GOTO Typed
7110    END IF
7120    !
7130 Typed:!
7140    WAIT 1
7150  SUBEND
7160  !
7170  !
7180 Select_them:SUB Select_them(Item$,Search_type$)
7190    !...set the picked flag on all files that match according to
7200    !...search type.
7210    COM /Defaults/ Source$[80],Destin$[80],Max_files,Loaded
7220    COM /Files/ Err_flag,Files$(*),N_files,Picked(*),Mode$
7230    N=0
7240    FOR I=1 TO N_files
7250      File$=TRIM$(Files$(I)[1,16])
7260      SELECT Search_type$
7270      CASE "SUB_STR"
7280        IF POS(File$,Item$) THEN 
7290          Picked(I)=1
7300          N=N+1
7310        END IF
7320      CASE "END_STR"
7330        Char_pos=LEN(File$)-LEN(Item$)+1
7340        IF Char_pos>0 THEN 
7350          IF POS(File$,Item$)=Char_pos THEN 
7360            Picked(I)=1
7370            N=N+1
7380          END IF
7390        END IF
7400      CASE "BEG_STR"
7410        IF POS(File$,Item$)=1 THEN 
7420          Picked(I)=1
7430          N=N+1
7440        END IF
7450      CASE "MATCH"
7460        IF File$=Item$ THEN 
7470          Picked(I)=1
7480          N=N+1
7490        END IF
7500      CASE "ALL"
7510        Picked(I)=1
7520        N=N+1
7530      END SELECT
7540    NEXT I
7550    IF N=1 THEN 
7560      DISP N;" File selected"
7570      WAIT 1
7580    ELSE
7590      DISP N;" Files selected"
7600      WAIT 1
7610    END IF
7620  SUBEND
7630  !
7640  !
7650 Show_help:SUB Show_help(OPTIONAL Page)
7660    !...show the help screen and return to current mode.
7670    !...optional parameter is for select options screen only.
7680    COM /Defaults/ Source$[80],Destin$[80],Max_files,Loaded
7690    COM /Files/ Err_flag,Files$(*),N_files,Picked(*),Mode$
7700    IF NPAR THEN GOTO Page_two
7710    !...Clear the screen.
7720    GOSUB Next_page
7730    PRINT "      Select a mode by typing ONLY the first character of the   "
7740    PRINT "         desired operation.  Modes are as follows:              "
7750    PRINT 
7760    PRINT "      Copy, Purge, Quit, List, Find, Showtree, Help             "
7770    PRINT 
7780    PRINT "       - (C)opy will request the source and destination devices."
7790    PRINT "            Enter the MSUS for each when prompted. If on SRM,   "
7800    PRINT "            enter :REMOTE and be prompted for the directory     "
7810    PRINT "            path (or enter the full MSUS at the Source?  prompt)"
7820    PRINT "            EXAMPLES:"
7830    PRINT "                :,700                                           "
7840    PRINT "                /USERS/BOB:REMOTE                               "
7850    PRINT "                /:REMOTE                                        "
7860    PRINT "            After entering the source and destination devices,  "
7870    PRINT "            the system will catalog the source device and allow "
7880    PRINT "            you to select individual files or all files on that "
7890    PRINT "            device.  See the HELP screen in the select menu for "
7900    PRINT "            details on select options.                          "
7910    Prompt("More... press <ENTER>",Ans$)
7920    GOSUB Next_page
7930    PRINT "       - (P)urge will request the source device for files to be "
7940    PRINT "            purged.  Enter a source device as for the Copy      "
7950    PRINT "            command.  After entering a source, files may be     "
7960    PRINT "            individually selected by wildcard, Knob, etc.       "
7970    PRINT "            See HELP screen in the select menu for details.     "
7980    PRINT "                                                                "
7990    PRINT "       - (Q)uit terminates the File copy program."
8000    PRINT "                                                                "
8010    PRINT "       - (L)ist displays files 85 at a time, columned on the    "
8020    PRINT "            display alphabetically.  You will be prompted       "
8030    PRINT "            for a source device as in the copy and purge        "
8040    PRINT "            commands.  Next you will be prompted for a mask.    "
8050    PRINT "            Enter a character string to be matched in the       "
8060    PRINT "            catalog.  Ex: BDAT, PROG, ASCII, Myfile, etc.       "
8070    PRINT "            Only the filenames and types that contain the mask  "
8080    PRINT "            will be displayed.  To see all files press <ENTER>  "
8090    PRINT ""
8100    PRINT "       - (H)elp provides this valuable help screen.";
8110    Prompt("more...  press <ENTER>",Ans$)
8120    GOSUB Next_page
8130    DISP 
8140    PRINT "       - (F)ind (SRM only) will search the indicated directory  "
8150    PRINT "            tree for the specified file.  All files beginning   "
8160    PRINT "            with the entered string will be listed along with   "
8170    PRINT "            their full directory path.  You will be prompted    "
8180    PRINT "            for a source directory.  Enter /:REMOTE to search   "
8190    PRINT "            the entire SRM or enter  /pathname:REMOTE to limit  "
8200    PRINT "            the search to a sub-tree.                           "
8210    PRINT "                                                                "
8220    PRINT "       - (S)howtree (SRM only) will print a recursive listing   "
8230    PRINT "            of all files within a given directory tree along    "
8240    PRINT "            with full directory paths.  Enter a source as for   "
8250    PRINT "            the Find command.  Output may be directed to a      "
8260    PRINT "            local printer, the CRT, or to a spooled printer."
8270    PRINT "            The listing will be followed by the size of the     "
8280    PRINT "            sub-tree in bytes.                                  "
8290    Prompt("Press <ENTER> to continue",Ans$)
8300    GOSUB Next_page
8310    SUBEXIT
8320 Page_two:  !
8330    GOSUB Next_page
8340    PRINT 
8350    PRINT "      Select Options: (All, Select, Wildcard, Next, Last, Done)"
8360    PRINT 
8370    PRINT "      - (A)ll will select all files displayed ON THE CURRENT "
8380    PRINT "         SCREEN ONLY.  To de-select files press <A> again."
8390    PRINT 
8400    PRINT "      - (S)elect will allow individual selection of files.  Use"
8410    PRINT "           the knob or arrow keys to move the pointer to the   "
8420    PRINT "           filename to be selected.  Press <ENTER> to select or"
8430    PRINT "           de-select files."
8440    PRINT 
8450    PRINT "      - (W)ildcard will prompt for a mask, '*' is the wildcard."
8460    PRINT "        This option will select files globally, NOT ONLY those"
8470    PRINT "        currently displayed. Examples:  "
8480    PRINT "          *string*   will select substring 'string'"
8490    PRINT "          *string    will select all files ending in 'string'"
8500    PRINT "           string*   will select all files beginning in 'string'"
8510    PRINT "          *          will select all files."
8520    Prompt("More...Press <ENTER>",Ans$)
8530    GOSUB Next_page
8540    PRINT 
8550    PRINT "      - (N)extpage will advance the display to the next page."
8560    PRINT 
8570    PRINT "      - (P)revpage will return the display to the previous page."
8580    PRINT 
8590    PRINT "      - (D)one will terminate the selection process and begin "
8600    PRINT "          the purge or copy operation."
8610    Prompt("Press <ENTER> to continue",Ans$)
8620    GOSUB Next_page
8630    SELECT Mode$
8640    CASE "Copy"
8650      Show_mode
8660      Show_source
8670      Show_destin
8680    CASE "Purge"
8690      Show_mode
8700      Show_source
8710    END SELECT
8720    SUBEXIT
8730 Next_page:  !
8740    Clear_screen
8750    CONTROL 1,1;1
8760    RETURN 
8770  SUBEND
8780  !
8790  !
8800 Header:SUB Header
8810    PRINT TABXY(27,7);"    File Copy Utility"
8820    PRINT TABXY(27,9);"           for"
8830    PRINT TABXY(27,11);"       Series 200"
8840  SUBEND
8850  !
8860  !
8870 Where_is:SUB Where_is(String$,Dir_path$)
8880    !...find any filename starting with the passed string on
8890    !...the passed directory path.
8900    DIM Disc$(1:250)[80],Path$[80]
8910    Path$=Dir_path$
8920    IF Path$="/" THEN Path$=""
8930    CAT Path$&":REMOTE" TO Disc$(*);COUNT N_files,NO HEADER
8940    I=1
8950    WHILE I<=N_files
8960      IF POS(Disc$(I)[32,36],"DIR") THEN 
8970        !...step into a directory and call where_is recursively.
8980        Old_length=LEN(Path$)
8990        Path$=Path$&"/"&TRIM$(Disc$(I)[1,21])
9000        CALL Where_is(String$,Path$)
9010        Path$=Path$[1,Old_length]
9020      ELSE
9030        !...test a non-directory entry for match and list it.
9040        IF POS(Disc$(I)[1,21],String$)=1 THEN 
9050          GOSUB Print_entry
9060        END IF
9070      END IF
9080      I=I+1
9090    END WHILE
9100    SUBEXIT
9110 Print_entry:!
9120    Records=VAL(Disc$(I)[39,45])
9130    Rec_len=VAL(Disc$(I)[47,54])
9140    Bytes=Records*Rec_len
9150    PRINT USING Out_image;Disc$(I)[56,64]&" ";Bytes;Disc$(I)[32,36];Path$&"/"&Disc$(I)[1,21]
9160 Out_image:IMAGE 10A,8D,2X,6A,54A
9170    RETURN 
9180  SUBEND
9190  !
9200  !
9210 Prompt_str:SUB Prompt_str(String$,Ans$,OPTIONAL Show$)
9220    !...prompt the user for a string value. output the current
9230    !...value of ans$ as default if optional parameter is set.
9240    !...if not set then clear current value of ans$ get a new one.
9250    DISP String$
9260    IF NPAR=3 THEN 
9270      OUTPUT 2;Ans$;
9280    ELSE
9290      Ans$=""
9300    END IF
9310    !...turn off the softkeys during the prompt.
9320    CONTROL 1,12;1
9330    ENTER 2;Ans$
9340    !...turn the softkeys back on.
9350    CONTROL 1,12;0
9360  SUBEND
9370  !
9380  !
9390 Lsr:SUB Lsr(Dir_path$,Total_bytes,Line_no,Dev$)
9400    !...search recursively thru the passed directory path and
9410    !...print all entries on the indicated device.  Keep track
9420    !...of the total disc usage.
9430    DIM Disc$(1:250)[80],Path$[100],Type$[5]
9440    IF POS(Dir_path$,":REMOTE") THEN 
9450      Path$=Dir_path$[1,POS(Dir_path$,":REMOTE")-1]
9460    ELSE
9470      Path$=Dir_path$
9480    END IF
9490    IF Path$="/" THEN Path$=""
9500    CAT Path$&":REMOTE" TO Disc$(*);COUNT N_files,NO HEADER
9510    I=1
9520    WHILE I<=N_files
9530      IF NOT POS(Disc$(I)[32,36],"DIR") THEN 
9540        !...list a non directory entry.
9550        Type$="OTHER"
9560        GOSUB Print_entry
9570      END IF
9580      I=I+1
9590    END WHILE
9600    I=1
9610    WHILE I<=N_files
9620      IF POS(Disc$(I)[32,36],"DIR") THEN 
9630        !...list directory entry and step in.
9640        Type$="DIR"
9650        Old_length=LEN(Path$)
9660        Path$=Path$&"/"&TRIM$(Disc$(I)[1,21])
9670        GOSUB Print_entry
9680        CALL Lsr(Path$,Total_bytes,Line_no,Dev$)
9690        Path$=Path$[1,Old_length]
9700      END IF
9710      I=I+1
9720    END WHILE
9730    SUBEXIT
9740 Print_entry:!
9750    !...if listing on crt then show one screen at a time.
9760    IF ((Line_no) MOD 17)=0 AND Dev$="CRT" AND Line_no<>0 THEN 
9770      Prompt("More...  press <ENTER>",Ans$)
9780      Clear_screen
9790    END IF
9800    Line_no=Line_no+1
9810    Records=VAL(Disc$(I)[39,45])
9820    Rec_len=VAL(Disc$(I)[47,54])
9830    Bytes=Records*Rec_len
9840    Total_bytes=Total_bytes+Bytes
9850    SELECT Type$
9860    CASE "OTHER"
9870      PRINT USING Out_image;Disc$(I)[56,64]&" ";Bytes;Disc$(I)[32,36];Path$&"/"&Disc$(I)[1,21]
9880    CASE "DIR"
9890      PRINT USING Out_image;Disc$(I)[56,64]&" ";Bytes;Disc$(I)[32,36];Path$&"/"
9900    END SELECT
9910 Out_image:IMAGE 10A,8D,2X,6A,54A
9920    RETURN 
9930  SUBEND
9940  !
9950  !
9960 Clear_screen:SUB Clear_screen
9970    !...clear the crt.
9980    OUTPUT 2;"<lf>";
9990  SUBEND
10000 !
10010 !
10020 Show_mode:SUB Show_mode
10030   !...display the current mode on the crt.
10040   COM /Files/ Err_flag,Files$(*),N_files,Picked(*),Mode$
10050   Clear_screen
10060   PRINT TABXY(30,16);"Mode: ";Mode$&RPT$(" ",20)
10070 SUBEND
10080 !
10090 !
10100 Find_file:SUB Find_file
10110   !...calling routine for where_is.
10120   COM /Files/ Err_flag,Files$(*),N_files,Picked(*),Mode$
10130   COM /Defaults/ Source$[80],Destin$[80],Max_files,Loaded
10140   DIM File_name$[80],Dir_path$[80]
10150   IF POS(Source$,":REMOTE") THEN 
10160     Dir_path$=Source$[1,POS(Source$,":REMOTE")-1]
10170     IF Dir_path$="/" THEN Dir_path$=""
10180     Prompt_str("Filename to find ?",File_name$)
10181     File_name$=TRIM$(File_name$)
10190     IF File_name$<>"" THEN 
10200       DISP "Searching for ";File_name$;" ..."
10210       PRINT TABXY(1,1)
10220       Where_is(File_name$,Dir_path$)
10230       Prompt("search complete, press <ENTER> to continue",Ans$)
10240     END IF
10250   ELSE
10260     DISP "ERROR:  'Find'  command used only on SRM"
10270     BEEP 1000,.025
10280     WAIT 2
10290   END IF
10300 SUBEND
10310 !
10320 !
10330 Showtree:SUB Showtree(Spool_dir$,Spool_dev$)
10340   !...calling routine for lsr.
10350   COM /Files/ Err_flag,Files$(*),N_files,Picked(*),Mode$
10360   COM /Defaults/ Source$[80],Destin$[80],Max_files,Loaded
10370   DIM File_name$[80],Dir_path$[80]
10380   IF NOT POS(Source$,":REMOTE") THEN 
10390     DISP "Error: Showtree for SRM only"
10400     BEEP 1000,.025
10410     WAIT 1.5
10420     Clear_screen
10430   ELSE
10440     Prompt("List to Local printer, Srm, or Crt ? (L/S/C)",Ans$)
10450     Error=0
10460     Line_no=0
10470     Dev$=""
10480     SELECT Ans$
10490     CASE "C"
10500       Dev$="CRT"
10510       PRINTER IS 1
10520     CASE "L"
10530       PRINTER IS 701
10540     CASE "S"
10550       Create_spool(Spool_dir$,Spool_dev$,Error)
10560       IF Error<>0 THEN GOTO Exit_showtree
10570     CASE ELSE
10580       GOTO Exit_showtree
10590     END SELECT
10600     Clear_screen
10610     DISP "Printing directory list of ";Source$;" ..."
10620     Total_bytes=0.
10630     CALL Lsr(Source$,Total_bytes,Line_no,Dev$)
10633     IF (Line_no MOD 17)>15 OR (Line_no MOD 17)=0 THEN 
10634       Prompt("More...  press <ENTER>",Ans$)
10635       Clear_screen
10637     END IF
10640     PRINT 
10650     PRINT USING Disc_use;"Total disc usage = ";Total_bytes;" Bytes"
10660     PRINTER IS 1
10670     Prompt("Output complete...  press <ENTER> to continue",Ans$)
10680   END IF
10690 Exit_showtree: !
10700 Disc_use:IMAGE 19A,10D,6A
10710 SUBEND
10720 !
10730 !
10740 Create_spool:SUB Create_spool(Spool_dir$,Spool_dev$,Error)
10750   !...create a spool file on the spool device.
10760   !...name the file DIRECT_LISTn, where n is the number of
10770   !...re-tries needed to create the file.
10780   DIM File_name$[20]
10790   Error=0
10800   I=1
10810 Create_file:!
10820   File_name$="/DIRECT_LIST"&VAL$(I)
10830   ON ERROR GOTO Increment
10840   CREATE BDAT Spool_dir$&File_name$&Spool_dev$,100
10850   PRINTER IS Spool_dir$&File_name$&Spool_dev$
10860   OFF ERROR 
10870   SUBEXIT
10880 Increment:!
10890   OFF ERROR 
10900   IF I<=10 THEN 
10910     I=I+1
10920     GOTO Create_file
10930   ELSE
10940     Error=1
10950     DISP "Error assigning spool file, check directory ";Spool_dir$
10960     BEEP 1000,.025
10970     WAIT 1.5
10980   END IF
10990 SUBEND
11000 !
11010 !
11020 Show_source:SUB Show_source
11030   !...show the current source on the crt.
11040   COM /Defaults/ Source$[80],Destin$[80],Max_files,Loaded
11050   PRINT TABXY(30,17);"Srce: ";Source$&RPT$(" ",38-MIN(LEN(Source$),38))
11060 SUBEND
11070 !
11080 !
11090 Show_destin:SUB Show_destin
11100   !...show the current destination on the crt.
11110   COM /Defaults/ Source$[80],Destin$[80],Max_files,Loaded
11120   PRINT TABXY(30,18);"Dest: ";Destin$&RPT$(" ",MAX(MIN(37-LEN(Destin$),37),0))
11130 SUBEND