00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include "file.h"
00041 #include "magic.h"
00042 #include <string.h>
00043 #include <ctype.h>
00044 #include <sys/types.h>
00045 #include "tar.h"
00046
00047 #ifndef lint
00048 FILE_RCSID("@(#)$File: is_tar.c,v 1.27 2007/01/12 17:38:28 christos Exp $")
00049 #endif
00050
00051 #define isodigit(c) ( ((c) >= '0') && ((c) <= '7') )
00052
00053 private int is_tar(const unsigned char *, size_t)
00054 ;
00055 private int from_oct(int, const char *)
00056 ;
00057
00058 protected int
00059 file_is_tar(struct magic_set *ms, const unsigned char *buf, size_t nbytes)
00060 {
00061
00062
00063
00064
00065 switch (is_tar(buf, nbytes)) {
00066 case 1:
00067 if (file_printf(ms, (ms->flags & MAGIC_MIME) ?
00068 "application/x-tar" : "tar archive") == -1)
00069 return -1;
00070 return 1;
00071 case 2:
00072 if (file_printf(ms, (ms->flags & MAGIC_MIME) ?
00073 "application/x-tar, POSIX" : "POSIX tar archive") == -1)
00074 return -1;
00075 return 1;
00076 case 3:
00077 if (file_printf(ms, (ms->flags & MAGIC_MIME) ?
00078 "application/x-tar, POSIX (GNU)" :
00079 "POSIX tar archive (GNU)") == -1)
00080 return -1;
00081 return 1;
00082 default:
00083 return 0;
00084 }
00085 }
00086
00087
00088
00089
00090
00091
00092
00093 private int
00094 is_tar(const unsigned char *buf, size_t nbytes)
00095 {
00096 const union record *header = (const union record *)(const void *)buf;
00097 int i;
00098 int sum, recsum;
00099 const char *p;
00100
00101 if (nbytes < sizeof(union record))
00102 return 0;
00103
00104 recsum = from_oct(8, header->header.chksum);
00105
00106 sum = 0;
00107 p = header->charptr;
00108 for (i = sizeof(union record); --i >= 0;) {
00109
00110
00111
00112
00113 sum += 0xFF & *p++;
00114 }
00115
00116
00117 for (i = sizeof(header->header.chksum); --i >= 0;)
00118 sum -= 0xFF & header->header.chksum[i];
00119 sum += ' '* sizeof header->header.chksum;
00120
00121 if (sum != recsum)
00122 return 0;
00123
00124 if (strcmp(header->header.magic, GNUTMAGIC) == 0)
00125 return 3;
00126 if (strcmp(header->header.magic, TMAGIC) == 0)
00127 return 2;
00128
00129 return 1;
00130 }
00131
00132
00133
00134
00135
00136
00137
00138 private int
00139 from_oct(int digs, const char *where)
00140 {
00141 int value;
00142
00143 while (isspace((unsigned char)*where)) {
00144 where++;
00145 if (--digs <= 0)
00146 return -1;
00147 }
00148 value = 0;
00149 while (digs > 0 && isodigit(*where)) {
00150 value = (value << 3) | (*where++ - '0');
00151 --digs;
00152 }
00153
00154 if (digs > 0 && *where && !isspace((unsigned char)*where))
00155 return -1;
00156
00157 return value;
00158 }