1 /* @(#)file.c 1.10 09/08/04 joerg */
2 #ifndef lint
3 static const char sccsid[] =
4 "@(#)file.c 1.10 09/08/04 joerg";
5 #endif
6 /*
7 ** find file types by using a modified "magic" file
8 **
9 ** based on file v3.22 by Ian F. Darwin (see below)
10 **
11 ** For each entry in the magic file, the message MUST start with
12 ** two 4 character strings which are the CREATOR and TYPE for the
13 ** Mac file. Any continuation lines are ignored. e.g magic entry
14 ** for a GIF file:
15 **
16 ** 0 string GIF8 8BIM GIFf
17 ** >4 string 7a \b, version 8%s,
18 ** >4 string 9a \b, version 8%s,
19 ** >6 leshort >0 %hd x
20 ** >8 leshort >0 %hd,
21 ** #>10 byte &0x80 color mapped,
22 ** #>10 byte&0x07 =0x00 2 colors
23 ** #>10 byte&0x07 =0x01 4 colors
24 ** #>10 byte&0x07 =0x02 8 colors
25 ** #>10 byte&0x07 =0x03 16 colors
26 ** #>10 byte&0x07 =0x04 32 colors
27 ** #>10 byte&0x07 =0x05 64 colors
28 ** #>10 byte&0x07 =0x06 128 colors
29 ** #>10 byte&0x07 =0x07 256 colors
30 **
31 ** Just the "8BIM" "GIFf" will be used whatever the type GIF file
32 ** it is.
33 **
34 ** Modified for mkhybrid James Pearson 19/5/98
35 */
36
37 /*
38 * file - find type of a file or files - main program.
39 *
40 * Copyright (c) Ian F. Darwin, 1987.
41 * Written by Ian F. Darwin.
42 *
43 * This software is not subject to any export provision of the United States
44 * Department of Commerce, and may be exported to any country or planet.
45 *
46 * Redistribution and use in source and binary forms, with or without
47 * modification, are permitted provided that the following conditions
48 * are met:
49 * 1. Redistributions of source code must retain the above copyright
50 * notice immediately at the beginning of the file, without modification,
51 * this list of conditions, and the following disclaimer.
52 * 2. Redistributions in binary form must reproduce the above copyright
53 * notice, this list of conditions and the following disclaimer in the
54 * documentation and/or other materials provided with the distribution.
55 *
56 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
57 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
58 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
59 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
60 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
61 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
62 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
63 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
64 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
65 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
66 * SUCH DAMAGE.
67 */
68 #ifndef lint
69 static const char moduleid[] =
70 "@(#)Id: file.c,v 1.38 1997/01/15 19:28:35 christos Exp";
71 #endif /* lint */
72
73 #include <stdio.h>
74 #include <stdlib.h>
75 #include <unistd.h> /* for read() */
76 #include <sys/stat.h>
77 #include <fcntl.h> /* for open() */
78
79 #ifdef RESTORE_TIME
80 #include <schily/utime.h>
81 #ifdef HAVE_UTIMES
82 #define USE_UTIMES
83 #endif
84 #endif
85
86 #include "patchlevel.h"
87 #include "file.h"
88
89 #ifdef MAIN
90 /* Global command-line options */
91 #ifdef DEBUG
92 int debug = 1; /* debugging */
93 #else
94 int debug = 0; /* debugging */
95 #endif /* DEBUG */
96 int lflag = 0; /* follow Symlinks (BSD only) */
97 int zflag = 0; /* follow (uncompress) compressed files */
98
99 /* Misc globals */
100 char *magicfile; /* where magic be found */
101
102 char *progname; /* used throughout */
103 #endif
104
105 char * get_magic_match (const char *inname);
106 void clean_magic (void);
107
108 /*
109 * get_magic_match - get the CREATOR/TYPE string
110 * based on the original process()
111 */
112 char *
get_magic_match(const char * inname)113 get_magic_match(const char *inname)
114 {
115 int fd = 0;
116 unsigned char buf[HOWMANY+1]; /* one extra for terminating '\0' */
117 struct stat sb;
118 int nbytes = 0; /* number of bytes read from a datafile */
119 char *match;
120
121 /* check the file is regular and non-zero length */
122 if (stat(inname, &sb) != 0)
123 return 0;
124
125 if (sb.st_size == 0 || ! S_ISREG(sb.st_mode))
126 return 0;
127
128 if ((fd = open(inname, O_RDONLY)) < 0)
129 return 0;
130
131 /*
132 * try looking at the first HOWMANY bytes
133 */
134 if ((nbytes = read(fd, (char *)buf, HOWMANY)) == -1)
135 return 0;
136
137 if (nbytes == 0)
138 return 0;
139 else {
140 buf[nbytes++] = '\0'; /* null-terminate it */
141 match = softmagic(buf, nbytes);
142 }
143
144 #ifdef RESTORE_TIME
145 /* really no point as we going to access the file later anyway */
146 {
147 /*
148 * Try to restore access, modification times if read it.
149 */
150 # ifdef USE_UTIMES
151 struct timeval utsbuf[2];
152 utsbuf[0].tv_sec = sb.st_atime;
153 utsbuf[1].tv_sec = sb.st_mtime;
154
155 (void) utimes(inname, utsbuf); /* don't care if loses */
156 # else
157 struct utimbuf utbuf;
158
159 utbuf.actime = sb.st_atime;
160 utbuf.modtime = sb.st_mtime;
161 (void) utime(inname, &utbuf); /* don't care if loses */
162 # endif
163 }
164 #endif
165 (void) close(fd);
166
167 return(match);
168 }
169
170 /*
171 * clean_magic - deallocate memory used
172 */
173 void
clean_magic(void)174 clean_magic(void)
175 {
176 if (__f_magic)
177 free(__f_magic);
178 }
179
180
181 #ifdef MAIN
main(int argc,char ** argv)182 main(int argc, char **argv)
183 {
184 char *ret;
185 char creator[5];
186 char type[5];
187
188 if (argc < 3)
189 exit(1);
190
191 init_magic(argv[1]);
192
193 ret = get_magic_match(argv[2]);
194
195 if (!ret)
196 ret = "unixTEXT";
197
198 sscanf(ret, "%4s%4s", creator, type);
199
200 creator[4] = type[4] = '\0';
201
202 printf("%s %s\n", creator, type);
203
204
205 exit(0);
206 }
207 #endif /* MAIN */
208
209