[BACK]Return to file.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / file

Diff for /src/usr.bin/file/file.c between version 1.17 and 1.18

version 1.17, 2007/02/19 13:02:08 version 1.18, 2008/05/08 01:40:56
Line 40 
Line 40 
 #include <sys/types.h>  #include <sys/types.h>
 #include <sys/param.h>  /* for MAXPATHLEN */  #include <sys/param.h>  /* for MAXPATHLEN */
 #include <sys/stat.h>  #include <sys/stat.h>
 #include <fcntl.h>      /* for open() */  
 #ifdef RESTORE_TIME  #ifdef RESTORE_TIME
 # if (__COHERENT__ >= 0x420)  # if (__COHERENT__ >= 0x420)
 #  include <sys/utime.h>  #  include <sys/utime.h>
Line 78 
Line 77 
   
   
 #ifdef S_IFLNK  #ifdef S_IFLNK
 #define SYMLINKFLAG "L"  #define SYMLINKFLAG "Lh"
 #else  #else
 #define SYMLINKFLAG ""  #define SYMLINKFLAG ""
 #endif  #endif
   
 #define USAGE   "Usage: %s [-bck" SYMLINKFLAG "Nnrsvz] [-F separator] [-f namefile] [-m magicfiles] file ...\n" \  # define USAGE  "Usage: %s [-bck" SYMLINKFLAG "nNrsvz0] [-e test] [-f namefile] [-F separator] [-m magicfiles] file...\n" \
                 "       %s [-m magicfiles] -C\n"                  "       %s [-m magicfiles] -C\n"
   
 #ifndef MAXPATHLEN  #ifndef MAXPATHLEN
 #define MAXPATHLEN      512  #define MAXPATHLEN      512
Line 93 
Line 92 
 private int             /* Global command-line options          */  private int             /* Global command-line options          */
         bflag = 0,      /* brief output format                  */          bflag = 0,      /* brief output format                  */
         nopad = 0,      /* Don't pad output                     */          nopad = 0,      /* Don't pad output                     */
         nobuffer = 0;   /* Do not buffer stdout                 */          nobuffer = 0,   /* Do not buffer stdout                 */
           nulsep = 0;     /* Append '\0' to the separator         */
   
 private const char *magicfile = 0;      /* where the magic is   */  private const char *magicfile = 0;      /* where the magic is   */
 private const char *default_magicfile = MAGIC;  private const char *default_magicfile = MAGIC;
 private char *separator = ":";  /* Default field separator      */  private const char *separator = ":";    /* Default field separator      */
   
 private char *progname;         /* used throughout              */  
   
 private struct magic_set *magic;  private struct magic_set *magic;
   extern char *__progname;
   
 private void unwrap(char *);  private void unwrap(char *);
 private void usage(void);  private void usage(void);
