[BACK]Return to is_tar.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / file

Annotation of src/usr.bin/file/is_tar.c, Revision 1.5

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