[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.6

1.6     ! deraadt     1: /*     $OpenBSD: is_tar.c,v 1.5 2002/02/19 19:39:38 millert 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"
1.6     ! deraadt    19: #include "file.h"
1.1       deraadt    20:
                     21: #define        isodigit(c)     ( ((c) >= '0') && ((c) <= '7') )
                     22:
1.3       millert    23: static int from_oct(int, char*);       /* Decode octal number */
1.1       deraadt    24:
                     25: /*
                     26:  * Return
                     27:  *     0 if the checksum is bad (i.e., probably not a tar archive),
                     28:  *     1 for old UNIX tar file,
                     29:  *     2 for Unix Std (POSIX) tar file.
                     30:  */
                     31: int
                     32: is_tar(buf, nbytes)
                     33: unsigned char *buf;
                     34: int nbytes;
                     35: {
1.4       mpech      36:        union record *header = (union record *)buf;
                     37:        int     i;
                     38:        int     sum, recsum;
                     39:        char    *p;
1.1       deraadt    40:
                     41:        if (nbytes < sizeof(union record))
                     42:                return 0;
                     43:
                     44:        recsum = from_oct(8,  header->header.chksum);
                     45:
                     46:        sum = 0;
                     47:        p = header->charptr;
                     48:        for (i = sizeof(union record); --i >= 0;) {
                     49:                /*
                     50:                 * We can't use unsigned char here because of old compilers,
                     51:                 * e.g. V7.
                     52:                 */
                     53:                sum += 0xFF & *p++;
                     54:        }
                     55:
                     56:        /* Adjust checksum to count the "chksum" field as blanks. */
                     57:        for (i = sizeof(header->header.chksum); --i >= 0;)
                     58:                sum -= 0xFF & header->header.chksum[i];
                     59:        sum += ' '* sizeof header->header.chksum;
                     60:
                     61:        if (sum != recsum)
                     62:                return 0;       /* Not a tar archive */
                     63:
                     64:        if (0==strcmp(header->header.magic, TMAGIC))
                     65:                return 2;               /* Unix Standard tar archive */
                     66:
                     67:        return 1;                       /* Old fashioned tar archive */
                     68: }
                     69:
                     70:
                     71: /*
                     72:  * Quick and dirty octal conversion.
                     73:  *
                     74:  * Result is -1 if the field is invalid (all blank, or nonoctal).
                     75:  */
1.3       millert    76: static int
1.1       deraadt    77: from_oct(digs, where)
1.4       mpech      78:        int     digs;
                     79:        char    *where;
1.1       deraadt    80: {
1.4       mpech      81:        int     value;
1.1       deraadt    82:
                     83:        while (isspace(*where)) {               /* Skip spaces */
                     84:                where++;
                     85:                if (--digs <= 0)
                     86:                        return -1;              /* All blank field */
                     87:        }
                     88:        value = 0;
                     89:        while (digs > 0 && isodigit(*where)) {  /* Scan til nonoctal */
                     90:                value = (value << 3) | (*where++ - '0');
                     91:                --digs;
                     92:        }
                     93:
                     94:        if (digs > 0 && *where && !isspace(*where))
                     95:                return -1;                      /* Ended on non-space/nul */
                     96:
                     97:        return value;
                     98: }