Line 124 
Line 123 
 int  int
 main(int argc, char *argv[])  main(int argc, char *argv[])
 {  {
         int c;          int c, i;
         int action = 0, didsomefiles = 0, errflg = 0;          int action = 0, didsomefiles = 0, errflg = 0;
         int flags = 0;          int flags = 0;
         char *home, *usermagic;          char *home, *usermagic;
         struct stat sb;          struct stat sb;
 #define OPTSTRING       "bcCdf:F:kLm:nNprsvz"          static const char hmagic[] = "/.magic";
   #define OPTSTRING       "bcCde:f:F:hkLm:nNprsvz0"
 #ifdef HAVE_GETOPT_LONG  #ifdef HAVE_GETOPT_LONG
         int longindex;          int longindex;
         private struct option long_options[] =          static const struct option long_options[] =
         {          {
                 {"version", 0, 0, 'v'},                  {"version", 0, 0, 'v'},
                 {"help", 0, 0, 0},                  {"help", 0, 0, 0},
                 {"brief", 0, 0, 'b'},                  {"brief", 0, 0, 'b'},
                 {"checking-printout", 0, 0, 'c'},                  {"checking-printout", 0, 0, 'c'},
                 {"debug", 0, 0, 'd'},                  {"debug", 0, 0, 'd'},
                   {"exclude", 1, 0, 'e' },
                 {"files-from", 1, 0, 'f'},                  {"files-from", 1, 0, 'f'},
                 {"separator", 1, 0, 'F'},                  {"separator", 1, 0, 'F'},
                 {"keep-going", 0, 0, 'k'},                  {"keep-going", 0, 0, 'k'},
 #ifdef S_IFLNK  #ifdef S_IFLNK
                 {"dereference", 0, 0, 'L'},                  {"dereference", 0, 0, 'L'},
                   {"no-dereference", 0, 0, 'h'},
 #endif  #endif
                 {"magic-file", 1, 0, 'm'},                  {"magic-file", 1, 0, 'm'},
 #if defined(HAVE_UTIME) || defined(HAVE_UTIMES)  #if defined(HAVE_UTIME) || defined(HAVE_UTIMES)
Line 155 
Line 157 
                 {"no-pad", 0, 0, 'N'},                  {"no-pad", 0, 0, 'N'},
                 {"special-files", 0, 0, 's'},                  {"special-files", 0, 0, 's'},
                 {"compile", 0, 0, 'C'},                  {"compile", 0, 0, 'C'},
                   {"print0", 0, 0, '0'},
                 {0, 0, 0, 0},                  {0, 0, 0, 0},
         };          };
 #endif  #endif
   
           static const struct {
                   const char *name;
                   int value;
           } nv[] = {
                   { "apptype",    MAGIC_NO_CHECK_APPTYPE },
                   { "ascii",      MAGIC_NO_CHECK_ASCII },
                   { "compress",   MAGIC_NO_CHECK_COMPRESS },
                   { "elf",        MAGIC_NO_CHECK_ELF },
                   { "fortran",    MAGIC_NO_CHECK_FORTRAN },
                   { "soft",       MAGIC_NO_CHECK_SOFT },
                   { "tar",        MAGIC_NO_CHECK_TAR },
                   { "tokens",     MAGIC_NO_CHECK_TOKENS },
                   { "troff",      MAGIC_NO_CHECK_TROFF },
           };
   
 #ifdef LC_CTYPE  #ifdef LC_CTYPE
         setlocale(LC_CTYPE, ""); /* makes islower etc work for other langs */          /* makes islower etc work for other langs */
           (void)setlocale(LC_CTYPE, "");
 #endif  #endif
   
 #ifdef __EMX__  #ifdef __EMX__
Line 168 
Line 187 
         _wildcard(&argc, &argv);          _wildcard(&argc, &argv);
 #endif  #endif
   
         if ((progname = strrchr(argv[0], '/')) != NULL)  
                 progname++;  
         else  
                 progname = argv[0];  
   
         magicfile = default_magicfile;          magicfile = default_magicfile;
         if ((usermagic = getenv("MAGIC")) != NULL)          if ((usermagic = getenv("MAGIC")) != NULL)
                 magicfile = usermagic;                  magicfile = usermagic;
         else          else
                 if ((home = getenv("HOME")) != NULL) {                  if ((home = getenv("HOME")) != NULL) {
                         size_t len = strlen(home) + 8;                          size_t len = strlen(home) + sizeof(hmagic);
                         if ((usermagic = malloc(len)) != NULL) {                          if ((usermagic = malloc(len)) != NULL) {
                                 (void)strlcpy(usermagic, home, len);                                  (void)strlcpy(usermagic, home, len);
                                 (void)strlcat(usermagic, "/.magic", len);                                  (void)strlcat(usermagic, hmagic, len);
                                 if (stat(usermagic, &sb)<0)                                  if (stat(usermagic, &sb)<0)
                                         free(usermagic);                                          free(usermagic);
                                 else                                  else
Line 189 
Line 203 
                         }                          }
                 }                  }
   
   #ifdef S_IFLNK
           flags |= getenv("POSIXLY_CORRECT") ? MAGIC_SYMLINK : 0;
   #endif
 #ifndef HAVE_GETOPT_LONG  #ifndef HAVE_GETOPT_LONG
         while ((c = getopt(argc, argv, OPTSTRING)) != -1)          while ((c = getopt(argc, argv, OPTSTRING)) != -1)
 #else  #else
Line 202 
Line 219 
                                 help();                                  help();
                         break;                          break;
 #endif  #endif
                   case '0':
                           nulsep = 1;
                           break;
                 case 'b':                  case 'b':
                         ++bflag;                          ++bflag;
                         break;                          break;
Line 214 
Line 234 
                 case 'd':                  case 'd':
                         flags |= MAGIC_DEBUG|MAGIC_CHECK;                          flags |= MAGIC_DEBUG|MAGIC_CHECK;
                         break;                          break;
                   case 'e':
                           for (i = 0; i < sizeof(nv) / sizeof(nv[0]); i++)
                                   if (strcmp(nv[i].name, optarg) == 0)
                                           break;
   
                           if (i == sizeof(nv) / sizeof(nv[0]))
                                   errflg++;
                           else
                                   flags |= nv[i].value;
                           break;
   
                 case 'f':                  case 'f':
                         if(action)                          if(action)
                                 usage();                                  usage();
Line 248 
Line 279 
                         flags |= MAGIC_DEVICES;                          flags |= MAGIC_DEVICES;
                         break;                          break;
                 case 'v':                  case 'v':
                         (void) fprintf(stdout, "%s-%d.%.2d\n", progname,                          (void)fprintf(stdout, "%s-%d.%.2d\n", __progname,
                                        FILE_VERSION_MAJOR, patchlevel);                                         FILE_VERSION_MAJOR, patchlevel);
                         (void) fprintf(stdout, "magic file from %s\n",                          (void)fprintf(stdout, "magic file from %s\n",
                                        magicfile);                                         magicfile);
                         return 1;                          return 1;
                 case 'z':                  case 'z':
Line 260 
Line 291 
                 case 'L':                  case 'L':
                         flags |= MAGIC_SYMLINK;                          flags |= MAGIC_SYMLINK;
                         break;                          break;
                   case 'h':
                           flags &= ~MAGIC_SYMLINK;
                           break;
 #endif  #endif
                 case '?':                  case '?':
                 default:                  default:
Line 276 
Line 310 
         case FILE_COMPILE:          case FILE_COMPILE:
                 magic = magic_open(flags|MAGIC_CHECK);                  magic = magic_open(flags|MAGIC_CHECK);
                 if (magic == NULL) {                  if (magic == NULL) {
                         (void)fprintf(stderr, "%s: %s\n", progname,                          (void)fprintf(stderr, "%s: %s\n", __progname,
                             strerror(errno));                              strerror(errno));
                         return 1;                          return 1;
                 }                  }
                 c = action == FILE_CHECK ? magic_check(magic, magicfile) :                  c = action == FILE_CHECK ? magic_check(magic, magicfile) :
                     magic_compile(magic, magicfile);                      magic_compile(magic, magicfile);
                 if (c == -1) {                  if (c == -1) {
                         (void)fprintf(stderr, "%s: %s\n", progname,                          (void)fprintf(stderr, "%s: %s\n", __progname,
                             magic_error(magic));                              magic_error(magic));
                         return -1;                          return -1;
                 }                  }
Line 309 
Line 343 
                         process(argv[optind], wid);                          process(argv[optind], wid);
         }          }
   
           magic_close(magic);
         return 0;          return 0;
 }  }
   
   
 private void  private void
   /*ARGSUSED*/
 load(const char *m, int flags)  load(const char *m, int flags)
 {  {
         if (magic)          if (magic || m == NULL)
                 return;                  return;
         magic = magic_open(flags);          magic = magic_open(flags);
         if (magic == NULL) {          if (magic == NULL) {
                 (void)fprintf(stderr, "%s: %s\n", progname, strerror(errno));                  (void)fprintf(stderr, "%s: %s\n", __progname, strerror(errno));
                 exit(1);                  exit(1);
         }          }
         if (magic_load(magic, magicfile) == -1) {          if (magic_load(magic, magicfile) == -1) {
                 (void)fprintf(stderr, "%s: %s\n",                  (void)fprintf(stderr, "%s: %s\n",
                     progname, magic_error(magic));                      __progname, magic_error(magic));
                 exit(1);                  exit(1);
         }          }
 }  }
