version 1.6, 2003/08/02 18:42:11 |
version 1.7, 2004/05/19 02:32:35 |
|
|
/* $OpenBSD$ */ |
/* $OpenBSD$ */ |
|
|
/* |
/* |
|
* Copyright (c) Ian F. Darwin 1986-1995. |
|
* Software written by Ian F. Darwin and others; |
|
* maintained 1995-present by Christos Zoulas and others. |
|
* |
|
* Redistribution and use in source and binary forms, with or without |
|
* modification, are permitted provided that the following conditions |
|
* are met: |
|
* 1. Redistributions of source code must retain the above copyright |
|
* notice immediately at the beginning of the file, without modification, |
|
* this list of conditions, and the following disclaimer. |
|
* 2. Redistributions in binary form must reproduce the above copyright |
|
* notice, this list of conditions and the following disclaimer in the |
|
* documentation and/or other materials provided with the distribution. |
|
* |
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND |
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR |
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
|
* SUCH DAMAGE. |
|
*/ |
|
/* |
* is_tar() -- figure out whether file is a tar archive. |
* is_tar() -- figure out whether file is a tar archive. |
* |
* |
* Stolen (by the author!) from the public domain tar program: |
* Stolen (by the author!) from the public domain tar program: |
* Pubic Domain version written 26 Aug 1985 John Gilmore (ihnp4!hoptoad!gnu). |
* Public Domain version written 26 Aug 1985 John Gilmore (ihnp4!hoptoad!gnu). |
* |
* |
* @(#)list.c 1.18 9/23/86 Public Domain - gnu |
* @(#)list.c 1.18 9/23/86 Public Domain - gnu |
* |
* |
|
|
* for file command by Ian Darwin. |
* for file command by Ian Darwin. |
*/ |
*/ |
|
|
|
#include "file.h" |
|
#include "magic.h" |
#include <string.h> |
#include <string.h> |
#include <ctype.h> |
#include <ctype.h> |
#include <sys/types.h> |
#include <sys/types.h> |
#include "tar.h" |
#include "tar.h" |
#include "file.h" |
|
|
|
|
#ifndef lint |
|
FILE_RCSID("@(#)$Id$") |
|
#endif |
|
|
#define isodigit(c) ( ((c) >= '0') && ((c) <= '7') ) |
#define isodigit(c) ( ((c) >= '0') && ((c) <= '7') ) |
|
|
static int from_oct(int, char*); /* Decode octal number */ |
private int is_tar(const unsigned char *, size_t); |
|
private int from_oct(int, const char *); /* Decode octal number */ |
|
|
|
protected int |
|
file_is_tar(struct magic_set *ms, const unsigned char *buf, size_t nbytes) |
|
{ |
|
/* |
|
* Do the tar test first, because if the first file in the tar |
|
* archive starts with a dot, we can confuse it with an nroff file. |
|
*/ |
|
switch (is_tar(buf, nbytes)) { |
|
case 1: |
|
if (file_printf(ms, (ms->flags & MAGIC_MIME) ? |
|
"application/x-tar" : "tar archive") == -1) |
|
return -1; |
|
return 1; |
|
case 2: |
|
if (file_printf(ms, (ms->flags & MAGIC_MIME) ? |
|
"application/x-tar, POSIX" : "POSIX tar archive") == -1) |
|
return -1; |
|
return 1; |
|
default: |
|
return 0; |
|
} |
|
} |
|
|
/* |
/* |
* Return |
* Return |
* 0 if the checksum is bad (i.e., probably not a tar archive), |
* 0 if the checksum is bad (i.e., probably not a tar archive), |
* 1 for old UNIX tar file, |
* 1 for old UNIX tar file, |
* 2 for Unix Std (POSIX) tar file. |
* 2 for Unix Std (POSIX) tar file. |
*/ |
*/ |
int |
private int |
is_tar(buf, nbytes) |
is_tar(const unsigned char *buf, size_t nbytes) |
unsigned char *buf; |
|
int nbytes; |
|
{ |
{ |
union record *header = (union record *)buf; |
const union record *header = (const union record *)(const void *)buf; |
int i; |
int i; |
int sum, recsum; |
int sum, recsum; |
char *p; |
const char *p; |
|
|
if (nbytes < sizeof(union record)) |
if (nbytes < sizeof(union record)) |
return 0; |
return 0; |
|
|
p = header->charptr; |
p = header->charptr; |
for (i = sizeof(union record); --i >= 0;) { |
for (i = sizeof(union record); --i >= 0;) { |
/* |
/* |
* We can't use unsigned char here because of old compilers, |
* We cannot use unsigned char here because of old compilers, |
* e.g. V7. |
* e.g. V7. |
*/ |
*/ |
sum += 0xFF & *p++; |
sum += 0xFF & *p++; |
|
|
* |
* |
* Result is -1 if the field is invalid (all blank, or nonoctal). |
* Result is -1 if the field is invalid (all blank, or nonoctal). |
*/ |
*/ |
static int |
private int |
from_oct(digs, where) |
from_oct(int digs, const char *where) |
int digs; |
|
char *where; |
|
{ |
{ |
int value; |
int value; |
|
|
while (isspace(*where)) { /* Skip spaces */ |
while (isspace((unsigned char)*where)) { /* Skip spaces */ |
where++; |
where++; |
if (--digs <= 0) |
if (--digs <= 0) |
return -1; /* All blank field */ |
return -1; /* All blank field */ |
|
|
--digs; |
--digs; |
} |
} |
|
|
if (digs > 0 && *where && !isspace(*where)) |
if (digs > 0 && *where && !isspace((unsigned char)*where)) |
return -1; /* Ended on non-space/nul */ |
return -1; /* Ended on non-space/nul */ |
|
|
return value; |
return value; |