Annotation of embedaddon/php/ext/fileinfo/libmagic/is_tar.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (c) Ian F. Darwin 1986-1995.
        !             3:  * Software written by Ian F. Darwin and others;
        !             4:  * maintained 1995-present by Christos Zoulas and others.
        !             5:  * 
        !             6:  * Redistribution and use in source and binary forms, with or without
        !             7:  * modification, are permitted provided that the following conditions
        !             8:  * are met:
        !             9:  * 1. Redistributions of source code must retain the above copyright
        !            10:  *    notice immediately at the beginning of the file, without modification,
        !            11:  *    this list of conditions, and the following disclaimer.
        !            12:  * 2. Redistributions in binary form must reproduce the above copyright
        !            13:  *    notice, this list of conditions and the following disclaimer in the
        !            14:  *    documentation and/or other materials provided with the distribution.
        !            15:  *  
        !            16:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
        !            17:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            18:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            19:  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
        !            20:  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            21:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            22:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            23:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            24:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            25:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            26:  * SUCH DAMAGE.
        !            27:  */
        !            28: /*
        !            29:  * is_tar() -- figure out whether file is a tar archive.
        !            30:  *
        !            31:  * Stolen (by the author!) from the public domain tar program:
        !            32:  * Public Domain version written 26 Aug 1985 John Gilmore (ihnp4!hoptoad!gnu).
        !            33:  *
        !            34:  * @(#)list.c 1.18 9/23/86 Public Domain - gnu
        !            35:  *
        !            36:  * Comments changed and some code/comments reformatted
        !            37:  * for file command by Ian Darwin.
        !            38:  */
        !            39: 
        !            40: #include "file.h"
        !            41: 
        !            42: #ifndef lint
        !            43: FILE_RCSID("@(#)$File: is_tar.c,v 1.36 2009/02/03 20:27:51 christos Exp $")
        !            44: #endif
        !            45: 
        !            46: #include "magic.h"
        !            47: #include <string.h>
        !            48: #include <ctype.h>
        !            49: #include "tar.h"
        !            50: 
        !            51: #define        isodigit(c)     ( ((c) >= '0') && ((c) <= '7') )
        !            52: 
        !            53: private int is_tar(const unsigned char *, size_t);
        !            54: private int from_oct(int, const char *);       /* Decode octal number */
        !            55: 
        !            56: static const char tartype[][32] = {
        !            57:        "tar archive",
        !            58:        "POSIX tar archive",
        !            59:        "POSIX tar archive (GNU)",
        !            60: };
        !            61: 
        !            62: protected int
        !            63: file_is_tar(struct magic_set *ms, const unsigned char *buf, size_t nbytes)
        !            64: {
        !            65:        /*
        !            66:         * Do the tar test first, because if the first file in the tar
        !            67:         * archive starts with a dot, we can confuse it with an nroff file.
        !            68:         */
        !            69:        int tar;
        !            70:        int mime = ms->flags & MAGIC_MIME;
        !            71: 
        !            72:        if ((ms->flags & MAGIC_APPLE) != 0)
        !            73:                return 0;
        !            74: 
        !            75:        tar = is_tar(buf, nbytes);
        !            76:        if (tar < 1 || tar > 3)
        !            77:                return 0;
        !            78: 
        !            79:        if (file_printf(ms, "%s", mime ? "application/x-tar" :
        !            80:            tartype[tar - 1]) == -1)
        !            81:                return -1;
        !            82:        return 1;
        !            83: }
        !            84: 
        !            85: /*
        !            86:  * Return 
        !            87:  *     0 if the checksum is bad (i.e., probably not a tar archive), 
        !            88:  *     1 for old UNIX tar file,
        !            89:  *     2 for Unix Std (POSIX) tar file,
        !            90:  *     3 for GNU tar file.
        !            91:  */
        !            92: private int
        !            93: is_tar(const unsigned char *buf, size_t nbytes)
        !            94: {
        !            95:        const union record *header = (const union record *)(const void *)buf;
        !            96:        int     i;
        !            97:        int     sum, recsum;
        !            98:        const char      *p;
        !            99: 
        !           100:        if (nbytes < sizeof(union record))
        !           101:                return 0;
        !           102: 
        !           103:        recsum = from_oct(8,  header->header.chksum);
        !           104: 
        !           105:        sum = 0;
        !           106:        p = header->charptr;
        !           107:        for (i = sizeof(union record); --i >= 0;) {
        !           108:                /*
        !           109:                 * We cannot use unsigned char here because of old compilers,
        !           110:                 * e.g. V7.
        !           111:                 */
        !           112:                sum += 0xFF & *p++;
        !           113:        }
        !           114: 
        !           115:        /* Adjust checksum to count the "chksum" field as blanks. */
        !           116:        for (i = sizeof(header->header.chksum); --i >= 0;)
        !           117:                sum -= 0xFF & header->header.chksum[i];
        !           118:        sum += ' '* sizeof header->header.chksum;       
        !           119: 
        !           120:        if (sum != recsum)
        !           121:                return 0;       /* Not a tar archive */
        !           122:        
        !           123:        if (strcmp(header->header.magic, GNUTMAGIC) == 0) 
        !           124:                return 3;               /* GNU Unix Standard tar archive */
        !           125:        if (strcmp(header->header.magic, TMAGIC) == 0) 
        !           126:                return 2;               /* Unix Standard tar archive */
        !           127: 
        !           128:        return 1;                       /* Old fashioned tar archive */
        !           129: }
        !           130: 
        !           131: 
        !           132: /*
        !           133:  * Quick and dirty octal conversion.
        !           134:  *
        !           135:  * Result is -1 if the field is invalid (all blank, or nonoctal).
        !           136:  */
        !           137: private int
        !           138: from_oct(int digs, const char *where)
        !           139: {
        !           140:        int     value;
        !           141: 
        !           142:        while (isspace((unsigned char)*where)) {        /* Skip spaces */
        !           143:                where++;
        !           144:                if (--digs <= 0)
        !           145:                        return -1;              /* All blank field */
        !           146:        }
        !           147:        value = 0;
        !           148:        while (digs > 0 && isodigit(*where)) {  /* Scan til nonoctal */
        !           149:                value = (value << 3) | (*where++ - '0');
        !           150:                --digs;
        !           151:        }
        !           152: 
        !           153:        if (digs > 0 && *where && !isspace((unsigned char)*where))
        !           154:                return -1;                      /* Ended on non-space/nul */
        !           155: 
        !           156:        return value;
        !           157: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>