file.c revision 1638af81f0b976a8a9b6936111b901c225d1e4ec
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
/* Copyright (c) 1987, 1988 Microsoft Corporation */
/* All Rights Reserved */
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#define _LARGEFILE64_SOURCE
/* Get definitions for the relocation types supported. */
#define ELF_TARGET_ALL
#include <ctype.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <libelf.h>
#include <stdlib.h>
#include <limits.h>
#include <locale.h>
#include <wctype.h>
#include <string.h>
#include <errno.h>
#include <door.h>
#include <procfs.h>
#include <gelf.h>
#include <elfcap.h>
#include <sgsrtcid.h>
#include "file.h"
typedef Elf64_Nhdr GElf_Nhdr;
/*
* Misc
*/
#define FBSZ 512
#define MLIST_SZ 12
/*
* The 0x8FCA0102 magic string was used in crash dumps generated by releases
* prior to Solaris 7.
*/
#define OLD_DUMP_MAGIC 0x8FCA0102
#if defined(__sparc)
#define NATIVE_ISA "SPARC"
#define OTHER_ISA "Intel"
#else
#define NATIVE_ISA "Intel"
#define OTHER_ISA "SPARC"
#endif
/* Assembly language comment char */
#ifdef pdp11
#define ASCOMCHAR '/'
#else
#define ASCOMCHAR '!'
#endif
/*
* Magic file variables
*/
static intmax_t maxmagicoffset;
static char *magicbuf;
static char *dfile;
static char *troff[] = { /* new troff intermediate lang */
"x", "T", "res", "init", "font", "202", "V0", "p1", 0};
static char *fort[] = { /* FORTRAN */
"function", "subroutine", "common", "dimension", "block",
"integer", "real", "data", "double",
"FUNCTION", "SUBROUTINE", "COMMON", "DIMENSION", "BLOCK",
"INTEGER", "REAL", "DATA", "DOUBLE", 0};
static char *asc[] = { /* Assembler Commands */
"sys", "mov", "tst", "clr", "jmp", "cmp", "set", "inc",
"dec", 0};
static char *c[] = { /* C Language */
"int", "char", "float", "double", "short", "long", "unsigned",
"register", "static", "struct", "extern", 0};
static char *as[] = { /* Assembler Pseudo Ops, prepended with '.' */
"globl", "global", "ident", "file", "byte", "even",
"text", "data", "bss", "comm", 0};
/*
* The line and debug section names are used by the strip command.
* Any changes in the strip implementation need to be reflected here.
*/
static char *debug_sections[] = { /* Debug sections in a ELF file */
/* start for MB env */
static int length;
static int IS_ascii;
static int Max;
/* end for MB env */
static int i; /* global index into first 'fbsz' bytes of file */
static int fbsz;
static int ifd = -1;
static int elffd = -1;
static int tret;
static int hflg;
static int dflg;
static int mflg;
static int M_flg;
static int iflg;
static char **mlist1; /* 1st ordered list of magic files */
static char **mlist2; /* 2nd ordered list of magic files */
static char **mlist1p; /* next entry in mlist1 */
static char **mlist2p; /* next entry in mlist2 */
static void ar_coff_or_aout(int ifd);
static int def_position_tests(void);
static void def_context_tests(void);
static int ccom(void);
static int ascom(void);
static int sccs(void);
static int get_door_target(char *, char *, size_t);
static int zipfile(char *, int);
static int is_crash_dump(const char *, int);
const char *);
static int is_in_list(char *[], char *);
static void usage(void);
static void default_magic(void);
static void add_to_mlist(char *, int);
static void fd_cleanup(void);
static int is_rtld_config(void);
#ifdef XPG4
/* SUSv3 requires a single <space> after the colon */
#else /* !XPG4 */
#endif /* XPG4 */
int
{
char *p;
int ch;
int cflg = 0;
int eflg = 0;
int fflg = 0;
int pathlen;
char **filep;
#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
#endif
(void) textdomain(TEXT_DOMAIN);
switch (ch) {
case 'M':
M_flg++;
break;
case 'c':
cflg++;
break;
case 'd':
if (!dflg) {
add_to_mlist(dfile, 0);
dflg++;
}
break;
case 'f':
fflg++;
usage();
}
if (pathlen == -1) {
gettext("pathconf: cannot determine "
"maximum path length\n"));
exit(1);
}
perror("malloc");
exit(1);
}
break;
case 'h':
hflg++;
break;
case 'i':
iflg++;
break;
case 'm':
mflg++;
break;
case '?':
eflg++;
break;
}
}
usage();
usage();
}
usage();
}
/* no -d, -m, nor -M option; also -i option doesn't need magic */
exit(2);
}
}
/* -m specified without -d nor -M */
#ifdef XPG4 /* For SUSv3 only */
/*
* The default position-dependent magic file tests
*/
exit(2);
}
}
exit(2);
}
#else /* !XPG4 */
/*
* Retain Solaris file behavior for -m before SUSv3,
* when the new -d and -M options are not specified.
* Use the -m file specified in place of the default
* now allow more than one magic file to be specified
* with multiple -m options, for consistency with
* other behavior.
*
* Put the magic table(s) specified by -m into
* the second magic table instead of the first
* (as indicated by the last argument to f_mkmtab()),
* must be executed alongside the default
* position-sensitive tests.
*/
exit(2);
}
}
#endif /* XPG4 */
} else {
/*
* For any other combination of -d, -m, and -M,
* use the magic files in command-line order.
* Store the entries from the two separate lists of magic
* files, if any, into two separate magic file tables.
* mlist1: magic tests executed before default magic tests
* mlist2: default magic tests and after
*/
exit(2);
}
}
exit(2);
}
}
}
/* Initialize the magic file variables; check both magic tables */
maxmagicoffset = f_getmaxoffset(0);
if (maxmagicoffset < tmpmax) {
}
exit(2);
}
if (cflg) {
f_prtmtab();
"stdout\n"));
exit(1);
}
exit(1);
}
exit(0);
}
register int l;
if (fflg) {
fflg = 0;
optind--;
continue;
}
l = strlen(p);
if (l > 0)
p[l - 1] = '\0';
} else
prf(p); /* print "file_name:<tab>" */
if (type(p))
tret = 1;
}
if (tret != 0) {
}
"stdout\n"));
exit(1);
}
exit(1);
}
return (0);
}
static int
{
int cc;
i = 0; /* reset index to beginning of file */
ifd = -1;
return (0); /* POSIX.2 */
}
}
case S_IFREG:
if (iflg) {
return (0);
}
break;
case S_IFCHR:
goto spcl;
case S_IFDIR:
return (0);
case S_IFIFO:
return (0);
case S_IFLNK:
return (1);
}
return (0);
case S_IFBLK:
spcl:
return (0);
case S_IFSOCK:
(void) printf("socket\n");
/* FIXME, should open and try to getsockname. */
return (0);
case S_IFDOOR:
else
return (0);
}
return (1);
}
if (ifd < 0) {
return (0); /* POSIX.2 */
}
/* need another fd for elf, since we might want to read the file too */
if (elffd < 0) {
ifd = -1;
return (0); /* POSIX.2 */
}
ifd = -1;
return (0); /* POSIX.2 */
}
if (fbsz == 0) {
fd_cleanup();
return (0);
}
/*
* First try user-specified position-dependent magic tests, if any,
* which need to execute before the default tests.
*/
(off_t)0)) == -1) {
fd_cleanup();
return (0);
}
/*
* ChecK against Magic Table entries.
* Check first magic table for magic tests to be applied
* before default tests.
* If no default tests are to be applied, all magic tests
* should occur in this magic table.
*/
case -1: /* Error */
exit(2);
break;
case 0: /* Not magic */
break;
default: /* Switch is magic index */
(void) putchar('\n');
fd_cleanup();
return (0);
/* NOTREACHED */
break;
}
/*
* default position-dependent tests,
* plus non-default magic tests, if any
*/
switch (def_position_tests()) {
case -1: /* error */
fd_cleanup();
return (1);
case 1: /* matching type found */
fd_cleanup();
return (0);
/* NOTREACHED */
break;
case 0: /* no matching type found */
break;
}
/* default context-sensitive tests */
} else {
/* no more tests to apply; no match was found */
}
fd_cleanup();
return (0);
}
/*
* def_position_tests() - applies default position-sensitive tests,
* looking for values in specific positions in the file.
* These are followed by default (followed by possibly some
* non-default) magic file tests.
*
* All position-sensitive tests, default or otherwise, must
* be applied before context-sensitive tests, to avoid
* false context-sensitive matches.
*
* Returns -1 on error which should result in error (non-zero)
* exit status for the file utility.
* Returns 0 if no matching file type found.
* Returns 1 if matching file type found.
*/
static int
def_position_tests(void)
{
if (sccs()) { /* look for "1hddddd" where d is a digit */
(void) printf("sccs \n");
return (1);
}
return (1);
(void) putchar('\n');
return (1);
/* LINTED: pointer cast may result in improper alignment */
} else if (*(int *)fbuf == CORE_MAGIC) {
/* LINTED: pointer cast may result in improper alignment */
(void) printf("a.out core file");
(void) putchar('\n');
return (1);
}
/*
* Runtime linker (ld.so.1) configuration file.
*/
if (is_rtld_config())
return (1);
/*
* ZIP files, JAR files, and Java executables
*/
return (1);
return (1);
/*
* ChecK against Magic Table entries.
* The magic entries checked here always start with default
* magic tests and may be followed by other, non-default magic
* tests. If no default tests are to be executed, all the
* magic tests should have been in the first magic table.
*/
case -1: /* Error */
exit(2);
break;
case 0: /* Not magic */
return (0);
/* NOTREACHED */
break;
default: /* Switch is magic index */
/*
* f_ckmtab recognizes file type,
* check if it is PostScript.
* if not, check if elf or a.out
*/
(void) putchar('\n');
} else {
/*
* Check that the file is executable (dynamic
* objects must be executable to be exec'ed,
* shared objects need not be, but by convention
* should be executable).
*
* Note that we should already have processed
* the file if it was an ELF file.
*/
(void) putchar('\n');
}
return (1);
/* NOTREACHED */
break;
}
return (0); /* file was not identified */
}
/*
* def_context_tests() - default context-sensitive tests.
* These are the last tests to be applied.
* If no match is found, prints out "data".
*/
static void
def_context_tests(void)
{
int j;
int nl;
char ch;
int len;
if (ccom() == 0)
goto notc;
while (fbuf[i] == '#') {
j = i;
while (fbuf[i++] != '\n') {
if (i - j > 255) {
return;
}
if (i >= fbsz)
goto notc;
}
if (ccom() == 0)
goto notc;
}
if (lookup(c) == 1) {
len = 1;
i += len;
if (i >= fbsz)
goto notc;
}
goto outa;
}
nl = 0;
while (fbuf[i] != '(') {
if (fbuf[i] <= 0)
goto notas;
if (fbuf[i] == ';') {
i++;
goto check;
}
if (fbuf[i++] == '\n')
if (nl++ > 6)
goto notc;
if (i >= fbsz)
goto notc;
}
while (fbuf[i] != ')') {
if (fbuf[i++] == '\n')
if (nl++ > 6)
goto notc;
if (i >= fbsz)
goto notc;
}
while (fbuf[i] != '{') {
len = 1;
if (fbuf[i] == '\n')
if (nl++ > 6)
goto notc;
i += len;
if (i >= fbsz)
goto notc;
}
goto outa;
notc:
i = 0; /* reset to begining of file again */
while (fbuf[i++] != '\n')
if (i >= fbsz)
goto notfort;
}
goto outa;
}
notfort: /* looking for assembler program */
i = 0; /* reset to beginning of file again */
if (ccom() == 0) /* assembler programs may contain */
/* c-style comments */
goto notas;
if (ascom() == 0)
goto notas;
j = i - 1;
if (fbuf[i] == '.') {
i++;
goto outa;
(void) printf(
gettext("[nt]roff, tbl, or eqn input text"));
goto outa;
}
}
if (ccom() == 0)
goto notas;
if (ascom() == 0)
goto notas;
if (i >= fbsz)
goto notas;
}
if (i++ >= fbsz)
goto notas;
j = i - 1;
if (fbuf[i] == '.') {
i++;
(void) printf(
gettext("assembler program text"));
goto outa;
(void) printf(
gettext("[nt]roff, tbl, or eqn input "
"text"));
goto outa;
}
}
}
goto outa;
/* start modification for multibyte env */
IS_ascii = 1;
else
/* end modification for multibyte env */
for (i = 0; i < Max; /* null */)
if (fbuf[i] & 0200) {
IS_ascii = 0;
return;
}
/* start modification for multibyte env */
return;
}
i += length;
}
else
i++;
i = fbsz;
/* end modification for multibyte env */
else if (IS_ascii)
else
outa:
/*
* This code is to make sure that no MB char is cut in half
* while still being used.
*/
while (i < fbsz) {
i++;
continue;
} else {
return;
}
i = i + length;
}
}
(void) printf("\n");
}
static int
{
int k;
i = 0;
for (k = 0; k < 6; k++) {
return (0);
return (0);
while (i < n && bp[i] != '\n')
i++;
if (i++ >= n)
return (0);
}
return (1);
}
/*
* Determine if the passed descriptor describes an ELF file.
* If so, return the Elf handle.
*/
static Elf *
is_elf_file(int elffd)
{
case ELF_K_ELF:
break;
default:
break;
}
return (elf);
}
static void
ar_coff_or_aout(int elffd)
{
/*
* Get the files elf descriptor and process it as an elf or
* a.out (4.x) file.
*/
case ELF_K_AR :
"or shared object"));
break;
case ELF_K_COFF:
"file type"));
break;
default:
/*
* This is either an unknown file or an aout format
* info. on a.out or non-Elf binaries.
*/
break;
}
}
static void
{
case ET_NONE:
break;
case ET_REL:
break;
case ET_EXEC:
break;
case ET_DYN:
break;
case ET_CORE:
else
break;
default:
break;
}
}
static void
print_elf_machine(int machine)
{
/*
* This table must be kept in sync with the EM_ constants
*/
"unknown machine", /* 0 - EM_NONE */
"WE32100", /* 1 - EM_M32 */
"SPARC", /* 2 - EM_SPARC */
"80386", /* 3 - EM_386 */
"M68000", /* 4 - EM_68K */
"M88000", /* 5 - EM_88K */
"80486", /* 6 - EM_486 */
"i860", /* 7 - EM_860 */
"MIPS RS3000 Big-Endian", /* 8 - EM_MIPS */
"S/370", /* 9 - EM_S370 */
"MIPS RS3000 Little-Endian", /* 10 - EM_MIPS_RS3_LE */
"MIPS RS6000", /* 11 - EM_RS6000 */
NULL, /* 12 - EM_UNKNOWN12 */
NULL, /* 13 - EM_UNKNOWN13 */
NULL, /* 14 - EM_UNKNOWN14 */
"PA-RISC", /* 15 - EM_PA_RISC */
"nCUBE", /* 16 - EM_nCUBE */
"VPP500", /* 17 - EM_VPP500 */
"SPARC32PLUS", /* 18 - EM_SPARC32PLUS */
"i960", /* 19 - EM_960 */
"PowerPC", /* 20 - EM_PPC */
"PowerPC64", /* 21 - EM_PPC64 */
"S/390", /* 22 - EM_S390 */
NULL, /* 23 - EM_UNKNOWN23 */
NULL, /* 24 - EM_UNKNOWN24 */
NULL, /* 25 - EM_UNKNOWN25 */
NULL, /* 26 - EM_UNKNOWN26 */
NULL, /* 27 - EM_UNKNOWN27 */
NULL, /* 28 - EM_UNKNOWN28 */
NULL, /* 29 - EM_UNKNOWN29 */
NULL, /* 30 - EM_UNKNOWN30 */
NULL, /* 31 - EM_UNKNOWN31 */
NULL, /* 32 - EM_UNKNOWN32 */
NULL, /* 33 - EM_UNKNOWN33 */
NULL, /* 34 - EM_UNKNOWN34 */
NULL, /* 35 - EM_UNKNOWN35 */
"V800", /* 36 - EM_V800 */
"FR20", /* 37 - EM_FR20 */
"RH32", /* 38 - EM_RH32 */
"RCE", /* 39 - EM_RCE */
"ARM", /* 40 - EM_ARM */
"Alpha", /* 41 - EM_ALPHA */
"S/390", /* 42 - EM_SH */
"SPARCV9", /* 43 - EM_SPARCV9 */
"Tricore", /* 44 - EM_TRICORE */
"ARC", /* 45 - EM_ARC */
"H8/300", /* 46 - EM_H8_300 */
"H8/300H", /* 47 - EM_H8_300H */
"H8S", /* 48 - EM_H8S */
"H8/500", /* 49 - EM_H8_500 */
"IA64", /* 50 - EM_IA_64 */
"MIPS-X", /* 51 - EM_MIPS_X */
"Coldfire", /* 52 - EM_COLDFIRE */
"M68HC12", /* 53 - EM_68HC12 */
"MMA", /* 54 - EM_MMA */
"PCP", /* 55 - EM_PCP */
"nCPU", /* 56 - EM_NCPU */
"NDR1", /* 57 - EM_NDR1 */
"Starcore", /* 58 - EM_STARCORE */
"ME16", /* 59 - EM_ME16 */
"ST100", /* 60 - EM_ST100 */
"TINYJ", /* 61 - EM_TINYJ */
"AMD64", /* 62 - EM_AMD64 */
"PDSP", /* 63 - EM_PDSP */
NULL, /* 64 - EM_UNKNOWN64 */
NULL, /* 65 - EM_UNKNOWN65 */
"FX66", /* 66 - EM_FX66 */
"ST9 PLUS", /* 67 - EM_ST9PLUS */
"ST7", /* 68 - EM_ST7 */
"68HC16", /* 69 - EM_68HC16 */
"68HC11", /* 70 - EM_68HC11 */
"68H08", /* 71 - EM_68HC08 */
"68HC05", /* 72 - EM_68HC05 */
"SVX", /* 73 - EM_SVX */
"ST19", /* 74 - EM_ST19 */
"VAX", /* 75 - EM_VAX */
"CRIS", /* 76 - EM_CRIS */
"Javelin", /* 77 - EM_JAVELIN */
"Firepath", /* 78 - EM_FIREPATH */
"ZSP", /* 79 - EM_ZSP */
"MMIX", /* 80 - EM_MMIX */
"HUANY", /* 81 - EM_HUANY */
"Prism", /* 82 - EM_PRISM */
"AVR", /* 83 - EM_AVR */
"FR30", /* 84 - EM_FR30 */
"D10V", /* 85 - EM_D10V */
"D30V", /* 86 - EM_D30V */
"V850", /* 87 - EM_V850 */
"M32R", /* 88 - EM_M32R */
"MN10300", /* 89 - EM_MN10300 */
"MN10200", /* 90 - EM_MN10200 */
"picoJava", /* 91 - EM_PJ */
"OpenRISC", /* 92 - EM_OPENRISC */
"Tangent-A5", /* 93 - EM_ARC_A5 */
"Xtensa" /* 94 - EM_XTENSA */
};
/* If new machine is added, refuse to compile until we're updated */
#if EM_NUM != 95
#error "Number of known ELF machine constants has changed"
#endif
const char *str;
if (str)
}
static void
{
switch (datatype) {
case ELFDATA2LSB:
(void) printf(" LSB");
break;
case ELFDATA2MSB:
(void) printf(" MSB");
break;
default:
break;
}
}
static void
print_elf_class(int class)
{
switch (class) {
case ELFCLASS32:
break;
case ELFCLASS64:
break;
default:
break;
}
}
static void
{
switch (machine) {
case EM_SPARCV9:
if (flags & EF_SPARC_EXT_MASK) {
if (flags & EF_SPARC_SUN_US3) {
", UltraSPARC3 Extensions Required"));
} else if (flags & EF_SPARC_SUN_US1) {
", UltraSPARC1 Extensions Required"));
}
if (flags & EF_SPARC_HAL_R1)
", HaL R1 Extensions Required"));
}
break;
case EM_SPARC32PLUS:
if (flags & EF_SPARC_32PLUS)
if (flags & EF_SPARC_SUN_US3) {
(void) printf("%s",
gettext(", UltraSPARC3 Extensions Required"));
} else if (flags & EF_SPARC_SUN_US1) {
(void) printf("%s",
gettext(", UltraSPARC1 Extensions Required"));
}
if (flags & EF_SPARC_HAL_R1)
(void) printf("%s",
gettext(", HaL R1 Extensions Required"));
break;
default:
break;
}
}
static int
{
/*
* capabilities are available.
*/
gettext("can't read ELF section header\n"));
return (1);
}
continue;
/*
* Get the data associated with the .cap section.
*/
gettext("can't read ELF section data\n"));
return (1);
}
char str[100];
gettext("can't read capabilities data\n"));
return (1);
}
}
}
}
return (0);
}
static int
{
char *ident;
/*
* verify information in file header
*/
return (1);
}
print_elf_class(ident[EI_CLASS]);
print_elf_datatype(ident[EI_DATA]);
(void) printf(" %s %d",
return (0);
return (1);
/*
* check type
*/
return (1);
/*
* read program header and check for dynamic section
*/
return (1);
}
gettext("can't read program header\n"));
return (1);
}
dynamic = 1;
break;
}
}
if (dynamic)
else
return (0);
}
/*
* is_stripped prints information on whether the executable has
* been stripped.
*/
static void
{
char *section_name;
int symtab = 0;
int debuginfo = 0;
return;
}
/*
* Definition time:
* - "not stripped" means that an executable file
* contains a Symbol Table (.symtab)
* - "stripped" means that an executable file
* does not contain a Symbol Table.
* When strip -l or strip -x is run, it strips the
* debugging information (.line section name (strip -l),
* .line, .debug*, .stabs*, .dwarf* section names
* and SHT_SUNW_DEBUGSTR and SHT_SUNW_DEBUG
* section types (strip -x), however the Symbol
* Table will still be present.
* Therefore, if
* - No Symbol Table present, then report
* "stripped"
* - Symbol Table present with debugging
* information (line number or debug section names,
* or SHT_SUNW_DEBUGSTR or SHT_SUNW_DEBUG section
* types) then report:
* "not stripped"
* - Symbol Table present with no debugging
* information (line number or debug section names,
* or SHT_SUNW_DEBUGSTR or SHT_SUNW_DEBUG section
* types) then report:
* "not stripped, no debugging information
* available"
*/
break;
}
continue;
}
symtab++;
continue;
}
if (!debuginfo &&
debuginfo++;
}
}
/*
* Now that we've scanned all sections, print out the appropriate
* diagnostic.
*/
if (symtab) {
if (!debuginfo) {
", no debugging information available"));
}
} else {
}
}
/*
* is_rtld_config - If file is a runtime linker config file, prints
* the description and returns True (1). Otherwise, silently returns
* False (0).
*/
int
is_rtld_config(void)
{
(void) printf("\n");
return (1);
}
return (0);
}
/*
* lookup -
* Attempts to match one of the strings from a list, 'tab',
* with what is in the file, starting at the current index position 'i'.
* Looks past any initial whitespace and expects whitespace or other
* delimiting characters to follow the matched string.
* A match identifies the file as being 'assembler', 'fortran', 'c', etc.
* Returns 1 for a successful match, 0 otherwise.
*/
static int
{
register char r;
register int k, j, l;
i++;
for (j = 0; tab[j] != 0; j++) {
l = 0;
if (r == '\0')
fbuf[k] == '/') {
i = k;
return (1);
}
}
return (0);
}
/*
* ccom -
* Increments the current index 'i' into the file buffer 'fbuf' past any
* whitespace lines and C-style comments found, starting at the current
* position of 'i'. Returns 1 as long as we don't increment i past the
* size of fbuf (fbsz). Otherwise, returns 0.
*/
static int
ccom(void)
{
register char cc;
int len;
if (i++ >= fbsz)
return (0);
i += 2;
if (fbuf[i] == '\\')
i++;
len = 1;
i += len;
if (i >= fbsz)
return (0);
}
if ((i += 2) >= fbsz)
return (0);
}
if (fbuf[i] == '\n')
if (ccom() == 0)
return (0);
return (1);
}
/*
* ascom -
* Increments the current index 'i' into the file buffer 'fbuf' past
* consecutive assembler program comment lines starting with ASCOMCHAR,
* starting at the current position of 'i'.
* Returns 1 as long as we don't increment i past the
* size of fbuf (fbsz). Otherwise returns 0.
*/
static int
ascom(void)
{
i++;
while (fbuf[i++] != '\n')
if (i >= fbsz)
return (0);
while (fbuf[i] == '\n')
if (i++ >= fbsz)
return (0);
}
return (1);
}
static int
sccs(void)
{ /* look for "1hddddd" where d is a digit */
register int j;
for (j = 2; j <= 6; j++) {
continue;
else
return (0);
}
} else {
return (0);
}
return (1);
}
static int
{
if (n < 50)
return (0); /* no point in statistics on squibs */
for (j = 0; j < NASC; j++)
ct[j] = 0;
for (j = 0; j < n; j += len) {
switch (bp[j]) {
case '.':
case ',':
case ')':
case '%':
case ';':
case ':':
case '?':
punct++;
badpun++;
}
len = 1;
}
return (0);
return (0);
return (0); /* shell file test */
}
/*
* Convert a word from an elf file to native format.
* This is needed because there's no elf routine to
* get and decode a Note section header.
*/
static void
{
}
static void
{
}
/*
* Return true if it is an old (pre-restructured /proc) core file.
*/
static int
{
register int inx;
return (0);
return (0);
}
/*
* If the next segment is also a note, use it instead.
*/
return (0);
}
/*
* Old core files have type NT_PRPSINFO.
*/
return (1);
return (0);
}
}
return (0);
}
/*
* If it's a core file, print out the name of the file that dumped core.
*/
static int
{
register int inx;
char *psinfo;
return (0);
gettext("can't read program header\n"));
return (0);
}
char *fname;
/*
* If the next segment is also a note, use it instead.
*/
gettext("can't read program header\n"));
return (0);
}
/*
* Note: the ABI states that n_namesz must
* be rounded up to a 4 byte boundary.
*/
/*
* We want to print the string contained
* in psinfo->pr_fname[], where 'psinfo'
* is either an old NT_PRPSINFO structure
* or a new NT_PSINFO structure.
*
* Old core files have only type NT_PRPSINFO.
* New core files have type NT_PSINFO.
*
* These structures are also different by
* virtue of being contained in a core file
* of either 32-bit or 64-bit type.
*
* To further complicate matters, we ourself
* might be compiled either 32-bit or 64-bit.
*
* For these reason, we just *know* the offsets of
* pr_fname[] into the four different structures
* here, regardless of how we are compiled.
*/
/* 32-bit core file, 32-bit structures */
else /* old: NT_PRPSINFO */
/* 64-bit core file, 64-bit structures */
else /* old: NT_PRPSINFO */
} else {
break;
}
break;
}
}
return (1);
}
static int
{
return (0);
return (0);
return (0);
return (0);
else
up = "";
else
gp = "";
else
*tp = '\0';
/*
* TRANSLATION_NOTE
* This message is printed by file command for shell scripts.
* The first %s is for the translation for "set-uid " (if the script
* has the set-uid bit set), or is for an empty string (if the
* script does not have the set-uid bit set).
* Similarly, the second %s is for the translation for "set-gid ",
* or is for an empty string.
* The third %s is for the translation for either: "shell", "c-shell",
* or "DTrace", or is for the pathname of the program the script
* executes.
*/
return (1);
}
static int
{
int fd;
if (fd >= 0)
return (-1);
}
if (fd >= 0)
return (-1);
}
return (0);
}
/*
* ZIP file header information
*/
#define SIGSIZ 4
#define LOCSIG "PK\003\004"
#define LOCHDRSIZ 30
#define CH(b, n) (((unsigned char *)(b))[n])
static int
{
return (0);
break;
return (1);
}
}
/*
* We could just print "ZIP archive" here.
*
* However, customers may be using their own entries in
* let's defer the printing of "ZIP archive" to there.
*/
return (0);
}
static int
{
/* LINTED: pointer cast may result in improper alignment */
/*
* The current DUMP_MAGIC string covers Solaris 7 and later releases.
* The utsname struct is only present in dumphdr_t's with dump_version
* greater than or equal to 9.
*/
NATIVE_ISA : OTHER_ISA);
} else {
return (0);
}
return (1);
}
static void
const char *isa)
{
/*
* A dumphdr_t is bigger than FBSZ, so we have to manually read the
* rest of it.
*/
"%s %s %s %u-bit %s crash dump from '%s'\n"),
} else {
}
}
static void
usage(void)
{
"usage: file [-dh] [-M mfile] [-m mfile] [-f ffile] file ...\n"
" file [-dh] [-M mfile] [-m mfile] -f ffile\n"
" file -i [-h] [-f ffile] file ...\n"
" file -i [-h] -f ffile\n"
" file -c [-d] [-M mfile] [-m mfile]\n"));
exit(2);
}
static uint32_t
{
return (out);
}
static uint32_t
{
return (in);
}
/*
* Check if str is in the string list str_list.
*/
static int
{
int i;
/*
* Only need to compare the strlen(str_list[i]) bytes.
* That way .stab will match on .stab* sections, and
* .debug will match on .debug* sections.
*/
return (1);
}
}
return (0);
}
/*
* default_magic -
* allocate space for and create the default magic file
* name string.
*/
static void
default_magic(void)
{
perror("file");
exit(2);
}
"/usr/lib/locale/%s/LC_MESSAGES/magic", msg_locale);
}
}
/*
* add_to_mlist -
* Add the given magic_file filename string to the list of magic
* files (mlist). This list of files will later be examined, and
* each magic file's entries will be added in order to
* the mtab table.
*
* The first flag is set to 1 to add to the first list, mlist1.
* The first flag is set to 0 to add to the second list, mlist2.
*/
static void
{
char **mlist; /* ordered list of magic files */
char **mlistp; /* next entry in mlist */
if (first) {
} else {
}
== NULL) {
perror("file");
exit(2);
}
}
mlist_sz *= 2;
perror("file");
exit(2);
}
}
/*
* now allocate memory for and copy the
* magic file name string
*/
perror("file");
exit(2);
}
mlistp++;
if (first) {
} else {
}
}
static void
fd_cleanup(void)
{
if (ifd != -1) {
ifd = -1;
}
if (elffd != -1) {
elffd = -1;
}
}