home *** CD-ROM | disk | FTP | other *** search
- /*
- BACKUP is by Steve de Plater
-
- 66 Priam St.
- Chester Hill, NSW, 2162, Australia
- Phone: (02) 644 4009
-
- VERSION LIST - Most recent version first.
-
- 04/Jul/82 Added "usage" display when a "?" is entered
- on command line or in response to drive prompt.
- Bill Bolton, Software Tools
-
-
- You may make as many copies of this programme in either
- source or .COM forms as you like for your own use, or for
- your friends, relatives, dogs, cats, mothers-in-law etc.
- HOWEVER if I ever hear of anyone commercially marketing
- this I'll come and find them and insert their heads
- into an S-100 slot!!!
-
- All I ask is that because I did the original work that
- you leave my name where it is in the programme. After
- all, nobody else should get the blame for my shoddy
- programming!
-
- The function of BACKUP is to copy files from one disk to
- another much as PIP does. The difference is that BACKUP
- normally will not make a copy when a filename is found on
- the destination disk. Therefore, if this programme is used
- then you can be sure that NO files will accidently be
- clobbered!
-
- BACKUP also allows the following features:
- (i) many filename masks may be included together.
- They must be separated only by commas, NO SPACES!
- e.g. "*.com,backup.c"
- (ii) The NOT wildcard is supported when used as the first
- character of a filename mask.
- e.g. "!*.com" would match ALL the non .COM files.
- (iii) both source and destination disks may be changed
- many times during a run, as prompted by BACKUP.
- (iv) If required, existing files may be renamed as .BAK
- and then the copy will proceed.
- (v) If required, then ONLY existing files will be copied
- e.g. for installing an updated copy of a compiler etc.
- (vi) If required, the copy will be stopped at the first ^Z
- detected.
- (vii) If required, the VERIFY programme will be called
- automatically, and the BACKUP parameters will be
- passed to it.
-
- CALLING PROCEDURE:
-
- BACKUP may be called simply by typing BACKUP<cr>;
- however, the following parameters may be included on the
- CP/M command line:
- (i) mask(s) This must be the first parameter and will
- control which files are copied.
-
- ALL THE PARAMETERS WHICH FOLLOW MAY OCCUR IN ANY ORDER AT ALL
- WITH OR WITHOUT SPACES BETWEEN THEM.
-
- (ii) <d copy FROM drive 'd'
- (iii) >d copy TO drive 'd'
- (iv) n Don't prompt for disk changes
- (v) b If file exists rename to .BAK and then copy
- (vi) v Run VERIFY after BACKUP is finished
- (vii) z Copy only to the first CP/M EOF (^Z).
- (viii) i Inverse mode. Copy ONLY files which exist on
- both source and destination disks.
- (ix) d Debug mode. Show where everything is in RAM
- BACKUP configures itself to make the most of
- your system.
- (x) r Remember which files have been backed up so
- that subsequent runs will not repeat.
- (Implies also the Check mode below.)
- (xi) c Check (only) for previous backups
- (xii) p Print out parameter settings
-
- \*******************************************************/
-
- #include bdscio.h
-
- #define VERSION "1.3"
- #define STACKSPACE 0x1000
- #define DATE "July 5th, 1982"
- #define TIME "14:00"
-
- #define V_DEFAULT FALSE /* these default values */
- #define Z_DEFAULT FALSE /* should be changed to */
- #define N_DEFAULT FALSE /* configure any special*/
- #define B_DEFAULT FALSE /* BACKUP for any */
- #define M_DEFAULT FALSE /* particular application*/
- #define D_DEFAULT FALSE
- #define R_DEFAULT FALSE
- #define C_DEFAULT FALSE
- #define P_DEFAULT TRUE
-
- char mask [50]; /* Buffer for filename masks */
- char pass_mask [50]; /* The masks passed to VERIFY*/
- char work_mask [16];
- char fcb1 [36];
- char fn [14];
- int code;
- int files;
- int copies;
- char *dir; /* Where to find DIR */
- char *databuf; /* Where to buffer stuff */
- unsigned stackspace;
- int sectors; /* sectors to buffer */
- char id;
- char od;
- char ld;
- char fn1 [16];
- char fn2 [16];
- char fn3 [16];
- char fn4 [16];
- char temp [20];
- char verify;
- char ctr_z;
- int found_eof;
- int no_wait;
- int debug;
- int bak;
- int mode;
- int remember;
- int check;
- int parm;
- int no_bak;
- int read_only;
- int system;
- int bak_flag;
- int not_mask;
- char mask2 [36];
- int masks;
- int matched;
- int total_matched;
- int total_copied;
- int no_questions;
-
-
- main (argc,argv)
- char **argv;
-
- {
- int x;
- int p,z;
- char *y;
-
-
- y = 0x501; *y = 0x20; /* modifies fn
- 'legfc' in RTP */
- stackspace = STACKSPACE; /* configure */
- dir = endext (); /* the RAM */
-
- printf ("\nBACKUP, Ver %s, ",VERSION);
- printf ("%s, by Steve de Plater\n\n",DATE);
-
- verify = V_DEFAULT;
- ctr_z = Z_DEFAULT;
- no_wait = N_DEFAULT;
- bak = B_DEFAULT;
- mode = M_DEFAULT;
- debug = D_DEFAULT;
- remember = R_DEFAULT;
- check = C_DEFAULT;
- parm = P_DEFAULT;
-
- getclp (argc,argv,&id,&od,
- &verify,&ctr_z,&no_wait,&bak,&mode,&debug,
- &remember,&check,&parm);
-
- if (remember)
- check = TRUE;
-
- if (parm){
- printf ("Parameter flag settings for this run are:\n");
- printflg ("(i) Run Verify :",verify);
- printflg ("(ii) Stop on ^Z :",ctr_z);
- printflg ("(iii) No-Waiting :",no_wait);
- printflg ("(iv) Backup file :",bak);
- printflg ("(v) Inverse mode :",mode);
- printflg ("(vi) Debug mode :",debug);
- printflg ("(vii) Remember :",remember);
- printflg ("(viii) Check prev. :",check);
- putch ('\n');
- }
-
- if (argc < 2)
- getmask ();
- else
- strcpy (mask,argv[1]);
- strcpy (pass_mask,mask);
-
- ld=bdos(25) + 'A';
-
- matched = copies = total_matched = total_copied = 0;
- no_questions = TRUE;
- do_it ();
-
- }
-
- getmask ()
-
- {
- int x;
-
- printf ("Which files? ");
- gets (mask);
- for (x=0; *(mask+x); x++)
- *(mask+x) = toupper (*(mask+x));
- no_questions = FALSE;
- }
-
- getdir (fcb)
- char *fcb;
-
- {
- int x,y,z;
- char *s;
-
- y=files<<4;
- s=0x80+(code<<5);
- if (*(s+12))
- return;
- files++;
- for (x=0; x<16; x++){
- dir[y]=*(s+x);
- y++;
- }
- }
-
- match_mask (s)
- char *s;
-
- {
- int x,y;
-
- y=TRUE;
- for (x=1; x<12; x++){
- if (((*(s+x)&0x7f) != mask2[x]) &&
- (mask2[x] != '?' )){
- y=FALSE;
- }
- }
- if (not_mask)
- return !y;
- else
- return y;
- }
-
- does_exist (s)
- char *s;
-
- {
- char fcb [36];
-
- setfcb (fcb,s);
- if (bdos (17,fcb) > 3)
- return FALSE;
- else
- return TRUE;
- }
-
- copy (s1,s2)
- char *s1,*s2;
-
- {
- int fd1,fd2;
- int x,y,z;
- int records;
-
- records=0;
- if ((fd1=open (s1,0)) == ERROR){
- printf (" OPEN ERROR: Can't open '%s\n",s1);
- quit (1);
- }
-
- if ((fd2=creat (s2)) == ERROR){
- change_disks (s2,fd1,fd2);
- return;
- }
-
- found_eof = FALSE;
-
- while (TRUE){
- x = read (fd1,databuf,sectors);
- if (!x)
- break;
- if (ctr_z)
- z = check_eof (databuf,x); /* returns sector */
- else /* which contains */
- z = x; /* ^Z */
- y = write (fd2,databuf,z);
- if (y != z){
- change_disks (s2,fd1,fd2);
- return;
- }
- records+=z;
- if (z < sectors)
- break;
- if (found_eof)
- break;
- }
- close (fd2);
- fabort (fd1);
- fabort (fd2);
- printf ("%4d records ",records);
- if (read_only)
- printf ("R/O ");
- else
- printf (" ");
-
- if (system)
- printf ("SYS ");
- else
- printf (" ");
-
- if (bak_flag)
- printf ("BAK");
- putch ('\n');
- copies++;
- }
-
- quit (a)
- int a;
-
- {
- char t1[5],t2[5];
-
- if (!a){
- printf ("%d file",matched);
- if (matched != 1)
- putch ('s');
- printf (" matched, %d copied\n",copies);
- }
- total_matched += matched;
- matched = 0;
- total_copied += copies;
- copies = 0;
-
- if (!no_wait){
- printf ("\nMore ? ");
- if (toupper (getchar ()) == 'Y'){
- printf ("\n\n");
- getmask ();
- id = od = FALSE;
- do_it ();
- }
- printf ("\nTotal Matched %d, Total Copied %d",
- total_matched,total_copied);
- printf ("\nMount system disk on drive '%c'\n",ld);
- printf (" press <CR> to continue: ");
- bios (3); putch ('\n');
- }
-
- temp[0]=ld;
- temp[1]=':';
- temp[2]=0;
- strcat (temp,"verify.com");
- if (verify)
- if (does_exist (temp)){
- t1[0]=id;
- t2[0]=od;
- t1[1]=0;
- t2[1]=0;
- strcpy (temp,"<");
- strcat (temp,t1);
- strcat (temp,">");
- strcat (temp,t2);
- if (ctr_z)
- strcat (temp,"Z");
- if (no_wait)
- strcat (temp,"N");
- if (debug)
- strcat (temp,"D");
- execl ("verify",pass_mask,temp,0);
- }
- else
- printf ("\nVERIFY.COM not on logged disk\n");
- exit (0);
- }
-
- trim_mask (s)
- char *s;
-
- {
- char *x;
- char t[16];
-
- x=s;
- if (*(x+1) == ':')
- x+=2;
- strcpy (t,x);
- strcpy (s,t);
- }
-
- check_eof (s,a)
- int a;
- char *s;
-
- {
- int x,y;
-
- y=a<<7;
- for (x=0; x<y; x++)
- if (*(s+x) == CPMEOF){
- return ((x>>7)+1);
- found_eof = TRUE;
- }
- return a;
- }
-
- getclp (argc,argv,i,o,v,z,n,b,m,d,r,c,p)
- int argc;
- char **argv;
- char *i; /* source disk */
- char *o; /* destination disk */
- int *v; /* verify flag */
- int *z; /* CP/M EOF (^Z) flag */
- int *n; /* no stop for disk change flag */
- int *b; /* >> to 'file'.BAK */
- int *m; /* mode flag, 'i' for inverse */
- int *d; /* debug mode flag */
- int *r; /* Remember (f4) flag */
- int *c; /* Check the (f4) flag */
- int *p; /* Print out Parameter settings */
-
- {
- char line [100];
- int x;
-
- *i=*o=FALSE;
- if (argc<3){
- if (*argv[1] == '?'){
- usage();
- exit(0);
- }
- return;
- }
- strcpy (line,argv[2]);
- for (x=3; x<argc; x++)
- strcat (line,argv[x]);
- for (x=0; x<strlen(line); x++)
- switch (line[x])
- {
- case '<': {
- *i=line[x+1];
- x++;
- break; }
- case '>': {
- *o=line[x+1];
- x++;
- break; }
- case '(': {
- *i=line[x+1];
- x++;
- break; }
- case ')': {
- *o=line[x+1];
- x++;
- break; }
- case 'V': {
- *v=!(*v);
- break; }
- case 'Z': {
- *z=!(*z);
- break; }
- case 'N': {
- *n=!(*n);
- break; }
- case 'B': {
- *b=!(*b);
- break; }
- case 'I': {
- *m=!(*m);
- break; }
- case 'D': {
- *d=!(*d);
- break; }
- case 'R': {
- *r=!(*r);
- break; }
- case 'C': {
- *c=!(*c);
- break; }
- case 'P': {
- *p=!(*p);
- break; }
- case '?': {
- usage();
- exit(0); }
- }
- }
-
- bak_file ()
-
- {
- int z;
-
- if (check)
- if (marked (fn1)){
- printf ("Not copying: %-14.14s - previously backed up\n",fn1);
- return;
- }
- printf ("Copying : %-14.14s - ",fn1);
- copy (fn1,fn2);
- if (read_only || system){
- strcpy (fn1,fn2);
- for (z=0; z<14; z++){
- if (fn2[z] != '.')
- continue;
- z++;
- if (read_only)
- fn2[z]=fn2[z]|0x80;
- z++;
- if (system)
- fn2[z]=fn2[z]|0x80;
- }
- rename (fn1,fn2);
- }
- if (remember)
- mark (fn1);
- }
-
- cant_kill (fn)
- char *fn;
-
- {
- int x,y,z;
- char myfcb [36];
- char *dma;
-
- setfcb (myfcb,fn);
- x = bdos (17,myfcb);
- if (x>3)
- return FALSE;
- x=x<<5;
- dma=0x80;
- return *(dma+x+9)&0x80;
- }
-
- bak_nor ()
-
- {
- if (does_exist (fn2)){
- if ((bak) && (!no_bak)){
- unlink (fn3);
- rename (fn2,fn3);
- bak_flag=TRUE;
- bak_file ();
- }
- else{
- printf ("File exists: %-14.14s",fn2);
- if ((bak) && (no_bak))
- printf (" - Read Only!");
- putch ('\n');
- }
- }
- else
- bak_file ();
- }
-
- bak_inv ()
-
- {
- if (!does_exist (fn2))
- return;
- if (bak && !no_bak){
- unlink (fn3);
- rename (fn2,fn3);
- bak_flag=TRUE;
- }
- else{
- if (cant_kill (fn2)){
- printf ("FILE EXISTS: %-14.14s",fn2);
- printf (" - Read Only!\n");
- return;
- }
- unlink (fn2);
- }
- bak_file ();
- }
-
- block_copy (s)
- char *s;
-
- {
- int x,z,p;
- char *y;
- int block_size;
-
- printf ("Matching mask '%s'\n\n",s);
-
- block_size=0;
- for (x=0; x<files; x++){
- y=dir+(x<<4);
- if (!match_mask (y))
- continue;
- if (*y == 0xe5)
- continue;
- *y=0xe5;
- matched++;
- block_size++;
- for (z=0; z<20; z++)
- temp[z]=NULL;
-
- for (z=1,p=0; z<9; z++,p++)
- temp[p] = *(y+z)&0x7f;
- while (temp[strlen(temp)-1]==0x20)
- temp[strlen(temp)-1]=NULL;
-
- strcat (temp,".");
- p=strlen (temp);
-
- for (z=9; z<12; z++,p++)
- temp[p] = *(y+z)&0x7f;
-
- read_only = *(y+9)&0x80;
- system = *(y+10)&0x80;
-
- fn1[0]=id;
- fn2[0]=od;
- fn1[1]=':';
- fn2[1]=':';
- fn1[2]=0;
- fn2[2]=0;
- strcat (fn1,temp);
- strcat (fn2,temp);
- strcpy (fn3,fn2);
- for (z=0; z<13; z++)
- if (fn3[z]=='.')
- fn3[z+1]=NULL;
-
- strcat (fn3,"BAK");
- bak_flag=FALSE;
- if (cant_kill (fn2) || cant_kill(fn3))
- no_bak=TRUE;
- else
- no_bak=FALSE;
-
- if (!mode)
- bak_nor ();
- else
- bak_inv ();
- }
- if (!block_size)
- printf ("NO FILE\n");
- printf ("\n");
- }
-
- mask_num (a)
- int a;
-
- {
- int x,y,z;
-
- y=z=0;
- for (x=0; x<16; x++)
- work_mask[x] = NULL;
- for (x=0; x<strlen(mask); x++){
- if (mask[x] == ',')
- y++;
- if (y==a)
- break;
- }
- if (x >= strlen(mask))
- return;
- if (x)
- x++;
- for (y=x; y<strlen(mask); y++,z++){
- if (mask[y] == ',')
- break;
- work_mask[z] = mask[y];
- }
- trim_mask (work_mask);
- if (work_mask[0]=='!'){
- for (x=0; x<13; x++)
- work_mask[x]=work_mask[x+1];
- not_mask=TRUE;
- }
- else
- not_mask=FALSE;
- setfcb (mask2,work_mask);
- }
-
- do_it ()
-
- {
- int x,p,z;
- char *y;
-
- if (!id){
- printf ("Source Drive: ");
- id = toupper (bios (3));
- if (id != '\r')
- if (id == '?'){
- printf("\n\n");
- usage();
- exit(0);
- }
- putch (id);
- putch ('\n');
- no_questions = FALSE;
- }
-
- if (!od){
- printf ("Destination Drive: ");
- od = toupper (bios (3));
- if (od != '\r')
- if (od == '?'){
- printf("\n\n");
- usage();
- exit(0);
- }
- putch (od);
- putch ('\n');
- no_questions = FALSE;
- }
-
- if (id == '\r')
- id=ld;
- if (od == '\r')
- od=ld;
- if (id == od){
- printf ("\nINPUT & OUTPUT DRIVES MUST DIFFER!\n");
- exit (1);
- }
- if ((id < 'A') || (id > 'P') ||
- (od < 'A') || (od > 'P')){
- printf ("\nINVALID DRIVE NAME!\n");
- exit (1);
- }
-
- if (!no_questions)
- printf ("\n");
-
- if (!no_wait){
- printf ("Mount disks, <CR> to continue: ");
- bios (3);
- printf ("\n\n");
- bdos (13);
- }
-
- files = 0;
- temp[0]=id;
- temp[1]=':';
- temp[2]=0;
- strcat (temp,"*.*");
- setfcb (fcb1,temp);
-
- code = bdos (17,fcb1); /* search for first */
- if (code > 3){
- printf ("NO FILE\n");
- quit (1);
- }
- getdir (fcb1);
- while (TRUE){
- code = bdos (18);
- if (code > 3)
- break;
- getdir (fcb1);
- }
-
-
- config2();
- masks=0;
- mask_num (0);
- while (strlen(work_mask)){
- block_copy (work_mask);
- masks++;
- mask_num (masks);
- }
- quit (0);
- }
-
- config2()
-
- {
- unsigned x,p,z;
- char *y,*top;
-
- top = (topofmem() - stackspace) & 0xff00;
- x = 16*files;
- p = (dir + x + 0x101);
- databuf = p & 0xff00;
- sectors = (top - databuf) >> 7;
-
- if (sectors < 8){
- printf ("NOT ENOUGH RAM TO RUN THIS PROGRAMME\n");
- quit (1);
- }
- if (debug){
- printf ("Compiled on %s, at %s\n\n",DATE,TIME);
- printf ("Directory assigned at: %04x\n",dir);
- printf ("Entries found: %4d\n", files);
- printf ("Buffer assigned at: %04x\n",databuf);
- printf ("Max. Records buffered: %4d\n", sectors);
- printf ("Stackspace Reserved: %04x\n",stackspace);
- printf ("Top of Buffer at: %04x\n\n",top);
- }
- }
-
- marked (s)
- char *s;
-
- {
- char fcb [36];
- int c;
- char *p;
-
- setfcb (fcb,s);
- c = bdos (17,fcb);
- p = 0x80 + 32*c + 4;
- if ((*p) & 0x80)
- return TRUE;
- else
- return FALSE;
- }
-
- mark (s)
- char *s;
-
- {
- char fcb [36];
-
- setfcb (fcb,s);
- fcb[4] = fcb[4] | 0x80;
- bdos (30,fcb);
- }
-
- change_disks (s2,fd1,fd2)
- char *s2;
- int fd1;
- int fd2;
-
- {
- char fcb [36];
- int x;
-
- setfcb (fcb,s2);
- for (x=1; x<13; x++)
- fcb[x]=fcb[x]&0x7f;
- bdos (30,fcb); /* reset flags (R/O etc), and */
- bdos (19,fcb); /* delete incomplete copy */
- fabort (fd1); /* and free up the fds in */
- fabort (fd2); /* the rtp */
-
- printf ("DESTINATION DISK IS FULL,\n\n");
- printf (" Change disk on drive '%c',\n",od);
- printf (" press <CR> to continue: ");
- bios (3);
- printf ("\n\n");
-
- bdos (13);
- if (!mode) /* check inverse mode */
- bak_nor (); /* and try again */
- else
- bak_inv ();
- }
-
- printflg (s,a)
- char *s;
- int a;
-
- {
- printf (" %s ",s);
- if (a)
- printf ("ON\n");
- else
- printf ("OFF\n");
- }
-
- usage()
-
- {
- printf("Usage : \t BACKUP parameters\n\n");
- printf("Where valid parameters are:\n\n");
- printf("(i)\tmask(s)\tThis must be the first parameter and will\n");
- printf("\t\tcontrol which files are copied.\n\n");
- printf("ALL THE PARAMETERS WHICH FOLLOW MAY OCCUR IN ANY ORDER\n\n");
- printf("(ii)\t<d\tcopy FROM drive 'd'\n");
- printf("(iii)\t>d\tcopy TO drive 'd'\n");
- printf("(iv)\tn\tDon't prompt for disk changes\n");
- printf("(v)\tb\tIf file exists rename to .BAK and then copy\n");
- printf("(vi)\tv\tRun VERIFY after BACKUP is finished\n");
- printf("(vii)\tz\tCopy only to the first CP/M EOF (^Z).\n");
- printf("(viii)\ti\tCopy ONLY files which exist on source and dest\n");
- printf("(ix)\td\tDebug mode. Show where everything is in RAM\n");
- printf("(x)\tr\tTag files as they are backed up\n");
- printf("(xi)\tc\tCheck (only) for previous backups\n");
- printf("(xii)\tp\tPrint out parameter settings\n");
- }