1 /*
2 ** Copyright (C) 2005-2020 by Carnegie Mellon University.
3 **
4 ** @OPENSOURCE_LICENSE_START@
5 ** See license information in ../../LICENSE.txt
6 ** @OPENSOURCE_LICENSE_END@
7 */
8
9 /*
10 ** Functions to print error message for skstream
11 **
12 */
13
14
15 #include <silk/silk.h>
16
17 RCSIDENT("$SiLK: skstream-err.c ef14e54179be 2020-04-14 21:57:45Z mthomas $");
18
19 #include "skstream_priv.h"
20
21
22 /*
23 * Typedef for a printf-type function, except this function has a
24 * context object as the first parameter.
25 */
26 typedef int (*msg_fn_with_context)(
27 void *ctxobj,
28 const char *fmt,
29 ...)
30 SK_CHECK_TYPEDEF_PRINTF(2, 3);
31
32
33 /*
34 * A structure to hold a buffer and the size of the buffer. This
35 * will be used at the context object for msg_fn_with_context.
36 */
37 typedef struct stream_err_msg_buf_st {
38 char *buf;
39 size_t len;
40 } stream_err_msg_buf_t;
41
42
43 /*
44 * The function which looks up the current error code of the stream
45 * and calls one of two possible functions to "print" the error
46 * message.
47 *
48 * This is a helper function for the two public functions,
49 * skStreamPrintLastErr() and skStreamLastErrMessage().
50 *
51 * The 'errfn1' callback is used if it is set. Otherwise, the
52 * 'errfn2' function is called if it is set with 'errfn2_ctx' as
53 * the first argument to that function. If neither is set,
54 * skAbort() is called.
55 */
56 static int
57 streamLastErrFunc(
58 const skstream_t *stream,
59 ssize_t errcode,
60 sk_msg_fn_t errfn1,
61 void *errfn2_ctx,
62 msg_fn_with_context errfn2);
63
64
65 /* FUNCTION DEFINITIONS */
66
67 SK_DIAGNOSTIC_FORMAT_NONLITERAL_PUSH
68
69 /*
70 * Callback to "print" the error message into a buffer. The buffer
71 * and its length are specified in the first argument.
72 */
73 static int
streamLastErrMsg(void * v_msg_buf,const char * fmt,...)74 streamLastErrMsg(
75 void *v_msg_buf,
76 const char *fmt,
77 ...)
78 {
79 stream_err_msg_buf_t *msg_buf = (stream_err_msg_buf_t*)v_msg_buf;
80 va_list args;
81 int rv;
82
83 va_start(args, fmt);
84 rv = vsnprintf(msg_buf->buf, msg_buf->len, fmt, args);
85 va_end(args);
86
87 return rv;
88 }
89
90 SK_DIAGNOSTIC_FORMAT_NONLITERAL_POP
91
92
93
94 /*
95 * Fill 'buffer' with the message that corresponds to the stream
96 * error code 'errcode'. The stream object may provide addition
97 * context for the message.
98 */
99 int
skStreamLastErrMessage(const skstream_t * stream,ssize_t errcode,char * buffer,size_t buffer_len)100 skStreamLastErrMessage(
101 const skstream_t *stream,
102 ssize_t errcode,
103 char *buffer,
104 size_t buffer_len)
105 {
106 stream_err_msg_buf_t msg_buf;
107
108 msg_buf.buf = buffer;
109 msg_buf.len = buffer_len;
110
111 return streamLastErrFunc(stream, errcode, NULL,
112 &msg_buf, &streamLastErrMsg);
113 }
114
115
116 /*
117 * Call 'errfn' to print the message that corresponds to the stream
118 * error code 'errcode'. The stream object may provide addition
119 * context for the message.
120 */
121 void
skStreamPrintLastErr(const skstream_t * stream,ssize_t errcode,sk_msg_fn_t errfn)122 skStreamPrintLastErr(
123 const skstream_t *stream,
124 ssize_t errcode,
125 sk_msg_fn_t errfn)
126 {
127 if (errfn == NULL) {
128 errfn = &skAppPrintErr;
129 }
130 streamLastErrFunc(stream, errcode, errfn, NULL, NULL);
131 }
132
133
134 /* This function is described above. */
135 static int
streamLastErrFunc(const skstream_t * stream,ssize_t errcode,sk_msg_fn_t errfn1,void * ef2_ctx,msg_fn_with_context errfn2)136 streamLastErrFunc(
137 const skstream_t *stream,
138 ssize_t errcode,
139 sk_msg_fn_t errfn1,
140 void *ef2_ctx,
141 msg_fn_with_context errfn2)
142 {
143 const char *msg;
144 char t_stamp1[SKTIMESTAMP_STRLEN];
145 char t_stamp2[SKTIMESTAMP_STRLEN];
146 char format_name[SK_MAX_STRLEN_FILE_FORMAT+1];
147 int64_t limit = 0;
148
149 #define ERR_FN(ef1_fmt_args, ef2_ctx_fmt_args) \
150 if (errfn1) { return errfn1 ef1_fmt_args ; } \
151 else if (errfn2) { return errfn2 ef2_ctx_fmt_args ; } \
152 else { skAbort() ; }
153
154 #ifdef TEST_PRINTF_FORMATS
155 #undef ERR_FN
156 #define ERR_FN(ef1_fmt_args, ef2_ctx_fmt_args) \
157 return printf ef1_fmt_args
158 #endif
159
160 /* macros for common error messages */
161 #define FILENAME_MSG(m) \
162 if (!stream) { \
163 ERR_FN(("%s", m), \
164 (ef2_ctx, "%s", m)); \
165 } else { \
166 ERR_FN(("%s '%s'", m, stream->pathname), \
167 (ef2_ctx, "%s '%s'", m, stream->pathname)); \
168 }
169
170 #define STRERROR_MSG(m) \
171 if (!stream) { \
172 ERR_FN(("%s", m), \
173 (ef2_ctx, "%s", m)); \
174 } \
175 else if (stream->errnum == 0) { \
176 ERR_FN(("%s '%s'", m, stream->pathname), \
177 (ef2_ctx, "%s '%s'", m, stream->pathname)); } \
178 else { \
179 ERR_FN(("%s '%s': %s", \
180 m, stream->pathname, strerror(stream->errnum)), \
181 (ef2_ctx, "%s '%s': %s", \
182 m, stream->pathname, strerror(stream->errnum))); \
183 }
184
185 switch (errcode) {
186 case SKSTREAM_OK:
187 FILENAME_MSG("Command completed successfully");
188 break;
189
190 case SKSTREAM_ERR_UNSUPPORT_FORMAT:
191 msg = "Cannot process file given its format";
192 if (!stream) {
193 ERR_FN(("%s", msg),
194 (ef2_ctx, "%s", msg));
195 } else {
196 skFileFormatGetName(format_name, sizeof(format_name),
197 skHeaderGetFileFormat(stream->silk_hdr));
198 ERR_FN(("%s: '%s' has format %s (0x%02x)", msg,
199 stream->pathname, format_name,
200 skHeaderGetFileFormat(stream->silk_hdr)),
201 (ef2_ctx, "%s: '%s' has format %s (0x%02x)", msg,
202 stream->pathname, format_name,
203 skHeaderGetFileFormat(stream->silk_hdr)));
204 }
205 break;
206
207 case SKSTREAM_ERR_REQUIRE_SILK_FLOW:
208 msg = "File does not contain SiLK Flow data";
209 if (!stream) {
210 ERR_FN(("%s", msg),
211 (ef2_ctx, "%s", msg));
212 } else {
213 skFileFormatGetName(format_name, sizeof(format_name),
214 skHeaderGetFileFormat(stream->silk_hdr));
215 ERR_FN(("%s: '%s' has format %s (0x%02x)", msg,
216 stream->pathname, format_name,
217 skHeaderGetFileFormat(stream->silk_hdr)),
218 (ef2_ctx, "%s: '%s' has format %s (0x%02x)", msg,
219 stream->pathname, format_name,
220 skHeaderGetFileFormat(stream->silk_hdr)));
221 }
222 break;
223
224 case SKSTREAM_ERR_UNSUPPORT_VERSION:
225 msg = "This SiLK release does not support";
226 if (!stream) {
227 ERR_FN(("%s the format and version of the file", msg),
228 (ef2_ctx, "%s the format and version of the file", msg));
229 } else {
230 sk_file_header_t *hdr = stream->silk_hdr;
231 skFileFormatGetName(format_name, sizeof(format_name),
232 skHeaderGetFileFormat(hdr));
233 ERR_FN(("%s %s(0x%02x) v%u records in the v%u file '%s'", msg,
234 format_name, skHeaderGetFileFormat(hdr),
235 skHeaderGetRecordVersion(hdr), skHeaderGetFileVersion(hdr),
236 stream->pathname),
237 (ef2_ctx,
238 "%s %s(0x%02x) v%u records in the v%u file '%s'", msg,
239 format_name, skHeaderGetFileFormat(hdr),
240 skHeaderGetRecordVersion(hdr), skHeaderGetFileVersion(hdr),
241 stream->pathname));
242 }
243 break;
244
245 case SKSTREAM_ERR_READ_SHORT: /* RWIO_ERR_READ_SHORT */
246 msg = "Read incomplete record";
247 if (!stream) {
248 ERR_FN(("%s", msg),
249 (ef2_ctx, "%s", msg));
250 } else {
251 ERR_FN(("%s (%lu of %lu bytes) from %s",
252 msg, (unsigned long)(stream->errobj.num),
253 (unsigned long)stream->recLen, stream->pathname),
254 (ef2_ctx, "%s (%lu of %lu bytes) from %s",
255 msg, (unsigned long)(stream->errobj.num),
256 (unsigned long)stream->recLen, stream->pathname));
257 }
258 break;
259
260 case SKSTREAM_ERR_STIME_UNDRFLO:
261 msg = "Record's start time less than that allowed in file";
262 if (!stream) {
263 ERR_FN(("%s", msg),
264 (ef2_ctx, "%s", msg));
265 } else {
266 sktimestamp_r(t_stamp1, rwRecGetStartTime(stream->errobj.rec),
267 SKTIMESTAMP_UTC);
268 skStreamGetLimit(stream, errcode, &limit);
269 sktimestamp_r(t_stamp2, limit, SKTIMESTAMP_UTC);
270 ERR_FN(("%s '%s': %sZ < %sZ", msg,
271 stream->pathname, t_stamp1, t_stamp2),
272 (ef2_ctx, "%s '%s': %sZ < %sZ", msg,
273 stream->pathname, t_stamp1, t_stamp2));
274 }
275 break;
276
277 case SKSTREAM_ERR_STIME_OVRFLO:
278 msg = "Record's start time greater than that allowed in file";
279 if (!stream) {
280 ERR_FN(("%s", msg),
281 (ef2_ctx, "%s", msg));
282 } else {
283 sktimestamp_r(t_stamp1, rwRecGetStartTime(stream->errobj.rec),
284 SKTIMESTAMP_UTC);
285 skStreamGetLimit(stream, errcode, &limit);
286 sktimestamp_r(t_stamp2, limit, SKTIMESTAMP_UTC);
287 ERR_FN(("%s '%s': %sZ > %sZ", msg,
288 stream->pathname, t_stamp1, t_stamp2),
289 (ef2_ctx, "%s '%s': %sZ > %sZ", msg,
290 stream->pathname, t_stamp1, t_stamp2));
291 }
292 break;
293
294 case SKSTREAM_ERR_ELPSD_OVRFLO:
295 msg = "Record's duration greater than that allowed in file";
296 if (!stream) {
297 ERR_FN(("%s", msg),
298 (ef2_ctx, "%s", msg));
299 } else {
300 /* Returned limit is milliseconds; displayed is seconds */
301 skStreamGetLimit(stream, errcode, &limit);
302 limit /= 1000;
303 ERR_FN(("%s '%s': %u > %" PRId64, msg,
304 stream->pathname,
305 rwRecGetElapsedSeconds(stream->errobj.rec), limit),
306 (ef2_ctx, "%s '%s': %u > %" PRId64, msg,
307 stream->pathname,
308 rwRecGetElapsedSeconds(stream->errobj.rec), limit));
309 }
310 break;
311
312 case SKSTREAM_ERR_PKTS_OVRFLO:
313 msg = "Record's packet count greater than that allowed in file";
314 if (!stream) {
315 ERR_FN(("%s", msg),
316 (ef2_ctx, "%s", msg));
317 } else {
318 skStreamGetLimit(stream, errcode, &limit);
319 ERR_FN(("%s '%s': %u > %" PRId64, msg,
320 stream->pathname, rwRecGetPkts(stream->errobj.rec), limit),
321 (ef2_ctx, "%s '%s': %u > %" PRId64, msg,
322 stream->pathname, rwRecGetPkts(stream->errobj.rec),limit));
323 }
324 break;
325
326 case SKSTREAM_ERR_PKTS_ZERO:
327 FILENAME_MSG("Record's packet count is zero while writing to file");
328 break;
329
330 case SKSTREAM_ERR_BPP_OVRFLO:
331 msg = "Record's byte-per-pkt ratio greater than that allowed in file";
332 if (!stream) {
333 ERR_FN(("%s", msg),
334 (ef2_ctx, "%s", msg));
335 } else {
336 skStreamGetLimit(stream, errcode, &limit);
337 ERR_FN(("%s '%s': %u > %" PRId64, msg,
338 stream->pathname, (rwRecGetBytes(stream->errobj.rec)
339 / rwRecGetPkts(stream->errobj.rec)),
340 limit),
341 (ef2_ctx, "%s '%s': %u > %" PRId64, msg,
342 stream->pathname, (rwRecGetBytes(stream->errobj.rec)
343 / rwRecGetPkts(stream->errobj.rec)),
344 limit));
345 }
346 break;
347
348 case SKSTREAM_ERR_SNMP_OVRFLO:
349 msg = "Record's SNMP index greater than that allowed in file";
350 if (!stream) {
351 ERR_FN(("%s", msg),
352 (ef2_ctx, "%s", msg));
353 } else {
354 const char *snmp_str = "input";
355 unsigned int snmp_val = rwRecGetInput(stream->errobj.rec);
356 skStreamGetLimit(stream, errcode, &limit);
357 if (snmp_val <= limit) {
358 snmp_str = "output";
359 snmp_val = rwRecGetOutput(stream->errobj.rec);
360 }
361 ERR_FN(("%s '%s': %s %" PRIu16 " > %" PRId64, msg,
362 stream->pathname, snmp_str, snmp_val, limit),
363 (ef2_ctx, "%s '%s': %s %" PRIu16 " > %" PRId64, msg,
364 stream->pathname, snmp_str, snmp_val, limit));
365 }
366 break;
367
368 case SKSTREAM_ERR_SENSORID_OVRFLO:
369 msg = "Record's Sensor ID greater than that allowed in file";
370 if (!stream) {
371 ERR_FN(("%s", msg),
372 (ef2_ctx, "%s", msg));
373 } else {
374 skStreamGetLimit(stream, errcode, &limit);
375 ERR_FN(("%s '%s': %" PRIu16 " > %" PRId64, msg,
376 stream->pathname,
377 rwRecGetSensor(stream->errobj.rec), limit),
378 (ef2_ctx, "%s '%s': %" PRIu16 " > %" PRId64, msg,
379 stream->pathname,
380 rwRecGetSensor(stream->errobj.rec), limit));
381 }
382 break;
383
384 case SKSTREAM_ERR_PROTO_MISMATCH:
385 msg = "Record's IP-protocol is not supported in file";
386 if (!stream) {
387 ERR_FN(("%s", msg),
388 (ef2_ctx, "%s", msg));
389 } else {
390 ERR_FN(("%s '%s': %u", msg,
391 stream->pathname,
392 (unsigned int)rwRecGetProto(stream->errobj.rec)),
393 (ef2_ctx, "%s '%s': %u", msg,
394 stream->pathname,
395 (unsigned int)rwRecGetProto(stream->errobj.rec)));
396 }
397 break;
398
399 case SKSTREAM_ERR_PKTS_GT_BYTES:
400 msg = "Record's 'pkts' value is greater than its 'bytes' value";
401 if (!stream) {
402 ERR_FN(("%s", msg),
403 (ef2_ctx, "%s", msg));
404 } else {
405 ERR_FN(("%s in file '%s': %u > %u", msg,
406 stream->pathname,
407 (unsigned int)rwRecGetPkts(stream->errobj.rec),
408 (unsigned int)rwRecGetBytes(stream->errobj.rec)),
409 (ef2_ctx, "%s in file '%s': %u > %u", msg,
410 stream->pathname,
411 (unsigned int)rwRecGetPkts(stream->errobj.rec),
412 (unsigned int)rwRecGetBytes(stream->errobj.rec)));
413 }
414 break;
415
416 case SKSTREAM_ERR_UNSUPPORT_IPV6:
417 FILENAME_MSG("Record has an unsupported IPv6 address");
418 break;
419
420 case SKSTREAM_ERR_ALLOC:
421 ERR_FN(("Memory allocation failed"),
422 (ef2_ctx, "Memory allocation failed"));
423 break;
424
425 case SKSTREAM_ERR_PREV_DATA:
426 FILENAME_MSG("Initial data has already been read or written");
427 break;
428
429 case SKSTREAM_ERR_BAD_MAGIC:
430 FILENAME_MSG("File does not appear to be a SiLK data file");
431 break;
432
433 case SKSTREAM_ERR_CLOSED:
434 FILENAME_MSG("Cannot modify a stream once it is closed");
435 break;
436
437 case SKSTREAM_ERR_EOF: /* RWIO_ERR_READ_EOF */
438 FILENAME_MSG("Reached end of file");
439 break;
440
441 case SKSTREAM_ERR_FILE_EXISTS:
442 STRERROR_MSG("Will not create new file over existing file");
443 break;
444
445 case SKSTREAM_ERR_INVALID_INPUT:
446 ERR_FN(("Argument's value is invalid"),
447 (ef2_ctx, "Argument's value is invalid"));
448 break;
449
450 case SKSTREAM_ERR_IOBUF:
451 if (!stream) {
452 ERR_FN(("Error reading/writing iobuffer"),
453 (ef2_ctx, "Error reading/writing iobuffer"));
454 } else {
455 ERR_FN(("Error %s iobuffer for '%s': %s",
456 ((stream->io_mode == SK_IO_READ) ? "reading" : "writing"),
457 stream->pathname, skIOBufStrError(stream->iobuf)),
458 (ef2_ctx, "Error %s iobuffer for '%s': %s",
459 ((stream->io_mode == SK_IO_READ) ? "reading" : "writing"),
460 stream->pathname, skIOBufStrError(stream->iobuf)));
461 }
462 break;
463
464 case SKSTREAM_ERR_ISTERMINAL:
465 if (!stream) {
466 ERR_FN(("Will not read/write binary data on a terminal"),
467 (ef2_ctx, "Will not read/write binary data on a terminal"));
468 } else {
469 ERR_FN(("Will not %s binary data on a terminal '%s'",
470 ((stream->io_mode == SK_IO_READ) ? "read" : "write"),
471 stream->pathname),
472 (ef2_ctx, "Will not %s binary data on a terminal '%s'",
473 ((stream->io_mode == SK_IO_READ) ? "read" : "write"),
474 stream->pathname));
475 }
476 break;
477
478 case SKSTREAM_ERR_LONG_LINE:
479 ERR_FN(("Input string is too long"),
480 (ef2_ctx, "Input string is too long"));
481 break;
482
483 case SKSTREAM_ERR_NOPAGER:
484 msg = "Unable to invoke pager";
485 if (!stream) {
486 ERR_FN(("%s", msg),
487 (ef2_ctx, "%s", msg));
488 } else {
489 ERR_FN(("%s '%s'",
490 msg, stream->pager),
491 (ef2_ctx, "%s '%s'",
492 msg, stream->pager));
493 }
494 break;
495
496 case SKSTREAM_ERR_NOT_BOUND:
497 ERR_FN(("Stream is not bound to a file"),
498 (ef2_ctx, "Stream is not bound to a file"));
499 break;
500
501 case SKSTREAM_ERR_NOT_OPEN:
502 FILENAME_MSG("Cannot read/write/close an unopened stream");
503 break;
504
505 case SKSTREAM_ERR_NOT_SEEKABLE:
506 FILENAME_MSG("Unsupported operation---cannot seek on stream");
507 break;
508
509 case SKSTREAM_ERR_NULL_ARGUMENT:
510 ERR_FN(("Unexpected NULL or empty argument"),
511 (ef2_ctx, "Unexpected NULL or empty argument"));
512 break;
513
514 case SKSTREAM_ERR_PREV_BOUND:
515 ERR_FN(("Cannot bind stream because it is already bound"),
516 (ef2_ctx, "Cannot bind stream because it is already bound"));
517 break;
518
519 case SKSTREAM_ERR_PREV_OPEN:
520 FILENAME_MSG("Stream is already open");
521 break;
522
523 case SKSTREAM_ERR_PREV_COPYINPUT:
524 FILENAME_MSG("Only one copy stream is supported per input stream");
525 break;
526
527 case SKSTREAM_ERR_READ:
528 STRERROR_MSG("Error reading from stream");
529 break;
530
531 case SKSTREAM_ERR_RLOCK:
532 STRERROR_MSG("Cannot get read lock on file");
533 break;
534
535 case SKSTREAM_ERR_SYS_FDOPEN:
536 STRERROR_MSG("Cannot convert file descriptor");
537 break;
538
539 case SKSTREAM_ERR_SYS_FORK:
540 skAppPrintErr("Cannot fork");
541 break;
542
543 case SKSTREAM_ERR_SYS_LSEEK:
544 STRERROR_MSG("Cannot seek on stream");
545 break;
546
547 case SKSTREAM_ERR_SYS_MKSTEMP:
548 STRERROR_MSG("Cannot create temporary file");
549 break;
550
551 case SKSTREAM_ERR_SYS_OPEN:
552 STRERROR_MSG("Error opening file");
553 break;
554
555 case SKSTREAM_ERR_SYS_PIPE:
556 STRERROR_MSG("Cannot create pipe");
557 break;
558
559 case SKSTREAM_ERR_SYS_MKDIR:
560 STRERROR_MSG("Cannot create directory component to file");
561 break;
562
563 case SKSTREAM_ERR_SYS_FCNTL_GETFL:
564 STRERROR_MSG("Cannot get status flags for stream");
565 break;
566
567 case SKSTREAM_ERR_SYS_FTRUNCATE:
568 STRERROR_MSG("Cannot set length of file");
569 break;
570
571 case SKSTREAM_ERR_COMPRESS_INVALID:
572 msg = "Specified compression identifier is not recognized";
573 if (!stream) {
574 ERR_FN(("%s", msg),
575 (ef2_ctx, "%s", msg));
576 } else {
577 ssize_t cm;
578 cm = (ssize_t)skHeaderGetCompressionMethod(stream->silk_hdr);
579 ERR_FN(("%s %" SK_PRIdZ " '%s'",
580 msg, cm, stream->pathname),
581 (ef2_ctx, "%s %" SK_PRIdZ " '%s'",
582 msg, cm, stream->pathname));
583 }
584 break;
585
586 case SKSTREAM_ERR_COMPRESS_UNAVAILABLE:
587 msg = "Specified compression method is not available";
588 if (!stream) {
589 ERR_FN(("%s", msg),
590 (ef2_ctx, "%s", msg));
591 } else {
592 skCompMethodGetName(
593 format_name, sizeof(format_name),
594 skHeaderGetCompressionMethod(stream->silk_hdr));
595 ERR_FN(("%s '%s' uses %s",
596 msg, stream->pathname, format_name),
597 (ef2_ctx, "%s '%s' uses %s",
598 msg, stream->pathname, format_name));
599 }
600 break;
601
602 case SKSTREAM_ERR_UNSUPPORT_CONTENT:
603 msg = "Action not supported on stream's content type";
604 if (!stream) {
605 ERR_FN(("%s", msg),
606 (ef2_ctx, "%s", msg));
607 } else {
608 const char *ct = "";
609 switch (stream->content_type) {
610 case SK_CONTENT_SILK:
611 case SK_CONTENT_SILK_FLOW:
612 ct = " is SiLK";
613 break;
614 case SK_CONTENT_TEXT:
615 ct = " is text";
616 break;
617 case SK_CONTENT_OTHERBINARY:
618 ct = " is binary";
619 break;
620 }
621 ERR_FN(("%s '%s'%s",
622 msg, stream->pathname, ct),
623 (ef2_ctx, "%s '%s'%s",
624 msg, stream->pathname, ct));
625 }
626 break;
627
628 case SKSTREAM_ERR_UNSUPPORT_IOMODE:
629 msg = "Action not permitted on stream";
630 if (!stream) {
631 ERR_FN(("%s", msg),
632 (ef2_ctx, "%s", msg));
633 } else {
634 const char *io = "";
635 switch (stream->io_mode) {
636 case SK_IO_READ:
637 io = ": read from";
638 break;
639 case SK_IO_WRITE:
640 io = ": write to";
641 break;
642 case SK_IO_APPEND:
643 io = ": append to";
644 break;
645 }
646 ERR_FN(("%s%s '%s'",
647 msg, io, stream->pathname),
648 (ef2_ctx, "%s%s '%s'",
649 msg, io, stream->pathname));
650 }
651 break;
652
653 case SKSTREAM_ERR_WLOCK:
654 STRERROR_MSG("Cannot get write lock on file");
655 break;
656
657 case SKSTREAM_ERR_WRITE:
658 STRERROR_MSG("Error writing to stream");
659 break;
660
661 case SKSTREAM_ERR_ZLIB:
662 msg = "Error in zlib library";
663 if (!stream) {
664 ERR_FN(("%s", msg),
665 (ef2_ctx, "%s", msg));
666 } else {
667 int zerr = 0;
668 const char *zerr_msg = NULL;
669 #if SK_ENABLE_ZLIB
670 if (stream->gz) {
671 zerr_msg = gzerror(stream->gz, &zerr);
672 } else
673 #endif /* SK_ENABLE_ZLIB */
674 {
675 zerr = stream->errnum;
676 }
677 if (zerr_msg) {
678 ERR_FN(("%s for '%s': %s",
679 msg, stream->pathname, zerr_msg),
680 (ef2_ctx, "%s for '%s': %s",
681 msg, stream->pathname, zerr_msg));
682 } else {
683 ERR_FN(("%s for '%s': [%d]",
684 msg, stream->pathname, zerr),
685 (ef2_ctx, "%s for '%s': [%d]",
686 msg, stream->pathname, zerr));
687 }
688 }
689 break;
690
691 case SKSTREAM_ERR_IO: /* -1 */
692 if (!stream) {
693 ERR_FN(("Bad read/write"),
694 (ef2_ctx, "Bad read/write"));
695 } else if (stream->err_info == SKSTREAM_ERR_IO) {
696 /* avoid infinite loop */
697 FILENAME_MSG("Bad read/write");
698 } else {
699 /* call ourself with the real error code */
700 return streamLastErrFunc(stream, stream->err_info,
701 errfn1, ef2_ctx, errfn2);
702 }
703 break;
704 }
705
706 if (errcode > 0) {
707 /* Pass it off to skheaders */
708 msg = "Error processing headers";
709 if (!stream) {
710 ERR_FN(("%s: %s", msg, skHeaderStrerror(errcode)),
711 (ef2_ctx, "%s: %s", msg, skHeaderStrerror(errcode)));
712 } else {
713 ERR_FN(("%s on file '%s': %s",
714 msg, stream->pathname, skHeaderStrerror(errcode)),
715 (ef2_ctx, "%s on file '%s': %s",
716 msg, stream->pathname, skHeaderStrerror(errcode)));
717 }
718 }
719
720 ERR_FN(("Unrecognized error code %" SK_PRIdZ, errcode),
721 (ef2_ctx, "Unrecognized error code %" SK_PRIdZ, errcode));
722 }
723
724
725 /*
726 ** Local Variables:
727 ** mode:c
728 ** indent-tabs-mode:nil
729 ** c-basic-offset:4
730 ** End:
731 */
732