Line 346 
Line 382 
         } else {          } else {
                 if ((f = fopen(fn, "r")) == NULL) {                  if ((f = fopen(fn, "r")) == NULL) {
                         (void)fprintf(stderr, "%s: Cannot open `%s' (%s).\n",                          (void)fprintf(stderr, "%s: Cannot open `%s' (%s).\n",
                             progname, fn, strerror(errno));                              __progname, fn, strerror(errno));
                         exit(1);                          exit(1);
                 }                  }
   
                 while (fgets(buf, sizeof(buf), f) != NULL) {                  while (fgets(buf, sizeof(buf), f) != NULL) {
                         cwid = file_mbswidth(buf) - 1;                          buf[strcspn(buf, "\n")] = '\0';
                           cwid = file_mbswidth(buf);
                         if (cwid > wid)                          if (cwid > wid)
                                 wid = cwid;                                  wid = cwid;
                 }                  }
Line 360 
Line 397 
         }          }
   
         while (fgets(buf, sizeof(buf), f) != NULL) {          while (fgets(buf, sizeof(buf), f) != NULL) {
                 buf[file_mbswidth(buf)-1] = '\0';                  buf[strcspn(buf, "\n")] = '\0';
                 process(buf, wid);                  process(buf, wid);
                 if(nobuffer)                  if(nobuffer)
                         (void) fflush(stdout);                          (void)fflush(stdout);
         }          }
   
         (void) fclose(f);          (void)fclose(f);
 }  }
   
   /*
    * Called for each input file on the command line (or in a list of files)
    */
 private void  private void
 process(const char *inname, int wid)  process(const char *inname, int wid)
 {  {
         const char *type;          const char *type;
         int std_in = strcmp(inname, "-") == 0;          int std_in = strcmp(inname, "-") == 0;
   
         if (wid > 0 && !bflag)          if (wid > 0 && !bflag) {
                 (void) printf("%s%s%*s ", std_in ? "/dev/stdin" : inname,                  (void)printf("%s", std_in ? "/dev/stdin" : inname);
                     separator, (int) (nopad ? 0 : (wid - file_mbswidth(inname))), "");                  if (nulsep)
                           (void)putc('\0', stdout);
                   else
                           (void)printf("%s", separator);
                   (void)printf("%*s ",
                       (int) (nopad ? 0 : (wid - file_mbswidth(inname))), "");
           }
   
         type = magic_file(magic, std_in ? NULL : inname);          type = magic_file(magic, std_in ? NULL : inname);
         if (type == NULL)          if (type == NULL)
                 printf("ERROR: %s\n", magic_error(magic));                  (void)printf("ERROR: %s\n", magic_error(magic));
         else          else
                 printf("%s\n", type);                  (void)printf("%s\n", type);
 }  }
   
   
