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