1f0d9efc0Sbeck /*
2f0d9efc0Sbeck ** find file types by using a modified "magic" file
3f0d9efc0Sbeck **
4f0d9efc0Sbeck ** based on file v3.22 by Ian F. Darwin (see below)
5f0d9efc0Sbeck **
6f0d9efc0Sbeck ** For each entry in the magic file, the message MUST start with
7f0d9efc0Sbeck ** two 4 character strings which are the CREATOR and TYPE for the
8f0d9efc0Sbeck ** Mac file. Any continuation lines are ignored. e.g magic entry
9f0d9efc0Sbeck ** for a GIF file:
10f0d9efc0Sbeck **
11f0d9efc0Sbeck ** 0 string GIF8 8BIM GIFf
12f0d9efc0Sbeck ** >4 string 7a \b, version 8%s,
13f0d9efc0Sbeck ** >4 string 9a \b, version 8%s,
14f0d9efc0Sbeck ** >6 leshort >0 %hd x
15f0d9efc0Sbeck ** >8 leshort >0 %hd,
16f0d9efc0Sbeck ** #>10 byte &0x80 color mapped,
17f0d9efc0Sbeck ** #>10 byte&0x07 =0x00 2 colors
18f0d9efc0Sbeck ** #>10 byte&0x07 =0x01 4 colors
19f0d9efc0Sbeck ** #>10 byte&0x07 =0x02 8 colors
20f0d9efc0Sbeck ** #>10 byte&0x07 =0x03 16 colors
21f0d9efc0Sbeck ** #>10 byte&0x07 =0x04 32 colors
22f0d9efc0Sbeck ** #>10 byte&0x07 =0x05 64 colors
23f0d9efc0Sbeck ** #>10 byte&0x07 =0x06 128 colors
24f0d9efc0Sbeck ** #>10 byte&0x07 =0x07 256 colors
25f0d9efc0Sbeck **
26f0d9efc0Sbeck ** Just the "8BIM" "GIFf" will be used whatever the type GIF file
27f0d9efc0Sbeck ** it is.
28f0d9efc0Sbeck **
29f0d9efc0Sbeck ** Modified for mkhybrid James Pearson 19/5/98
30f0d9efc0Sbeck */
31f0d9efc0Sbeck
32f0d9efc0Sbeck /*
33f0d9efc0Sbeck * file - find type of a file or files - main program.
34f0d9efc0Sbeck *
35f0d9efc0Sbeck * Copyright (c) Ian F. Darwin, 1987.
36f0d9efc0Sbeck * Written by Ian F. Darwin.
37f0d9efc0Sbeck *
38f0d9efc0Sbeck * This software is not subject to any license of the American Telephone
39f0d9efc0Sbeck * and Telegraph Company or of the Regents of the University of California.
40f0d9efc0Sbeck *
41f0d9efc0Sbeck * Permission is granted to anyone to use this software for any purpose on
42f0d9efc0Sbeck * any computer system, and to alter it and redistribute it freely, subject
43f0d9efc0Sbeck * to the following restrictions:
44f0d9efc0Sbeck *
45f0d9efc0Sbeck * 1. The author is not responsible for the consequences of use of this
46f0d9efc0Sbeck * software, no matter how awful, even if they arise from flaws in it.
47f0d9efc0Sbeck *
48f0d9efc0Sbeck * 2. The origin of this software must not be misrepresented, either by
49f0d9efc0Sbeck * explicit claim or by omission. Since few users ever read sources,
50f0d9efc0Sbeck * credits must appear in the documentation.
51f0d9efc0Sbeck *
52f0d9efc0Sbeck * 3. Altered versions must be plainly marked as such, and must not be
53f0d9efc0Sbeck * misrepresented as being the original software. Since few users
54f0d9efc0Sbeck * ever read sources, credits must appear in the documentation.
55f0d9efc0Sbeck *
56f0d9efc0Sbeck * 4. This notice may not be removed or altered.
57f0d9efc0Sbeck */
58f0d9efc0Sbeck #include <stdio.h>
59f0d9efc0Sbeck #include <stdlib.h>
60f0d9efc0Sbeck #include <string.h>
61f0d9efc0Sbeck #include <sys/types.h>
62f0d9efc0Sbeck #include <sys/param.h> /* for MAXPATHLEN */
63f0d9efc0Sbeck #include <sys/stat.h>
64f0d9efc0Sbeck #include <fcntl.h> /* for open() */
65f0d9efc0Sbeck #if (__COHERENT__ >= 0x420)
66f0d9efc0Sbeck # include <sys/utime.h>
67f0d9efc0Sbeck #else
68f0d9efc0Sbeck # ifdef USE_UTIMES
69f0d9efc0Sbeck # include <sys/time.h>
70f0d9efc0Sbeck # else
71f0d9efc0Sbeck # include <utime.h>
72f0d9efc0Sbeck # endif
73f0d9efc0Sbeck #endif
74f0d9efc0Sbeck #include <unistd.h> /* for read() */
75f0d9efc0Sbeck
76f0d9efc0Sbeck #include <netinet/in.h> /* for byte swapping */
77f0d9efc0Sbeck
78f0d9efc0Sbeck #include "patchlevel.h"
79f0d9efc0Sbeck #include "file.h"
80*68cbdb5eSespie #include "proto.h"
81f0d9efc0Sbeck
82f0d9efc0Sbeck int /* Global command-line options */
83f0d9efc0Sbeck #ifdef DEBUG
84f0d9efc0Sbeck debug = 1, /* debugging */
85f0d9efc0Sbeck #else
86f0d9efc0Sbeck debug = 0, /* debugging */
87f0d9efc0Sbeck #endif /* DEBUG */
88f0d9efc0Sbeck lflag = 0, /* follow Symlinks (BSD only) */
89f0d9efc0Sbeck zflag = 0; /* follow (uncompress) compressed files */
90f0d9efc0Sbeck
91f0d9efc0Sbeck int /* Misc globals */
92f0d9efc0Sbeck nmagic = 0; /* number of valid magic[]s */
93f0d9efc0Sbeck
94f0d9efc0Sbeck struct magic *magic; /* array of magic entries */
95f0d9efc0Sbeck
96f0d9efc0Sbeck char *magicfile; /* where magic be found */
97f0d9efc0Sbeck
98f0d9efc0Sbeck char *progname; /* used throughout */
99f0d9efc0Sbeck int lineno; /* line number in the magic file */
100f0d9efc0Sbeck
101f0d9efc0Sbeck #if 0
102f0d9efc0Sbeck static int byteconv4 __P((int, int, int));
103f0d9efc0Sbeck static short byteconv2 __P((int, int, int));
104f0d9efc0Sbeck #endif
105f0d9efc0Sbeck
106f0d9efc0Sbeck #if 0
107f0d9efc0Sbeck /*
108f0d9efc0Sbeck * byteconv4
109f0d9efc0Sbeck * Input:
110f0d9efc0Sbeck * from 4 byte quantity to convert
111f0d9efc0Sbeck * same whether to perform byte swapping
112f0d9efc0Sbeck * big_endian whether we are a big endian host
113f0d9efc0Sbeck */
114f0d9efc0Sbeck static int
byteconv4(from,same,big_endian)115f0d9efc0Sbeck byteconv4(from, same, big_endian)
116f0d9efc0Sbeck int from;
117f0d9efc0Sbeck int same;
118f0d9efc0Sbeck int big_endian;
119f0d9efc0Sbeck {
120f0d9efc0Sbeck if (same)
121f0d9efc0Sbeck return from;
122f0d9efc0Sbeck else if (big_endian) /* lsb -> msb conversion on msb */
123f0d9efc0Sbeck {
124f0d9efc0Sbeck union {
125f0d9efc0Sbeck int i;
126f0d9efc0Sbeck char c[4];
127f0d9efc0Sbeck } retval, tmpval;
128f0d9efc0Sbeck
129f0d9efc0Sbeck tmpval.i = from;
130f0d9efc0Sbeck retval.c[0] = tmpval.c[3];
131f0d9efc0Sbeck retval.c[1] = tmpval.c[2];
132f0d9efc0Sbeck retval.c[2] = tmpval.c[1];
133f0d9efc0Sbeck retval.c[3] = tmpval.c[0];
134f0d9efc0Sbeck
135f0d9efc0Sbeck return retval.i;
136f0d9efc0Sbeck }
137f0d9efc0Sbeck else
138f0d9efc0Sbeck return ntohl(from); /* msb -> lsb conversion on lsb */
139f0d9efc0Sbeck }
140f0d9efc0Sbeck
141f0d9efc0Sbeck /*
142f0d9efc0Sbeck * byteconv2
143f0d9efc0Sbeck * Same as byteconv4, but for shorts
144f0d9efc0Sbeck */
145f0d9efc0Sbeck static short
byteconv2(from,same,big_endian)146f0d9efc0Sbeck byteconv2(from, same, big_endian)
147f0d9efc0Sbeck int from;
148f0d9efc0Sbeck int same;
149f0d9efc0Sbeck int big_endian;
150f0d9efc0Sbeck {
151f0d9efc0Sbeck if (same)
152f0d9efc0Sbeck return from;
153f0d9efc0Sbeck else if (big_endian) /* lsb -> msb conversion on msb */
154f0d9efc0Sbeck {
155f0d9efc0Sbeck union {
156f0d9efc0Sbeck short s;
157f0d9efc0Sbeck char c[2];
158f0d9efc0Sbeck } retval, tmpval;
159f0d9efc0Sbeck
160f0d9efc0Sbeck tmpval.s = (short) from;
161f0d9efc0Sbeck retval.c[0] = tmpval.c[1];
162f0d9efc0Sbeck retval.c[1] = tmpval.c[0];
163f0d9efc0Sbeck
164f0d9efc0Sbeck return retval.s;
165f0d9efc0Sbeck }
166f0d9efc0Sbeck else
167f0d9efc0Sbeck return ntohs(from); /* msb -> lsb conversion on lsb */
168f0d9efc0Sbeck }
169f0d9efc0Sbeck #endif
170f0d9efc0Sbeck
171f0d9efc0Sbeck /*
172f0d9efc0Sbeck * get_magic_match - get the CREATOR/TYPE string
173f0d9efc0Sbeck * based on the original process()
174f0d9efc0Sbeck */
175f0d9efc0Sbeck char *
get_magic_match(inname)176f0d9efc0Sbeck get_magic_match(inname)
177f0d9efc0Sbeck const char *inname;
178f0d9efc0Sbeck {
179f0d9efc0Sbeck int fd = 0;
180f0d9efc0Sbeck unsigned char buf[HOWMANY+1]; /* one extra for terminating '\0' */
181f0d9efc0Sbeck struct stat sb;
182f0d9efc0Sbeck int nbytes = 0; /* number of bytes read from a datafile */
183f0d9efc0Sbeck char *match;
184f0d9efc0Sbeck
185f0d9efc0Sbeck /* check the file is regular and non-zero length */
186f0d9efc0Sbeck if (stat(inname, &sb) != 0)
187f0d9efc0Sbeck return 0;
188f0d9efc0Sbeck
189f0d9efc0Sbeck if (sb.st_size == 0 || ! S_ISREG(sb.st_mode))
190f0d9efc0Sbeck return 0;
191f0d9efc0Sbeck
192f0d9efc0Sbeck if ((fd = open(inname, O_RDONLY)) < 0)
193f0d9efc0Sbeck return 0;
194f0d9efc0Sbeck
195f0d9efc0Sbeck /*
196f0d9efc0Sbeck * try looking at the first HOWMANY bytes
197f0d9efc0Sbeck */
198f0d9efc0Sbeck if ((nbytes = read(fd, (char *)buf, HOWMANY)) == -1)
199f0d9efc0Sbeck return 0;
200f0d9efc0Sbeck
201f0d9efc0Sbeck if (nbytes == 0)
202f0d9efc0Sbeck return 0;
203f0d9efc0Sbeck else {
204f0d9efc0Sbeck buf[nbytes++] = '\0'; /* null-terminate it */
205f0d9efc0Sbeck match = softmagic(buf, nbytes);
206f0d9efc0Sbeck }
207f0d9efc0Sbeck
208f0d9efc0Sbeck #ifdef RESTORE_TIME
209f0d9efc0Sbeck /* really no point as we going to access the file later anyway */
210f0d9efc0Sbeck {
211f0d9efc0Sbeck /*
212f0d9efc0Sbeck * Try to restore access, modification times if read it.
213f0d9efc0Sbeck */
214f0d9efc0Sbeck # ifdef USE_UTIMES
215f0d9efc0Sbeck struct timeval utsbuf[2];
216f0d9efc0Sbeck utsbuf[0].tv_sec = sb.st_atime;
217f0d9efc0Sbeck utsbuf[1].tv_sec = sb.st_mtime;
218f0d9efc0Sbeck
219f0d9efc0Sbeck (void) utimes(inname, utsbuf); /* don't care if loses */
220f0d9efc0Sbeck # else
221f0d9efc0Sbeck struct utimbuf utbuf;
222f0d9efc0Sbeck
223f0d9efc0Sbeck utbuf.actime = sb.st_atime;
224f0d9efc0Sbeck utbuf.modtime = sb.st_mtime;
225f0d9efc0Sbeck (void) utime(inname, &utbuf); /* don't care if loses */
226f0d9efc0Sbeck # endif
227f0d9efc0Sbeck #endif
228f0d9efc0Sbeck (void) close(fd);
229f0d9efc0Sbeck
230f0d9efc0Sbeck return(match);
231f0d9efc0Sbeck }
232f0d9efc0Sbeck
233f0d9efc0Sbeck /*
234f0d9efc0Sbeck * clean_magic - deallocate memory used
235f0d9efc0Sbeck */
236f0d9efc0Sbeck void
237f0d9efc0Sbeck clean_magic()
238f0d9efc0Sbeck {
239f0d9efc0Sbeck if (magic)
240f0d9efc0Sbeck free(magic);
241f0d9efc0Sbeck }
242f0d9efc0Sbeck
243f0d9efc0Sbeck
244f0d9efc0Sbeck #ifdef MAIN
245f0d9efc0Sbeck main(argc, argv)
246f0d9efc0Sbeck int argc;
247f0d9efc0Sbeck char **argv;
248f0d9efc0Sbeck {
249f0d9efc0Sbeck char *ret;
250f0d9efc0Sbeck char creator[5];
251f0d9efc0Sbeck char type[5];
252f0d9efc0Sbeck
253f0d9efc0Sbeck if (argc < 3)
254f0d9efc0Sbeck exit(1);
255f0d9efc0Sbeck
256f0d9efc0Sbeck init_magic(argv[1]);
257f0d9efc0Sbeck
258f0d9efc0Sbeck ret = get_magic_match(argv[2]);
259f0d9efc0Sbeck
260f0d9efc0Sbeck if (!ret)
261f0d9efc0Sbeck ret = "unixTEXT";
262f0d9efc0Sbeck
263f0d9efc0Sbeck sscanf(ret, "%4s%4s", creator, type);
264f0d9efc0Sbeck
265f0d9efc0Sbeck creator[4] = type[4] = '\0';
266f0d9efc0Sbeck
267f0d9efc0Sbeck printf("%s %s\n", creator, type);
268f0d9efc0Sbeck
269f0d9efc0Sbeck
270f0d9efc0Sbeck exit(0);
271f0d9efc0Sbeck }
272f0d9efc0Sbeck #endif /* MAIN */
273f0d9efc0Sbeck
274