Fixed cvs to work with/without object directories and added missing rcslean
[unix-history] / usr.bin / file / is_tar.c
CommitLineData
15637ed4
RG
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 *
9 * Comments changed and some code/comments reformatted
10 * for file command by Ian Darwin.
11 */
12
13#include <ctype.h>
14#include <sys/types.h>
15#include "tar.h"
16
17#define isodigit(c) ( ((c) >= '0') && ((c) <= '7') )
18
19long from_oct(); /* Decode octal number */
20
21/*
22 * Return
23 * 0 if the checksum is bad (i.e., probably not a tar archive),
24 * 1 for old UNIX tar file,
25 * 2 for Unix Std (POSIX) tar file.
26 */
27int
28is_tar(header)
29 register union record *header;
30{
31 register int i;
32 register long sum, recsum;
33 register char *p;
34
35 recsum = from_oct(8, header->header.chksum);
36
37 sum = 0;
38 p = header->charptr;
39 for (i = sizeof(*header); --i >= 0;) {
40 /*
41 * We can't use unsigned char here because of old compilers,
42 * e.g. V7.
43 */
44 sum += 0xFF & *p++;
45 }
46
47 /* Adjust checksum to count the "chksum" field as blanks. */
48 for (i = sizeof(header->header.chksum); --i >= 0;)
49 sum -= 0xFF & header->header.chksum[i];
50 sum += ' '* sizeof header->header.chksum;
51
52 if (sum != recsum)
53 return 0; /* Not a tar archive */
54
55 if (0==strcmp(header->header.magic, TMAGIC))
56 return 2; /* Unix Standard tar archive */
57
58 return 1; /* Old fashioned tar archive */
59}
60
61
62/*
63 * Quick and dirty octal conversion.
64 *
65 * Result is -1 if the field is invalid (all blank, or nonoctal).
66 */
67long
68from_oct(digs, where)
69 register int digs;
70 register char *where;
71{
72 register long value;
73
74 while (isspace(*where)) { /* Skip spaces */
75 where++;
76 if (--digs <= 0)
77 return -1; /* All blank field */
78 }
79 value = 0;
80 while (digs > 0 && isodigit(*where)) { /* Scan til nonoctal */
81 value = (value << 3) | (*where++ - '0');
82 --digs;
83 }
84
85 if (digs > 0 && *where && !isspace(*where))
86 return -1; /* Ended on non-space/nul */
87
88 return value;
89}