home *** CD-ROM | disk | FTP | other *** search
/ FreeWare Collection 2 / FreeSoftwareCollection2pd199x-jp.img / ms_dos / update / update.c < prev    next >
Text File  |  1990-06-14  |  8KB  |  370 lines

  1. /*
  2.  *    update.exe
  3.  *    copy files with time stamp considering
  4.  *
  5.  *    for Turbo C 1.5ja (SPL) / compile with COMPACT memory model
  6.  *    (C) 1988 Sey
  7.  *    1988/4/27    1.0
  8.  *         9/3    1.1    kanji file name available
  9.  *         10/20    1.2    disk full check / default destination directory
  10.  *         11/16    1.2a    1 bug fixed
  11.  *         12/16    1.3    drive or directory only is available for source
  12.  *    1989/ 3/ 2    1.4    disk space check before copying
  13.  *                free location of option in arguments
  14.  *          5/ 9    1.5    verify mode added(-v)
  15.  */
  16. #define    VERSION    "1.5 "
  17.  
  18. #include    <dos.h>
  19. #include    <errno.h>
  20. #include    <stdio.h>
  21. #include    <stdlib.h>
  22. #include    <dir.h>
  23. #include    <io.h>
  24. #include    <fcntl.h>
  25. #include    <alloc.h>
  26. #include    <stat.h>
  27. #include    <ctype.h>
  28.  
  29. #define    MAXARG    256
  30. #define    MAXBUFF    65534
  31. #define MINBUFF 1024
  32. char        *buff[10];
  33. unsigned     buffsize[10],buffuse[10];
  34.  
  35. void
  36. usage()
  37.     {
  38.     printf("UPDATE - copy files when source is newer  ver.%s (C)"
  39.         "1988 Sey\n"
  40.         "usage : update [-{ev}] <source> [<source>...] [<destination>]\n"
  41.         "\t<source> is file or directory\n"
  42.         "\t<destination> is directory (default current)\n"
  43.         "\t-e limits sources to that alredy Exist in <destination>\n"
  44.         "\t-v sets Verify flag\n"
  45.         ,VERSION);
  46.     exit(1);
  47.     }
  48. /* end usage */
  49.  
  50. void
  51. fatal(char *msg)
  52.     {
  53.     printf("update : %s\n",msg);
  54.     exit(1);
  55.     }
  56. /* end fatal */
  57.  
  58. int
  59. isdir(char *pathname)                   /* is directory ? */
  60.     {
  61.     struct    ffblk    ffblk;
  62.  
  63.     if( jstrmatch(pathname,"*?") != NULL )    /* wild cards are not */
  64.         return(0);            /* available in directory */
  65.     if( strcmp(pathname,"\\") == 0 )        /* root directory */
  66.         return(2);
  67.     if( strlen(pathname) == 3 &&        /* root directory */
  68.         *(pathname + 1) == ':' &&
  69.         *(pathname + 2) == '\\' )
  70.         return(2);
  71.     if( pathname[strlen(pathname)-1] == '\\' )
  72.         pathname[strlen(pathname)-1] = '\0';
  73.     if( !findfirst(pathname,&ffblk,FA_DIREC) &&
  74.         ffblk.ff_attrib & FA_DIREC )
  75.         return(1);
  76.     else
  77.         return(0);
  78.     }
  79. /* end isdir */
  80.  
  81. long
  82. dfree(int drive)
  83.     {
  84.     struct    dfree    df;
  85.     long    dfree;
  86.  
  87.     getdfree( drive,&df );
  88.     dfree = df.df_avail;
  89.     dfree *= df.df_sclus;
  90.     dfree *= df.df_bsec;
  91.     return( dfree );
  92.     }
  93. /* end dfree */
  94.  
  95. long
  96. fileclususe(int handle,int drive)
  97.     {
  98.     struct    dfree    df;
  99.     long    clussize;
  100.  
  101.     getdfree( drive,&df );
  102.     clussize = (long)df.df_sclus * df.df_bsec;
  103.     return( ((filelength(handle) + clussize - 1) / clussize) * clussize );
  104.     }
  105. /* end fileclususe */
  106.  
  107. long
  108. spend(char *src,char *dstdir,int copy_if_exist)
  109.     {
  110.     char    dst[MAXPATH];
  111.     char    sdrive[MAXDRIVE],sdir[MAXDIR],sname[MAXFILE],sext[MAXEXT];
  112.         int    shandle,dhandle;
  113.     struct    ftime    stime,dtime;
  114.     int    ddrive;
  115.     long    spend;
  116.  
  117.         ddrive = dstdir[1] == ':' ? toupper(dstdir[0]) - '@' : 0;
  118.         if( (shandle = open(src,O_RDONLY)) == -1 )
  119.         return(0);
  120.     getftime(shandle,&stime);
  121.     jfnsplit(src,sdrive,sdir,sname,sext);
  122.     strcpy(dst,dstdir);
  123.     if( *(dst + strlen(dst) - 1) != '\\' )
  124.         strcat(dst,"\\");
  125.     strcat(dst,sname);
  126.     strcat(dst,sext);
  127.     if( (dhandle = open(dst,O_WRONLY)) == -1 )
  128.         if( errno == ENOENT && !copy_if_exist )
  129.             spend = fileclususe(shandle,ddrive);
  130.         else
  131.             spend = 0;            
  132.     else
  133.         {
  134.         getftime(dhandle,&dtime);
  135.         if( *((unsigned long *)&dtime) >= *((unsigned long *)&stime) )
  136.             spend = 0;
  137.         else
  138.             spend = fileclususe(shandle,ddrive)
  139.                 - fileclususe(dhandle,ddrive);
  140.         }
  141.     close(shandle);
  142.     close(dhandle);
  143.     return(spend);
  144.     }
  145. /* end spend */
  146.  
  147. int
  148. update(char *src,char *dstdir,int copy_if_exist)
  149.     {
  150.     char    dst[MAXPATH];
  151.     char    sdrive[MAXDRIVE],sdir[MAXDIR],sname[MAXFILE],sext[MAXEXT];
  152.     struct    ftime    stime,dtime;
  153.         int    shandle,dhandle;
  154.     int    ddrive;
  155.  
  156.         ddrive = dstdir[1] == ':' ? toupper(dstdir[0]) - '@' : 0;
  157.         if( (shandle = open(src,O_RDONLY)) == -1 )
  158.         {
  159.         printf("cannot open %s\n",src);
  160.         return(1);
  161.         }
  162.     getftime(shandle,&stime);
  163.  
  164.     jfnsplit(src,sdrive,sdir,sname,sext);
  165.     strcpy(dst,dstdir);
  166.     if( *(dst + strlen(dst) - 1) != '\\' )
  167.         strcat(dst,"\\");
  168.     strcat(dst,sname);
  169.     strcat(dst,sext);
  170.     if( (dhandle = open(dst,O_RDONLY)) == -1 )
  171.         {
  172.         if( copy_if_exist )
  173.             {
  174.             /* printf("%s -x-> %s not exist\n",src,dst); */
  175.             close(shandle);
  176.             return(0);
  177.             }
  178.         else
  179.             {
  180.             if( filelength(shandle) > dfree(ddrive) )
  181.                 {
  182.                 printf("%s -x-> %s not enough disk space\n"
  183.                     ,src,dst);
  184.                 close(shandle);
  185.                 return(1);
  186.                 }
  187.             if( (dhandle = open(dst
  188.                 ,O_CREAT|O_BINARY,S_IREAD|S_IWRITE)) == -1 )
  189.                 {
  190.                 printf("%s -x-> %s cannot create\n",src,dst);
  191.                 close(shandle);
  192.                 return(1);
  193.                 }
  194.             }
  195.         }
  196.     else
  197.         {
  198.         getftime(dhandle,&dtime);
  199.         if( *((unsigned long *)&dtime) >= *((unsigned long *)&stime) )
  200.                     {
  201.             close(shandle);
  202.             close(dhandle);
  203.             return(0);
  204.             }
  205.         if( filelength(shandle)
  206.              > dfree(ddrive) + fileclususe(dhandle,ddrive))
  207.             {
  208.             printf("%s -x-> %s not enough disk space\n",src,dst);
  209.             close(shandle);
  210.             close(dhandle);
  211.             return(1);
  212.             }
  213.         close(dhandle);
  214.         if( (dhandle = open(dst,O_WRONLY|O_TRUNC|O_BINARY)) == -1 )
  215.             {
  216.             printf("%s -x-> %s protected\n",src,dst);
  217.             close(shandle);
  218.             return(1);
  219.             }
  220.         }
  221.     printf("%s -> %s\n",src,dst);
  222.     {
  223.     int        fin;
  224.     unsigned    j;
  225.  
  226.     for( fin = 0 ; fin == 0 ; )
  227.         {
  228.         for( j = 0; buffsize[j] > 0 && j < 10; j++ )
  229.             if( (buffuse[j]
  230.                  = (unsigned)_read(shandle,buff[j],buffsize[j]))
  231.                  == 0 )
  232.                 {
  233.                 fin = 1;
  234.                 break;
  235.                 }
  236.                 for( j = 0; buffuse[j] > 0 && j < 10; j++ )
  237.                         if( (unsigned)_write(dhandle,buff[j],buffuse[j])
  238.                  < buffuse[j] )
  239.                 {
  240.                 unlink(dst);
  241.                 printf("sorry! may be diskfull,%s is destroyed"
  242.                     ,dst);
  243.                 return(1);
  244.                 }
  245.         }
  246.     }
  247.     setftime(dhandle,&stime);
  248.     close(shandle);
  249.     close(dhandle);
  250.     return(0);
  251.     }
  252. /* end update */
  253.  
  254. char
  255. *strmerge(char *a,char *b)
  256.     {
  257.     char    *p;
  258.  
  259.     if( (p = (char *)malloc(strlen(a)+strlen(b)+1)) == NULL )
  260.         fatal("not enough memory");
  261.     strcpy(p,a);
  262.     strcat(p,b);
  263.     return(p);
  264.     }
  265. /* end strmerge */
  266.  
  267. char
  268. *dirchck(char *path)
  269.     {
  270.     int    isdir_;
  271.     char    *p;
  272.  
  273.     if( (isdir_ = isdir(path)) == 1 )
  274.         path = strmerge(path,"\\*.*");
  275.     else if( isdir_ == 2 )
  276.         path = strmerge(path,"*.*");
  277.     else if( path[1] == ':' && path[2] == '\0' )
  278.         path = strmerge(path,"*.*");
  279.     return(path);
  280.     }
  281. /* end dirchck */
  282.  
  283. main(int ac,char *av[])
  284.     {
  285.     int    oac,aac;
  286.     char    **oav,**aav,*p;
  287.     int    xac,j,isdir_,missdst = 0,copy_if_exist = 0,failcopy = 0;
  288.     int    verify;
  289.     char    *xav[MAXARG],dstdir[MAXPATH+2],work[MAXPATH+2];
  290.     unsigned long    buffall = 0;
  291.     long    dspend;
  292.     int    ddrive;
  293.  
  294.     if( ac < 2 )
  295.         usage();
  296.     verify = getverify();
  297.     setverify(0);
  298.     optarg(ac,av,&oac,&oav,&aac,&aav,"-");
  299.     for( j = 0; j < oac; j++ )
  300.         {
  301.         for( p = oav[j] + 1; *p; p++ )
  302.             switch( *p )
  303.                 {
  304.             case 'e': case 'E':
  305.                 copy_if_exist = 1; break;
  306.             case 'v': case 'V':
  307.                 setverify(1); break;
  308.             default:
  309.                 fatal("unknown option");
  310.                 }
  311.         }
  312.     if( aac == 2 )
  313.         {
  314.         getcwd( dstdir,MAXPATH+2 );
  315.         missdst = 1;
  316.         }
  317.     else
  318.         {
  319.         strcpy(dstdir,aav[aac-1]);
  320.         if( !isdir(dstdir))
  321.             {
  322.             if( dstdir[1] == ':' && dstdir[2] == '\0' )
  323.                 {
  324.                 getcurdir( toupper(dstdir[0]) - '@',work);
  325.                 strcat( dstdir,"\\" );
  326.                 strcat( dstdir,work );
  327.                 }
  328.             else
  329.                 {
  330.                 getcwd( dstdir,MAXPATH+2 );
  331.                 missdst = 1;
  332.                 }
  333.             }
  334.         }
  335.     ddrive = dstdir[1] == ':' ? toupper(dstdir[0]) - '@' : 0;
  336.  
  337.     for( j = 0; j < 10; j++ )
  338.         {
  339.         if( (buffsize[j] = (unsigned)min(MAXBUFF,coreleft())) == 0 )
  340.             break;
  341.         if( (buff[j] = (char *)malloc(buffsize[j])) == NULL )
  342.             {
  343.             buffsize[j] = 0;
  344.             break;
  345.             }
  346.         buffall += buffsize[j];
  347.         }
  348.     if( buffsize[0] < MINBUFF )
  349.         fatal("not enough memory");
  350.     printf("using %lu bytes of buffer\n",buffall);
  351.  
  352.     for( j = 1 ; j < aac - 1 + missdst; j++ )
  353.         aav[j] = dirchck(aav[j]);
  354.  
  355.     xac = exargs(aac-1+missdst,aav,xav,MAXARG);
  356.  
  357.     for( dspend = 0,j = 0 ; j < xac ; j++ )
  358.         dspend += spend(xav[j],dstdir,copy_if_exist);
  359.     if( dspend > dfree(ddrive) )
  360.         fatal("not enough disk space");
  361.     for( j = 0 ; j < xac ; j++ )
  362.         failcopy |= update(xav[j],dstdir,copy_if_exist);
  363.  
  364.     setverify(verify);
  365.     free(buff);
  366.     exit(failcopy);
  367.     }
  368. /* end main */
  369.  
  370. /* end source update.c */