10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*3466Srie * Common Development and Distribution License (the "License").
6*3466Srie * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
210Sstevel@tonic-gate /*
22*3466Srie * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
230Sstevel@tonic-gate * Use is subject to license terms.
240Sstevel@tonic-gate */
250Sstevel@tonic-gate
260Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
270Sstevel@tonic-gate /* All Rights Reserved */
280Sstevel@tonic-gate
290Sstevel@tonic-gate /* Copyright (c) 1987, 1988 Microsoft Corporation */
300Sstevel@tonic-gate /* All Rights Reserved */
310Sstevel@tonic-gate
320Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
330Sstevel@tonic-gate
340Sstevel@tonic-gate #include <stdio.h>
350Sstevel@tonic-gate #include <stdlib.h>
360Sstevel@tonic-gate #include <string.h>
370Sstevel@tonic-gate #include <ctype.h>
380Sstevel@tonic-gate #include <errno.h>
390Sstevel@tonic-gate #include <limits.h>
400Sstevel@tonic-gate #include <inttypes.h>
410Sstevel@tonic-gate #include <sys/types.h>
420Sstevel@tonic-gate #include <libintl.h>
430Sstevel@tonic-gate
440Sstevel@tonic-gate /*
450Sstevel@tonic-gate * Types
460Sstevel@tonic-gate */
470Sstevel@tonic-gate
480Sstevel@tonic-gate #define BYTE 1
490Sstevel@tonic-gate #define SHORT 2
500Sstevel@tonic-gate #define LONG 4
510Sstevel@tonic-gate #define LLONG 8
520Sstevel@tonic-gate #define UBYTE 16
530Sstevel@tonic-gate #define USHORT 32
540Sstevel@tonic-gate #define ULONG 64
550Sstevel@tonic-gate #define ULLONG 128
560Sstevel@tonic-gate #define STR 256
570Sstevel@tonic-gate
580Sstevel@tonic-gate /*
590Sstevel@tonic-gate * Opcodes
600Sstevel@tonic-gate */
610Sstevel@tonic-gate
620Sstevel@tonic-gate #define EQ 0
630Sstevel@tonic-gate #define GT 1
640Sstevel@tonic-gate #define LT 2
650Sstevel@tonic-gate #define STRC 3 /* string compare */
660Sstevel@tonic-gate #define ANY 4
670Sstevel@tonic-gate #define AND 5
680Sstevel@tonic-gate #define NSET 6 /* True if bit is not set */
690Sstevel@tonic-gate #define SUB 64 /* or'ed in, SUBstitution string, for example */
700Sstevel@tonic-gate /* %ld, %s, %lo mask: with bit 6 on, used to locate */
710Sstevel@tonic-gate /* print formats */
720Sstevel@tonic-gate /*
730Sstevel@tonic-gate * Misc
740Sstevel@tonic-gate */
750Sstevel@tonic-gate
760Sstevel@tonic-gate #define BSZ 128
770Sstevel@tonic-gate #define NENT 200
780Sstevel@tonic-gate
790Sstevel@tonic-gate /*
800Sstevel@tonic-gate * Structure of magic file entry
810Sstevel@tonic-gate */
820Sstevel@tonic-gate
830Sstevel@tonic-gate struct entry {
840Sstevel@tonic-gate char e_level; /* 0 or 1 */
850Sstevel@tonic-gate off_t e_off; /* in bytes */
860Sstevel@tonic-gate uint32_t e_type; /* BYTE, SHORT, STR, et al */
870Sstevel@tonic-gate char e_opcode; /* EQ, GT, LT, ANY, AND, NSET */
880Sstevel@tonic-gate uint64_t e_mask; /* if non-zero, mask value with this */
890Sstevel@tonic-gate union {
900Sstevel@tonic-gate uint64_t num;
910Sstevel@tonic-gate char *str;
920Sstevel@tonic-gate } e_value;
930Sstevel@tonic-gate const char *e_str;
940Sstevel@tonic-gate };
950Sstevel@tonic-gate
96*3466Srie /* Non-localized string giving name of command. Defined in file.c */
97*3466Srie extern const char *File;
98*3466Srie
990Sstevel@tonic-gate typedef struct entry Entry;
1000Sstevel@tonic-gate
1010Sstevel@tonic-gate static Entry *mtab1; /* 1st magic table, applied before default tests */
1020Sstevel@tonic-gate
1030Sstevel@tonic-gate /*
1040Sstevel@tonic-gate * 2nd magic table, includes default tests and magic entries
1050Sstevel@tonic-gate * to be applied after default position-sensitive tests
1060Sstevel@tonic-gate */
1070Sstevel@tonic-gate static Entry *mtab2;
1080Sstevel@tonic-gate
1090Sstevel@tonic-gate static Entry *mend1; /* one past last-allocated entry in mtab1 */
1100Sstevel@tonic-gate static Entry *mend2; /* one past last-allocated entry in mtab2 */
1110Sstevel@tonic-gate
1120Sstevel@tonic-gate static Entry *ep1; /* current entry in mtab1 */
1130Sstevel@tonic-gate static Entry *ep2; /* current entry in mtab2 */
1140Sstevel@tonic-gate
1150Sstevel@tonic-gate static char *
getstr(char * p,char * file)116*3466Srie getstr(char *p, char *file)
1170Sstevel@tonic-gate {
1180Sstevel@tonic-gate char *newstr;
1190Sstevel@tonic-gate char *s;
1200Sstevel@tonic-gate long val;
1210Sstevel@tonic-gate int base;
1220Sstevel@tonic-gate
1230Sstevel@tonic-gate newstr = (char *)malloc((strlen(p) + 1) * sizeof (char));
1240Sstevel@tonic-gate if (newstr == NULL) {
125*3466Srie int err = errno;
126*3466Srie (void) fprintf(stderr, gettext("%s: malloc failed: %s\n"),
127*3466Srie File, strerror(err));
1280Sstevel@tonic-gate return (NULL);
1290Sstevel@tonic-gate }
1300Sstevel@tonic-gate
1310Sstevel@tonic-gate s = newstr;
1320Sstevel@tonic-gate while (*p != '\0') {
1330Sstevel@tonic-gate if (*p != '\\') {
1340Sstevel@tonic-gate *s++ = *p++;
1350Sstevel@tonic-gate continue;
1360Sstevel@tonic-gate }
1370Sstevel@tonic-gate p++;
1380Sstevel@tonic-gate if (*p == '\0')
1390Sstevel@tonic-gate break;
1400Sstevel@tonic-gate if (isdigit(*p)) {
1410Sstevel@tonic-gate if (*p == '0' && (*(p+1) == 'x' || *(p+1) == 'X')) {
1420Sstevel@tonic-gate /* hex */
1430Sstevel@tonic-gate base = 16;
1440Sstevel@tonic-gate } else {
1450Sstevel@tonic-gate base = 8;
1460Sstevel@tonic-gate }
1470Sstevel@tonic-gate errno = 0;
1480Sstevel@tonic-gate val = strtol(p, &p, base);
1490Sstevel@tonic-gate if (val > UCHAR_MAX || val < 0 || errno != 0) {
150*3466Srie (void) fprintf(stderr, gettext("%s: %s: magic "
151*3466Srie "table invalid string value\n"), File,
152*3466Srie file);
1530Sstevel@tonic-gate return (NULL);
1540Sstevel@tonic-gate }
1550Sstevel@tonic-gate *s++ = (char)val;
1560Sstevel@tonic-gate } else {
1570Sstevel@tonic-gate /* escape the character */
1580Sstevel@tonic-gate switch (*p) {
1590Sstevel@tonic-gate case 'n':
1600Sstevel@tonic-gate *s = '\n';
1610Sstevel@tonic-gate break;
1620Sstevel@tonic-gate case 'r':
1630Sstevel@tonic-gate *s = '\r';
1640Sstevel@tonic-gate break;
1650Sstevel@tonic-gate case 'a':
1660Sstevel@tonic-gate *s = '\a';
1670Sstevel@tonic-gate break;
1680Sstevel@tonic-gate case 'b':
1690Sstevel@tonic-gate *s = '\b';
1700Sstevel@tonic-gate break;
1710Sstevel@tonic-gate case 'f':
1720Sstevel@tonic-gate *s = '\f';
1730Sstevel@tonic-gate break;
1740Sstevel@tonic-gate case 't':
1750Sstevel@tonic-gate *s = '\t';
1760Sstevel@tonic-gate break;
1770Sstevel@tonic-gate case 'v':
1780Sstevel@tonic-gate *s = '\v';
1790Sstevel@tonic-gate break;
1800Sstevel@tonic-gate default:
1810Sstevel@tonic-gate *s = *p;
1820Sstevel@tonic-gate break;
1830Sstevel@tonic-gate }
1840Sstevel@tonic-gate p++;
1850Sstevel@tonic-gate s++;
1860Sstevel@tonic-gate }
1870Sstevel@tonic-gate }
1880Sstevel@tonic-gate *s = '\0';
1890Sstevel@tonic-gate return (newstr);
1900Sstevel@tonic-gate }
1910Sstevel@tonic-gate
1920Sstevel@tonic-gate /*
1930Sstevel@tonic-gate * f_mkmtab - fills mtab array of magic table entries with
1940Sstevel@tonic-gate * values from the file magfile.
1950Sstevel@tonic-gate * May be called more than once if multiple magic
1960Sstevel@tonic-gate * files were specified.
1970Sstevel@tonic-gate * Stores entries sequentially in one of two magic
1980Sstevel@tonic-gate * tables: mtab1, if first = 1; mtab2 otherwise.
1990Sstevel@tonic-gate *
2000Sstevel@tonic-gate * If -c option is specified, cflg is non-zero, and
2010Sstevel@tonic-gate * f_mkmtab() reports on errors in the magic file.
2020Sstevel@tonic-gate *
2030Sstevel@tonic-gate * Two magic tables may need to be created. The first
2040Sstevel@tonic-gate * one (mtab1) contains magic entries to be checked before
2050Sstevel@tonic-gate * the programmatic default position-sensitive tests in
2060Sstevel@tonic-gate * def_position_tests().
2070Sstevel@tonic-gate * The second one (mtab2) should start with the default
2080Sstevel@tonic-gate * /etc/magic file entries and is to be checked after
2090Sstevel@tonic-gate * the programmatic default position-sensitive tests in
2100Sstevel@tonic-gate * def_position_tests(). The parameter "first" would
2110Sstevel@tonic-gate * be 1 for the former set of tables, 0 for the latter
2120Sstevel@tonic-gate * set of magic tables.
2130Sstevel@tonic-gate * No mtab2 should be created if file will not be
2140Sstevel@tonic-gate * applying default tests; in that case, all magic table
2150Sstevel@tonic-gate * entries should be in mtab1.
2160Sstevel@tonic-gate *
2170Sstevel@tonic-gate * f_mkmtab returns 0 on success, -1 on error. The calling
2180Sstevel@tonic-gate * program is not expected to proceed after f_mkmtab()
2190Sstevel@tonic-gate * returns an error.
2200Sstevel@tonic-gate */
2210Sstevel@tonic-gate
2220Sstevel@tonic-gate int
f_mkmtab(char * magfile,int cflg,int first)2230Sstevel@tonic-gate f_mkmtab(char *magfile, int cflg, int first)
2240Sstevel@tonic-gate {
2250Sstevel@tonic-gate Entry *mtab; /* generic magic table pointer */
2260Sstevel@tonic-gate Entry *ep; /* current magic table entry */
2270Sstevel@tonic-gate Entry *mend; /* one past last-allocated entry of mtab */
2280Sstevel@tonic-gate FILE *fp;
2290Sstevel@tonic-gate int lcnt = 0;
2300Sstevel@tonic-gate char buf[BSZ];
2310Sstevel@tonic-gate size_t tbsize;
2320Sstevel@tonic-gate size_t oldsize;
2330Sstevel@tonic-gate
2340Sstevel@tonic-gate if (first) {
2350Sstevel@tonic-gate mtab = mtab1;
2360Sstevel@tonic-gate mend = mend1;
2370Sstevel@tonic-gate ep = ep1;
2380Sstevel@tonic-gate } else {
2390Sstevel@tonic-gate mtab = mtab2;
2400Sstevel@tonic-gate mend = mend2;
2410Sstevel@tonic-gate ep = ep2;
2420Sstevel@tonic-gate }
2430Sstevel@tonic-gate
2440Sstevel@tonic-gate /* mtab may have been allocated on a previous f_mkmtab call */
2450Sstevel@tonic-gate if (mtab == (Entry *)NULL) {
246*3466Srie if ((mtab = calloc(sizeof (Entry), NENT)) == NULL) {
247*3466Srie int err = errno;
248*3466Srie (void) fprintf(stderr, gettext("%s: malloc "
249*3466Srie "failed: %s\n"), File, strerror(err));
2500Sstevel@tonic-gate return (-1);
2510Sstevel@tonic-gate }
2520Sstevel@tonic-gate
2530Sstevel@tonic-gate ep = mtab;
2540Sstevel@tonic-gate mend = &mtab[NENT];
2550Sstevel@tonic-gate }
2560Sstevel@tonic-gate
257*3466Srie errno = 0;
258*3466Srie if ((fp = fopen(magfile, "r")) == NULL) {
259*3466Srie int err = errno;
260*3466Srie (void) fprintf(stderr, gettext("%s: %s: cannot open magic "
261*3466Srie "file: %s\n"), File, magfile, err ? strerror(err) : "");
2620Sstevel@tonic-gate return (-1);
2630Sstevel@tonic-gate }
2640Sstevel@tonic-gate while (fgets(buf, BSZ, fp) != NULL) {
2650Sstevel@tonic-gate char *p = buf;
2660Sstevel@tonic-gate char *p2;
2670Sstevel@tonic-gate char *p3;
2680Sstevel@tonic-gate char opc;
2690Sstevel@tonic-gate
2700Sstevel@tonic-gate /*
2710Sstevel@tonic-gate * ensure we have one extra entry allocated
2720Sstevel@tonic-gate * to mark end of the table, after the while loop
2730Sstevel@tonic-gate */
2740Sstevel@tonic-gate if (ep >= (mend - 1)) {
2750Sstevel@tonic-gate oldsize = mend - mtab;
2760Sstevel@tonic-gate tbsize = (NENT + oldsize) * sizeof (Entry);
2770Sstevel@tonic-gate if ((mtab = realloc(mtab, tbsize)) == NULL) {
278*3466Srie int err = errno;
279*3466Srie (void) fprintf(stderr, gettext("%s: malloc "
280*3466Srie "failed: %s\n"), File, strerror(err));
2810Sstevel@tonic-gate return (-1);
2820Sstevel@tonic-gate } else {
2830Sstevel@tonic-gate (void) memset(mtab + oldsize, 0,
2840Sstevel@tonic-gate sizeof (Entry) * NENT);
2850Sstevel@tonic-gate mend = &mtab[tbsize / sizeof (Entry)];
2860Sstevel@tonic-gate ep = &mtab[oldsize-1];
2870Sstevel@tonic-gate }
2880Sstevel@tonic-gate }
2890Sstevel@tonic-gate
2900Sstevel@tonic-gate lcnt++;
2910Sstevel@tonic-gate if (*p == '\n' || *p == '#')
2920Sstevel@tonic-gate continue;
2930Sstevel@tonic-gate
2940Sstevel@tonic-gate
2950Sstevel@tonic-gate /* LEVEL */
2960Sstevel@tonic-gate if (*p == '>') {
2970Sstevel@tonic-gate ep->e_level = 1;
2980Sstevel@tonic-gate p++;
2990Sstevel@tonic-gate }
3000Sstevel@tonic-gate /* OFFSET */
3010Sstevel@tonic-gate p2 = strchr(p, '\t');
3020Sstevel@tonic-gate if (p2 == NULL) {
3030Sstevel@tonic-gate if (cflg)
304*3466Srie (void) fprintf(stderr, gettext("%s: %s: format "
305*3466Srie "error, no tab after %s on line %d\n"),
306*3466Srie File, magfile, p, lcnt);
3070Sstevel@tonic-gate continue;
3080Sstevel@tonic-gate }
3090Sstevel@tonic-gate *p2++ = NULL;
3100Sstevel@tonic-gate ep->e_off = strtol((const char *)p, (char **)NULL, 0);
3110Sstevel@tonic-gate while (*p2 == '\t')
3120Sstevel@tonic-gate p2++;
3130Sstevel@tonic-gate /* TYPE */
3140Sstevel@tonic-gate p = p2;
3150Sstevel@tonic-gate p2 = strchr(p, '\t');
3160Sstevel@tonic-gate if (p2 == NULL) {
3170Sstevel@tonic-gate if (cflg)
318*3466Srie (void) fprintf(stderr, gettext("%s: %s: format "
319*3466Srie "error, no tab after %s on line %d\n"),
320*3466Srie File, magfile, p, lcnt);
3210Sstevel@tonic-gate continue;
3220Sstevel@tonic-gate }
3230Sstevel@tonic-gate *p2++ = NULL;
3240Sstevel@tonic-gate p3 = strchr(p, '&');
3250Sstevel@tonic-gate if (p3 != NULL) {
3260Sstevel@tonic-gate *p3++ = '\0';
3270Sstevel@tonic-gate ep->e_mask = strtoull((const char *)p3, (char **)NULL,
3280Sstevel@tonic-gate 0); /* returns 0 or ULLONG_MAX on error */
3290Sstevel@tonic-gate } else {
3300Sstevel@tonic-gate ep->e_mask = 0ULL;
3310Sstevel@tonic-gate }
3320Sstevel@tonic-gate switch (*p) {
3330Sstevel@tonic-gate case 'd':
3340Sstevel@tonic-gate if (*(p+1) == NULL) {
3350Sstevel@tonic-gate /* d */
3360Sstevel@tonic-gate ep->e_type = LONG;
3370Sstevel@tonic-gate } else if (*(p+2) == NULL) { /* d? */
3380Sstevel@tonic-gate switch (*(p+1)) {
3390Sstevel@tonic-gate case 'C':
3400Sstevel@tonic-gate case '1':
3410Sstevel@tonic-gate /* dC, d1 */
3420Sstevel@tonic-gate ep->e_type = BYTE;
3430Sstevel@tonic-gate break;
3440Sstevel@tonic-gate case 'S':
3450Sstevel@tonic-gate case '2':
3460Sstevel@tonic-gate /* dS, d2 */
3470Sstevel@tonic-gate ep->e_type = SHORT;
3480Sstevel@tonic-gate break;
3490Sstevel@tonic-gate case 'I':
3500Sstevel@tonic-gate case 'L':
3510Sstevel@tonic-gate case '4':
3520Sstevel@tonic-gate /* dI, dL, d4 */
3530Sstevel@tonic-gate ep->e_type = LONG;
3540Sstevel@tonic-gate break;
3550Sstevel@tonic-gate case '8':
3560Sstevel@tonic-gate /* d8 */
3570Sstevel@tonic-gate ep->e_type = LLONG;
3580Sstevel@tonic-gate break;
3590Sstevel@tonic-gate default:
3600Sstevel@tonic-gate ep->e_type = LONG;
3610Sstevel@tonic-gate break;
3620Sstevel@tonic-gate }
3630Sstevel@tonic-gate }
3640Sstevel@tonic-gate break;
3650Sstevel@tonic-gate case 'l':
3660Sstevel@tonic-gate if (*(p+1) == 'l') { /* llong */
3670Sstevel@tonic-gate ep->e_type = LLONG;
3680Sstevel@tonic-gate } else { /* long */
3690Sstevel@tonic-gate ep->e_type = LONG;
3700Sstevel@tonic-gate }
3710Sstevel@tonic-gate break;
3720Sstevel@tonic-gate case 's':
3730Sstevel@tonic-gate if (*(p+1) == 'h') {
3740Sstevel@tonic-gate /* short */
3750Sstevel@tonic-gate ep->e_type = SHORT;
3760Sstevel@tonic-gate } else {
3770Sstevel@tonic-gate /* s or string */
3780Sstevel@tonic-gate ep->e_type = STR;
3790Sstevel@tonic-gate }
3800Sstevel@tonic-gate break;
3810Sstevel@tonic-gate case 'u':
3820Sstevel@tonic-gate if (*(p+1) == NULL) {
3830Sstevel@tonic-gate /* u */
3840Sstevel@tonic-gate ep->e_type = ULONG;
3850Sstevel@tonic-gate } else if (*(p+2) == NULL) { /* u? */
3860Sstevel@tonic-gate switch (*(p+1)) {
3870Sstevel@tonic-gate case 'C':
3880Sstevel@tonic-gate case '1':
3890Sstevel@tonic-gate /* uC, u1 */
3900Sstevel@tonic-gate ep->e_type = UBYTE;
3910Sstevel@tonic-gate break;
3920Sstevel@tonic-gate case 'S':
3930Sstevel@tonic-gate case '2':
3940Sstevel@tonic-gate /* uS, u2 */
3950Sstevel@tonic-gate ep->e_type = USHORT;
3960Sstevel@tonic-gate break;
3970Sstevel@tonic-gate case 'I':
3980Sstevel@tonic-gate case 'L':
3990Sstevel@tonic-gate case '4':
4000Sstevel@tonic-gate /* uI, uL, u4 */
4010Sstevel@tonic-gate ep->e_type = ULONG;
4020Sstevel@tonic-gate break;
4030Sstevel@tonic-gate case '8':
4040Sstevel@tonic-gate /* u8 */
4050Sstevel@tonic-gate ep->e_type = ULLONG;
4060Sstevel@tonic-gate break;
4070Sstevel@tonic-gate default:
4080Sstevel@tonic-gate ep->e_type = ULONG;
4090Sstevel@tonic-gate break;
4100Sstevel@tonic-gate }
4110Sstevel@tonic-gate } else { /* u?* */
4120Sstevel@tonic-gate switch (*(p+1)) {
4130Sstevel@tonic-gate case 'b': /* ubyte */
4140Sstevel@tonic-gate ep->e_type = UBYTE;
4150Sstevel@tonic-gate break;
4160Sstevel@tonic-gate case 's': /* ushort */
4170Sstevel@tonic-gate ep->e_type = USHORT;
4180Sstevel@tonic-gate break;
4190Sstevel@tonic-gate case 'l':
4200Sstevel@tonic-gate if (*(p+2) == 'l') {
4210Sstevel@tonic-gate /* ullong */
4220Sstevel@tonic-gate ep->e_type = ULLONG;
4230Sstevel@tonic-gate } else {
4240Sstevel@tonic-gate /* ulong */
4250Sstevel@tonic-gate ep->e_type = ULONG;
4260Sstevel@tonic-gate }
4270Sstevel@tonic-gate break;
4280Sstevel@tonic-gate default:
4290Sstevel@tonic-gate /* default, same as "u" */
4300Sstevel@tonic-gate ep->e_type = ULONG;
4310Sstevel@tonic-gate break;
4320Sstevel@tonic-gate }
4330Sstevel@tonic-gate }
4340Sstevel@tonic-gate break;
4350Sstevel@tonic-gate default:
4360Sstevel@tonic-gate /* retain (undocumented) default type */
4370Sstevel@tonic-gate ep->e_type = BYTE;
4380Sstevel@tonic-gate break;
4390Sstevel@tonic-gate }
4400Sstevel@tonic-gate if (ep->e_type == 0) {
4410Sstevel@tonic-gate ep->e_type = BYTE; /* default */
4420Sstevel@tonic-gate }
4430Sstevel@tonic-gate while (*p2 == '\t')
4440Sstevel@tonic-gate p2++;
4450Sstevel@tonic-gate /* OP-VALUE */
4460Sstevel@tonic-gate p = p2;
4470Sstevel@tonic-gate p2 = strchr(p, '\t');
4480Sstevel@tonic-gate if (p2 == NULL) {
4490Sstevel@tonic-gate if (cflg)
450*3466Srie (void) fprintf(stderr, gettext("%s: %s: format "
451*3466Srie "error, no tab after %s on line %d\n"),
452*3466Srie File, magfile, p, lcnt);
4530Sstevel@tonic-gate continue;
4540Sstevel@tonic-gate }
4550Sstevel@tonic-gate *p2++ = NULL;
4560Sstevel@tonic-gate if (ep->e_type != STR) {
4570Sstevel@tonic-gate opc = *p++;
4580Sstevel@tonic-gate switch (opc) {
4590Sstevel@tonic-gate case '=':
4600Sstevel@tonic-gate ep->e_opcode = EQ;
4610Sstevel@tonic-gate break;
4620Sstevel@tonic-gate
4630Sstevel@tonic-gate case '>':
4640Sstevel@tonic-gate ep->e_opcode = GT;
4650Sstevel@tonic-gate break;
4660Sstevel@tonic-gate
4670Sstevel@tonic-gate case '<':
4680Sstevel@tonic-gate ep->e_opcode = LT;
4690Sstevel@tonic-gate break;
4700Sstevel@tonic-gate
4710Sstevel@tonic-gate case 'x':
4720Sstevel@tonic-gate ep->e_opcode = ANY;
4730Sstevel@tonic-gate break;
4740Sstevel@tonic-gate
4750Sstevel@tonic-gate case '&':
4760Sstevel@tonic-gate ep->e_opcode = AND;
4770Sstevel@tonic-gate break;
4780Sstevel@tonic-gate
4790Sstevel@tonic-gate case '^':
4800Sstevel@tonic-gate ep->e_opcode = NSET;
4810Sstevel@tonic-gate break;
4820Sstevel@tonic-gate default: /* EQ (i.e. 0) is default */
4830Sstevel@tonic-gate p--; /* since global ep->e_opcode=0 */
4840Sstevel@tonic-gate }
4850Sstevel@tonic-gate }
4860Sstevel@tonic-gate if (ep->e_opcode != ANY) {
4870Sstevel@tonic-gate if (ep->e_type != STR) {
4880Sstevel@tonic-gate ep->e_value.num = strtoull((const char *)p,
4890Sstevel@tonic-gate (char **)NULL, 0);
490*3466Srie } else if ((ep->e_value.str =
491*3466Srie getstr(p, magfile)) == NULL) {
4920Sstevel@tonic-gate return (-1);
4930Sstevel@tonic-gate }
4940Sstevel@tonic-gate }
4950Sstevel@tonic-gate p2 += strspn(p2, "\t");
4960Sstevel@tonic-gate /* STRING */
4970Sstevel@tonic-gate if ((ep->e_str = strdup(p2)) == NULL) {
498*3466Srie int err = errno;
499*3466Srie (void) fprintf(stderr, gettext("%s: malloc "
500*3466Srie "failed: %s\n"), File, strerror(err));
5010Sstevel@tonic-gate return (-1);
5020Sstevel@tonic-gate } else {
5030Sstevel@tonic-gate if ((p = strchr(ep->e_str, '\n')) != NULL)
5040Sstevel@tonic-gate *p = '\0';
5050Sstevel@tonic-gate if (strchr(ep->e_str, '%') != NULL)
5060Sstevel@tonic-gate ep->e_opcode |= SUB;
5070Sstevel@tonic-gate }
5080Sstevel@tonic-gate ep++;
5090Sstevel@tonic-gate } /* end while (fgets) */
5100Sstevel@tonic-gate
5110Sstevel@tonic-gate ep->e_off = -1L; /* mark end of table */
5120Sstevel@tonic-gate if (first) {
5130Sstevel@tonic-gate mtab1 = mtab;
5140Sstevel@tonic-gate mend1 = mend;
5150Sstevel@tonic-gate ep1 = ep;
5160Sstevel@tonic-gate } else {
5170Sstevel@tonic-gate mtab2 = mtab;
5180Sstevel@tonic-gate mend2 = mend;
5190Sstevel@tonic-gate ep2 = ep;
5200Sstevel@tonic-gate }
521*3466Srie if (fclose(fp) != 0) {
522*3466Srie int err = errno;
523*3466Srie (void) fprintf(stderr, gettext("%s: fclose failed: %s\n"),
524*3466Srie File, strerror(err));
5250Sstevel@tonic-gate return (-1);
5260Sstevel@tonic-gate }
5270Sstevel@tonic-gate return (0);
5280Sstevel@tonic-gate }
5290Sstevel@tonic-gate
5300Sstevel@tonic-gate /*
5310Sstevel@tonic-gate * Check for Magic Table entries in the file.
5320Sstevel@tonic-gate *
5330Sstevel@tonic-gate * Since there may be two sets of magic tables, first = 1
5340Sstevel@tonic-gate * for the first magic table (mtab1) and 0 for the second magic
5350Sstevel@tonic-gate * table (mtab2).
5360Sstevel@tonic-gate */
5370Sstevel@tonic-gate int
f_ckmtab(char * buf,int bufsize,int first)5380Sstevel@tonic-gate f_ckmtab(char *buf, int bufsize, int first)
5390Sstevel@tonic-gate {
5400Sstevel@tonic-gate int result;
5410Sstevel@tonic-gate Entry *mtab;
5420Sstevel@tonic-gate Entry *ep;
5430Sstevel@tonic-gate char *p;
5440Sstevel@tonic-gate int lev1 = 0;
5450Sstevel@tonic-gate
5460Sstevel@tonic-gate uint16_t u16_val;
5470Sstevel@tonic-gate uint32_t u32_val;
5480Sstevel@tonic-gate uint64_t u64_val;
5490Sstevel@tonic-gate
5500Sstevel@tonic-gate if (first) {
5510Sstevel@tonic-gate mtab = mtab1;
5520Sstevel@tonic-gate } else {
5530Sstevel@tonic-gate mtab = mtab2;
5540Sstevel@tonic-gate }
5550Sstevel@tonic-gate
5560Sstevel@tonic-gate if (mtab == (Entry *)NULL) {
5570Sstevel@tonic-gate return (0); /* no magic file tests in this table */
5580Sstevel@tonic-gate }
5590Sstevel@tonic-gate
5600Sstevel@tonic-gate for (ep = mtab; ep->e_off != -1L; ep++) { /* -1 offset marks end of */
5610Sstevel@tonic-gate if (lev1) { /* valid magic file entries */
5620Sstevel@tonic-gate if (ep->e_level != 1)
5630Sstevel@tonic-gate break;
5640Sstevel@tonic-gate } else if (ep->e_level == 1) {
5650Sstevel@tonic-gate continue;
5660Sstevel@tonic-gate }
5670Sstevel@tonic-gate if (ep->e_off > (off_t)bufsize)
5680Sstevel@tonic-gate continue;
5690Sstevel@tonic-gate p = &buf[ep->e_off];
5700Sstevel@tonic-gate switch (ep->e_type) {
5710Sstevel@tonic-gate case STR:
5720Sstevel@tonic-gate {
5730Sstevel@tonic-gate if (strncmp(p, ep->e_value.str,
5740Sstevel@tonic-gate strlen(ep->e_value.str)))
5750Sstevel@tonic-gate continue;
5760Sstevel@tonic-gate if (lev1) {
5770Sstevel@tonic-gate (void) putchar(' ');
5780Sstevel@tonic-gate }
5790Sstevel@tonic-gate if (ep->e_opcode & SUB)
5800Sstevel@tonic-gate (void) printf(ep->e_str,
5810Sstevel@tonic-gate ep->e_value.str);
5820Sstevel@tonic-gate else
5830Sstevel@tonic-gate (void) printf(ep->e_str);
5840Sstevel@tonic-gate lev1 = 1;
5850Sstevel@tonic-gate continue;
5860Sstevel@tonic-gate /*
5870Sstevel@tonic-gate * We've matched the string and printed the message;
5880Sstevel@tonic-gate * no STR processing occurs beyond this point.
5890Sstevel@tonic-gate */
5900Sstevel@tonic-gate }
5910Sstevel@tonic-gate
5920Sstevel@tonic-gate case BYTE:
5930Sstevel@tonic-gate case UBYTE:
5940Sstevel@tonic-gate u64_val = (uint64_t)(uint8_t)(*p);
5950Sstevel@tonic-gate break;
5960Sstevel@tonic-gate
5970Sstevel@tonic-gate case SHORT:
5980Sstevel@tonic-gate case USHORT:
5990Sstevel@tonic-gate (void) memcpy(&u16_val, p, sizeof (uint16_t));
6000Sstevel@tonic-gate u64_val = (uint64_t)u16_val;
6010Sstevel@tonic-gate break;
6020Sstevel@tonic-gate
6030Sstevel@tonic-gate case LONG:
6040Sstevel@tonic-gate case ULONG:
6050Sstevel@tonic-gate (void) memcpy(&u32_val, p, sizeof (uint32_t));
6060Sstevel@tonic-gate u64_val = (uint64_t)u32_val;
6070Sstevel@tonic-gate break;
6080Sstevel@tonic-gate
6090Sstevel@tonic-gate case LLONG:
6100Sstevel@tonic-gate case ULLONG:
6110Sstevel@tonic-gate (void) memcpy(&(u64_val), p, sizeof (uint64_t));
6120Sstevel@tonic-gate break;
6130Sstevel@tonic-gate
6140Sstevel@tonic-gate }
6150Sstevel@tonic-gate
6160Sstevel@tonic-gate if (ep->e_mask) {
6170Sstevel@tonic-gate u64_val &= ep->e_mask;
6180Sstevel@tonic-gate }
6190Sstevel@tonic-gate
6200Sstevel@tonic-gate /*
6210Sstevel@tonic-gate * Compare the values according to the size and sign
6220Sstevel@tonic-gate * of the type. For =, &, and ^ operators, the sign
6230Sstevel@tonic-gate * does not have any effect, so these are always compared
6240Sstevel@tonic-gate * unsigned. Only for < and > operators is the
6250Sstevel@tonic-gate * sign significant.
6260Sstevel@tonic-gate * If the file value was masked, the compare should
6270Sstevel@tonic-gate * be unsigned.
6280Sstevel@tonic-gate */
6290Sstevel@tonic-gate switch (ep->e_opcode & ~SUB) {
6300Sstevel@tonic-gate case EQ:
6310Sstevel@tonic-gate switch (ep->e_type) {
6320Sstevel@tonic-gate case BYTE:
6330Sstevel@tonic-gate case UBYTE:
6340Sstevel@tonic-gate if ((uint8_t)u64_val !=
6350Sstevel@tonic-gate (uint8_t)(ep->e_value.num))
6360Sstevel@tonic-gate continue;
6370Sstevel@tonic-gate break;
6380Sstevel@tonic-gate case SHORT:
6390Sstevel@tonic-gate case USHORT:
6400Sstevel@tonic-gate if ((uint16_t)u64_val !=
6410Sstevel@tonic-gate (uint16_t)(ep->e_value.num))
6420Sstevel@tonic-gate continue;
6430Sstevel@tonic-gate break;
6440Sstevel@tonic-gate case LONG:
6450Sstevel@tonic-gate case ULONG:
6460Sstevel@tonic-gate if ((uint32_t)u64_val !=
6470Sstevel@tonic-gate (uint32_t)(ep->e_value.num))
6480Sstevel@tonic-gate continue;
6490Sstevel@tonic-gate break;
6500Sstevel@tonic-gate case LLONG:
6510Sstevel@tonic-gate case ULLONG:
6520Sstevel@tonic-gate if (u64_val != ep->e_value.num)
6530Sstevel@tonic-gate continue;
6540Sstevel@tonic-gate break;
6550Sstevel@tonic-gate default:
6560Sstevel@tonic-gate continue;
6570Sstevel@tonic-gate }
6580Sstevel@tonic-gate break;
6590Sstevel@tonic-gate case GT:
6600Sstevel@tonic-gate switch (ep->e_type) {
6610Sstevel@tonic-gate case BYTE:
6620Sstevel@tonic-gate if (ep->e_mask == 0) {
6630Sstevel@tonic-gate if ((int8_t)u64_val <=
6640Sstevel@tonic-gate (int8_t)(ep->e_value.num))
6650Sstevel@tonic-gate continue;
6660Sstevel@tonic-gate break;
6670Sstevel@tonic-gate }
6680Sstevel@tonic-gate /*FALLTHROUGH*/
6690Sstevel@tonic-gate case UBYTE:
6700Sstevel@tonic-gate if ((uint8_t)u64_val <=
6710Sstevel@tonic-gate (uint8_t)(ep->e_value.num))
6720Sstevel@tonic-gate continue;
6730Sstevel@tonic-gate break;
6740Sstevel@tonic-gate case SHORT:
6750Sstevel@tonic-gate if (ep->e_mask == 0) {
6760Sstevel@tonic-gate if ((int16_t)u64_val <=
6770Sstevel@tonic-gate (int16_t)(ep->e_value.num))
6780Sstevel@tonic-gate continue;
6790Sstevel@tonic-gate break;
6800Sstevel@tonic-gate }
6810Sstevel@tonic-gate /*FALLTHROUGH*/
6820Sstevel@tonic-gate case USHORT:
6830Sstevel@tonic-gate if ((uint16_t)u64_val <=
6840Sstevel@tonic-gate (uint16_t)(ep->e_value.num))
6850Sstevel@tonic-gate continue;
6860Sstevel@tonic-gate break;
6870Sstevel@tonic-gate case LONG:
6880Sstevel@tonic-gate if (ep->e_mask == 0) {
6890Sstevel@tonic-gate if ((int32_t)u64_val <=
6900Sstevel@tonic-gate (int32_t)(ep->e_value.num))
6910Sstevel@tonic-gate continue;
6920Sstevel@tonic-gate break;
6930Sstevel@tonic-gate }
6940Sstevel@tonic-gate /*FALLTHROUGH*/
6950Sstevel@tonic-gate case ULONG:
6960Sstevel@tonic-gate if ((uint32_t)u64_val <=
6970Sstevel@tonic-gate (uint32_t)(ep->e_value.num))
6980Sstevel@tonic-gate continue;
6990Sstevel@tonic-gate break;
7000Sstevel@tonic-gate case LLONG:
7010Sstevel@tonic-gate if (ep->e_mask == 0) {
7020Sstevel@tonic-gate if ((int64_t)u64_val <=
7030Sstevel@tonic-gate (int64_t)(ep->e_value.num))
7040Sstevel@tonic-gate continue;
7050Sstevel@tonic-gate break;
7060Sstevel@tonic-gate }
7070Sstevel@tonic-gate /*FALLTHROUGH*/
7080Sstevel@tonic-gate case ULLONG:
7090Sstevel@tonic-gate if (u64_val <= ep->e_value.num)
7100Sstevel@tonic-gate continue;
7110Sstevel@tonic-gate break;
7120Sstevel@tonic-gate default:
7130Sstevel@tonic-gate continue;
7140Sstevel@tonic-gate }
7150Sstevel@tonic-gate break;
7160Sstevel@tonic-gate case LT:
7170Sstevel@tonic-gate switch (ep->e_type) {
7180Sstevel@tonic-gate case BYTE:
7190Sstevel@tonic-gate if (ep->e_mask == 0) {
7200Sstevel@tonic-gate if ((int8_t)u64_val >=
7210Sstevel@tonic-gate (int8_t)(ep->e_value.num))
7220Sstevel@tonic-gate continue;
7230Sstevel@tonic-gate break;
7240Sstevel@tonic-gate }
7250Sstevel@tonic-gate /*FALLTHROUGH*/
7260Sstevel@tonic-gate case UBYTE:
7270Sstevel@tonic-gate if ((uint8_t)u64_val >=
7280Sstevel@tonic-gate (uint8_t)(ep->e_value.num))
7290Sstevel@tonic-gate continue;
7300Sstevel@tonic-gate break;
7310Sstevel@tonic-gate case SHORT:
7320Sstevel@tonic-gate if (ep->e_mask == 0) {
7330Sstevel@tonic-gate if ((int16_t)u64_val >=
7340Sstevel@tonic-gate (int16_t)(ep->e_value.num))
7350Sstevel@tonic-gate continue;
7360Sstevel@tonic-gate break;
7370Sstevel@tonic-gate }
7380Sstevel@tonic-gate /*FALLTHROUGH*/
7390Sstevel@tonic-gate case USHORT:
7400Sstevel@tonic-gate if ((uint16_t)u64_val >=
7410Sstevel@tonic-gate (uint16_t)(ep->e_value.num))
7420Sstevel@tonic-gate continue;
7430Sstevel@tonic-gate break;
7440Sstevel@tonic-gate case LONG:
7450Sstevel@tonic-gate if (ep->e_mask == 0) {
7460Sstevel@tonic-gate if ((int32_t)u64_val >=
7470Sstevel@tonic-gate (int32_t)(ep->e_value.num))
7480Sstevel@tonic-gate continue;
7490Sstevel@tonic-gate break;
7500Sstevel@tonic-gate }
7510Sstevel@tonic-gate /*FALLTHROUGH*/
7520Sstevel@tonic-gate case ULONG:
7530Sstevel@tonic-gate if ((uint32_t)u64_val >=
7540Sstevel@tonic-gate (uint32_t)(ep->e_value.num))
7550Sstevel@tonic-gate continue;
7560Sstevel@tonic-gate break;
7570Sstevel@tonic-gate case LLONG:
7580Sstevel@tonic-gate if (ep->e_mask == 0) {
7590Sstevel@tonic-gate if ((int64_t)u64_val >=
7600Sstevel@tonic-gate (int64_t)(ep->e_value.num))
7610Sstevel@tonic-gate continue;
7620Sstevel@tonic-gate break;
7630Sstevel@tonic-gate }
7640Sstevel@tonic-gate /*FALLTHROUGH*/
7650Sstevel@tonic-gate case ULLONG:
7660Sstevel@tonic-gate if (u64_val >= ep->e_value.num)
7670Sstevel@tonic-gate continue;
7680Sstevel@tonic-gate break;
7690Sstevel@tonic-gate default:
7700Sstevel@tonic-gate continue;
7710Sstevel@tonic-gate }
7720Sstevel@tonic-gate break;
7730Sstevel@tonic-gate case AND:
7740Sstevel@tonic-gate switch (ep->e_type) {
7750Sstevel@tonic-gate case BYTE:
7760Sstevel@tonic-gate case UBYTE:
7770Sstevel@tonic-gate if (((uint8_t)u64_val &
7780Sstevel@tonic-gate (uint8_t)(ep->e_value.num)) ==
7790Sstevel@tonic-gate (uint8_t)(ep->e_value.num))
7800Sstevel@tonic-gate break;
7810Sstevel@tonic-gate continue;
7820Sstevel@tonic-gate case SHORT:
7830Sstevel@tonic-gate case USHORT:
7840Sstevel@tonic-gate if (((uint16_t)u64_val &
7850Sstevel@tonic-gate (uint16_t)(ep->e_value.num)) ==
7860Sstevel@tonic-gate (uint16_t)(ep->e_value.num))
7870Sstevel@tonic-gate break;
7880Sstevel@tonic-gate continue;
7890Sstevel@tonic-gate case LONG:
7900Sstevel@tonic-gate case ULONG:
7910Sstevel@tonic-gate if (((uint32_t)u64_val &
7920Sstevel@tonic-gate (uint32_t)(ep->e_value.num)) ==
7930Sstevel@tonic-gate (uint32_t)(ep->e_value.num))
7940Sstevel@tonic-gate break;
7950Sstevel@tonic-gate continue;
7960Sstevel@tonic-gate case LLONG:
7970Sstevel@tonic-gate case ULLONG:
7980Sstevel@tonic-gate if ((u64_val & ep->e_value.num) ==
7990Sstevel@tonic-gate ep->e_value.num)
8000Sstevel@tonic-gate break;
8010Sstevel@tonic-gate continue;
8020Sstevel@tonic-gate default:
8030Sstevel@tonic-gate continue;
8040Sstevel@tonic-gate }
8050Sstevel@tonic-gate break;
8060Sstevel@tonic-gate case NSET:
8070Sstevel@tonic-gate switch (ep->e_type) {
8080Sstevel@tonic-gate case BYTE:
8090Sstevel@tonic-gate case UBYTE:
8100Sstevel@tonic-gate if (((uint8_t)u64_val &
8110Sstevel@tonic-gate (uint8_t)(ep->e_value.num)) !=
8120Sstevel@tonic-gate (uint8_t)(ep->e_value.num))
8130Sstevel@tonic-gate break;
8140Sstevel@tonic-gate continue;
8150Sstevel@tonic-gate case SHORT:
8160Sstevel@tonic-gate case USHORT:
8170Sstevel@tonic-gate if (((uint16_t)u64_val &
8180Sstevel@tonic-gate (uint16_t)(ep->e_value.num)) !=
8190Sstevel@tonic-gate (uint16_t)(ep->e_value.num))
8200Sstevel@tonic-gate break;
8210Sstevel@tonic-gate continue;
8220Sstevel@tonic-gate case LONG:
8230Sstevel@tonic-gate case ULONG:
8240Sstevel@tonic-gate if (((uint32_t)u64_val &
8250Sstevel@tonic-gate (uint32_t)(ep->e_value.num)) !=
8260Sstevel@tonic-gate (uint32_t)(ep->e_value.num))
8270Sstevel@tonic-gate break;
8280Sstevel@tonic-gate continue;
8290Sstevel@tonic-gate case LLONG:
8300Sstevel@tonic-gate case ULLONG:
8310Sstevel@tonic-gate if ((u64_val & ep->e_value.num) !=
8320Sstevel@tonic-gate ep->e_value.num)
8330Sstevel@tonic-gate break;
8340Sstevel@tonic-gate continue;
8350Sstevel@tonic-gate default:
8360Sstevel@tonic-gate continue;
8370Sstevel@tonic-gate }
8380Sstevel@tonic-gate break;
8390Sstevel@tonic-gate case ANY: /* matches anything */
8400Sstevel@tonic-gate break;
8410Sstevel@tonic-gate default: /* shouldn't occur; ignore it */
8420Sstevel@tonic-gate continue;
8430Sstevel@tonic-gate }
8440Sstevel@tonic-gate if (lev1)
8450Sstevel@tonic-gate (void) putchar(' ');
8460Sstevel@tonic-gate if (ep->e_opcode & SUB) {
8470Sstevel@tonic-gate switch (ep->e_type) {
8480Sstevel@tonic-gate case LLONG:
8490Sstevel@tonic-gate #ifdef XPG4
8500Sstevel@tonic-gate if (ep->e_mask == 0) {
8510Sstevel@tonic-gate (void) printf(ep->e_str,
8520Sstevel@tonic-gate (int64_t)u64_val);
8530Sstevel@tonic-gate break;
8540Sstevel@tonic-gate }
8550Sstevel@tonic-gate #endif /* XPG4 */
8560Sstevel@tonic-gate /*FALLTHROUGH*/
8570Sstevel@tonic-gate case ULLONG:
8580Sstevel@tonic-gate (void) printf(ep->e_str, u64_val);
8590Sstevel@tonic-gate break;
8600Sstevel@tonic-gate case LONG:
8610Sstevel@tonic-gate #ifdef XPG4
8620Sstevel@tonic-gate if (ep->e_mask == 0) {
8630Sstevel@tonic-gate (void) printf(ep->e_str,
8640Sstevel@tonic-gate (int32_t)u64_val);
8650Sstevel@tonic-gate break;
8660Sstevel@tonic-gate }
8670Sstevel@tonic-gate #endif /* XPG4 */
8680Sstevel@tonic-gate /*FALLTHROUGH*/
8690Sstevel@tonic-gate case ULONG:
8700Sstevel@tonic-gate (void) printf(ep->e_str,
8710Sstevel@tonic-gate (uint32_t)u64_val);
8720Sstevel@tonic-gate break;
8730Sstevel@tonic-gate case SHORT:
8740Sstevel@tonic-gate #ifdef XPG4
8750Sstevel@tonic-gate if (ep->e_mask == 0) {
8760Sstevel@tonic-gate (void) printf(ep->e_str,
8770Sstevel@tonic-gate (int16_t)u64_val);
8780Sstevel@tonic-gate break;
8790Sstevel@tonic-gate }
8800Sstevel@tonic-gate #endif /* XPG4 */
8810Sstevel@tonic-gate /*FALLTHROUGH*/
8820Sstevel@tonic-gate case USHORT:
8830Sstevel@tonic-gate (void) printf(ep->e_str,
8840Sstevel@tonic-gate (uint16_t)u64_val);
8850Sstevel@tonic-gate break;
8860Sstevel@tonic-gate case BYTE:
8870Sstevel@tonic-gate #ifdef XPG4
8880Sstevel@tonic-gate if (ep->e_mask == 0) {
8890Sstevel@tonic-gate (void) printf(ep->e_str,
8900Sstevel@tonic-gate (int8_t)u64_val);
8910Sstevel@tonic-gate break;
8920Sstevel@tonic-gate }
8930Sstevel@tonic-gate #endif /* XPG4 */
8940Sstevel@tonic-gate /*FALLTHROUGH*/
8950Sstevel@tonic-gate case UBYTE:
8960Sstevel@tonic-gate (void) printf(ep->e_str,
8970Sstevel@tonic-gate (uint8_t)u64_val);
8980Sstevel@tonic-gate break;
8990Sstevel@tonic-gate case STR:
9000Sstevel@tonic-gate /*
9010Sstevel@tonic-gate * Note: Currently can't get type
9020Sstevel@tonic-gate * STR here because we already
9030Sstevel@tonic-gate * did a 'continue' out of the
9040Sstevel@tonic-gate * loop earlier for case STR
9050Sstevel@tonic-gate */
9060Sstevel@tonic-gate break;
9070Sstevel@tonic-gate }
9080Sstevel@tonic-gate } else
9090Sstevel@tonic-gate (void) printf(ep->e_str);
9100Sstevel@tonic-gate lev1 = 1;
9110Sstevel@tonic-gate }
9120Sstevel@tonic-gate result = lev1 ? (int)(1 + ep - mtab) : 0;
9130Sstevel@tonic-gate
9140Sstevel@tonic-gate return (result);
9150Sstevel@tonic-gate }
9160Sstevel@tonic-gate
9170Sstevel@tonic-gate static void
showstr(char * s,int width)9180Sstevel@tonic-gate showstr(char *s, int width)
9190Sstevel@tonic-gate {
9200Sstevel@tonic-gate char c;
9210Sstevel@tonic-gate
9220Sstevel@tonic-gate while ((c = *s++) != '\0')
9230Sstevel@tonic-gate if (c >= 040 && c < 0176) {
9240Sstevel@tonic-gate (void) putchar(c);
9250Sstevel@tonic-gate width--;
9260Sstevel@tonic-gate } else {
9270Sstevel@tonic-gate (void) putchar('\\');
9280Sstevel@tonic-gate switch (c) {
9290Sstevel@tonic-gate
9300Sstevel@tonic-gate case '\n':
9310Sstevel@tonic-gate (void) putchar('n');
9320Sstevel@tonic-gate width -= 2;
9330Sstevel@tonic-gate break;
9340Sstevel@tonic-gate
9350Sstevel@tonic-gate case '\r':
9360Sstevel@tonic-gate (void) putchar('r');
9370Sstevel@tonic-gate width -= 2;
9380Sstevel@tonic-gate break;
9390Sstevel@tonic-gate
9400Sstevel@tonic-gate case '\a':
9410Sstevel@tonic-gate (void) putchar('a');
9420Sstevel@tonic-gate width -= 2;
9430Sstevel@tonic-gate break;
9440Sstevel@tonic-gate
9450Sstevel@tonic-gate case '\b':
9460Sstevel@tonic-gate (void) putchar('b');
9470Sstevel@tonic-gate width -= 2;
9480Sstevel@tonic-gate break;
9490Sstevel@tonic-gate
9500Sstevel@tonic-gate case '\t':
9510Sstevel@tonic-gate (void) putchar('t');
9520Sstevel@tonic-gate width -= 2;
9530Sstevel@tonic-gate break;
9540Sstevel@tonic-gate
9550Sstevel@tonic-gate case '\f':
9560Sstevel@tonic-gate (void) putchar('f');
9570Sstevel@tonic-gate width -= 2;
9580Sstevel@tonic-gate break;
9590Sstevel@tonic-gate
9600Sstevel@tonic-gate case '\v':
9610Sstevel@tonic-gate (void) putchar('v');
9620Sstevel@tonic-gate width -= 2;
9630Sstevel@tonic-gate break;
9640Sstevel@tonic-gate
9650Sstevel@tonic-gate default:
9660Sstevel@tonic-gate (void) printf("%.3o", c & 0377);
9670Sstevel@tonic-gate width -= 4;
9680Sstevel@tonic-gate break;
9690Sstevel@tonic-gate }
9700Sstevel@tonic-gate }
9710Sstevel@tonic-gate while (width >= 0) {
9720Sstevel@tonic-gate (void) putchar(' ');
9730Sstevel@tonic-gate width--;
9740Sstevel@tonic-gate };
9750Sstevel@tonic-gate }
9760Sstevel@tonic-gate
9770Sstevel@tonic-gate static char *
type_to_name(Entry * ep)9780Sstevel@tonic-gate type_to_name(Entry *ep)
9790Sstevel@tonic-gate {
9800Sstevel@tonic-gate static char buf[20];
9810Sstevel@tonic-gate char *s;
9820Sstevel@tonic-gate
9830Sstevel@tonic-gate switch (ep->e_type) {
9840Sstevel@tonic-gate case BYTE:
9850Sstevel@tonic-gate s = "byte";
9860Sstevel@tonic-gate break;
9870Sstevel@tonic-gate case SHORT:
9880Sstevel@tonic-gate s = "short";
9890Sstevel@tonic-gate break;
9900Sstevel@tonic-gate case LONG:
9910Sstevel@tonic-gate s = "long";
9920Sstevel@tonic-gate break;
9930Sstevel@tonic-gate case LLONG:
9940Sstevel@tonic-gate s = "llong";
9950Sstevel@tonic-gate break;
9960Sstevel@tonic-gate case UBYTE:
9970Sstevel@tonic-gate s = "ubyte";
9980Sstevel@tonic-gate break;
9990Sstevel@tonic-gate case USHORT:
10000Sstevel@tonic-gate s = "ushort";
10010Sstevel@tonic-gate break;
10020Sstevel@tonic-gate case ULONG:
10030Sstevel@tonic-gate s = "ulong";
10040Sstevel@tonic-gate break;
10050Sstevel@tonic-gate case ULLONG:
10060Sstevel@tonic-gate s = "ullong";
10070Sstevel@tonic-gate break;
10080Sstevel@tonic-gate case STR:
10090Sstevel@tonic-gate return ("string");
10100Sstevel@tonic-gate default:
10110Sstevel@tonic-gate /* more of an emergency measure .. */
10120Sstevel@tonic-gate (void) sprintf(buf, "%d", ep->e_type);
10130Sstevel@tonic-gate return (buf);
10140Sstevel@tonic-gate }
10150Sstevel@tonic-gate if (ep->e_mask) {
10160Sstevel@tonic-gate (void) snprintf(buf, sizeof (buf), "%s&0x%llx", s, ep->e_mask);
10170Sstevel@tonic-gate return (buf);
10180Sstevel@tonic-gate } else
10190Sstevel@tonic-gate return (s);
10200Sstevel@tonic-gate }
10210Sstevel@tonic-gate
10220Sstevel@tonic-gate static char
op_to_name(char op)10230Sstevel@tonic-gate op_to_name(char op)
10240Sstevel@tonic-gate {
10250Sstevel@tonic-gate char c;
10260Sstevel@tonic-gate
10270Sstevel@tonic-gate switch (op & ~SUB) {
10280Sstevel@tonic-gate
10290Sstevel@tonic-gate case EQ:
10300Sstevel@tonic-gate case STRC:
10310Sstevel@tonic-gate c = '=';
10320Sstevel@tonic-gate break;
10330Sstevel@tonic-gate
10340Sstevel@tonic-gate case GT:
10350Sstevel@tonic-gate c = '>';
10360Sstevel@tonic-gate break;
10370Sstevel@tonic-gate
10380Sstevel@tonic-gate case LT:
10390Sstevel@tonic-gate c = '<';
10400Sstevel@tonic-gate break;
10410Sstevel@tonic-gate
10420Sstevel@tonic-gate case ANY:
10430Sstevel@tonic-gate c = 'x';
10440Sstevel@tonic-gate break;
10450Sstevel@tonic-gate
10460Sstevel@tonic-gate case AND:
10470Sstevel@tonic-gate c = '&';
10480Sstevel@tonic-gate break;
10490Sstevel@tonic-gate
10500Sstevel@tonic-gate case NSET:
10510Sstevel@tonic-gate c = '^';
10520Sstevel@tonic-gate break;
10530Sstevel@tonic-gate
10540Sstevel@tonic-gate default:
10550Sstevel@tonic-gate c = '?';
10560Sstevel@tonic-gate break;
10570Sstevel@tonic-gate }
10580Sstevel@tonic-gate
10590Sstevel@tonic-gate return (c);
10600Sstevel@tonic-gate }
10610Sstevel@tonic-gate
10620Sstevel@tonic-gate /*
10630Sstevel@tonic-gate * f_prtmtab - Prints out a header, then entries from both magic
10640Sstevel@tonic-gate * tables, mtab1 and mtab2, if any exist.
10650Sstevel@tonic-gate */
10660Sstevel@tonic-gate void
f_prtmtab(void)10670Sstevel@tonic-gate f_prtmtab(void)
10680Sstevel@tonic-gate {
10690Sstevel@tonic-gate Entry *mtab;
10700Sstevel@tonic-gate Entry *ep;
10710Sstevel@tonic-gate int count;
10720Sstevel@tonic-gate
10730Sstevel@tonic-gate (void) printf("%-7s %-7s %-10s %-7s %-11s %s\n",
10740Sstevel@tonic-gate "level", "off", "type", "opcode", "value", "string");
10750Sstevel@tonic-gate for (mtab = mtab1, count = 1; count <= 2; count++, mtab = mtab2) {
10760Sstevel@tonic-gate if (mtab == (Entry *)NULL) {
10770Sstevel@tonic-gate continue;
10780Sstevel@tonic-gate }
10790Sstevel@tonic-gate for (ep = mtab; ep->e_off != -1L; ep++) {
10800Sstevel@tonic-gate (void) printf("%-7d %-7ld %-10s %-7c ",
10810Sstevel@tonic-gate ep->e_level,
10820Sstevel@tonic-gate ep->e_off, type_to_name(ep),
10830Sstevel@tonic-gate op_to_name(ep->e_opcode));
10840Sstevel@tonic-gate if (ep->e_type == STR) {
10850Sstevel@tonic-gate showstr(ep->e_value.str, 10);
10860Sstevel@tonic-gate } else { /* numeric */
10870Sstevel@tonic-gate (void) printf("%-#11llo", ep->e_value.num);
10880Sstevel@tonic-gate }
10890Sstevel@tonic-gate (void) printf(" %s", ep->e_str);
10900Sstevel@tonic-gate if (ep->e_opcode & SUB)
10910Sstevel@tonic-gate (void) printf("\tsubst");
10920Sstevel@tonic-gate (void) printf("\n");
10930Sstevel@tonic-gate }
10940Sstevel@tonic-gate }
10950Sstevel@tonic-gate }
10960Sstevel@tonic-gate
10970Sstevel@tonic-gate intmax_t
f_getmaxoffset(int first)10980Sstevel@tonic-gate f_getmaxoffset(int first)
10990Sstevel@tonic-gate {
11000Sstevel@tonic-gate Entry *mtab;
11010Sstevel@tonic-gate Entry *ep;
11020Sstevel@tonic-gate intmax_t cur;
11030Sstevel@tonic-gate intmax_t max = 0;
11040Sstevel@tonic-gate
11050Sstevel@tonic-gate if (first) {
11060Sstevel@tonic-gate mtab = mtab1;
11070Sstevel@tonic-gate } else {
11080Sstevel@tonic-gate mtab = mtab2;
11090Sstevel@tonic-gate }
11100Sstevel@tonic-gate if (mtab == (Entry *)NULL) {
11110Sstevel@tonic-gate return (0);
11120Sstevel@tonic-gate }
11130Sstevel@tonic-gate for (ep = mtab; ep->e_off != -1L; ep++) {
11140Sstevel@tonic-gate cur = ep->e_off;
11150Sstevel@tonic-gate switch (ep->e_type) {
11160Sstevel@tonic-gate case STR:
11170Sstevel@tonic-gate cur += strlen(ep->e_value.str);
11180Sstevel@tonic-gate break;
11190Sstevel@tonic-gate case BYTE:
11200Sstevel@tonic-gate case UBYTE:
11210Sstevel@tonic-gate cur += sizeof (uchar_t);
11220Sstevel@tonic-gate break;
11230Sstevel@tonic-gate case SHORT:
11240Sstevel@tonic-gate case USHORT:
11250Sstevel@tonic-gate cur += sizeof (uint16_t);
11260Sstevel@tonic-gate break;
11270Sstevel@tonic-gate case LONG:
11280Sstevel@tonic-gate case ULONG:
11290Sstevel@tonic-gate cur += sizeof (uint32_t);
11300Sstevel@tonic-gate break;
11310Sstevel@tonic-gate case LLONG:
11320Sstevel@tonic-gate case ULLONG:
11330Sstevel@tonic-gate cur += sizeof (uint64_t);
11340Sstevel@tonic-gate break;
11350Sstevel@tonic-gate }
11360Sstevel@tonic-gate if (cur <= INT_MAX && cur > max) {
11370Sstevel@tonic-gate max = cur;
11380Sstevel@tonic-gate }
11390Sstevel@tonic-gate }
11400Sstevel@tonic-gate
11410Sstevel@tonic-gate return (max);
11420Sstevel@tonic-gate }
1143