home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2427 / coffdate.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-01-01  |  5.1 KB  |  221 lines

  1. /*    coffdate
  2.  *
  3.  *    displays the date embedded in COFF files and optionally alters the
  4.  *    files' access and modify dates to be that of their COFF f_timdat.
  5.  *
  6.  *    usage:    coffdate  [ -a ]  [ -m ]  [ - { c | s } ]  filelist
  7.  *
  8.  *    where:    -a    resets file's access date&time to the COFF f_timdat
  9.  *        -m    resets file's modify date&time to the COFF f_timdat
  10.  *        -c    list only COFF files (i.e. suppress "not a COFF file")
  11.  *        -s    silent operation
  12.  *
  13.  *    options may be combined noting that -c and -s are mutually exclusive.
  14.  *
  15.  *    This version is for mc68k COFF files; to function with other systems'
  16.  *    COFF files the equates in chkCOFF() need to be changed to reflect those
  17.  *    in /usr/include/sgs.h or /usr/include/filehdr.h on those other systems.
  18.  *
  19.  *    V1.0    30-Dec-1990, Thad Floryan (thad@cup.portal.com)
  20.  */
  21.  
  22. #include <fcntl.h>    /* for low-level I/O definitions    */
  23. #include <filehdr.h>    /* for COFF header first part        */
  24. #include <sgs.h>    /* for COFF magic            */
  25. #include <stdio.h>    /* for standard I/O defs, BUFSIZ, etc.    */
  26. #include <time.h>    /* for ctime(3C) definitions        */
  27. #include <sys/stat.h>
  28. #include <sys/types.h>
  29.  
  30. struct utimbuf {    /* structure for utime(2); not in any *.h file */
  31.     time_t    actime;    /* access time    */
  32.     time_t    modtime;/* modify time    */
  33. };
  34.  
  35. #define CROFFSET 24    /* offset of '\n' in ctime(3C) string    */
  36. #define CTIMELEN 26    /* length of ctime(3C) string        */
  37.  
  38. static char *version = "@(#) coffdate V1.0, Thad Floryan, 30-Dec-1990";
  39.  
  40. static char *usage_text[] = {
  41.     "usage:    coffdate  [ -a ]  [ -m ]  [ - { c | s } ]  filelist\n",
  42.     "where:    -a  resets file's access date&time to the COFF f_timdat",
  43.     "    -m  resets file's modify date&time to the COFF f_timdat",
  44.     "    -c  list only COFF files (i.e. suppress \"not a COFF file\")",
  45.     "    -s  silent operation",
  46.     0
  47. };
  48.  
  49. static int OPTaccess = 0;    /* option switch for access dates    */
  50. static int OPTmodify = 0;    /* option switch for modify dates    */
  51. static int OPTcoff   = 0;    /* option switch for COFF-only        */
  52. static int OPTsilent = 0;    /* option switch for silent operation    */
  53.  
  54. main( argc, argv )
  55.     int    argc;
  56.     char    *argv[];
  57. {
  58.     extern     char *malloc();
  59.     extern    int close(), free(), getopt(), open(), read(), stat(), utime();
  60.  
  61.     extern    int optind;
  62.  
  63.     long    chkCOFF();
  64.     void    dpyCOFF(), usage();
  65.  
  66.     long    COFFdate;    /* -1 if not COFF, else COFF's f_timdat    */
  67.     void    *bufptr;    /* file data input buffer        */
  68.     char    errstr[80];    /* holds expanded error string        */
  69.     int    fd;        /* file descriptor            */
  70.     int    ndx;        /* general loop index and subscript    */
  71.     int    numread;    /* number of bytes read from file    */
  72.     int    optchr;        /* option char from getopt(3C)        */
  73.     struct stat statbuf;    /* buffer for stat(2) results        */
  74.     struct utimbuf ambuf;    /* buffer for utime(2) input        */
  75.  
  76.  
  77.     while ( ( optchr = getopt( argc, argv, "amcs?hH" ) ) != EOF )
  78.     {
  79.         switch (optchr)
  80.         {
  81.         case 'a':    ++OPTaccess;
  82.                 break;
  83.         case 'm':    ++OPTmodify;
  84.                 break;
  85.         case 'c':    if ( OPTsilent )
  86.                     usage();
  87.                 else
  88.                     ++OPTcoff;
  89.                 break;
  90.         case 's':    if ( OPTcoff )
  91.                     usage();
  92.                 else
  93.                     ++OPTsilent;
  94.                 break;
  95.         case '?':
  96.         case 'h':
  97.         case 'H':
  98.         default:    usage();
  99.         }
  100.     }
  101.  
  102.     if ( optind == argc )
  103.     {
  104.         usage();    /* does exit(1) and never returns    */
  105.     }
  106.  
  107.     bufptr = malloc( BUFSIZ );
  108.  
  109.     for ( ndx = optind; ndx < argc; ndx++ )
  110.     {
  111.         if ( ( fd = open( argv[ndx], O_RDONLY, 0 ) ) < 0 )
  112.         {
  113.         sprintf( errstr, "?%s: cannot open %s", argv[0], argv[ndx] );
  114.         perror( errstr );
  115.         }
  116.         else
  117.         {
  118.         COFFdate = -1L;
  119.  
  120.         if ( (numread = read( fd, bufptr, BUFSIZ ) ) < 0 )
  121.         {
  122.             sprintf( errstr, "?%s: error reading %s",
  123.                  argv[0], argv[ndx] );
  124.             perror( errstr );
  125.         }
  126.         else
  127.         {
  128.             COFFdate = chkCOFF( bufptr, numread );
  129.             dpyCOFF( COFFdate, argv[ndx] );
  130.         }
  131.         close( fd );
  132.  
  133.         if ( COFFdate >= 0 && ( OPTaccess || OPTmodify ) )
  134.         {
  135.             if ( stat ( argv[ndx], &statbuf ) < 0 )
  136.             {
  137.             sprintf( errstr,"?%s: stat() failure on %s",
  138.                  argv[0], argv[ndx] );
  139.             perror( errstr );
  140.             }
  141.             else
  142.             {
  143.             ambuf.actime  = (OPTaccess) ? (time_t) COFFdate :
  144.                               statbuf.st_atime;
  145.             ambuf.modtime = (OPTmodify) ? (time_t) COFFdate :
  146.                               statbuf.st_mtime;
  147.             if ( utime( argv[ndx], &ambuf ) < 0 )
  148.             {
  149.                 sprintf( errstr,"?%s: utime() failure for %s",
  150.                      argv[0], argv[ndx] );
  151.                 perror( errstr );
  152.             }
  153.             }
  154.         }
  155.         }
  156.     }
  157.     free( bufptr );
  158. }
  159.  
  160. long chkCOFF( bufptr, bufsize )
  161.     FILHDR    *bufptr;
  162.     int    bufsize;
  163. {
  164.     int    magic;
  165.  
  166.     if ( bufsize > FILHSZ )
  167.     {
  168.         magic = bufptr->f_magic;
  169.  
  170.         if (magic == AOUT1MAGIC    ||
  171.         magic == AOUT2MAGIC    ||
  172.         magic == AOUT3MAGIC    ||
  173.         magic == MC68KWRMAGIC    ||
  174.         magic == MC68KROMAGIC    ||
  175.         magic == MC68KPGMAGIC      )
  176.         {
  177.         return bufptr->f_timdat;
  178.         }
  179.         else
  180.         {
  181.         return -1L;
  182.         }
  183.     }
  184.     else
  185.     {
  186.         return -1L;
  187.     }
  188. }
  189.  
  190. void dpyCOFF( ldate, filename )
  191.     long    ldate;
  192.     char    *filename;
  193. {
  194.     char    timebuf[CTIMELEN];
  195.  
  196.     if ( OPTsilent ) return;
  197.  
  198.     if ( ldate >= 0L )
  199.     {
  200.         strcpy( timebuf, ctime( &ldate ) );
  201.         timebuf[CROFFSET] = '\0';
  202.         fprintf( stdout, "%s  %s\n", timebuf, filename );
  203.     }
  204.     else if ( OPTcoff == 0 )
  205.     {
  206.         fprintf( stdout, "not a COFF file           %s\n", filename );
  207.     }
  208. }
  209.  
  210. void usage()
  211. {
  212.     int    ndx = 0;
  213.  
  214.     while ( usage_text[ndx] != 0 )
  215.     {
  216.         fprintf( stderr, "%s\n", usage_text[ndx++] );
  217.     }
  218.     fprintf( stderr, "%s\n", version );
  219.     exit( 1 );
  220. }
  221.