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