wmem: allow wmem_destroy_list to ignore a NULL list.
[wireshark-sm.git] / ui / alert_box.c
blobff68a8486dc5d8acda8ce658ccbbb183f4627116
1 /* alert_box.c
2 * Routines to put up various "standard" alert boxes used in multiple
3 * places
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
12 #include "config.h"
14 #include <string.h>
15 #include <errno.h>
17 #include <wiretap/wtap.h>
18 #include <wsutil/filesystem.h>
19 #include <wsutil/report_message.h>
21 #include "ui/alert_box.h"
23 #include "ui/simple_dialog.h"
26 * Alert box for general errors.
28 void
29 failure_alert_box(const char *msg_format, ...)
31 va_list ap;
33 va_start(ap, msg_format);
34 vsimple_error_message_box(msg_format, ap);
35 va_end(ap);
38 void
39 vfailure_alert_box(const char *msg_format, va_list ap)
41 vsimple_error_message_box(msg_format, ap);
44 void
45 vwarning_alert_box(const char *msg_format, va_list ap)
47 vsimple_warning_message_box(msg_format, ap);
51 * Alert box for a failed attempt to open a capture file for reading.
52 * "filename" is the name of the file being opened; "err" is assumed
53 * to be a UNIX-style errno or a WTAP_ERR_ value; "err_info" is assumed
54 * to be a string giving further information for some WTAP_ERR_ values.
56 * XXX - add explanatory secondary text for at least some of the errors;
57 * various HIGs suggest that you should, for example, suggest that the
58 * user remove files if the file system is full. Perhaps that's because
59 * they're providing guidelines for people less sophisticated than the
60 * typical Wireshark user is, but....
62 void
63 cfile_open_failure_alert_box(const char *filename, int err, char *err_info)
65 char *display_basename;
67 if (err < 0) {
68 /* Wiretap error. */
69 display_basename = g_filename_display_basename(filename);
70 switch (err) {
72 case WTAP_ERR_NOT_REGULAR_FILE:
73 simple_error_message_box(
74 "The file \"%s\" is a \"special file\" or socket or other non-regular file.",
75 display_basename);
76 break;
78 case WTAP_ERR_RANDOM_OPEN_PIPE:
79 simple_error_message_box(
80 "The file \"%s\" is a pipe or FIFO; Wireshark can't read pipe or FIFO files.\n"
81 "To capture from a pipe or FIFO use wireshark -i -",
82 display_basename);
83 break;
85 case WTAP_ERR_FILE_UNKNOWN_FORMAT:
86 simple_error_message_box(
87 "The file \"%s\" isn't a capture file in a format Wireshark understands.",
88 display_basename);
89 break;
91 case WTAP_ERR_UNSUPPORTED:
92 simple_error_message_box(
93 "The file \"%s\" contains record data that Wireshark doesn't support.\n"
94 "(%s)",
95 display_basename,
96 err_info != NULL ? err_info : "no information supplied");
97 g_free(err_info);
98 break;
100 case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
101 simple_error_message_box(
102 "The file \"%s\" is a capture for a network type that Wireshark doesn't support.",
103 display_basename);
104 break;
106 case WTAP_ERR_BAD_FILE:
107 simple_error_message_box(
108 "The file \"%s\" appears to be damaged or corrupt.\n"
109 "(%s)",
110 display_basename,
111 err_info != NULL ? err_info : "no information supplied");
112 g_free(err_info);
113 break;
115 case WTAP_ERR_CANT_OPEN:
116 simple_error_message_box(
117 "The file \"%s\" could not be opened for some unknown reason.",
118 display_basename);
119 break;
121 case WTAP_ERR_SHORT_READ:
122 simple_error_message_box(
123 "The file \"%s\" appears to have been cut short"
124 " in the middle of a packet or other data.",
125 display_basename);
126 break;
128 case WTAP_ERR_DECOMPRESS:
129 simple_error_message_box(
130 "The file \"%s\" cannot be decompressed; it may be damaged or corrupt.\n"
131 "(%s)", display_basename,
132 err_info != NULL ? err_info : "no information supplied");
133 g_free(err_info);
134 break;
136 case WTAP_ERR_INTERNAL:
137 simple_error_message_box(
138 "An internal error occurred opening the file \"%s\".\n"
139 "(%s)", display_basename,
140 err_info != NULL ? err_info : "no information supplied");
141 g_free(err_info);
142 break;
144 case WTAP_ERR_DECOMPRESSION_NOT_SUPPORTED:
145 simple_error_message_box(
146 "The file \"%s\" cannot be decompressed; it is compressed in a way that we don't support.\n"
147 "(%s)", display_basename,
148 err_info != NULL ? err_info : "no information supplied");
149 g_free(err_info);
150 break;
152 default:
153 simple_error_message_box(
154 "The file \"%s\" could not be opened: %s.",
155 display_basename,
156 wtap_strerror(err));
157 break;
159 g_free(display_basename);
160 } else {
161 /* OS error. */
162 open_failure_alert_box(filename, err, false);
167 * Alert box for a failed attempt to open a capture file for writing.
168 * "filename" is the name of the file being opened; "err" is assumed
169 * to be a UNIX-style errno or a WTAP_ERR_ value; "err_info" is assumed
170 * to be a string giving further information for some WTAP_ERR_ values;
171 * "file_type_subtype" is a WTAP_FILE_TYPE_SUBTYPE_ value for the type
172 * and subtype of file being opened.
174 * XXX - add explanatory secondary text for at least some of the errors;
175 * various HIGs suggest that you should, for example, suggest that the
176 * user remove files if the file system is full. Perhaps that's because
177 * they're providing guidelines for people less sophisticated than the
178 * typical Wireshark user is, but....
180 void
181 cfile_dump_open_failure_alert_box(const char *filename, int err,
182 char *err_info, int file_type_subtype)
184 char *display_basename;
186 if (err < 0) {
187 /* Wiretap error. */
188 display_basename = g_filename_display_basename(filename);
189 switch (err) {
191 case WTAP_ERR_NOT_REGULAR_FILE:
192 simple_error_message_box(
193 "The file \"%s\" is a \"special file\" or socket or other non-regular file.",
194 display_basename);
195 break;
197 case WTAP_ERR_CANT_WRITE_TO_PIPE:
198 simple_error_message_box(
199 "The file \"%s\" is a pipe, and %s capture files can't be "
200 "written to a pipe.",
201 display_basename, wtap_file_type_subtype_description(file_type_subtype));
202 break;
204 case WTAP_ERR_UNWRITABLE_FILE_TYPE:
205 simple_error_message_box(
206 "Wireshark doesn't support writing capture files in that format.");
207 break;
209 case WTAP_ERR_UNWRITABLE_ENCAP:
210 simple_error_message_box("Wireshark can't save this capture in that format.");
211 break;
213 case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
214 simple_error_message_box(
215 "Wireshark can't save this capture in that format.");
216 break;
218 case WTAP_ERR_CANT_OPEN:
219 simple_error_message_box(
220 "The file \"%s\" could not be created for some unknown reason.",
221 display_basename);
222 break;
224 case WTAP_ERR_SHORT_WRITE:
225 simple_error_message_box(
226 "A full header couldn't be written to the file \"%s\".",
227 display_basename);
228 break;
230 case WTAP_ERR_COMPRESSION_NOT_SUPPORTED:
231 simple_error_message_box(
232 "This file type cannot be written as a compressed file.");
233 break;
235 case WTAP_ERR_INTERNAL:
236 simple_error_message_box(
237 "An internal error occurred creating the file \"%s\".\n"
238 "(%s)",
239 display_basename,
240 err_info != NULL ? err_info : "no information supplied");
241 g_free(err_info);
242 break;
244 default:
245 simple_error_message_box(
246 "The file \"%s\" could not be created: %s.",
247 display_basename,
248 wtap_strerror(err));
249 break;
251 g_free(display_basename);
252 } else {
253 /* OS error. */
254 open_failure_alert_box(filename, err, true);
259 * Alert box for a failed attempt to read from a capture file.
260 * "err" is assumed to be a UNIX-style errno or a WTAP_ERR_ value;
261 * "err_info" is assumed to be a string giving further information for
262 * some WTAP_ERR_ values.
264 void
265 cfile_read_failure_alert_box(const char *filename, int err, char *err_info)
267 char *display_name;
269 if (filename == NULL)
270 display_name = g_strdup("capture file");
271 else {
272 char *display_basename;
274 display_basename = g_filename_display_basename(filename);
275 display_name = ws_strdup_printf("capture file \"%s\"", display_basename);
276 g_free(display_basename);
279 switch (err) {
281 case WTAP_ERR_UNSUPPORTED:
282 simple_error_message_box(
283 "The %s contains record data that Wireshark doesn't support.\n"
284 "(%s)",
285 display_name,
286 err_info != NULL ? err_info : "no information supplied");
287 g_free(err_info);
288 break;
290 case WTAP_ERR_SHORT_READ:
291 simple_error_message_box(
292 "The %s appears to have been cut short in the middle of a packet.",
293 display_name);
294 break;
296 case WTAP_ERR_BAD_FILE:
297 simple_error_message_box(
298 "The %s appears to be damaged or corrupt.\n"
299 "(%s)",
300 display_name,
301 err_info != NULL ? err_info : "no information supplied");
302 g_free(err_info);
303 break;
305 case WTAP_ERR_DECOMPRESS:
306 simple_error_message_box(
307 "The %s cannot be decompressed; it may be damaged or corrupt.\n"
308 "(%s)",
309 display_name,
310 err_info != NULL ? err_info : "no information supplied");
311 g_free(err_info);
312 break;
314 case WTAP_ERR_INTERNAL:
315 simple_error_message_box(
316 "An internal error occurred while reading the %s.\n(%s)",
317 display_name,
318 err_info != NULL ? err_info : "no information supplied");
319 g_free(err_info);
320 break;
322 case WTAP_ERR_DECOMPRESSION_NOT_SUPPORTED:
323 simple_error_message_box(
324 "The %s cannot be decompressed; it is compressed in a way that we don't support.\n"
325 "(%s)",
326 display_name,
327 err_info != NULL ? err_info : "no information supplied");
328 g_free(err_info);
329 break;
331 default:
332 simple_error_message_box(
333 "An error occurred while reading the %s: %s.",
334 display_name,
335 wtap_strerror(err));
336 break;
338 g_free(display_name);
342 * Alert box for a failed attempt to write to a capture file.
343 * "in_filename" is the name of the file from which the record being
344 * written came; "out_filename" is the name of the file to which we're
345 * writing; "err" is assumed "err" is assumed to be a UNIX-style errno
346 * or a WTAP_ERR_ value; "err_info" is assumed to be a string giving
347 * further information for some WTAP_ERR_ values; "framenum" is the frame
348 * number of the record on which the error occurred; "file_type_subtype"
349 * is a WTAP_FILE_TYPE_SUBTYPE_ value for the type and subtype of file
350 * being written.
352 void
353 cfile_write_failure_alert_box(const char *in_filename, const char *out_filename,
354 int err, char *err_info, uint64_t framenum,
355 int file_type_subtype)
357 char *in_file_string;
358 char *out_display_basename;
360 if (err < 0) {
361 /* Wiretap error. */
362 if (in_filename == NULL)
363 in_file_string = g_strdup("");
364 else
365 in_file_string = ws_strdup_printf(" of file \"%s\"", in_filename);
367 switch (err) {
369 case WTAP_ERR_UNWRITABLE_ENCAP:
371 * This is a problem with the particular frame we're writing and
372 * the file type and subtype we're writing; note that, and report
373 * the frame number and file type/subtype.
375 simple_error_message_box(
376 "Frame %" PRIu64 "%s has a network type that can't be saved in a \"%s\" file.",
377 framenum, in_file_string,
378 wtap_file_type_subtype_description(file_type_subtype));
379 break;
381 case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
383 * This is a problem with the particular frame we're writing and
384 * the file type and subtype we're writing; note that, and report
385 * the frame number and file type/subtype.
387 simple_error_message_box(
388 "Frame %" PRIu64 "%s has a network type that differs from the network type of earlier packets, which isn't supported in a \"%s\" file.",
389 framenum, in_file_string,
390 wtap_file_type_subtype_description(file_type_subtype));
391 break;
393 case WTAP_ERR_PACKET_TOO_LARGE:
395 * This is a problem with the particular frame we're writing and
396 * the file type and subtype we're writing; note that, and report
397 * the frame number and file type/subtype.
399 simple_error_message_box(
400 "Frame %" PRIu64 "%s is larger than Wireshark supports in a \"%s\" file.",
401 framenum, in_file_string,
402 wtap_file_type_subtype_description(file_type_subtype));
403 break;
405 case WTAP_ERR_UNWRITABLE_REC_TYPE:
407 * This is a problem with the particular record we're writing and
408 * the file type and subtype we're writing; note that, and report
409 * the record number and file type/subtype.
411 simple_error_message_box(
412 "Record %" PRIu64 "%s has a record type that can't be saved in a \"%s\" file.",
413 framenum, in_file_string,
414 wtap_file_type_subtype_description(file_type_subtype));
415 break;
417 case WTAP_ERR_UNWRITABLE_REC_DATA:
419 * This is a problem with the particular record we're writing and
420 * the file type and subtype we're writing; note that, and report
421 * the record number and file type/subtype.
423 simple_error_message_box(
424 "Record %" PRIu64 "%s has data that can't be saved in a \"%s\" file.\n"
425 "(%s)",
426 framenum, in_file_string,
427 wtap_file_type_subtype_description(file_type_subtype),
428 err_info != NULL ? err_info : "no information supplied");
429 g_free(err_info);
430 break;
432 case WTAP_ERR_SHORT_WRITE:
433 out_display_basename = g_filename_display_basename(out_filename);
434 simple_error_message_box(
435 "A full write couldn't be done to the file \"%s\".",
436 out_display_basename);
437 g_free(out_display_basename);
438 break;
440 case WTAP_ERR_INTERNAL:
441 out_display_basename = g_filename_display_basename(out_filename);
442 simple_error_message_box(
443 "An internal error occurred while writing to the file \"%s\".\n(%s)",
444 out_display_basename,
445 err_info != NULL ? err_info : "no information supplied");
446 g_free(out_display_basename);
447 g_free(err_info);
448 break;
450 default:
451 out_display_basename = g_filename_display_basename(out_filename);
452 simple_error_message_box(
453 "An error occurred while writing to the file \"%s\": %s.",
454 out_display_basename, wtap_strerror(err));
455 g_free(out_display_basename);
456 break;
458 g_free(in_file_string);
459 } else {
460 /* OS error. */
461 write_failure_alert_box(out_filename, err);
466 * Alert box for a failed attempt to close a capture file.
467 * "err" is assumed to be a UNIX-style errno or a WTAP_ERR_ value;
468 * "err_info" is assumed to be a string giving further information for
469 * some WTAP_ERR_ values.
471 * When closing a capture file:
473 * some information in the file that can't be determined until
474 * all packets have been written might be written to the file
475 * (such as a table of the file offsets of all packets);
477 * data buffered in the low-level file writing code might be
478 * flushed to the file;
480 * for remote file systems, data written to the file but not
481 * yet sent to the server might be sent to the server or, if
482 * that data was sent asynchronously, "out of space", "disk
483 * quota exceeded", or "I/O error" indications might have
484 * been received but not yet delivered, and the close operation
485 * could deliver them;
487 * so we have to check for write errors here.
489 * XXX - add explanatory secondary text for at least some of the errors;
490 * various HIGs suggest that you should, for example, suggest that the
491 * user remove files if the file system is full. Perhaps that's because
492 * they're providing guidelines for people less sophisticated than the
493 * typical Wireshark user is, but....
495 void
496 cfile_close_failure_alert_box(const char *filename, int err, char *err_info)
498 char *display_basename;
500 if (err < 0) {
501 /* Wiretap error. */
502 display_basename = g_filename_display_basename(filename);
503 switch (err) {
505 case WTAP_ERR_CANT_CLOSE:
506 simple_error_message_box(
507 "The file \"%s\" couldn't be closed for some unknown reason.",
508 display_basename);
509 break;
511 case WTAP_ERR_SHORT_WRITE:
512 simple_error_message_box(
513 "A full write couldn't be done to the file \"%s\".",
514 display_basename);
515 break;
517 case WTAP_ERR_INTERNAL:
518 simple_error_message_box(
519 "An internal error occurred closing the file \"%s\".\n"
520 "(%s)",
521 display_basename,
522 err_info != NULL ? err_info : "no information supplied");
523 g_free(err_info);
524 break;
526 default:
527 simple_error_message_box(
528 "An error occurred while closing the file \"%s\": %s.",
529 display_basename, wtap_strerror(err));
530 break;
532 g_free(display_basename);
533 } else {
534 /* OS error.
535 We assume that a close error from the OS is really a write error. */
536 write_failure_alert_box(filename, err);
541 * Alert box for a failed attempt to open or create a file.
542 * "err" is assumed to be a UNIX-style errno; "for_writing" is true if
543 * the file is being opened for writing and false if it's being opened
544 * for reading.
546 * XXX - add explanatory secondary text for at least some of the errors;
547 * various HIGs suggest that you should, for example, suggest that the
548 * user remove files if the file system is full. Perhaps that's because
549 * they're providing guidelines for people less sophisticated than the
550 * typical Wireshark user is, but....
552 void
553 open_failure_alert_box(const char *filename, int err, bool for_writing)
555 char *display_basename;
557 display_basename = g_filename_display_basename(filename);
558 simple_message_box(ESD_TYPE_ERROR, NULL, NULL,
559 file_open_error_message(err, for_writing),
560 display_basename);
561 g_free(display_basename);
565 * Alert box for a failed attempt to read a file.
566 * "err" is assumed to be a UNIX-style errno.
568 void
569 read_failure_alert_box(const char *filename, int err)
571 char *display_basename;
573 display_basename = g_filename_display_basename(filename);
574 simple_message_box(ESD_TYPE_ERROR, NULL, NULL,
575 "An error occurred while reading from the file \"%s\": %s.",
576 display_basename, g_strerror(err));
577 g_free(display_basename);
581 * Alert box for a failed attempt to write to a file.
582 * "err" is assumed to be a UNIX-style errno.
584 * XXX - add explanatory secondary text for at least some of the errors;
585 * various HIGs suggest that you should, for example, suggest that the
586 * user remove files if the file system is full. Perhaps that's because
587 * they're providing guidelines for people less sophisticated than the
588 * typical Wireshark user is, but....
590 void
591 write_failure_alert_box(const char *filename, int err)
593 char *display_basename;
595 display_basename = g_filename_display_basename(filename);
596 simple_message_box(ESD_TYPE_ERROR, NULL, NULL,
597 file_write_error_message(err), display_basename);
598 g_free(display_basename);
602 * Alert box for a failed attempt to rename a file.
603 * "err" is assumed to be a UNIX-style errno.
605 * XXX - whether we mention the source pathname, the target pathname,
606 * or both depends on the error and on what we find if we look for
607 * one or both of them.
609 void
610 rename_failure_alert_box(const char *old_filename, const char *new_filename,
611 int err)
613 char *old_display_basename, *new_display_basename;
615 old_display_basename = g_filename_display_basename(old_filename);
616 new_display_basename = g_filename_display_basename(new_filename);
617 switch (err) {
619 case ENOENT:
620 /* XXX - should check whether the source exists and, if not,
621 report it as the problem and, if so, report the destination
622 as the problem. */
623 simple_error_message_box("The path to the file \"%s\" doesn't exist.",
624 old_display_basename);
625 break;
627 case EACCES:
628 /* XXX - if we're doing a rename after a safe save, we should
629 probably say something else. */
630 simple_error_message_box("You don't have permission to move the capture file from \"%s\" to \"%s\".",
631 old_display_basename, new_display_basename);
632 break;
634 default:
635 /* XXX - this should probably mention both the source and destination
636 pathnames. */
637 simple_error_message_box("The file \"%s\" could not be moved to \"%s\": %s.",
638 old_display_basename, new_display_basename,
639 wtap_strerror(err));
640 break;
642 g_free(old_display_basename);
643 g_free(new_display_basename);
647 * Register these routines with the report_message mechanism.
649 void
650 init_report_alert_box(const char *friendly_program_name)
652 static const struct report_message_routines report_alert_box_routines = {
653 vfailure_alert_box,
654 vwarning_alert_box,
655 open_failure_alert_box,
656 read_failure_alert_box,
657 write_failure_alert_box,
658 rename_failure_alert_box,
659 cfile_open_failure_alert_box,
660 cfile_dump_open_failure_alert_box,
661 cfile_read_failure_alert_box,
662 cfile_write_failure_alert_box,
663 cfile_close_failure_alert_box
666 init_report_message(friendly_program_name, &report_alert_box_routines);