1 /* failure_message.c
2  * Routines to print various "standard" failure messages used in multiple
3  * places
4  *
5  * Wireshark - Network traffic analyzer
6  * By Gerald Combs <gerald@wireshark.org>
7  * Copyright 1998 Gerald Combs
8  *
9  * SPDX-License-Identifier: GPL-2.0-or-later
10  */
11 
12 #include "config.h"
13 
14 #include <string.h>
15 #include <errno.h>
16 
17 #include <wiretap/wtap.h>
18 #include <wsutil/filesystem.h>
19 #include <wsutil/report_message.h>
20 #include <ui/cmdarg_err.h>
21 
22 #include "ui/failure_message.h"
23 
24 /*
25  * Generic error message.
26  */
27 void
failure_message(const char * msg_format,va_list ap)28 failure_message(const char *msg_format, va_list ap)
29 {
30     vcmdarg_err(msg_format, ap);
31 }
32 
33 /*
34  * Error message for a failed attempt to open or create a file
35  * other than a capture file.
36  * "filename" is the name of the file being opened; "err" is assumed
37  * to be a UNIX-style errno; "for_writing" is TRUE if we're opening
38  * the file for writing and FALSE if we're opening it for reading.
39  */
40 void
open_failure_message(const char * filename,int err,gboolean for_writing)41 open_failure_message(const char *filename, int err, gboolean for_writing)
42 {
43     cmdarg_err(file_open_error_message(err, for_writing), filename);
44 }
45 
46 /*
47  * Error message for a failed attempt to read from a file other than
48  * a capture file.
49  * "filename" is the name of the file being read from; "err" is assumed
50  * to be a UNIX-style errno.
51  */
52 void
read_failure_message(const char * filename,int err)53 read_failure_message(const char *filename, int err)
54 {
55     cmdarg_err("An error occurred while reading from the file \"%s\": %s.",
56                filename, g_strerror(err));
57 }
58 
59 /*
60  * Error message for a failed attempt to write to a file other than
61  * a capture file.
62  * "filename" is the name of the file being written to; "err" is assumed
63  * to be a UNIX-style errno.
64  */
65 void
write_failure_message(const char * filename,int err)66 write_failure_message(const char *filename, int err)
67 {
68     cmdarg_err("An error occurred while writing to the file \"%s\": %s.",
69                filename, g_strerror(err));
70 }
71 
72 static char *
input_file_description(const char * fname)73 input_file_description(const char *fname)
74 {
75     char *fstring;
76 
77     if (strcmp(fname, "-") == 0) {
78         /* We're reading from the standard input */
79         fstring = g_strdup("standard input");
80     } else {
81         /* We're reading from a file */
82         fstring = g_strdup_printf("file \"%s\"", fname);
83     }
84     return fstring;
85 }
86 
87 static char *
output_file_description(const char * fname)88 output_file_description(const char *fname)
89 {
90     char *fstring;
91 
92     if (strcmp(fname, "-") == 0) {
93         /* We're writing to to the standard output */
94         fstring = g_strdup("standard output");
95     } else {
96         /* We're writing to a file */
97         fstring = g_strdup_printf("file \"%s\"", fname);
98     }
99     return fstring;
100 }
101 
102 /*
103  * Error message for a failed attempt to open a capture file for reading.
104  * "filename" is the name of the file being opened; "err" is assumed
105  * to be a UNIX-style errno or a WTAP_ERR_ value; "err_info" is assumed
106  * to be a string giving further information for some WTAP_ERR_ values.
107  */
108 void
cfile_open_failure_message(const char * filename,int err,gchar * err_info)109 cfile_open_failure_message(const char *filename, int err, gchar *err_info)
110 {
111     if (err < 0) {
112         /*
113          * Wiretap error.
114          * Get a string that describes what we're opening.
115          */
116         char *file_description = input_file_description(filename);
117 
118         switch (err) {
119 
120         case WTAP_ERR_NOT_REGULAR_FILE:
121             cmdarg_err("The %s is a \"special file\" or socket or other non-regular file.",
122                        file_description);
123             break;
124 
125         case WTAP_ERR_RANDOM_OPEN_PIPE:
126             cmdarg_err("The %s is a pipe or FIFO; %s can't read pipe or FIFO files in two-pass mode.",
127                        file_description, get_friendly_program_name());
128             break;
129 
130         case WTAP_ERR_FILE_UNKNOWN_FORMAT:
131             cmdarg_err("The %s isn't a capture file in a format %s understands.",
132                        file_description, get_friendly_program_name());
133             break;
134 
135         case WTAP_ERR_UNSUPPORTED:
136             cmdarg_err("The %s contains record data that %s doesn't support.\n"
137                        "(%s)",
138                        file_description, get_friendly_program_name(),
139                        err_info != NULL ? err_info : "no information supplied");
140             g_free(err_info);
141             break;
142 
143         case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
144             cmdarg_err("The %s is a capture for a network type that %s doesn't support.",
145                        file_description, get_friendly_program_name());
146             break;
147 
148         case WTAP_ERR_BAD_FILE:
149             cmdarg_err("The %s appears to be damaged or corrupt.\n"
150                        "(%s)",
151                        file_description,
152                        err_info != NULL ? err_info : "no information supplied");
153             g_free(err_info);
154             break;
155 
156         case WTAP_ERR_CANT_OPEN:
157             cmdarg_err("The %s could not be opened for some unknown reason.",
158                        file_description);
159             break;
160 
161         case WTAP_ERR_SHORT_READ:
162             cmdarg_err("The %s appears to have been cut short in the middle of a packet or other data.",
163                        file_description);
164             break;
165 
166         case WTAP_ERR_DECOMPRESS:
167             cmdarg_err("The %s cannot be decompressed; it may be damaged or corrupt."
168                        "(%s)",
169                        file_description,
170                        err_info != NULL ? err_info : "no information supplied");
171             g_free(err_info);
172             break;
173 
174         case WTAP_ERR_INTERNAL:
175             cmdarg_err("An internal error occurred opening the %s.\n"
176                        "(%s)",
177                        file_description,
178                        err_info != NULL ? err_info : "no information supplied");
179             g_free(err_info);
180             break;
181 
182         case WTAP_ERR_DECOMPRESSION_NOT_SUPPORTED:
183             cmdarg_err("The %s cannot be decompressed; it is compressed in a way that we don't support."
184                        "(%s)",
185                        file_description,
186                        err_info != NULL ? err_info : "no information supplied");
187             g_free(err_info);
188             break;
189 
190         default:
191             cmdarg_err("The %s could not be opened: %s.",
192                        file_description,
193                        wtap_strerror(err));
194             break;
195         }
196         g_free(file_description);
197     } else
198         cmdarg_err(file_open_error_message(err, FALSE), filename);
199 }
200 
201 /*
202  * Error message for a failed attempt to open a capture file for writing.
203  * "filename" is the name of the file being opened; "err" is assumed
204  * to be a UNIX-style errno or a WTAP_ERR_ value; "err_info" is assumed
205  * to be a string giving further information for some WTAP_ERR_ values;
206  * "file_type_subtype" is a WTAP_FILE_TYPE_SUBTYPE_ value for the type
207  * and subtype of file being opened.
208  */
209 void
cfile_dump_open_failure_message(const char * filename,int err,gchar * err_info,int file_type_subtype)210 cfile_dump_open_failure_message(const char *filename, int err, gchar *err_info,
211                                 int file_type_subtype)
212 {
213     if (err < 0) {
214         /*
215          * Wiretap error.
216          * Get a string that describes what we're opening.
217          */
218         char *file_description = output_file_description(filename);
219 
220         switch (err) {
221 
222         case WTAP_ERR_NOT_REGULAR_FILE:
223             cmdarg_err("The %s is a \"special file\" or socket or other non-regular file.",
224                        file_description);
225             break;
226 
227         case WTAP_ERR_CANT_WRITE_TO_PIPE:
228             cmdarg_err("The %s is a pipe, and \"%s\" capture files can't be written to a pipe.",
229                        file_description,
230                        wtap_file_type_subtype_name(file_type_subtype));
231             break;
232 
233         case WTAP_ERR_UNWRITABLE_FILE_TYPE:
234             cmdarg_err("%s doesn't support writing capture files in that format.",
235                        get_friendly_program_name());
236             break;
237 
238         case WTAP_ERR_UNWRITABLE_ENCAP:
239             cmdarg_err("The capture file being read can't be written as a \"%s\" file.",
240                        wtap_file_type_subtype_name(file_type_subtype));
241             break;
242 
243         case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
244             cmdarg_err("The capture file being read can't be written as a \"%s\" file.",
245                        wtap_file_type_subtype_name(file_type_subtype));
246             break;
247 
248         case WTAP_ERR_CANT_OPEN:
249             cmdarg_err("The %s could not be created for some unknown reason.",
250                        file_description);
251             break;
252 
253         case WTAP_ERR_SHORT_WRITE:
254             cmdarg_err("A full header couldn't be written to the %s.",
255                        file_description);
256             break;
257 
258         case WTAP_ERR_COMPRESSION_NOT_SUPPORTED:
259             cmdarg_err("This file type cannot be written as a compressed file.");
260             break;
261 
262         case WTAP_ERR_INTERNAL:
263             cmdarg_err("An internal error occurred creating the %s.\n"
264                        "(%s)",
265                        file_description,
266                        err_info != NULL ? err_info : "no information supplied");
267             g_free(err_info);
268             break;
269 
270         default:
271             cmdarg_err("The %s could not be created: %s.",
272                        file_description,
273                        wtap_strerror(err));
274             break;
275         }
276         g_free(file_description);
277     } else
278         cmdarg_err(file_open_error_message(err, TRUE), filename);
279 }
280 
281 /*
282  * Error message for a failed attempt to read from a capture file.
283  * "filename" is the name of the file being opened; "err" is assumed
284  * to be a UNIX-style errno or a WTAP_ERR_ value; "err_info" is assumed
285  * to be a string giving further information for some WTAP_ERR_ values.
286  */
287 void
cfile_read_failure_message(const char * filename,int err,gchar * err_info)288 cfile_read_failure_message(const char *filename, int err, gchar *err_info)
289 {
290     char *file_string;
291 
292     /* Get a string that describes what we're reading from */
293     file_string = input_file_description(filename);
294 
295     switch (err) {
296 
297     case WTAP_ERR_UNSUPPORTED:
298         cmdarg_err("The %s contains record data that %s doesn't support.\n"
299                    "(%s)",
300                    file_string, get_friendly_program_name(),
301                    err_info != NULL ? err_info : "no information supplied");
302         g_free(err_info);
303         break;
304 
305     case WTAP_ERR_SHORT_READ:
306         cmdarg_err("The %s appears to have been cut short in the middle of a packet.",
307                    file_string);
308         break;
309 
310     case WTAP_ERR_BAD_FILE:
311         cmdarg_err("The %s appears to be damaged or corrupt.\n"
312                    "(%s)",
313                    file_string,
314                    err_info != NULL ? err_info : "no information supplied");
315         g_free(err_info);
316         break;
317 
318     case WTAP_ERR_DECOMPRESS:
319         cmdarg_err("The %s cannot be decompressed; it may be damaged or corrupt.\n"
320                    "(%s)",
321                    file_string,
322                    err_info != NULL ? err_info : "no information supplied");
323         g_free(err_info);
324         break;
325 
326     case WTAP_ERR_INTERNAL:
327         cmdarg_err("An internal error occurred while reading the %s.\n(%s)",
328                    file_string,
329                    err_info != NULL ? err_info : "no information supplied");
330         g_free(err_info);
331         break;
332 
333     case WTAP_ERR_DECOMPRESSION_NOT_SUPPORTED:
334         cmdarg_err("The %s cannot be decompressed; it is compressed in a way that we don't support.\n"
335                    "(%s)",
336                    file_string,
337                    err_info != NULL ? err_info : "no information supplied");
338         g_free(err_info);
339         break;
340 
341     default:
342         cmdarg_err("An error occurred while reading the %s: %s.",
343                    file_string, wtap_strerror(err));
344         break;
345     }
346     g_free(file_string);
347 }
348 
349 /*
350  * Error message for a failed attempt to write to a capture file.
351  * "in_filename" is the name of the file from which the record
352  * being written came; "out_filename" is the name of the file to
353  * which we're writing; "err" is assumed "err" is assumed to be a
354  * UNIX-style errno or a WTAP_ERR_ value; "err_info" is assumed to be
355  * a string giving further information for some WTAP_ERR_ values;
356  * "framenum" is the frame number of the record on which the error
357  * occurred; "file_type_subtype" is a WTAP_FILE_TYPE_SUBTYPE_ value
358  * for the type and subtype of file being written.
359  */
360 void
cfile_write_failure_message(const char * in_filename,const char * out_filename,int err,gchar * err_info,guint32 framenum,int file_type_subtype)361 cfile_write_failure_message(const char *in_filename, const char *out_filename,
362                             int err, gchar *err_info,
363                             guint32 framenum, int file_type_subtype)
364 {
365     char *in_file_string;
366     char *in_frame_string;
367     char *out_file_string;
368 
369     /* Get a string that describes what we're reading from */
370     if (in_filename == NULL) {
371         in_frame_string = g_strdup("");
372     } else {
373         in_file_string = input_file_description(in_filename);
374         in_frame_string = g_strdup_printf(" %u of %s", framenum,
375                                           in_file_string);
376         g_free(in_file_string);
377     }
378 
379     /* Get a string that describes what we're writing to */
380     out_file_string = output_file_description(out_filename);
381 
382     switch (err) {
383 
384     case WTAP_ERR_UNWRITABLE_ENCAP:
385         /*
386          * This is a problem with the particular frame we're writing
387          * and the file type and subtype we're writing; note that,
388          * and report the frame number and file type/subtype.
389          */
390         cmdarg_err("Frame%s has a network type that can't be saved in a \"%s\" file.",
391                    in_frame_string,
392                    wtap_file_type_subtype_name(file_type_subtype));
393         break;
394 
395     case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
396         /*
397          * This is a problem with the particular frame we're writing and
398          * the file type and subtype we're writing; note that, and report
399          * the frame number and file type/subtype.
400          */
401         cmdarg_err("Frame%s has a network type that differs from the network type of earlier packets, which isn't supported in a \"%s\" file.",
402                    in_frame_string,
403                    wtap_file_type_subtype_description(file_type_subtype));
404         break;
405 
406     case WTAP_ERR_PACKET_TOO_LARGE:
407         /*
408          * This is a problem with the particular frame we're writing
409          * and the file type and subtype we're writing; note that,
410          * and report the frame number and file type/subtype.
411          */
412         cmdarg_err("Frame%s is larger than %s supports in a \"%s\" file.",
413                    in_frame_string, get_friendly_program_name(),
414                    wtap_file_type_subtype_name(file_type_subtype));
415         break;
416 
417     case WTAP_ERR_UNWRITABLE_REC_TYPE:
418         /*
419          * This is a problem with the particular record we're writing
420          * and the file type and subtype we're writing; note that,
421          * and report the record number and file type/subtype.
422          */
423         cmdarg_err("Record%s has a record type that can't be saved in a \"%s\" file.",
424                    in_frame_string,
425                    wtap_file_type_subtype_name(file_type_subtype));
426         break;
427 
428     case WTAP_ERR_UNWRITABLE_REC_DATA:
429         /*
430          * This is a problem with the particular record we're writing
431          * and the file type and subtype we're writing; note that,
432          * and report the record number and file type/subtype.
433          */
434         cmdarg_err("Record%s has data that can't be saved in a \"%s\" file.\n"
435                    "(%s)",
436                    in_frame_string,
437                    wtap_file_type_subtype_name(file_type_subtype),
438                    err_info != NULL ? err_info : "no information supplied");
439         g_free(err_info);
440         break;
441 
442     case WTAP_ERR_INTERNAL:
443         cmdarg_err("An internal error occurred while writing record%s to the %s.\n(%s)",
444                    in_frame_string, out_file_string,
445                    err_info != NULL ? err_info : "no information supplied");
446         g_free(err_info);
447         break;
448 
449     case ENOSPC:
450         cmdarg_err("Not all the packets could be written to the %s because there is "
451                    "no space left on the file system.",
452                    out_file_string);
453         break;
454 
455 #ifdef EDQUOT
456     case EDQUOT:
457         cmdarg_err("Not all the packets could be written to the %s because you are "
458                    "too close to, or over your disk quota.",
459                    out_file_string);
460   break;
461 #endif
462 
463     case WTAP_ERR_SHORT_WRITE:
464         cmdarg_err("A full write couldn't be done to the %s.",
465                    out_file_string);
466         break;
467 
468     default:
469         cmdarg_err("An error occurred while writing to the %s: %s.",
470                    out_file_string, wtap_strerror(err));
471         break;
472     }
473     g_free(in_frame_string);
474     g_free(out_file_string);
475 }
476 
477 /*
478  * Error message for a failed attempt to close a capture file.
479  * "filename" is the name of the file being closed; "err" is assumed
480  * to be a UNIX-style errno or a WTAP_ERR_ value; "err_info" is assumed
481  * to be a string giving further information for some WTAP_ERR_ values.
482  *
483  * When closing a capture file:
484  *
485  *    some information in the file that can't be determined until
486  *    all packets have been written might be written to the file
487  *    (such as a table of the file offsets of all packets);
488  *
489  *    data buffered in the low-level file writing code might be
490  *    flushed to the file;
491  *
492  *    for remote file systems, data written to the file but not
493  *    yet sent to the server might be sent to the server or, if
494  *    that data was sent asynchronously, "out of space", "disk
495  *    quota exceeded", or "I/O error" indications might have
496  *    been received but not yet delivered, and the close operation
497  *    could deliver them;
498  *
499  * so we have to check for write errors here.
500  */
501 void
cfile_close_failure_message(const char * filename,int err,gchar * err_info)502 cfile_close_failure_message(const char *filename, int err, gchar *err_info)
503 {
504     char *file_string;
505 
506     /* Get a string that describes what we're writing to */
507     file_string = output_file_description(filename);
508 
509     switch (err) {
510 
511     case ENOSPC:
512         cmdarg_err("Not all the packets could be written to the %s because there is "
513                    "no space left on the file system.",
514                    file_string);
515     break;
516 
517 #ifdef EDQUOT
518     case EDQUOT:
519         cmdarg_err("Not all the packets could be written to the %s because you are "
520                    "too close to, or over your disk quota.",
521                    file_string);
522   break;
523 #endif
524 
525     case WTAP_ERR_CANT_CLOSE:
526         cmdarg_err("The %s couldn't be closed for some unknown reason.",
527                    file_string);
528         break;
529 
530     case WTAP_ERR_SHORT_WRITE:
531         cmdarg_err("A full write couldn't be done to the %s.",
532                    file_string);
533         break;
534 
535     case WTAP_ERR_INTERNAL:
536         cmdarg_err("An internal error occurred closing the file \"%s\".\n"
537                    "(%s)",
538                    file_string,
539                    err_info != NULL ? err_info : "no information supplied");
540         g_free(err_info);
541         break;
542 
543     default:
544         cmdarg_err("An error occurred while closing the file %s: %s.",
545                    file_string, wtap_strerror(err));
546         break;
547     }
548     g_free(file_string);
549 }
550