Print this page
2990 file(1) should have a -s flag to process special files


  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  22 /*        All Rights Reserved   */
  23 
  24 
  25 /*      Copyright (c) 1987, 1988 Microsoft Corporation  */
  26 /*        All Rights Reserved   */
  27 
  28 /*
  29  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  30  * Use is subject to license terms.
  31  */
  32 




  33 #define _LARGEFILE64_SOURCE
  34 
  35 /* Get definitions for the relocation types supported. */
  36 #define ELF_TARGET_ALL
  37 
  38 #include <ctype.h>
  39 #include <unistd.h>
  40 #include <fcntl.h>
  41 #include <signal.h>
  42 #include <stdio.h>
  43 #include <libelf.h>
  44 #include <stdlib.h>
  45 #include <limits.h>
  46 #include <locale.h>
  47 #include <wctype.h>
  48 #include <string.h>
  49 #include <errno.h>
  50 #include <door.h>
  51 #include <sys/param.h>
  52 #include <sys/types.h>


 124                 "text", "data", "bss", "comm", 0};
 125 
 126 /*
 127  * The line and debug section names are used by the strip command.
 128  * Any changes in the strip implementation need to be reflected here.
 129  */
 130 static char     *debug_sections[] = { /* Debug sections in a ELF file */
 131                 ".debug", ".stab", ".dwarf", ".line", NULL};
 132 
 133 /* start for MB env */
 134 static wchar_t  wchar;
 135 static int      length;
 136 static int      IS_ascii;
 137 static int      Max;
 138 /* end for MB env */
 139 static int      i;      /* global index into first 'fbsz' bytes of file */
 140 static int      fbsz;
 141 static int      ifd = -1;
 142 static int      elffd = -1;
 143 static int      tret;

 144 static int      hflg;
 145 static int      dflg;
 146 static int      mflg;
 147 static int      M_flg;
 148 static int      iflg;
 149 static struct stat64    mbuf;
 150 
 151 static char     **mlist1;       /* 1st ordered list of magic files */
 152 static char     **mlist2;       /* 2nd ordered list of magic files */
 153 static size_t   mlist1_sz;      /* number of ptrs allocated for mlist1 */
 154 static size_t   mlist2_sz;      /* number of ptrs allocated for mlist2 */
 155 static char     **mlist1p;      /* next entry in mlist1 */
 156 static char     **mlist2p;      /* next entry in mlist2 */
 157 
 158 static ssize_t  mread;
 159 
 160 static void ar_coff_or_aout(int ifd);
 161 static int type(char *file);
 162 static int def_position_tests(char *file);
 163 static void def_context_tests(void);


 201 
 202 int
 203 main(int argc, char **argv)
 204 {
 205         char    *p;
 206         int     ch;
 207         FILE    *fl;
 208         int     cflg = 0;
 209         int     eflg = 0;
 210         int     fflg = 0;
 211         char    *ap = NULL;
 212         int     pathlen;
 213         char    **filep;
 214 
 215         (void) setlocale(LC_ALL, "");
 216 #if !defined(TEXT_DOMAIN)       /* Should be defined by cc -D */
 217 #define TEXT_DOMAIN "SYS_TEST"  /* Use this only if it weren't */
 218 #endif
 219         (void) textdomain(TEXT_DOMAIN);
 220 
 221         while ((ch = getopt(argc, argv, "M:cdf:him:")) != EOF) {
 222                 switch (ch) {
 223 
 224                 case 'M':
 225                         add_to_mlist(optarg, !dflg);
 226                         M_flg++;
 227                         break;
 228 
 229                 case 'c':
 230                         cflg++;
 231                         break;
 232 
 233                 case 'd':
 234                         if (!dflg) {
 235                                 default_magic();
 236                                 add_to_mlist(dfile, 0);
 237                                 dflg++;
 238                         }
 239                         break;
 240 




 241                 case 'f':
 242                         fflg++;
 243                         errno = 0;
 244                         if ((fl = fopen(optarg, "r")) == NULL) {
 245                                 int err = errno;
 246                                 (void) fprintf(stderr, gettext("%s: cannot "
 247                                     "open file %s: %s\n"), File, optarg,
 248                                     err ? strerror(err) : "");
 249                                 usage();
 250                         }
 251                         pathlen = pathconf("/", _PC_PATH_MAX);
 252                         if (pathlen == -1) {
 253                                 int err = errno;
 254                                 (void) fprintf(stderr, gettext("%s: cannot "
 255                                     "determine maximum path length: %s\n"),
 256                                     File, strerror(err));
 257                                 exit(1);
 258                         }
 259                         pathlen += 2; /* for null and newline in fgets */
 260                         if ((ap = malloc(pathlen * sizeof (char))) == NULL) {


 274                         break;
 275 
 276                 case 'm':
 277                         add_to_mlist(optarg, !dflg);
 278                         mflg++;
 279                         break;
 280 
 281                 case '?':
 282                         eflg++;
 283                         break;
 284                 }
 285         }
 286         if (!cflg && !fflg && (eflg || optind == argc))
 287                 usage();
 288         if (iflg && (dflg || mflg || M_flg)) {
 289                 usage();
 290         }
 291         if (iflg && cflg) {
 292                 usage();
 293         }


 294 
 295         if (!dflg && !mflg && !M_flg && !iflg) {
 296         /* no -d, -m, nor -M option; also -i option doesn't need magic  */
 297                 default_magic();
 298                 if (f_mkmtab(dfile, cflg, 0) == -1) {
 299                         exit(2);
 300                 }
 301         }
 302 
 303         else if (mflg && !M_flg && !dflg) {
 304         /* -m specified without -d nor -M */
 305 
 306 #ifdef XPG4     /* For SUSv3 only */
 307 
 308                 /*
 309                  * The default position-dependent magic file tests
 310                  * in /etc/magic will follow all the -m magic tests.
 311                  */
 312 
 313                 for (filep = mlist1; filep < mlist1p; filep++) {


 441         int     (*statf)() = hflg ? lstat64 : stat64;
 442 
 443         i = 0;          /* reset index to beginning of file */
 444         ifd = -1;
 445         if ((*statf)(file, &mbuf) < 0) {
 446                 if (statf == lstat64 || lstat64(file, &mbuf) < 0) {
 447                         int err = errno;
 448                         (void) printf(gettext("cannot open: %s\n"),
 449                             strerror(err));
 450                         return (0);             /* POSIX.2 */
 451                 }
 452         }
 453         switch (mbuf.st_mode & S_IFMT) {
 454         case S_IFREG:
 455                 if (iflg) {
 456                         (void) printf(gettext("regular file\n"));
 457                         return (0);
 458                 }
 459                 break;
 460         case S_IFCHR:


 461                 (void) printf(gettext("character"));
 462                 goto spcl;
 463 
 464         case S_IFDIR:
 465                 (void) printf(gettext("directory\n"));
 466                 return (0);
 467 
 468         case S_IFIFO:
 469                 (void) printf(gettext("fifo\n"));
 470                 return (0);
 471 
 472         case S_IFLNK:
 473                 if ((cc = readlink(file, buf, BUFSIZ)) < 0) {
 474                         int err = errno;
 475                         (void) printf(gettext("readlink error: %s\n"),
 476                             strerror(err));
 477                         return (1);
 478                 }
 479                 buf[cc] = '\0';
 480                 (void) printf(gettext("symbolic link to %s\n"), buf);
 481                 return (0);
 482 
 483         case S_IFBLK:


 484                 (void) printf(gettext("block"));
 485                                         /* major and minor, see sys/mkdev.h */
 486 spcl:
 487                 (void) printf(gettext(" special (%d/%d)\n"),
 488                     major(mbuf.st_rdev), minor(mbuf.st_rdev));
 489                 return (0);
 490 
 491         case S_IFSOCK:
 492                 (void) printf("socket\n");
 493                 /* FIXME, should open and try to getsockname. */
 494                 return (0);
 495 
 496         case S_IFDOOR:
 497                 if (get_door_target(file, buf, sizeof (buf)) == 0)
 498                         (void) printf(gettext("door to %s\n"), buf);
 499                 else
 500                         (void) printf(gettext("door\n"));
 501                 return (0);
 502 
 503         }


1628                 const char *c = swap(dh.dump_flags) & DF_COMPRESSED ?
1629                     "compressed " : "";
1630                 const char *l = swap(dh.dump_flags) & DF_LIVE ?
1631                     "live" : "crash";
1632 
1633                 (void) printf(gettext(
1634                     "%s %s %s %u-bit %s %s%s dump from '%s'\n"),
1635                     dh.dump_utsname.sysname, dh.dump_utsname.release,
1636                     dh.dump_utsname.version, swap(dh.dump_wordsize), isa,
1637                     c, l, dh.dump_utsname.nodename);
1638         } else {
1639                 (void) printf(gettext("SunOS %u-bit %s crash dump\n"),
1640                     swap(dhp->dump_wordsize), isa);
1641         }
1642 }
1643 
1644 static void
1645 usage(void)
1646 {
1647         (void) fprintf(stderr, gettext(
1648             "usage: file [-dh] [-M mfile] [-m mfile] [-f ffile] file ...\n"
1649             "       file [-dh] [-M mfile] [-m mfile] -f ffile\n"
1650             "       file -i [-h] [-f ffile] file ...\n"
1651             "       file -i [-h] -f ffile\n"
1652             "       file -c [-d] [-M mfile] [-m mfile]\n"));
1653         exit(2);
1654 }
1655 
1656 static uint32_t
1657 swap_uint32(uint32_t in)
1658 {
1659         uint32_t out;
1660 
1661         out = (in & 0x000000ff) << 24;
1662         out |= (in & 0x0000ff00) << 8; /* >> 8 << 16 */
1663         out |= (in & 0x00ff0000) >> 8; /* >> 16 << 8 */
1664         out |= (in & 0xff000000) >> 24;
1665 
1666         return (out);
1667 }
1668 
1669 static uint32_t




  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  22 /*        All Rights Reserved   */
  23 
  24 
  25 /*      Copyright (c) 1987, 1988 Microsoft Corporation  */
  26 /*        All Rights Reserved   */
  27 
  28 /*
  29  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  30  * Use is subject to license terms.
  31  */
  32 
  33 /*
  34  * Copyright 2012, Josef 'Jeff' Sipek <jeffpc@31bits.net>. All rights reserved.
  35  */
  36 
  37 #define _LARGEFILE64_SOURCE
  38 
  39 /* Get definitions for the relocation types supported. */
  40 #define ELF_TARGET_ALL
  41 
  42 #include <ctype.h>
  43 #include <unistd.h>
  44 #include <fcntl.h>
  45 #include <signal.h>
  46 #include <stdio.h>
  47 #include <libelf.h>
  48 #include <stdlib.h>
  49 #include <limits.h>
  50 #include <locale.h>
  51 #include <wctype.h>
  52 #include <string.h>
  53 #include <errno.h>
  54 #include <door.h>
  55 #include <sys/param.h>
  56 #include <sys/types.h>


 128                 "text", "data", "bss", "comm", 0};
 129 
 130 /*
 131  * The line and debug section names are used by the strip command.
 132  * Any changes in the strip implementation need to be reflected here.
 133  */
 134 static char     *debug_sections[] = { /* Debug sections in a ELF file */
 135                 ".debug", ".stab", ".dwarf", ".line", NULL};
 136 
 137 /* start for MB env */
 138 static wchar_t  wchar;
 139 static int      length;
 140 static int      IS_ascii;
 141 static int      Max;
 142 /* end for MB env */
 143 static int      i;      /* global index into first 'fbsz' bytes of file */
 144 static int      fbsz;
 145 static int      ifd = -1;
 146 static int      elffd = -1;
 147 static int      tret;
 148 static int      sflg;
 149 static int      hflg;
 150 static int      dflg;
 151 static int      mflg;
 152 static int      M_flg;
 153 static int      iflg;
 154 static struct stat64    mbuf;
 155 
 156 static char     **mlist1;       /* 1st ordered list of magic files */
 157 static char     **mlist2;       /* 2nd ordered list of magic files */
 158 static size_t   mlist1_sz;      /* number of ptrs allocated for mlist1 */
 159 static size_t   mlist2_sz;      /* number of ptrs allocated for mlist2 */
 160 static char     **mlist1p;      /* next entry in mlist1 */
 161 static char     **mlist2p;      /* next entry in mlist2 */
 162 
 163 static ssize_t  mread;
 164 
 165 static void ar_coff_or_aout(int ifd);
 166 static int type(char *file);
 167 static int def_position_tests(char *file);
 168 static void def_context_tests(void);


 206 
 207 int
 208 main(int argc, char **argv)
 209 {
 210         char    *p;
 211         int     ch;
 212         FILE    *fl;
 213         int     cflg = 0;
 214         int     eflg = 0;
 215         int     fflg = 0;
 216         char    *ap = NULL;
 217         int     pathlen;
 218         char    **filep;
 219 
 220         (void) setlocale(LC_ALL, "");
 221 #if !defined(TEXT_DOMAIN)       /* Should be defined by cc -D */
 222 #define TEXT_DOMAIN "SYS_TEST"  /* Use this only if it weren't */
 223 #endif
 224         (void) textdomain(TEXT_DOMAIN);
 225 
 226         while ((ch = getopt(argc, argv, "M:cdsf:him:")) != EOF) {
 227                 switch (ch) {
 228 
 229                 case 'M':
 230                         add_to_mlist(optarg, !dflg);
 231                         M_flg++;
 232                         break;
 233 
 234                 case 'c':
 235                         cflg++;
 236                         break;
 237 
 238                 case 'd':
 239                         if (!dflg) {
 240                                 default_magic();
 241                                 add_to_mlist(dfile, 0);
 242                                 dflg++;
 243                         }
 244                         break;
 245 
 246                 case 's':
 247                         sflg++;
 248                         break;
 249 
 250                 case 'f':
 251                         fflg++;
 252                         errno = 0;
 253                         if ((fl = fopen(optarg, "r")) == NULL) {
 254                                 int err = errno;
 255                                 (void) fprintf(stderr, gettext("%s: cannot "
 256                                     "open file %s: %s\n"), File, optarg,
 257                                     err ? strerror(err) : "");
 258                                 usage();
 259                         }
 260                         pathlen = pathconf("/", _PC_PATH_MAX);
 261                         if (pathlen == -1) {
 262                                 int err = errno;
 263                                 (void) fprintf(stderr, gettext("%s: cannot "
 264                                     "determine maximum path length: %s\n"),
 265                                     File, strerror(err));
 266                                 exit(1);
 267                         }
 268                         pathlen += 2; /* for null and newline in fgets */
 269                         if ((ap = malloc(pathlen * sizeof (char))) == NULL) {


 283                         break;
 284 
 285                 case 'm':
 286                         add_to_mlist(optarg, !dflg);
 287                         mflg++;
 288                         break;
 289 
 290                 case '?':
 291                         eflg++;
 292                         break;
 293                 }
 294         }
 295         if (!cflg && !fflg && (eflg || optind == argc))
 296                 usage();
 297         if (iflg && (dflg || mflg || M_flg)) {
 298                 usage();
 299         }
 300         if (iflg && cflg) {
 301                 usage();
 302         }
 303         if (sflg && (iflg || cflg))
 304                 usage();
 305 
 306         if (!dflg && !mflg && !M_flg && !iflg) {
 307         /* no -d, -m, nor -M option; also -i option doesn't need magic  */
 308                 default_magic();
 309                 if (f_mkmtab(dfile, cflg, 0) == -1) {
 310                         exit(2);
 311                 }
 312         }
 313 
 314         else if (mflg && !M_flg && !dflg) {
 315         /* -m specified without -d nor -M */
 316 
 317 #ifdef XPG4     /* For SUSv3 only */
 318 
 319                 /*
 320                  * The default position-dependent magic file tests
 321                  * in /etc/magic will follow all the -m magic tests.
 322                  */
 323 
 324                 for (filep = mlist1; filep < mlist1p; filep++) {


 452         int     (*statf)() = hflg ? lstat64 : stat64;
 453 
 454         i = 0;          /* reset index to beginning of file */
 455         ifd = -1;
 456         if ((*statf)(file, &mbuf) < 0) {
 457                 if (statf == lstat64 || lstat64(file, &mbuf) < 0) {
 458                         int err = errno;
 459                         (void) printf(gettext("cannot open: %s\n"),
 460                             strerror(err));
 461                         return (0);             /* POSIX.2 */
 462                 }
 463         }
 464         switch (mbuf.st_mode & S_IFMT) {
 465         case S_IFREG:
 466                 if (iflg) {
 467                         (void) printf(gettext("regular file\n"));
 468                         return (0);
 469                 }
 470                 break;
 471         case S_IFCHR:
 472                 if (sflg)
 473                         break;
 474                 (void) printf(gettext("character"));
 475                 goto spcl;
 476 
 477         case S_IFDIR:
 478                 (void) printf(gettext("directory\n"));
 479                 return (0);
 480 
 481         case S_IFIFO:
 482                 (void) printf(gettext("fifo\n"));
 483                 return (0);
 484 
 485         case S_IFLNK:
 486                 if ((cc = readlink(file, buf, BUFSIZ)) < 0) {
 487                         int err = errno;
 488                         (void) printf(gettext("readlink error: %s\n"),
 489                             strerror(err));
 490                         return (1);
 491                 }
 492                 buf[cc] = '\0';
 493                 (void) printf(gettext("symbolic link to %s\n"), buf);
 494                 return (0);
 495 
 496         case S_IFBLK:
 497                 if (sflg)
 498                         break;
 499                 (void) printf(gettext("block"));
 500                                         /* major and minor, see sys/mkdev.h */
 501 spcl:
 502                 (void) printf(gettext(" special (%d/%d)\n"),
 503                     major(mbuf.st_rdev), minor(mbuf.st_rdev));
 504                 return (0);
 505 
 506         case S_IFSOCK:
 507                 (void) printf("socket\n");
 508                 /* FIXME, should open and try to getsockname. */
 509                 return (0);
 510 
 511         case S_IFDOOR:
 512                 if (get_door_target(file, buf, sizeof (buf)) == 0)
 513                         (void) printf(gettext("door to %s\n"), buf);
 514                 else
 515                         (void) printf(gettext("door\n"));
 516                 return (0);
 517 
 518         }


1643                 const char *c = swap(dh.dump_flags) & DF_COMPRESSED ?
1644                     "compressed " : "";
1645                 const char *l = swap(dh.dump_flags) & DF_LIVE ?
1646                     "live" : "crash";
1647 
1648                 (void) printf(gettext(
1649                     "%s %s %s %u-bit %s %s%s dump from '%s'\n"),
1650                     dh.dump_utsname.sysname, dh.dump_utsname.release,
1651                     dh.dump_utsname.version, swap(dh.dump_wordsize), isa,
1652                     c, l, dh.dump_utsname.nodename);
1653         } else {
1654                 (void) printf(gettext("SunOS %u-bit %s crash dump\n"),
1655                     swap(dhp->dump_wordsize), isa);
1656         }
1657 }
1658 
1659 static void
1660 usage(void)
1661 {
1662         (void) fprintf(stderr, gettext(
1663             "usage: file [-dhs] [-M mfile] [-m mfile] [-f ffile] file ...\n"
1664             "       file [-dhs] [-M mfile] [-m mfile] -f ffile\n"
1665             "       file -i [-h] [-f ffile] file ...\n"
1666             "       file -i [-h] -f ffile\n"
1667             "       file -c [-d] [-M mfile] [-m mfile]\n"));
1668         exit(2);
1669 }
1670 
1671 static uint32_t
1672 swap_uint32(uint32_t in)
1673 {
1674         uint32_t out;
1675 
1676         out = (in & 0x000000ff) << 24;
1677         out |= (in & 0x0000ff00) << 8; /* >> 8 << 16 */
1678         out |= (in & 0x00ff0000) >> 8; /* >> 16 << 8 */
1679         out |= (in & 0xff000000) >> 24;
1680 
1681         return (out);
1682 }
1683 
1684 static uint32_t