home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / CMDS / dback.lzh / dback.c < prev    next >
C/C++ Source or Header  |  1992-03-06  |  18KB  |  655 lines

  1. /*
  2. ** Dback <from dir> <to dir>
  3. **  Copies all files in range of files to another disc
  4. **  (in the same way as dsave), 
  5. **  - creating directories where needed
  6. **  - overwriting old versions of files
  7. **  - going recursively down the tree.
  8. **  optionally will merely list files instead of copying them.
  9. **
  10. **     options are:
  11. **            -b = <num>k as for copy
  12. **            -d = backup selected directory 
  13. **            -e = execute
  14. **            -f = omit files with suffix 
  15. **            -k = do not copy OS9Boot files
  16. **            -l = no recursion
  17. **            -p = pause before implementing
  18. **            -s = start copying at file 
  19. **            -t = terminate copying at file
  20. **            -v = verify, as for copy
  21. **            -? = report usage
  22. **    Defaults 
  23. **             source directory (default curr)
  24. **             target directory (default /d0)
  25. **
  26. **  copyright 1991 by Cowen Software Ltd
  27. **  23 Bristol Ave, Levenshulme, Manchester,
  28. **  GB-M19 3NU, England, UK
  29. **  released to the public domain for non-commercial use
  30. **   
  31. */
  32.  
  33.  
  34. #include <stdio.h>
  35. #include <modes.h>
  36. #include <ctype.h>
  37. #include <direct.h>
  38.  
  39. extern int os9forkc();
  40. extern int errno;
  41. extern char **environ;
  42.  
  43. #define TRUE  1
  44. #define FALSE 0
  45. #define trace FALSE
  46. #define FNSIZ     132
  47. #define dirlength 300
  48. #define comlength 600
  49. #define maxf      20
  50.  
  51.  
  52. char  *fptr[maxf];
  53. int   flen[maxf];
  54. int   numf = 0;
  55.  
  56. int   i;
  57.  
  58. char  dext[] = "_bak";
  59. char  dextflag;
  60.  
  61.  
  62.  
  63. char  eflag = FALSE;                           /* execute            */
  64. char  bflag = FALSE;                           /* buffer    specified*/ 
  65. char  pflag = FALSE;                           /* pause     specified*/ 
  66. char  kflag = FALSE;                           /* omit /h0/os9boot   */
  67. char  lflag = FALSE;                           /* not recursive      */
  68. char  sflag = FALSE;                           /* start     specified*/ 
  69. char  tflag = FALSE;                           /* terminate specified*/
  70. char  srcflag = FALSE;                         /* source    specified*/
  71. char  tarflag = FALSE;                         /* target    specified*/
  72. char  vflag = FALSE;                           /* verify    specified*/ 
  73.  
  74. char  *sptr;
  75. char  *tptr;
  76. char  *tarptr;
  77. char  *srcptr;
  78. char  *bptr;
  79. char  *vptr;
  80.                                                /* defaults */
  81. char  bdef[]   = "-b=4k";
  82. char  sdef[]   = " ";
  83. char  tdef[]   = "~";
  84. char  srcdef[] = ".";
  85. char  tardef[] = "/d0";
  86. char  voff[]   = " ";
  87. char  von[]    = "-v";
  88. char  slash[]  = "/";
  89.  
  90. int   dnum = 0,
  91.       dind = 0;
  92. char  *dptr[50];
  93.  
  94. char  relpath[dirlength];
  95.  
  96. int   rlen,
  97.       srclen,
  98.       tarlen;
  99.             
  100. struct fildes srcdb;
  101. struct fildes tardb;
  102.  
  103. char  srcpath[comlength];
  104. char  tarpath[comlength];
  105.  
  106. char  filename[32];                            /* holds each file name */ 
  107.  
  108. char *copyblk[] = { "copy","-r",0,0,0,0,0};
  109. char *delblk[]  = { "del",0,0};
  110.  
  111. int portfd;
  112. char env[] = "/term";
  113.  
  114. main(argc,argv)
  115.  int   argc;
  116.  char  **argv;
  117.    {
  118.    char *p;
  119.    char *portptr;
  120.    int  tarfd;
  121.    int x;
  122.    
  123.    portptr = getenv("PORT");
  124. #if trace
  125. fprintf(stderr,"portptr = %s \n",portptr);
  126. fflush(stderr);
  127. #endif
  128.    if (portptr == NULL) portfd = 0;
  129.    else portfd = open(portptr, S_IREAD);
  130.    if (portfd == -1) error("can't open port",0);
  131.  
  132. #if trace
  133. fprintf(stderr,"params: = %d \n",argc);
  134. fflush(stderr);
  135. #endif
  136.       
  137.    getflags(argc,argv);
  138.  
  139.    if (numf > 0)  for (x=0;x<numf;x++)
  140.                         flen[x] = strlen(fptr[x]);
  141.       
  142.    while ( (--argc) )
  143.       {
  144.       if (*(p = *++argv) != '-')
  145.          {
  146.          if (!srcflag)  { srcptr = p; srcflag = TRUE; continue;}
  147.          if (!tarflag)  { tarptr = p; tarflag = TRUE; continue;}
  148.          error("Too many  parameters",0);
  149.          }   
  150.       }
  151.  
  152.    if ( (dnum > 0) & (sflag | tflag) )
  153.                error("Sorry, you can't use -d with -s or -t",0);
  154.    if (sflag == FALSE) sptr = sdef;
  155.    if (tflag == FALSE) tptr = tdef;
  156.    if (bflag == FALSE) bptr = bdef;
  157.    if (srcflag == FALSE) srcptr = srcdef;
  158.    if (tarflag == FALSE) tarptr = tardef;
  159.    if (vflag == FALSE) vptr = voff;   else vptr = von;
  160.  
  161.    copyblk[4] = bptr;
  162.    if (vflag) copyblk[5] = vptr;
  163.    
  164.    if (pflag) confirm();
  165.  
  166.    if ( (tarfd = open(tarptr,S_IFDIR + S_IREAD) ) == -1)
  167.           error ("Can't open directory ",tarptr);
  168.    close(tarfd);
  169.    
  170.    srclen = strlen(srcptr);
  171.    tarlen = strlen(tarptr);
  172.    
  173. #if trace
  174. fprintf(stderr,"bptr=%s vptr=%s sptr=%s tptr=%s srcptr=%s tarptr=%s  \n",
  175.                 bptr,   vptr,   sptr,   tptr,   srcptr,   tarptr);
  176. fflush(stderr);
  177. #endif
  178.  
  179.    if (dnum == 0)                    dodees("");
  180.    if (dnum > 0) while (dnum > dind) dodees(dptr[dind++]);
  181.    }   
  182.  
  183.  
  184.  
  185.  
  186. dodees(thisdee)
  187. char *thisdee;
  188.    {
  189.    int srcfd;
  190.    
  191. #if trace
  192. fprintf(stderr,"dodees (entry); thisdee %s;\n",thisdee);
  193. fflush(stderr);
  194. #endif
  195.    
  196.    strcpy(relpath,thisdee);  
  197.    strcpy(tarpath, tarptr);
  198.    strcpy(srcpath, srcptr);
  199.    if (dnum > 0)  {  strcat(tarpath, slash);
  200.                      strcat(srcpath, slash);
  201.                   }
  202.    strcat(tarpath, relpath);
  203.    strcat(srcpath, relpath);
  204.                   
  205.    fprintf(stderr,"Backing up %s/%s to %s/%s onto %s\n",
  206.                      srcpath,sptr,srcpath,tptr,tarpath);
  207.  
  208.    if ( (srcfd = open(srcpath,S_IFDIR + S_IREAD) ) == -1)
  209.           error ("Can't open directory ",srcpath);
  210.    
  211.    donext(srcfd); 
  212.    close(srcfd);
  213.  
  214. #if trace
  215. fprintf(stderr,"dodees(end) srcfd=%d \n",srcfd);
  216. fflush(stderr);
  217. #endif
  218.                  
  219.    }   
  220.  
  221.  
  222.  
  223.  
  224.  
  225. donext(srcfd,rellen)
  226. int   srcfd;                                /* dir path no*/
  227.  
  228. /*    This procedure is called for each directory 
  229.       which is to be copied.
  230.       Initially it checks the target directory exists, and if not
  231.       it tries to create it.  Then it opens the directory, and 
  232.       reads all files in it.
  233.       Each valid file is passed to checkfile for processing
  234.       NOTE the file name as given on entry has each 
  235.       filename in turn appended to it, then the original length restored
  236.       this means that we must check to see if the tree of directories
  237.       has got too long, and overflowed the dirname buffer.
  238. */
  239.       
  240.    {
  241.    struct dirent     dirbuf;                /* single dir ent read buf */
  242.    int   tarfd;
  243.    int   rply;
  244.    int   rellen;                            /* length of relname */
  245.    int   filelen;
  246.    
  247.    rellen = strlen(relpath);
  248.  
  249. #if trace
  250. fprintf(stderr,"donext srcfd = %d; rellen = %d \n",srcfd,rellen);
  251. fflush(stderr);
  252. #endif
  253.  
  254.    if (rellen + 1 > dirlength) error("pathname too long",0);
  255.    if (rellen + tarlen + 1 > comlength ) error( "target path too long",0);
  256.    
  257.    if (rellen > 0) { strcat(relpath, slash);
  258.                      rellen++;
  259.                    }                          
  260.  
  261.    if ( (tarfd = open(tarpath,S_IFDIR + S_IREAD) ) == -1)
  262.           {
  263.           printf("makdir %s\n",tarpath);
  264.           if (eflag)  {
  265.                       makdir (tarpath,S_IFDIR,
  266.                               S_IREAD+S_IWRITE+S_IOREAD+S_IOWRITE);
  267.                       if ( (tarfd = open(tarpath,S_IFDIR + S_IREAD) ) == -1)
  268.                            error ("Can't open file ",tarpath);
  269.                       }
  270.           }
  271.    if (tarfd != -1) close(tarfd);
  272.  
  273.  
  274.    while(rply = read(srcfd, &dirbuf, sizeof(dirbuf)))    /* now copy names */
  275.        {
  276.  
  277. #if trace
  278. fprintf(stderr,"donext(read) relpath=%s, rply = %d,  dirbuf = %32s\n",
  279.                              relpath,    rply,      &dirbuf);
  280. fflush(stderr);
  281. #endif
  282.        if (rply != sizeof(dirbuf)) error("error reading directory",0);
  283.        relpath[rellen] = '\0';                       /* restore original length*/
  284.  
  285.        strhcpy(filename, &dirbuf);
  286.        filename[28] = '\0';                  /* shouldn't be needed
  287.                                              but I am a pessimist */
  288.                                              
  289. #if trace
  290. fprintf(stderr,"filename = %d %d %d %s \n",
  291.                 filename[0],filename[1],filename[2],filename);
  292. fflush(stderr);
  293. #endif
  294.  
  295.        if (filename[0]           == 0) continue;
  296.        if (strcmp(filename,".")  == 0) continue;
  297.        if (strcmp(filename,"..") == 0) continue;
  298.  
  299.        filelen = strlen(filename);
  300.        if ( (rellen + filelen + 1) > dirlength)
  301.            error ("Partial path is too long",relpath);
  302.  
  303.        if ( (rellen + filelen + 1 + srclen) > comlength)
  304.                error ("Source directory path is too long",srcpath);
  305.             
  306.        if ( (rellen + filelen + 1 + tarlen) > comlength)
  307.                error ("Target path is too long", tarpath);
  308.  
  309.  
  310.        strcat(relpath,filename);             /* stick the next element
  311.        rlen = strlen(relpath);                on to the rel path*/ 
  312.  
  313.        strcpy(srcpath, srcptr);
  314.        strcat(srcpath, slash);
  315.        strcat(srcpath, relpath);
  316.        srclen = strlen(srcpath);
  317. #if trace
  318. fprintf(stderr,"donext(while) relpath=%s,srcpath=%s,tarpath=%s\n",
  319.                               relpath,   srcpath,   tarpath);
  320. fflush(stderr);
  321. #endif
  322.  
  323.        if (strcmp(relpath, sptr) <  0) continue;
  324.        if (strcmp(relpath, tptr) >= 0) continue;
  325.    
  326.        strcpy(tarpath, tarptr);
  327.        strcat(tarpath, slash);
  328.        strcat(tarpath, relpath);
  329.        tarlen = strlen(tarpath);
  330.  
  331.        checkfile();                          /* check this file */ 
  332.  
  333.       }
  334.       
  335.  
  336. #if trace
  337. fprintf(stderr,"donext(end) \n");
  338. fflush(stderr);
  339. #endif
  340.  
  341.      
  342.    }
  343.  
  344.  
  345.  
  346. checkfile()
  347.  
  348. /*   now check each file, as follows
  349.      1, try to open it as a file, if that fails try as a directory,
  350.         in checkdir.
  351.      2, otherwise look at the file details, if the file is already backed
  352.         up, do nothing, otherwise back it up.
  353. */
  354.  
  355.    {
  356.    int srcfd;
  357.    int  x;
  358.    
  359. #if trace
  360. fprintf(stderr,"checkfile (entry); srcpath %s; tarpath %s\n",srcpath,tarpath);
  361. fflush(stderr);
  362. #endif
  363.    
  364.    srcfd = open(srcpath, S_IREAD);
  365.    
  366.    if (srcfd == -1) {checkdir(); return;}
  367.    x = _gs_gfd(srcfd,&srcdb,sizeof(srcdb));
  368.    if (x == -1)  { fprintf(stderr,"FD Read Fail %d on %s",errno,srcpath);
  369.                   error("aborting",0);
  370.                  }
  371.    close(srcfd);
  372.  
  373.    if (checkdate() ) copyfile();
  374.                   
  375.    }
  376.    
  377.  
  378. checkdate()
  379.  
  380. /*   returns false if it's a suffix to omit
  381.      else opens target files, and checks dates,
  382.      returns true if
  383.      1, target does not exist
  384.      2. source has later date than target
  385.      3, source and target have different file sizes
  386. */
  387.    {
  388.    int  x;
  389.    int tarfd;
  390.  
  391.    
  392. #if trace
  393. fprintf(stderr,"numf=%d; tarpath= %s; tarlen=%d;",numf,tarpath,tarlen);
  394. fprintf(stderr,"fptr[0]=%s; flen[0]=%d\n",fptr[0],flen[0]);
  395. fflush(stderr);
  396. #endif
  397.  
  398.    if (numf > 0)  for (x=0;x<numf;x++)
  399.                         if ( ! strucmp (fptr[x],&tarpath[tarlen-flen[x]]) )
  400.                            return(FALSE);
  401.                               
  402.    tarfd = open(tarpath, S_IREAD);
  403.    if (tarfd == -1 ) return(TRUE);
  404.  
  405.    x = _gs_gfd(tarfd,&tardb,sizeof(tardb));
  406.    if (x == -1)  { fprintf(stderr,"FD Read Fail %d on %s",errno,tarpath);
  407.                   error("aborting",0);
  408.                  }
  409.    close(tarfd);
  410.    
  411. #if trace
  412. fprintf(stderr,"size- src: %d, tar: %d\n",srcdb.fd_fsize[0],tardb.fd_fsize[0]);
  413. fflush(stderr);
  414. #endif
  415.  
  416.    if (strncmp(srcdb.fd_fsize,tardb.fd_fsize,4) > 0 ) return (TRUE);
  417.  
  418.    if (strncmp(srcdb.fd_date,tardb.fd_date,5) > 0 ) return (TRUE);
  419.    return(FALSE);
  420.            
  421.    }
  422.    
  423.  
  424.  
  425. checkdir()
  426.  
  427. /*   try to open as a directory, if it is one then  pass it back to donext.
  428. */
  429.    {
  430.    int srcfd;
  431.    
  432. #if trace
  433. fprintf(stderr,"checkdir (entry); srcpath %s;\n",srcpath);
  434. fflush(stderr);
  435. #endif
  436.    
  437.    srcfd = open(srcpath,S_IFDIR + S_IREAD);
  438.    
  439.    if (srcfd == -1) { fprintf(stderr,"Open Fail %d on %s \n",errno,srcpath);
  440.                       fflush(stderr); return;
  441.                     }
  442.    
  443.    if ( !lflag ) donext(srcfd); 
  444.  
  445.    close(srcfd);
  446.  
  447. #if trace
  448. fprintf(stderr,"checkdir(end) srcfd=%d \n",srcfd);
  449. fflush(stderr);
  450. #endif
  451.                   
  452.    }
  453.    
  454.   
  455.  
  456. copyfile()
  457. /* Now we have a file to copy - copy it if eflag or just
  458. list it.
  459. */
  460.    {
  461.    int pid;
  462.    unsigned status;
  463.    
  464.    if (kflag & (strucmp(filename,"OS9BOOT") == 0 ) ) return;
  465.    
  466.    printf("copy -r %s %s %s %s\n", bptr,vptr,srcpath,tarpath);
  467.    
  468.    if (eflag)
  469.         {
  470.            copyblk[2] = srcpath;
  471.         copyblk[3] = tarpath;
  472.    
  473.         pid = os9exec(os9forkc,copyblk[0],copyblk,environ,0,0,3);
  474.         if (pid < 0)  error("Can't create copy process",0);
  475.         wait(&status);  
  476.         if (status != 0)
  477.             { fprintf(stderr,"\ncan't copy %s to %s\n",srcpath, tarpath);
  478.               fprintf(stderr,"Deleting %s\n", tarpath);
  479.               delblk[1] = tarpath;
  480.               pid = os9exec(os9forkc,delblk[0],delblk,environ,0,0,3);
  481.               if (pid < 0) error("Can't create delete process",0);
  482.               wait(&status);
  483.               if (status != 0) error("Delete Failed!!!",0);
  484.               else             error("Deleted OK",0);
  485.             }
  486.         }
  487.    }
  488.                
  489.  
  490.  
  491.  
  492. getflags(carg,varg)
  493.  int   carg;
  494. char  **varg;
  495.    {
  496.    char  *p, c;
  497.    while ( (--carg) )
  498.       {
  499.       if (*(p = *++varg) == '-')
  500.          {
  501.          while (c = *++p)
  502.             {
  503.             switch (c)
  504.                {
  505.                case '?' :
  506.                      help();
  507.                      break; 
  508.                case 'e' :                             /*execute*/
  509.                      eflag = TRUE;
  510.                      break;
  511.                case 'l' :
  512.                      lflag = TRUE;                    /* not recursive*/
  513.                      break; 
  514.                case 'p' :                             /* pause */
  515.                      pflag = TRUE;
  516.                      break;
  517.                case 'v' :
  518.                      vflag = TRUE;                    /* verify */
  519.                      break; 
  520.                case 'k' :
  521.                      kflag = TRUE;                    /* omit /h0/os9boot */
  522.                      break; 
  523.                case 'd' :                             /* selected dirs */
  524.                      if (dnum >= 49) error("Too many -d 's",0);
  525.                      while(*++p == ' ');
  526.                      if (*p++ != '=') error ("no suffix for -d option",0);
  527.                      if (*p == '\0')  error("null suffix for -d option",0);
  528.                      dptr[dnum++] = p;
  529.                      while (c = *p) p++;   /* skip past extension name */
  530.                      p--;                  /* and point to the closing null */
  531.                      break;
  532.                case 'f' :
  533.                      dextflag = FALSE;
  534.                      while(*++p == ' ');
  535.                      if (*p++ != '=')  dextflag = TRUE;
  536.                      else if (*p == '\0') dextflag = TRUE;
  537.                      if (numf >= maxf) error("Too many -f parameters",0);
  538.                      if (dextflag) fptr[numf++] = dext;
  539.                      else fptr[numf++] = p;
  540.                      while (c = *p) p++;   /* skip past extension name */
  541.                      p--;                  /* and point to the closing null */
  542.                      break;
  543.                case 'b' :
  544.                      bptr = p;
  545.                      *(--bptr) = '-'; 
  546.                      while(*++p == ' ');
  547.                      if (*p++ != '=') error ("no suffix for -b option",0);
  548.                      if (*p == '\0') error ("null suffix for -b option",0);
  549.                      if (bflag) error("Too many -b parameters",0);
  550.                      bflag = TRUE;
  551.                      while (c = *p) p++;   /* skip past extension name */
  552.                      p--;                  /* and point to the closing null */
  553.                      break;
  554.                case 's' :
  555.                      while(*++p == ' ');
  556.                      if (*p++ != '=') error ("no suffix for -s option",0);
  557.                      if (*p == '\0') error ("null suffix for -s option",0);
  558.                      if (sflag) error("Too many -s parameters",0);
  559.                      sflag = TRUE;
  560.                      sptr = p;
  561.                      while (c = *p) p++;   /* skip past extension name */
  562.                      p--;                  /* and point to the closing null */
  563.                      break;
  564.                case 't' :
  565.                      while(*++p == ' ');
  566.                      if (*p++ != '=') error ("no suffix for -t option",0);
  567.                      if (*p == '\0') error ("null suffix for -t option",0);
  568.                      if (tflag) error("Too many -t parameters",0);
  569.                      tflag = TRUE;
  570.                      tptr = p;
  571.                      while (c = *p) p++;   /* skip past extension name */
  572.                      p--;                  /* and point to the closing null */
  573.                      break;
  574.                default :
  575.                      help();
  576.                      break; 
  577.                }
  578.             }
  579.          }   
  580.       }
  581.    }   
  582.  
  583.  
  584.  
  585. confirm()
  586. {
  587. char  keypress;
  588.  
  589. #if trace
  590. fprintf(stderr,"portfd = %d \n",portfd);
  591. fflush(stderr);
  592. #endif
  593. do { fprintf(stderr,"Continue? ");
  594.      fflush(stderr);
  595.      read(portfd,&keypress,1);
  596.      fprintf(stderr,"\n");
  597.      fflush(stderr);
  598.      keypress = toupper(keypress);
  599.      if (keypress == 'N') exit(1);
  600.    }
  601.    while (keypress != 'Y'); 
  602.    pflag = FALSE;
  603. }   
  604.  
  605.  
  606.  
  607.  
  608. error(s1, s2)
  609. char  *s1, *s2;
  610.  
  611. /*
  612. ** write the two strings passed and then a <cr>
  613. */
  614.  
  615.    {
  616.  
  617.    if (s1)
  618.          fprintf(stderr, "%s", s1 );
  619.    if (s2)
  620.          fprintf(stderr, "%s", s2 );
  621.    fprintf(stderr, "\n");
  622.    fflush(stderr);
  623.    exit (1);
  624.    }
  625.  
  626.  
  627.  
  628. help()
  629.  
  630. /*
  631. ** provide usage info for this srcpath
  632. */
  633.  
  634.    {
  635.    fprintf(stderr, "Usage: Dback [-options] <fromdir> <todir> [-options]\n" );
  636.    fprintf(stderr, "     -b=<no>k= copy buffer \n" );
  637.    fprintf(stderr, "     -d=file = backup selected directory \n" );
  638.    fprintf(stderr, "     -e      = execute     \n" );
  639.    fprintf(stderr, "     -f=xxx  = omit files suffixed xxx (default:_BAK)\n" );
  640.    fprintf(stderr, "     -k      = omit OS9Boot files \n" );
  641.    fprintf(stderr, "     -l      = no recursion\n" );
  642.    fprintf(stderr, "     -p      = pause before copying \n" );
  643.    fprintf(stderr, "     -s=file = start copying at \n" );
  644.    fprintf(stderr, "     -t=file = terminate copying at \n" );
  645.    fprintf(stderr, "     -v      = verify   \n" );
  646.    fprintf(stderr, "     -?      = report help \n" );
  647.    fprintf(stderr, "Defaults \n" );
  648.    fprintf(stderr, " source directory (default =  . ) \n" );
  649.    fprintf(stderr, " target directory (default = /d0) \n" );
  650.    fprintf(stderr, "\n");
  651.    fflush(stderr);
  652.    exit (0);
  653.    }
  654.  
  655.