Line 447 
Line 493 
 size_t  size_t
 file_mbswidth(const char *s)  file_mbswidth(const char *s)
 {  {
 #ifdef HAVE_WCHAR_H  #if defined(HAVE_WCHAR_H) && defined(HAVE_MBRTOWC) && defined(HAVE_WCWIDTH)
         size_t bytesconsumed, old_n, n, width = 0;          size_t bytesconsumed, old_n, n, width = 0;
         mbstate_t state;          mbstate_t state;
         wchar_t nextchar;          wchar_t nextchar;
Line 481 
Line 527 
 private void  private void
 usage(void)  usage(void)
 {  {
         (void)fprintf(stderr, USAGE, progname, progname);          (void)fprintf(stderr, USAGE, __progname, __progname);
 #ifdef HAVE_GETOPT_LONG  #ifdef HAVE_GETOPT_LONG
         (void)fputs("Try `file --help' for more information.\n", stderr);          (void)fputs("Try `file --help' for more information.\n", stderr);
 #endif  #endif
Line 492 
Line 538 
 private void  private void
 help(void)  help(void)
 {  {
         puts(          (void)puts(
 "Usage: file [OPTION]... [FILE]...\n"  "Usage: file [OPTION]... [FILE]...\n"
 "Determine file type of FILEs.\n"  "Determine file type of FILEs.\n"
 "\n"  "\n"
Line 503 
Line 549 
 "  -c, --checking-printout    print the parsed form of the magic file, use in\n"  "  -c, --checking-printout    print the parsed form of the magic file, use in\n"
 "                               conjunction with -m to debug a new magic file\n"  "                               conjunction with -m to debug a new magic file\n"
 "                               before installing it\n"  "                               before installing it\n"
   "  -e, --exclude              exclude test from the list of test to be\n"
   "                               performed for file. Valid tests are:\n"
   "                               ascii, apptype, elf, compress, soft, tar\n"
 "  -f, --files-from FILE      read the filenames to be examined from FILE\n"  "  -f, --files-from FILE      read the filenames to be examined from FILE\n"
 "  -F, --separator string     use string as separator instead of `:'\n"  "  -F, --separator string     use string as separator instead of `:'\n"
 "  -k, --keep-going           don't stop at the first match\n"  "  -k, --keep-going           don't stop at the first match\n"
Line 513 
Line 562 
 "  -r, --raw                  don't translate unprintable chars to \\ooo\n"  "  -r, --raw                  don't translate unprintable chars to \\ooo\n"
 "  -s, --special-files        treat special (block/char devices) files as\n"  "  -s, --special-files        treat special (block/char devices) files as\n"
 "                             ordinary ones\n"  "                             ordinary ones\n"
   "or\n"
 "      --help                 display this help and exit\n"  "      --help                 display this help and exit\n"
   "or\n"
 "      --version              output version information and exit\n"  "      --version              output version information and exit\n"
   "or\n"
   "  -C, --compile              compile file specified by -m\n"
 );  );
         exit(0);          exit(0);
 }  }

Legend:
Removed from v.1.17  
changed lines
  Added in v.1.18