~ubuntu-branches/ubuntu/wily/zoo/wily

1 by Petr Cech
Import upstream version 2.10
1
#ifndef LINT
2
/* @(#) prterror.c 2.8 88/01/31 18:48:17 */
3
static char sccsid[]="@(#) prterror.c 2.8 88/01/31 18:48:17";
4
#endif /* LINT */
5
6
/*
7
The contents of this file are hereby released to the public domain.
8
9
                                 -- Rahul Dhesi 1986/11/14
10
11
*/
12
13
#include "options.h"
14
#ifndef	OK_STDIO
15
#include <stdio.h>
16
#define	OK_STDIO
17
#endif
18
#include "various.h"
19
#include "zooio.h"
20
#include "zoofns.h"
21
22
#ifdef NEEDCTYP
23
# include <ctype.h>	/* for isdigit() */
24
#endif
25
26
#ifdef STDARG
27
# include <stdarg.h>
28
#else
29
# ifdef VARARGS
30
#  include <varargs.h>
31
# else
32
#  include "MUST DEFINE STDARG OR VARARGS"
33
# endif
34
#endif
35
36
#ifdef NEED_VPRINTF
37
static int zvfprintf();
38
#endif
39
40
/* General error handler.  Input format:
41
42
   parameter 1:  'w', 'e', or 'f'.
43
44
      'm':  message
45
      'M':  message without preceding identification
46
      'w':  WARNING
47
      'e':  ERROR
48
      'f':  FATAL
49
      'F':  FATAL but program doesn't exist immediately
50
51
   All text printed is preceded by "Zoo:  " or "Ooz:  "  depending
52
   upon conditional compilation, except in the case of 'M' messages
53
   which are printed without any text being added.
54
55
   For messages, the text supplied is printed if and only if the global
56
   variable "quiet" is zero.  Control then returns to the caller.
57
58
   For warnings, errors, and fatal errors, the variable "quiet" is used
59
	as follows.  Warning messages are suppressed if quiet > 1;  error
60
	messages are suppressed if quiet > 2.  Fatal error messages are 
61
	never suppressed--doing so would be a bit risky.
62
63
   For warnings and errors, the error message is preceded by the "WARNING:"
64
   or "ERROR".  The error message is printed and control returns to the
65
   caller.
66
67
   For fatal errors, the error message is preceded by "FATAL:" and an
68
   error message is printed.  If the option was 'f', the program exits with 
69
   a status of 1.  If the option was 'F', control returns to the caller and 
70
   it is assumed that the caller will do any cleaning up necessary and then 
71
   exit with an error status.
72
73
   parameter 2:  The format control string for printf.   
74
	remining parameters:  passed on to vprintf().
75
76
	All messages, whether informative or error, are sent to standard
77
	output via printf.  It might be a good idea to eventually send 'e' and
78
	'f' class messages to the standard error stream.  Best would be
79
	some way of telling if standard output and standard error are not
80
	the same device, so that we could always send error messages to
81
	standard error, and also duplicate them to standard output if 
82
	different from standard error.  This is one thing that VMS seems
83
	to be capable of doing.  There seems to be no way of doing this
84
	in the general case.
85
*/
86
87
extern int quiet;
88
89
/* These declarations must be equivalent to those in errors.i */
90
char no_match[] = "No files matched.\n";
91
char failed_consistency[] = "Archive header failed consistency check.\n";
92
char invalid_header[] = "Invalid or corrupted archive.\n";
93
char internal_error[]="Internal error.\n";
94
char disk_full[]      = "I/O error or disk full.\n";
95
char bad_directory[]  = "Directory entry in archive is invalid.\n";
96
char no_memory[] = "Ran out of memory.\n";
97
char too_many_files[] = "Some filenames ignored -- can only handle %d.\n";
98
char packfirst[] = "Old format archive -- please pack first with P command.\n";
99
char garbled[] = "Command is garbled.\n";
100
char start_ofs[] = "Starting at %ld (offset %ld)\n";
101
102
#ifndef OOZ
103
char wrong_version[]=
104
   "Zoo %d.%d or later is needed to fully manipulate this archive.\n";
105
char cant_process[] =
106
   "The rest of the archive (%lu bytes) cannot be processed.\n";
