This commit was generated by cvs2svn to track changes on a CVS vendor
[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
286a6f32 8 * is_tar.c,v 1.2 1993/06/10 00:38:12 jtc Exp
15637ed4
RG
9 *
10 * Comments changed and some code/comments reformatted
11 * for file command by Ian Darwin.
12 */
13
286a6f32 14#include <string.h>
15637ed4
RG
15#include <ctype.h>
16#include <sys/types.h>
17#include "tar.h"
18
19#define isodigit(c) ( ((c) >= '0') && ((c) <= '7') )
20
286a6f32
C
21#if defined(__STDC__) || defined(__cplusplus)
22static long from_oct(int, char*); /* Decode octal number */
23#else
24static long from_oct();
25#endif
15637ed4
RG
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 */
33int
286a6f32
C
34is_tar(buf)
35unsigned char *buf;
15637ed4 36{
286a6f32 37 register union record *header = (union record *)buf;
15637ed4
RG
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;
286a6f32 46 for (i = sizeof(union record); --i >= 0;) {
15637ed4
RG
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 */
286a6f32 74static long
15637ed4
RG
75from_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}