print.c revision 84685
1/*
2 * print.c - debugging printout routines
3 *
4 * Copyright (c) Ian F. Darwin, 1987.
5 * Written by Ian F. Darwin.
6 *
7 * This software is not subject to any license of the American Telephone
8 * and Telegraph Company or of the Regents of the University of California.
9 *
10 * Permission is granted to anyone to use this software for any purpose on
11 * any computer system, and to alter it and redistribute it freely, subject
12 * to the following restrictions:
13 *
14 * 1. The author is not responsible for the consequences of use of this
15 *    software, no matter how awful, even if they arise from flaws in it.
16 *
17 * 2. The origin of this software must not be misrepresented, either by
18 *    explicit claim or by omission.  Since few users ever read sources,
19 *    credits must appear in the documentation.
20 *
21 * 3. Altered versions must be plainly marked as such, and must not be
22 *    misrepresented as being the original software.  Since few users
23 *    ever read sources, credits must appear in the documentation.
24 *
25 * 4. This notice may not be removed or altered.
26 */
27
28#include "file.h"
29#include <stdio.h>
30#include <errno.h>
31#include <string.h>
32#ifdef __STDC__
33# include <stdarg.h>
34#else
35# include <varargs.h>
36#endif
37#include <stdlib.h>
38#ifdef HAVE_UNISTD_H
39#include <unistd.h>
40#endif
41#include <time.h>
42
43#ifndef lint
44FILE_RCSID("@(#)$Id: print.c,v 1.34 2001/08/07 16:01:26 christos Exp $")
45#endif  /* lint */
46
47#define SZOF(a)	(sizeof(a) / sizeof(a[0]))
48
49void
50mdump(m)
51	struct magic *m;
52{
53	static const char *typ[] = { "invalid", "byte", "short", "invalid",
54				     "long", "string", "date", "beshort",
55				     "belong", "bedate", "leshort", "lelong",
56				     "ledate", "pstring", "ldate", "beldate",
57				     "leldate" };
58	static const char optyp[] = { '@', '&', '|', '^', '+', '-',
59				      '*', '/', '%' };
60	(void) fputc('[', stderr);
61	(void) fprintf(stderr, ">>>>>>>> %d" + 8 - (m->cont_level & 7),
62		       m->offset);
63
64	if (m->flag & INDIR) {
65		(void) fprintf(stderr, "(%s,",
66			       /* Note: type is unsigned */
67			       (m->in_type < SZOF(typ)) ?
68					typ[m->in_type] : "*bad*");
69		if (m->in_op & OPINVERSE)
70			(void) fputc('~', stderr);
71		(void) fprintf(stderr, "%c%d),",
72			       ((m->in_op&0x7F) < SZOF(optyp)) ?
73					optyp[m->in_op&0x7F] : '?',
74				m->in_offset);
75	}
76	(void) fprintf(stderr, " %s%s", (m->flag & UNSIGNED) ? "u" : "",
77		       /* Note: type is unsigned */
78		       (m->type < SZOF(typ)) ? typ[m->type] : "*bad*");
79	if (m->mask_op & OPINVERSE)
80		(void) fputc('~', stderr);
81	if (m->mask) {
82		((m->mask_op&0x7F) < SZOF(optyp)) ?
83			(void) fputc(optyp[m->mask_op&0x7F], stderr) :
84			(void) fputc('?', stderr);
85		if(STRING != m->type || PSTRING != m->type)
86			(void) fprintf(stderr, "%.8x", m->mask);
87		else {
88			if (m->mask & STRING_IGNORE_LOWERCASE)
89				(void) fputc(CHAR_IGNORE_LOWERCASE, stderr);
90			if (m->mask & STRING_COMPACT_BLANK)
91				(void) fputc(CHAR_COMPACT_BLANK, stderr);
92			if (m->mask & STRING_COMPACT_OPTIONAL_BLANK)
93				(void) fputc(CHAR_COMPACT_OPTIONAL_BLANK,
94				stderr);
95		}
96	}
97
98	(void) fprintf(stderr, ",%c", m->reln);
99
100	if (m->reln != 'x') {
101		switch (m->type) {
102		case BYTE:
103		case SHORT:
104		case LONG:
105		case LESHORT:
106		case LELONG:
107		case BESHORT:
108		case BELONG:
109			(void) fprintf(stderr, "%d", m->value.l);
110			break;
111		case STRING:
112		case PSTRING:
113			showstr(stderr, m->value.s, -1);
114			break;
115		case DATE:
116		case LEDATE:
117		case BEDATE:
118			(void)fprintf(stderr, "%s,", fmttime(m->value.l, 1));
119			break;
120		case LDATE:
121		case LELDATE:
122		case BELDATE:
123			(void)fprintf(stderr, "%s,", fmttime(m->value.l, 0));
124			break;
125		default:
126			(void) fputs("*bad*", stderr);
127			break;
128		}
129	}
130	(void) fprintf(stderr, ",\"%s\"]\n", m->desc);
131}
132
133/*
134 * ckfputs - fputs, but with error checking
135 * ckfprintf - fprintf, but with error checking
136 */
137void
138ckfputs(str, fil)
139	const char *str;
140	FILE *fil;
141{
142	if (fputs(str,fil) == EOF)
143		error("write failed.\n");
144}
145
146/*VARARGS*/
147void
148#ifdef __STDC__
149ckfprintf(FILE *f, const char *fmt, ...)
150#else
151ckfprintf(va_alist)
152	va_dcl
153#endif
154{
155	va_list va;
156#ifdef __STDC__
157	va_start(va, fmt);
158#else
159	FILE *f;
160	const char *fmt;
161	va_start(va);
162	f = va_arg(va, FILE *);
163	fmt = va_arg(va, const char *);
164#endif
165	(void) vfprintf(f, fmt, va);
166	if (ferror(f))
167		error("write failed.\n");
168	va_end(va);
169}
170
171/*
172 * error - print best error message possible and exit
173 */
174/*VARARGS*/
175void
176#ifdef __STDC__
177error(const char *f, ...)
178#else
179error(va_alist)
180	va_dcl
181#endif
182{
183	va_list va;
184#ifdef __STDC__
185	va_start(va, f);
186#else
187	const char *f;
188	va_start(va);
189	f = va_arg(va, const char *);
190#endif
191	/* cuz we use stdout for most, stderr here */
192	(void) fflush(stdout);
193
194	if (progname != NULL)
195		(void) fprintf(stderr, "%s: ", progname);
196	(void) vfprintf(stderr, f, va);
197	va_end(va);
198	exit(1);
199}
200
201/*VARARGS*/
202void
203#ifdef __STDC__
204magwarn(const char *f, ...)
205#else
206magwarn(va_alist)
207	va_dcl
208#endif
209{
210	va_list va;
211#ifdef __STDC__
212	va_start(va, f);
213#else
214	const char *f;
215	va_start(va);
216	f = va_arg(va, const char *);
217#endif
218	/* cuz we use stdout for most, stderr here */
219	(void) fflush(stdout);
220
221	if (progname != NULL)
222		(void) fprintf(stderr, "%s: %s, %d: ",
223			       progname, magicfile, lineno);
224	(void) vfprintf(stderr, f, va);
225	va_end(va);
226	fputc('\n', stderr);
227}
228
229
230char *
231fmttime(v, local)
232	long v;
233	int local;
234{
235	char *pp, *rt;
236	time_t t = (time_t)v;
237	struct tm *tm;
238
239	if (local) {
240		pp = ctime(&t);
241	} else {
242#ifndef HAVE_DAYLIGHT
243		static int daylight = 0;
244#ifdef HAVE_TM_ISDST
245		static time_t now = (time_t)0;
246
247		if (now == (time_t)0) {
248			struct tm *tm1;
249			(void)time(&now);
250			tm1 = localtime(&now);
251			daylight = tm1->tm_isdst;
252		}
253#endif /* HAVE_TM_ISDST */
254#endif /* HAVE_DAYLIGHT */
255		if (daylight)
256			t += 3600;
257		tm = gmtime(&t);
258		pp = asctime(tm);
259	}
260
261	if ((rt = strchr(pp, '\n')) != NULL)
262		*rt = '\0';
263	return pp;
264}
265