Commit | Line | Data |
---|---|---|
66a734b3 WJ |
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 | ||
19 | long 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 | */ | |
27 | int | |
28 | is_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 | */ | |
67 | long | |
68 | from_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 | } |