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 #include "system.h"
00029 #include "file.h"
00030 #include "patchlevel.h"
00031 #include "debug.h"
00032
00033 FILE_RCSID("@(#)Id: file.c,v 1.66 2002/07/03 19:00:41 christos Exp ")
00034
00035
00036
00037 #ifdef S_IFLNK
00038 # define USAGE "Usage: %s [-bciknsvzL] [-f namefile] [-m magicfiles] file...\n"
00039 #else
00040 # define USAGE "Usage: %s [-bciknsvz] [-f namefile] [-m magicfiles] file...\n"
00041 #endif
00042
00043 #ifdef __EMX__
00044 static char *apptypeName = NULL;
00045 int os2_apptype (const char *fn, char *buf, int nb);
00046 #endif
00047
00048 #ifndef MAXPATHLEN
00049 #define MAXPATHLEN 512
00050 #endif
00051
00052
00053
00054 static int nobuffer = 0;
00055
00056
00057 static const char * default_separator = ":";
00058
00059
00060
00061
00062
00063 static void
00064 unwrap(fmagic fm, char *fn)
00065
00066
00067 {
00068 char buf[MAXPATHLEN];
00069 FILE *f;
00070 int wid = 0, cwid;
00071 int xx;
00072
00073 if (strcmp("-", fn) == 0) {
00074 f = stdin;
00075 wid = 1;
00076 } else {
00077 if ((f = fopen(fn, "r")) == NULL) {
00078 error(EXIT_FAILURE, 0, "Cannot open `%s' (%s).\n", fn, strerror(errno));
00079
00080 }
00081
00082 while (fgets(buf, sizeof(buf), f) != NULL) {
00083 cwid = strlen(buf) - 1;
00084 if (cwid > wid)
00085 wid = cwid;
00086 }
00087
00088 rewind(f);
00089 }
00090
00091
00092 while (fgets(buf, sizeof(buf), f) != NULL)
00093
00094 {
00095 buf[strlen(buf)-1] = '\0';
00096 fm->obp = fm->obuf;
00097 *fm->obp = '\0';
00098 fm->nob = sizeof(fm->obuf);
00099 xx = fmagicProcess(fm, buf, wid);
00100 fprintf(stdout, "%s\n", fm->obuf);
00101 if (nobuffer)
00102 (void) fflush(stdout);
00103 }
00104
00105 (void) fclose(f);
00106 }
00107
00108
00109
00110 static void
00111 usage(void)
00112
00113
00114 {
00115 (void)fprintf(stderr, USAGE, __progname);
00116 (void)fprintf(stderr, "Usage: %s -C [-m magic]\n", __progname);
00117 #ifdef HAVE_GETOPT_H
00118 (void)fputs("Try `file --help' for more information.\n", stderr);
00119 #endif
00120 exit(EXIT_FAILURE);
00121 }
00122
00123 #ifdef HAVE_GETOPT_H
00124
00125 static void
00126 help(void)
00127
00128
00129 {
00130 (void) puts(
00131 "Usage: file [OPTION]... [FILE]...\n"
00132 "Determine file type of FILEs.\n"
00133 "\n"
00134 " -m, --magic-file LIST use LIST as a colon-separated list of magic\n"
00135 " number files\n"
00136 " -z, --uncompress try to look inside compressed files\n"
00137 " -b, --brief do not prepend filenames to output lines\n"
00138 " -c, --checking-printout print the parsed form of the magic file, use in\n"
00139 " conjunction with -m to debug a new magic file\n"
00140 " before installing it\n"
00141 " -f, --files-from FILE read the filenames to be examined from FILE\n"
00142 " -F, --separator string use string as separator instead of `:'\n"
00143 " -i, --mime output mime type strings\n"
00144 " -k, --keep-going don't stop at the first match\n"
00145 " -L, --dereference causes symlinks to be followed\n"
00146 " -n, --no-buffer do not buffer output\n"
00147 " -N, --no-pad do not pad output\n"
00148 " -s, --special-files treat special (block/char devices) files as\n"
00149 " ordinary ones\n"
00150 " --help display this help and exit\n"
00151 " --version output version information and exit\n"
00152 );
00153 exit(0);
00154 }
00155 #endif
00156
00157
00158
00159
00160
00161 int
00162 main(int argc, char **argv)
00163
00164
00165
00166
00167
00168
00169 {
00170 int xx;
00171 int c;
00172 int action = 0, didsomefiles = 0, errflg = 0, ret = 0, app = 0;
00173 char *mime, *home, *usermagic;
00174 fmagic fm = global_fmagic;
00175 struct stat sb;
00176 #define OPTSTRING "bcdf:ikm:nsvzCL"
00177 #ifdef HAVE_GETOPT_H
00178 int longindex = 0;
00179
00180 static struct option long_options[] =
00181 {
00182 {"version", 0, 0, 'v'},
00183 {"help", 0, 0, 0},
00184 {"brief", 0, 0, 'b'},
00185 {"checking-printout", 0, 0, 'c'},
00186 {"debug", 0, 0, 'd'},
00187 {"files-from", 1, 0, 'f'},
00188 {"separator", 1, 0, 'F'},
00189 {"mime", 0, 0, 'i'},
00190 {"keep-going", 0, 0, 'k'},
00191 #ifdef S_IFLNK
00192 {"dereference", 0, 0, 'L'},
00193 #endif
00194 {"magic-file", 1, 0, 'm'},
00195 {"uncompress", 0, 0, 'z'},
00196 {"no-buffer", 0, 0, 'n'},
00197 {"no-pad", 0, 0, 'N'},
00198 {"special-files", 0, 0, 's'},
00199 {"compile", 0, 0, 'C'},
00200 {0, 0, 0, 0},
00201 };
00202
00203 #endif
00204
00205 #if HAVE_MCHECK_H && HAVE_MTRACE
00206
00207 mtrace();
00208
00209 #endif
00210
00211 #ifdef LC_CTYPE
00212 setlocale(LC_CTYPE, "");
00213 #endif
00214
00215 #ifdef __EMX__
00216
00217 _wildcard(&argc, &argv);
00218 #endif
00219
00220
00221 fm->magicfile = default_magicfile;
00222 fm->separator = default_separator;
00223
00224 if ((usermagic = getenv("MAGIC")) != NULL)
00225 fm->magicfile = usermagic;
00226 else {
00227 if ((home = getenv("HOME")) != NULL) {
00228 size_t nb = strlen(home) + 8;
00229 usermagic = xmalloc(nb);
00230 (void)strcpy(usermagic, home);
00231 (void)strcat(usermagic, "/.magic");
00232 if (stat(usermagic, &sb)<0)
00233 free(usermagic);
00234 else
00235 fm->magicfile = usermagic;
00236 }
00237 }
00238
00239 #ifndef HAVE_GETOPT_H
00240 while ((c = getopt(argc, argv, OPTSTRING)) != -1)
00241 #else
00242 while ((c = getopt_long(argc, argv, OPTSTRING, long_options,
00243 &longindex)) != -1)
00244 #endif
00245 {
00246 switch (c) {
00247 #ifdef HAVE_GETOPT_H
00248 case 0 :
00249 if (longindex == 1)
00250 help();
00251 break;
00252 #endif
00253 case 'b':
00254 fm->flags |= FMAGIC_FLAGS_BRIEF;
00255 break;
00256 case 'c':
00257 action = FILE_CHECK;
00258 break;
00259 case 'C':
00260 action = FILE_COMPILE;
00261 break;
00262 case 'd':
00263 fm->flags |= FMAGIC_FLAGS_DEBUG;
00264 break;
00265 case 'f':
00266 if (!app) {
00267 ret = fmagicSetup(fm, fm->magicfile, action);
00268 if (action)
00269 exit(ret);
00270 app = 1;
00271 }
00272 unwrap(fm, optarg);
00273 ++didsomefiles;
00274 break;
00275 case 'F':
00276
00277 fm->separator = optarg;
00278
00279 break;
00280 case 'i':
00281 fm->flags |= FMAGIC_FLAGS_MIME;
00282 mime = malloc(strlen(fm->magicfile) + sizeof(".mime"));
00283 if (mime != NULL) {
00284 (void)strcpy(mime, fm->magicfile);
00285 (void)strcat(mime, ".mime");
00286 }
00287 fm->magicfile = mime;
00288 break;
00289 case 'k':
00290 fm->flags |= FMAGIC_FLAGS_CONTINUE;
00291 break;
00292 case 'm':
00293
00294 fm->magicfile = optarg;
00295
00296 break;
00297 case 'n':
00298 ++nobuffer;
00299 break;
00300 case 'N':
00301 fm->flags |= FMAGIC_FLAGS_NOPAD;
00302 break;
00303 case 's':
00304 fm->flags |= FMAGIC_FLAGS_SPECIAL;
00305 break;
00306 case 'v':
00307 (void) fprintf(stdout, "%s-%d.%d\n", __progname,
00308 FILE_VERSION_MAJOR, patchlevel);
00309 (void) fprintf(stdout, "magic file from %s\n",
00310 fm->magicfile);
00311 return 1;
00312 case 'z':
00313 fm->flags |= FMAGIC_FLAGS_UNCOMPRESS;
00314 break;
00315 #ifdef S_IFLNK
00316 case 'L':
00317 fm->flags |= FMAGIC_FLAGS_FOLLOW;
00318 break;
00319 #endif
00320 case '?':
00321 default:
00322 errflg++;
00323 break;
00324 }
00325 }
00326
00327 if (errflg)
00328 usage();
00329
00330 if (!app) {
00331
00332 ret = fmagicSetup(fm, fm->magicfile, action);
00333
00334 if (action)
00335 exit(ret);
00336 app = 1;
00337 }
00338
00339 if (optind == argc) {
00340 if (!didsomefiles)
00341 usage();
00342 } else {
00343 int i, wid, nw;
00344 for (wid = 0, i = optind; i < argc; i++) {
00345 nw = strlen(argv[i]);
00346 if (nw > wid)
00347 wid = nw;
00348 }
00349 for (; optind < argc; optind++) {
00350 fm->obp = fm->obuf;
00351 *fm->obp = '\0';
00352 fm->nob = sizeof(fm->obuf);
00353 xx = fmagicProcess(fm, argv[optind], wid);
00354 fprintf(stdout, "%s\n", fm->obuf);
00355 if (nobuffer)
00356 (void) fflush(stdout);
00357 }
00358 }
00359
00360 #if HAVE_MCHECK_H && HAVE_MTRACE
00361
00362 muntrace();
00363
00364 #endif
00365
00366 return 0;
00367 }
00368