home *** CD-ROM | disk | FTP | other *** search
- /* copy - conditional file copy program (with query)
- Must be linked with 'PLIDIO.REL'.
- syntax: COPY <destination> <source>
- destination may be drive name only (source drive ~= destination)
- source may be a wild card specification */
-
-
- copy: procedure options(main);
- %replace
- TRUE by '1'b,
- FALSE by '0'b,
- VERSION by 'COPY 1.0',
- VERDATE by '02/05/81',
- HELP_CMD by 'HELP ',
- EOF by '^Z',
- INTRRPT by '^C',
- BUFWDS by 64, /* words per buffer */
- LISTDIM by 20, /* files per copy list allocation */
- LISTBLKS by 5, /* number of allocations */
- LISTLNGTH by 100, /* LISTDIM * LISTBLKS */
- ALLOCWDS by 112, /* ((LISTDIM * 11) + 5) / 2 */
- ALLOCBYTES by 224; /* ALLOCWDS * 2 */
-
- %include 'diomod.dcl';
-
- dcl
- version_date char(8) external static init(VERDATE);
-
-
- declare
- 1 default1 based(dfcb0()),
- 3 space fixed(7),
- 3 command char(8);
-
-
- dcl
- 1 dest based(dfcb0()),
- %include 'fcb.dcl';
-
- dcl
- 1 source based(dfcb1()),
- %include 'fcb.dcl';
-
-
- dcl
- 1 sourcefile,
- %include 'fcb.dcl';
-
-
- dcl
- 1 renfile,
- %include 'fcb.dcl';
-
-
- declare
- fcbp pointer,
- 1 dir_fcb based(fcbp),
- %include 'fcb.dcl';
-
-
- declare
- 1 copy_fcb(LISTDIM) based,
- 3 fname char(8),
- 3 ftype char(3);
-
-
- declare
- save_drive bin fixed(7),
- maxwords bin fixed(15),
- nbuffs bin fixed(15),
- bufptr pointer,
- cptr(LISTBLKS) pointer,
- dir_mask(0:127) bit(8) based(dbuff()),
- (i,j,n) bin fixed(15) static init(0),
- msg char(47) varying static init(
- '^I^Isyntax: COPY <destination file> <source file>');
-
- on error(70) begin;
- put list('No Source File',msg);
- call reboot();
- end;
-
-
- on error(7) begin;
- n = n - 1;
- put skip list('List Space Exhausted');
- call copy_list;
- put skip list('Rebooting');
- call reboot();
- end;
-
- put list(VERSION);
- put skip;
- if command = HELP_CMD then do;
- put skip list('COPY - Copy with Query');
- put skip(2) list('Command line');
- put skip list(msg);
- put skip list('where:');
- put edit('<destination> is an unambiguous filename or drive',
- '<source> is unambiguous unless destination is a different drive')
- (skip(2),a);
- put skip(2);
- call reboot();
- end;
-
- redo: maxwords = memwds();
- bufptr = memptr();
- call get_nbuffs;
-
- /* get actual drives */
- if source.drive = 0 then
- source.drive = curdsk() + 1;
- if dest.drive = 0 then
- dest.drive = curdsk() + 1;
-
- /* test for wild card in destination */
- if wildcard(dfcb0()) then do;
- put skip list('Invalid destination');
- call reboot();
- end;
-
- /* process copy command */
- if dest.drive = source.drive & dest ~= source
- & ~wildcard(dfcb1()) then do;
- sourcefile = source;
- call diocopy;
- end;
- else if dest.drive ~= source.drive then
- if wildcard(dfcb1()) then do;
- save_drive = source.drive;
- call setdma(dbuff());
- call alloc;
- i = sear(dfcb1());
- if i > -1 then do;
- do while(i > -1);
- unspec(i) = unspec(i) & '00000011'b; /* for CP/M 1.4 */
- fcbp = addr(dir_mask(i * 32));
- if dir_fcb.drive = user() then do;
- if query() then
- call add_to_list;
- end;
- i = searn();
- end;
- call copy_list;
- end;
- else
- signal error(70);
- end;
- else do;
- sourcefile = source;
- if dest.fname = '' & dest.ftype = '' then do;
- save_drive = dest.drive;
- dest = sourcefile;
- dest.drive = save_drive;
- end;
- call diocopy;
- end;
- else
- put list('Invalid Format',msg);
- call reboot();
-
- /* user - procedure to get user number if version > = cp/m 2.0 */
- user: procedure returns(fixed(7));
-
- if vers() = '0000'b4 then
- return(0);
- else
- return(getusr());
- end user;
-
- /* wildcard - returns true if fcb based at ptr has question marks */
- wildcard: procedure(p) returns(bit(1));
- declare
- p pointer,
- 1 wild_fcb based(p),
- 3 drive bin fixed(7),
- 3 name char(12);
-
- if index(wild_fcb.name,'?') > 0 then
- return(TRUE);
- else
- return(FALSE);
- end wildcard;
-
- /* add_to_list - add fcb to copy list */
- add_to_list: procedure;
-
- j = j + 1;
- if j > LISTDIM then do;
- call alloc;
- j = 1;
- end;
- call get_nbuffs;
- cptr(n)->copy_fcb(j).fname = dir_fcb.fname;
- cptr(n)->copy_fcb(j).ftype = dir_fcb.ftype;
- end add_to_list;
-
- /* alloc - allocate another block of copy list */
- alloc: procedure;
- declare
- fixed15 fixed based;
-
- n = n + 1;
- if n > LISTBLKS then
- signal error(7);
- maxwords = maxwords - ALLOCWDS;
- addr(bufptr)->fixed15 = addr(bufptr)->fixed15 + ALLOCBYTES;
- allocate copy_fcb set(cptr(n));
- end alloc;
-
-
- /* copy_list - copy files in copy list */
- copy_list: procedure;
- declare
- k fixed,
- l fixed(7);
-
- call get_nbuffs;
- put skip list('Copying: ');
- k = 0;
- do i = 1 to n;
- do l = 1 to LISTDIM while( i < n | l <= j);
- sourcefile.drive = save_drive;
- sourcefile.fname = cptr(i)->copy_fcb(l).fname;
- sourcefile.ftype = cptr(i)->copy_fcb(l).ftype;
- dest.fname = cptr(i)->copy_fcb(l).fname;
- dest.ftype = cptr(i)->copy_fcb(l).ftype;
- call diocopy;
- put list('.');
- k = k + 1;
- end;
- end;
- put skip list(k,'file(s) copied to',ascii(64+dest.drive)||':');
- end copy_list;
-
-
- /* query - query and delete if response is 'y'es */
- query: procedure returns(bit(1));
- declare
- c char(1);
-
- put skip list(ascii(64+source.drive)||':',
- dir_fcb.fname||'.'||dir_fcb.ftype,'?');
- c = rdcon();
- if c = INTRRPT then
- call reboot();
- else if c = EOF then do;
- call copy_list;
- call reboot();
- end;
- else if translate(c,'Y','y') = 'Y' then
- return(TRUE);
- else
- return(FALSE);
- end query;
-
- /* get_nbuffs - calculate number of buffers available for copy */
- get_nbuffs: procedure;
-
- nbuffs = divide(maxwords,BUFWDS,15);
- if nbuffs = 0 then
- do;
- put skip list('No Buffer Space - Rebooting');
- call reboot();
- end;
-
- end get_nbuffs;
-
-
- /* diocopy - direct io copy from source to dest */
- diocopy: procedure;
- declare
- /* buffer management */
- eofile bit(8),
- i fixed(15),
- m fixed(15),
- memory (0:0) bit(16) based(bufptr),
- buffs fixed(15);
-
-
- /* copy fcb to rename file, count extents */
- renfile = dest;
-
- /* destination file will be deleted later */
- dest.ftype = '$$$';
-
- /* delete any existing x.$$$ file */
- call delete(addr(dest));
- sourcefile.fext = 0;
-
- /* open the source file, if possible */
- if open(addr(sourcefile)) = -1 then
- signal error(70);
-
- /* source file opened, create $$$ file */
- dest.fext = 0;
- dest.crec = 0;
- if make(addr(dest)) = -1 then
- do;
- put skip list('No Directory Space on',
- ascii(64+dest.drive)||':');
- call reboot();
- end;
-
- /* $$$ temp file created, now copy from source */
- eofile = FALSE;
- buffs = nbuffs;
- sourcefile.crec = 0;
- do while (^eofile);
- m = 0;
- /* fill buffers */
- do i = 0 repeat (i+1) while (i<buffs);
- call abort_test;
- call setdma(addr(memory(m)));
- m = m + BUFWDS;
- if rdseq(addr(sourcefile)) ^= 0 then
- do;
- eofile = TRUE;
- /* truncate buffer */
- buffs = i;
- end;
- end;
-
- m = 0;
- /* write buffers */
- do i = 0 to buffs-1;
- call abort_test;
- call setdma(addr(memory(m)));
- m = m + BUFWDS;
- if wrseq(addr(dest)) ^= 0 then
- do;
- put skip list(ascii(64+dest.drive)||
- ': Disk Full');
- call reboot();
- end;
- end;
- end;
-
- /* close destination file and rename */
- dest.space(1) = sourcefile.space(1);
-
- if close(addr(dest)) = -1 then
- call reboot();
-
- /* destination file closed, erase old file */
- call delete(addr(renfile));
-
- /* now rename $$$ file to old file name */
- dest.name2 = renfile.name1;
- call rename(addr(dest));
- end diocopy;
-
- /* abort_test - abort if console character */
- abort_test: procedure;
- dcl c char(1);
-
- if break() then do;
- c = rdcon();
- put skip list('Abort (Y/N)? ');
- c = rdcon();
- if c = 'Y' | c ='y' then do;
- put skip list('Copy Aborted');
- call reboot();
- end;
- end;
- end abort_test;
-
- end copy;
-