home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1992 June / SIMTEL_0692.cdr / msdos / dirutl / ma_touch.arc / TOUCH.C < prev    next >
Encoding:
C/C++ Source or Header  |  1988-10-21  |  5.8 KB  |  300 lines

  1. /*title  touch -- change modification dates on files */
  2.  
  3. /* 3 October 1987 -- M. Armbrust */
  4. /* 21 October 1988 -- M. Armbrust -- added "-f" option */
  5.  
  6. /*noinclude*/
  7. #include <stdio.h>
  8. #include <process.h>
  9. #include <dos.h>
  10. /*include*/
  11.  
  12. void main(int ,char * *);
  13. void Usage(void);
  14. int GetNum(char * *);
  15. void SetFileTime(char *);
  16. void GetTime(void);
  17. void GetFileTime(char *);
  18.  
  19. int                status = 0;
  20. int                create = 0;
  21. int                readonly = 0;
  22. int                gotDate = 0;
  23. int                gotTime = 0;
  24. struct    {
  25.     int                year;
  26.     int                month;
  27.     int                day;
  28.     int                hour;
  29.     int                minute;
  30.     int                second;
  31.     }            dt;
  32. int                days[12] = {31,29,31,30,31,30,31,31,30,31,30,31};
  33.  
  34. void main (argc, argv)
  35.     int                argc;
  36.     char            *argv[];
  37.     {
  38.  
  39.     GetTime ();
  40.  
  41.     if (argc == 1) Usage();
  42.  
  43.     while (--argc) {
  44.         if ((**++argv == '-' || **argv == '/') 
  45.                                         && (*argv)[1] != 0 && (*argv)[2] == 0)
  46.             switch ((*argv)[1]) {
  47.  
  48.                 case 'c':
  49.                 case 'C':
  50.                     create = 1;
  51.                     break;
  52.  
  53.                 case 'r':
  54.                 case 'R':
  55.                     readonly =1;
  56.                     break;
  57.  
  58.                 case 'd':
  59.                 case 'D':
  60.                     if (!--argc) 
  61.                         Usage();
  62.                     ++argv;
  63.  
  64.                     gotDate = 1;
  65.                     if (!gotTime) 
  66.                         dt.hour = dt.minute = dt.second = 0;
  67.  
  68.                     dt.month = GetNum (argv);
  69.                     if (dt.month < 1 || dt.month > 12) 
  70.                         Usage();
  71.  
  72.                     if (**argv != '/' && **argv != '-') 
  73.                         Usage();
  74.  
  75.                     ++*argv;
  76.  
  77.                     dt.day = GetNum (argv);
  78.                     if (dt.day < 1 || dt.day > days[dt.month-1]) 
  79.                         Usage();
  80.  
  81.                     if (!**argv) 
  82.                         break;
  83.  
  84.                     if (**argv != '/' && **argv != '-') 
  85.                         Usage();
  86.  
  87.                     ++*argv;
  88.  
  89.                     dt.year = GetNum (argv);
  90.                     if (dt.year < 80) 
  91.                         dt.year += 2000;
  92.                     if (dt.year <= 99) 
  93.                         dt.year += 1900;
  94.                     if (dt.year < 1980) 
  95.                         Usage();
  96.  
  97.                     if (**argv) 
  98.                         Usage();
  99.  
  100.                     break;
  101.  
  102.                 case 't':
  103.                 case 'T':
  104.                     if (!--argc) 
  105.                         Usage();
  106.                     ++argv;
  107.  
  108.                     gotTime = 1;
  109.  
  110.                     dt.hour = GetNum (argv);
  111.                     if (dt.hour < 0 || dt.hour > 23) 
  112.                         Usage();
  113.  
  114.                     if (**argv != ':') 
  115.                         Usage();
  116.  
  117.                     ++*argv;
  118.  
  119.                     dt.minute = GetNum (argv);
  120.                     if (dt.minute < 0 || dt.minute > 59) 
  121.                         Usage();
  122.  
  123.                     if (!**argv) 
  124.                         break;
  125.  
  126.                     if (**argv != ':') 
  127.                         Usage();
  128.  
  129.                     ++*argv;
  130.  
  131.                     dt.second = GetNum (argv);
  132.                     if (dt.second < 0 || dt.second > 59) 
  133.                         Usage();
  134.  
  135.                     if (**argv) 
  136.                         Usage();
  137.  
  138.                     break;
  139.  
  140.                 case 'f':
  141.                 case 'F':
  142.  
  143.                     ++argv;
  144.                     --argc;
  145.  
  146.                     if (argc == 0 || **argv == '-' || **argv == '/') {
  147.                         fprintf (stderr, "touch: -f requires filename\n");
  148.                         exit(4);
  149.                         }
  150.  
  151.                     GetFileTime (*argv);
  152.                     break;
  153.  
  154.                 default:
  155.                     Usage();
  156.                 }
  157.  
  158.         else
  159.             SetFileTime (*argv);
  160.  
  161.         }
  162.  
  163.     exit (status);
  164.     }
  165.  
  166.  
  167. void Usage ()
  168.     {
  169.     fprintf (stderr, "usage:  touch [-c] [-r] [-d mm/dd[/yy]] [-t hh:mm[:ss]] [-f file] files\n");
  170.     fprintf (stderr, "           -c create file if does not exist\n");
  171.     fprintf (stderr, "           -r force access to read-only files\n");
  172.     fprintf (stderr, "           -d date to set; defaults to current date if time specified\n");
  173.     fprintf (stderr, "           -t time to set; defaults to 00:00:00 if date specified\n");
  174.     fprintf (stderr, "           -f copy file's time stamp to other files\n");
  175.     exit (1);
  176.     }
  177.  
  178.  
  179. int GetNum (argv)
  180.     char **argv;
  181.     {
  182.     register int num = 0;
  183.     register int c;
  184.  
  185.     while ( (c = **argv) >= '0' && c <= '9') {
  186.         num = num * 10 + c - '0';
  187.         ++*argv;
  188.         }
  189.     return num;
  190.     }
  191.  
  192.  
  193. void SetFileTime (file)
  194.     char        *file;
  195.     {
  196.     union REGS    r;
  197.     int            handle;
  198.  
  199.     r.h.ah = 0x3D;    /* open handle for write */
  200.     r.h.al = (unsigned char) (readonly ? 0 : 1);
  201.     r.x.dx = (int) file;
  202.     intdos (&r, &r);
  203.     if (r.x.cflag && r.x.ax <= 3 && create) {
  204.         r.h.ah = 0x3C;        /* create/open handle */
  205.         r.x.cx = 0;
  206.         r.x.dx = (int) file;
  207.         intdos (&r, &r);
  208.         }
  209.     if (r.x.cflag) {
  210.         fprintf (stderr, "touch: could not access \"%s\"; ", file);
  211.         switch (r.x.ax) {
  212.             case 2: fprintf (stderr, "file not found.\n");
  213.                     break;
  214.             case 3: fprintf (stderr, "path not found.\n");
  215.                     break;
  216.             case 4: fprintf (stderr, "too many open files.\n");
  217.                     break;
  218.             case 5: fprintf (stderr, "access denied.\n");
  219.                     break;
  220.             default:fprintf (stderr, "unknown error.\n");
  221.             }
  222.         status = 2;
  223.         return;
  224.         }
  225.     handle = r.x.ax;
  226.  
  227.     r.x.ax = 0x5701;    /* set file date/time */
  228.     r.x.bx = handle;
  229.     r.x.cx = (dt.hour << 11) + (dt.minute << 5) + ((dt.second + 1) >> 1);
  230.     r.x.dx = ((dt.year - 1980) << 9) + (dt.month << 5) + dt.day;
  231.     intdos (&r, &r);
  232.  
  233.     r.h.ah = 0x3E;        /* close handle */
  234.     r.x.bx = handle;
  235.     intdos (&r, &r);
  236.     }
  237.  
  238.  
  239. void GetTime ()
  240.     {
  241.     union REGS r;
  242.  
  243.     r.h.ah = 0x2A;        /* Get Date */
  244.     intdos (&r, &r);
  245.     dt.year = r.x.cx;
  246.     dt.month = r.h.dh;
  247.     dt.day = r.h.dl;
  248.  
  249.     r.h.ah = 0x2C;        /* Get Time */
  250.     intdos (&r, &r);
  251.     dt.hour = r.h.ch;
  252.     dt.minute = r.h.cl;
  253.     dt.second = r.h.dh;
  254.     }
  255.  
  256.  
  257. void GetFileTime (file)
  258.     char        *file;
  259.     {
  260.     union REGS    r;
  261.     int            handle;
  262.  
  263.     r.x.ax = 0x3D00;        /* open handle for read */
  264.     r.x.dx = (int) file;
  265.     intdos (&r, &r);
  266.     if (r.x.cflag) {
  267.         fprintf (stderr, "touch:  -f could not access \"%s\"; ", file);
  268.         switch (r.x.ax) {
  269.             case 2: fprintf (stderr, "file not found.\n");
  270.                     break;
  271.             case 3: fprintf (stderr, "path not found.\n");
  272.                     break;
  273.             case 4: fprintf (stderr, "too many open files.\n");
  274.                     break;
  275.             case 5: fprintf (stderr, "access denied.\n");
  276.                     break;
  277.             default:fprintf (stderr, "unknown error.\n");
  278.             }
  279.         exit (4);
  280.         }
  281.     handle = r.x.ax;
  282.  
  283.     r.x.ax = 0x5700;    /* get file date/time */
  284.     r.x.bx = handle;
  285.     intdos (&r, &r);
  286.  
  287.     dt.year   = ((r.x.dx >> 9) & 0x7F) + 1980;
  288.     dt.month  = (r.x.dx >> 5) & 0x0F;
  289.     dt.day    = r.x.dx & 0x1F;
  290.     dt.hour   = (r.x.cx >> 11) & 0x1F;
  291.     dt.minute = (r.x.cx >> 5) & 0x3F;
  292.     dt.second = (r.x.cx << 1) & 0x3F;
  293.  
  294.     r.h.ah = 0x3E;        /* close handle */
  295.     r.x.bx = handle;
  296.     intdos (&r, &r);
  297.     }
  298.  
  299.  
  300.