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