home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / file39a.zip / src / is_tar.c < prev    next >
C/C++ Source or Header  |  1993-04-05  |  2KB  |  97 lines

  1. /*
  2.  * is_tar() -- figure out whether file is a tar archive.
  3.  *
  4.  * Stolen (by the author!) from the public domain tar program:
  5.  * Pubic Domain version written 26 Aug 1985 John Gilmore (ihnp4!hoptoad!gnu).
  6.  *
  7.  * @(#)list.c 1.18 9/23/86 Public Domain - gnu
  8.  * $Id: is_tar.c,v 1.7 92/09/08 15:32:19 ian Exp $
  9.  *
  10.  * Comments changed and some code/comments reformatted
  11.  * for file command by Ian Darwin.
  12.  */
  13.  
  14. #include <string.h>
  15. #include <ctype.h>
  16. #include <sys/types.h>
  17. #include "tar.h"
  18.  
  19. #define    isodigit(c)    ( ((c) >= '0') && ((c) <= '7') )
  20.  
  21. #if    defined(__STDC__) || defined(__cplusplus)
  22. static long from_oct(int, char*);    /* Decode octal number */
  23. #else
  24. static long from_oct();
  25. #endif
  26.  
  27. /*
  28.  * Return 
  29.  *    0 if the checksum is bad (i.e., probably not a tar archive), 
  30.  *    1 for old UNIX tar file,
  31.  *    2 for Unix Std (POSIX) tar file.
  32.  */
  33. int
  34. is_tar(buf)
  35. unsigned char *buf;
  36. {
  37.     register union record *header = (union record *)buf;
  38.     register int    i;
  39.     register long    sum, recsum;
  40.     register char    *p;
  41.  
  42.     recsum = from_oct(8,  header->header.chksum);
  43.  
  44.     sum = 0;
  45.     p = header->charptr;
  46.     for (i = sizeof(union record); --i >= 0;) {
  47.         /*
  48.          * We can't use unsigned char here because of old compilers,
  49.          * e.g. V7.
  50.          */
  51.         sum += 0xFF & *p++;
  52.     }
  53.  
  54.     /* Adjust checksum to count the "chksum" field as blanks. */
  55.     for (i = sizeof(header->header.chksum); --i >= 0;)
  56.         sum -= 0xFF & header->header.chksum[i];
  57.     sum += ' '* sizeof header->header.chksum;    
  58.  
  59.     if (sum != recsum)
  60.         return 0;    /* Not a tar archive */
  61.     
  62.     if (0==strcmp(header->header.magic, TMAGIC)) 
  63.         return 2;        /* Unix Standard tar archive */
  64.  
  65.     return 1;            /* Old fashioned tar archive */
  66. }
  67.  
  68.  
  69. /*
  70.  * Quick and dirty octal conversion.
  71.  *
  72.  * Result is -1 if the field is invalid (all blank, or nonoctal).
  73.  */
  74. static long
  75. from_oct(digs, where)
  76.     register int    digs;
  77.     register char    *where;
  78. {
  79.     register long    value;
  80.  
  81.     while (isspace(*where)) {        /* Skip spaces */
  82.         where++;
  83.         if (--digs <= 0)
  84.             return -1;        /* All blank field */
  85.     }
  86.     value = 0;
  87.     while (digs > 0 && isodigit(*where)) {    /* Scan til nonoctal */
  88.         value = (value << 3) | (*where++ - '0');
  89.         --digs;
  90.     }
  91.  
  92.     if (digs > 0 && *where && !isspace(*where))
  93.         return -1;            /* Ended on non-space/nul */
  94.  
  95.     return value;
  96. }
  97.