Rizin
unix-like reverse engineering framework and cli tools
is_tar.c
Go to the documentation of this file.
1 /* $OpenBSD: is_tar.c,v 1.10 2009/10/27 23:59:37 deraadt Exp $ */
2 /*
3  * Copyright (c) Ian F. Darwin 1986-1995.
4  * Software written by Ian F. Darwin and others;
5  * maintained 1995-present by Christos Zoulas and others.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  * notice immediately at the beginning of the file, without modification,
12  * this list of conditions, and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in the
15  * documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
21  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29 /*
30  * is_tar() -- figure out whether file is a tar archive.
31  *
32  * Stolen (by the author!) from the public domain tar program:
33  * Public Domain version written 26 Aug 1985 John Gilmore (ihnp4!hoptoad!gnu).
34  *
35  * @(#)list.c 1.18 9/23/86 Public Domain - gnu
36  *
37  * Comments changed and some code/comments reformatted
38  * for file command by Ian Darwin.
39  */
40 #include <rz_userconf.h>
41 
42 #if !USE_LIB_MAGIC
43 
44 #include "file.h"
45 #include <string.h>
46 #include <ctype.h>
47 #include <sys/types.h>
48 #include "tar.h"
49 
50 static const char tartype[][32] = {
51  "tar archive",
52  "POSIX tar archive",
53  "POSIX tar archive (GNU)",
54 };
55 
56 /*
57  * Quick and dirty octal conversion.
58  *
59  * Result is -1 if the field is invalid (all blank, or nonoctal).
60  */
61 #define isodigit(c) (((c) >= '0') && ((c) <= '7'))
62 static int from_oct(int digs, const char *where) {
63  int value = 0;
64  while (isspace((ut8)*where)) { /* Skip spaces */
65  where++;
66  if (--digs <= 0) {
67  return -1; /* All blank field */
68  }
69  }
70  while (digs > 0 && isodigit(*where)) { /* Scan til nonoctal */
71  value = (value << 3) | (*where++ - '0');
72  --digs;
73  }
74  if (digs > 0 && *where && !isspace((ut8)*where)) {
75  return -1; /* Ended on non-space/nul */
76  }
77  return value;
78 }
79 
80 /*
81  * Return
82  * 0 if the checksum is bad (i.e., probably not a tar archive),
83  * 1 for old UNIX tar file,
84  * 2 for Unix Std (POSIX) tar file,
85  * 3 for GNU tar file.
86  */
87 static int is_tar(const ut8 *buf, size_t nbytes) {
88  const union record *header = (const union record *)(const void *)buf;
89  int i, sum, recsum;
90  const char *p;
91 
92  if (nbytes < sizeof(union record)) {
93  return 0;
94  }
95 
96  recsum = from_oct(8, header->header.chksum);
97 
98  sum = 0;
99  p = header->charptr;
100  for (i = sizeof(union record); --i >= 0;) {
101  /*
102  * We cannot use ut8 here because of old compilers,
103  * e.g. V7.
104  */
105  sum += 0xFF & *p++;
106  }
107 
108  /* Adjust checksum to count the "chksum" field as blanks. */
109  for (i = sizeof header->header.chksum; --i >= 0;) {
110  sum -= 0xFF & header->header.chksum[i];
111  }
112  sum += ' ' * sizeof header->header.chksum;
113  if (sum != recsum) {
114  return 0; /* Not a tar archive */
115  }
116  if (strcmp(header->header.magic, GNUTMAGIC) == 0) {
117  return 3; /* GNU Unix Standard tar archive */
118  }
119  if (strcmp(header->header.magic, TMAGIC) == 0) {
120  return 2; /* Unix Standard tar archive */
121  }
122  return 1; /* Old fashioned tar archive */
123 }
124 
125 int file_is_tar(RzMagic *ms, const ut8 *buf, size_t nbytes) {
126  /*
127  * Do the tar test first, because if the first file in the tar
128  * archive starts with a dot, we can confuse it with an nroff file.
129  */
130  int tar = is_tar(buf, nbytes);
131  int mime = ms->flags & RZ_MAGIC_MIME;
132 
133  if (tar < 1 || tar > 3) {
134  return 0;
135  }
136  if (mime == RZ_MAGIC_MIME_ENCODING) {
137  return 0;
138  }
139  if (file_printf(ms, mime ? "application/x-tar" : tartype[tar - 1]) == -1) {
140  return -1;
141  }
142  return 1;
143 }
144 #endif
lzma_index ** i
Definition: index.h:629
static int value
Definition: cmd_api.c:93
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void nbytes
Definition: sflib.h:113
int file_printf(struct rz_magic_set *, const char *,...)
checking print the parsed form of the magic use in n conjunction with m to debug a new magic file n before installing it n mime
Definition: file_opts.h:30
voidpf void * buf
Definition: ioapi.h:138
static int is_tar(const ut8 *buf, size_t nbytes)
Definition: is_tar.c:87
int file_is_tar(RzMagic *ms, const ut8 *buf, size_t nbytes)
Definition: is_tar.c:125
#define isodigit(c)
Definition: is_tar.c:61
static int from_oct(int digs, const char *where)
Definition: is_tar.c:62
static const char tartype[][32]
Definition: is_tar.c:50
uint8_t ut8
Definition: lh5801.h:11
void * p
Definition: libc.cpp:67
#define header(is_bt, len_min, ret_op)
#define isspace(c)
Definition: safe-ctype.h:141
#define TMAGIC
Definition: tar.h:73
#define GNUTMAGIC
Definition: tar.h:74
Definition: tar.h:52
int tar(gzFile in, int action, int arg, int argc, char **argv)
Definition: untgz.c:386