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>