2 * is_tar() -- figure out whether file is a tar archive.
4 * Stolen (by the author!) from the public domain tar program:
5 * Public Domain version written 26 Aug 1985 John Gilmore (ihnp4!hoptoad!gnu).
7 * @(#)list.c 1.18 9/23/86 Public Domain - gnu
8 * $Id: is_tar.c,v 1.17 2002/07/03 18:26:38 christos Exp $
10 * Comments changed and some code/comments reformatted
11 * for file command by Ian Darwin.
17 #include <sys/types.h>
21 FILE_RCSID("@(#)$Id: is_tar.c,v 1.17 2002/07/03 18:26:38 christos Exp $")
24 #define isodigit(c) ( ((c) >= '0') && ((c) <= '7') )
26 static int from_oct(int, char *); /* Decode octal number */
30 * 0 if the checksum is bad (i.e., probably not a tar archive),
31 * 1 for old UNIX tar file,
32 * 2 for Unix Std (POSIX) tar file.
35 is_tar(unsigned char *buf, int nbytes)
37 union record *header = (union record *)buf;
42 if (nbytes < sizeof(union record))
45 recsum = from_oct(8, header->header.chksum);
49 for (i = sizeof(union record); --i >= 0;) {
51 * We can't use unsigned char here because of old compilers,
57 /* Adjust checksum to count the "chksum" field as blanks. */
58 for (i = sizeof(header->header.chksum); --i >= 0;)
59 sum -= 0xFF & header->header.chksum[i];
60 sum += ' '* sizeof header->header.chksum;
63 return 0; /* Not a tar archive */
65 if (0==strcmp(header->header.magic, TMAGIC))
66 return 2; /* Unix Standard tar archive */
68 return 1; /* Old fashioned tar archive */
73 * Quick and dirty octal conversion.
75 * Result is -1 if the field is invalid (all blank, or nonoctal).
78 from_oct(int digs, char *where)
82 while (isspace((unsigned char)*where)) { /* Skip spaces */
85 return -1; /* All blank field */
88 while (digs > 0 && isodigit(*where)) { /* Scan til nonoctal */
89 value = (value << 3) | (*where++ - '0');
93 if (digs > 0 && *where && !isspace((unsigned char)*where))
94 return -1; /* Ended on non-space/nul */