107
char option_ignored[] = "Ignoring option %c.\n";
108
char inv_option[] = "Option %c is invalid.\n";
109
char bad_crc[] = "\007Bad CRC, %s probably corrupted\n";
110
#endif
111
112
#ifdef OOZ
113
char could_not_open[] = "Could not open ";
114
#else
115
char could_not_open[] = "Could not open %s.\n";
116
#endif
117
118
#ifdef STDARG
119
void prterror(int level, char *format, ...)
120
#else
121
/*VARARGS*/
122
void prterror(va_alist)
123
va_dcl
124
#endif
125
{
126
	va_list args;
127
   char string[120];       /* local format string */
128
#ifdef VARARGS
129
	int level;
130
	char *format;
131
#endif
132
133
#ifdef STDARG
134
	va_start(args, format);
135
#else
136
	va_start(args);
137
	level = va_arg(args, int);
138
	format = va_arg(args, char *);
139
#endif
140
141
   *string = '\0';         /* get a null string to begin with */
142
143
#ifdef OOZ
144
   strcpy (string, "Ooz:  ");
145
#else
146
   strcpy (string, "Zoo:  ");
147
#endif
148
149
   switch (level) {
150
      case 'M': *string = '\0';                    /* fall through to 'm' */
151
      case 'm': if (quiet) return; break;
152
      case 'w': 
153
			if (quiet > 1) return;
154
			strcat (string, "WARNING:  "); break;
155
      case 'e': 
156
			if (quiet > 2) return;
157
			strcat (string, "ERROR:  ");   break;
158
      case 'F':
159
      case 'f': strcat (string, "FATAL:  ");   break;
160
      default: prterror ('f', internal_error);  /* slick recursive call */
161
   }
162
163
   strcat (string, format);      /* just append supplied format string */
164
165
	/* and print the whole thing */
166
#ifdef NEED_VPRINTF
167
	(void) zvfprintf(stdout, string, args);
168
#else
169
   (void) vprintf(string, args);
170
#endif
171
	fflush (stdout);
172
173
   if (level == 'f')       /* and abort on fatal error 'f' but not 'F' */
174
      zooexit (1);
175
}
176
177
178
#ifdef NEED_VPRINTF
179
/* Some systems don't have vprintf;  if so, we roll our own.  The following
180
has been adapted from a Usenet posting by Jef Poskanzer <jef@well.sf.ca.us>.
181
182
This is a portable mini-vfprintf that depends only on fprintf.
183
184
We don't call this routine vfprintf to avoid unexpected conflicts with any 
185
library routine of the same name, notwithstanding the fact that we will 
186
usually use it only when there is no conflict.  Also, even though we only 
187
need vprintf, the routine used here implements vfprintf.  This will allow 
188
future uses as needed when output is to be sent to a stream other than
189
stdout.  */
190
191
/* Whether to support double.  Better not to, because it may cause
192
math stuff to be linked in */
193
194
#undef NEED_DOUBLE
195
196
static int zvfprintf(stream, format, args)
197
FILE *stream;
198
char *format;
199
va_list args;
200
{
201
	char *ep;
202
	char fchar;
203
	char tformat[512];
204
	int do_long;		/* whether to print as long (l format suffix) */
205
	int do_star;		/* * used in format => get width from argument */
206
	int star_size;		/* size arg corresponding to "*" format */
207
	int i;
208
	long l;
209
	unsigned u;
210
	unsigned long ul;
211
	char *s;
212
#ifdef NEED_DOUBLE
213
	double d;
214
#endif
215
216
	while (*format != '\0') {
217
		if (*format != '%') { /* Not special, just write out the char. */
218
			putc(*format, stream);
219
			++format;
220
	   } else {
221
			do_star = 0;
222
			do_long = 0;
223
			ep = format + 1;
224
225
			/* Skip over all the field width and precision junk. */
226
			if (*ep == '-')
227
				++ep;
228
			if (*ep == '0')
229
				++ep;
230
			while (isdigit(*ep))
231
				++ep;
232
	      if (*ep == '.') {
233
				++ep;
234
				while (isdigit(*ep))
235
					++ep;
236
			}
237
			if (*ep == '#')
238
				++ep;
239
			if (*ep == '*') {
240
				do_star = 1;
241
				star_size = va_arg(args, int);	/* get * argument */
242
				++ep;
243
			}
244
			if (*ep == 'l') {
245
				do_long = 1;
246
				++ep;
247
			}
248
249
	      /* Here's the field type.  Extract it, and copy this format
250
	      ** specifier to a temp string so we can add an end-of-string.
251
	      */
252
	      fchar = *ep;
253
	      (void) strncpy(tformat, format, ep - format + 1);
254
	      tformat[ep - format + 1] = '\0';
255
256
	      /* Now do a one-argument printf with the format string we have 
257
			isolated.  If the * format was used, we will also supply the 
258
			additional parameter star_size, which we have already obtained 
259
			from the variable argument list.  */
260
261
	      switch (fchar) {
262
			 case 'd':
263
				if (do_long) {
264
					l = va_arg(args, long);
265
					if (do_star)
266
						(void) fprintf(stream, tformat, star_size, l);
267
					else
268
						(void) fprintf(stream, tformat, l);
269
				} else {
270
					i = va_arg(args, int);
271
					if (do_star)
272
						(void) fprintf(stream, tformat, star_size, i);
273
					else
274
						(void) fprintf(stream, tformat, i);
275
				}
276
				break;
277
278
	       case 'o':
279
	       case 'x':
280
	       case 'u':
281
		      if (do_long) {
282
					ul = va_arg(args, unsigned long);
283
					if (do_star)
284
						(void) fprintf(stream, tformat, star_size, ul);
285
					else
286
						(void) fprintf(stream, tformat, ul);
287
		      } else {
288
			      u = va_arg(args, unsigned);
289
					if (do_star)
290
						(void) fprintf(stream, tformat, star_size, u);
291
					else
292
						(void) fprintf(stream, tformat, u);
293
		      }
294
			   break;
295
296
			 case 'c':
297
				i = (char) va_arg(args, int);
298
				if (do_star)
299
					(void) fprintf(stream, tformat, star_size, i);
300
				else
301
					(void) fprintf(stream, tformat, i);
302
				break;
303
304
			 case 's':
305
				s = va_arg(args, char *);
306
				if (do_star)
307
					(void) fprintf(stream, tformat, star_size, s);
308
				else
309
					(void) fprintf(stream, tformat, s);
310
				break;
311
312
#ifdef NEED_DOUBLE
313
	       case 'e':
314
	       case 'f':
315
	       case 'g':
316
				d = va_arg(args, double);
317
				if (do_star)
318
					(void) fprintf(stream, tformat, star_size, d);
319
				else
320
					(void) fprintf(stream, tformat, d);
321
				break;
322
#endif
323
324
	       case '%':
325
				putc('%', stream);
326
				break;
327
328
			 default:
329
				return -1;
330
			}
331
332
			/* Resume formatting on the next character. */
333
			format = ep + 1;
334
		}
335
	}
336
	va_end(args);
337
	return 0;
338
}
339
#endif /*NEED_VPRINTF*/