4 * $Id: file.c,v 1.33 1999/06/22 22:02:11 gram Exp $
6 * Ethereal - Network traffic analyzer
7 * By Gerald Combs <gerald@zing.org>
8 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
43 #ifdef NEED_SNPRINTF_H
49 # include "snprintf.h"
52 #ifdef NEED_STRERROR_H
56 #ifdef HAVE_SYS_TYPES_H
57 # include <sys/types.h>
60 #ifdef HAVE_NETINET_IN_H
61 # include <netinet/in.h>
71 #include "packet-ncp.h"
73 #define TAIL_TIMEOUT 2000 /* msec */
75 extern GtkWidget *packet_list, *prog_bar, *info_bar, *byte_view, *tree_view;
76 extern GtkStyle *pl_style;
77 extern guint file_ctx;
79 extern int sync_pipe[];
81 guint cap_input_id, tail_timeout_id;
83 static guint32 firstsec, firstusec;
84 static guint32 lastsec, lastusec;
87 static void wtap_dispatch_cb(u_char *, const struct wtap_pkthdr *, int,
90 static void pcap_dispatch_cb(u_char *, const struct pcap_pkthdr *,
94 static void init_col_widths(capture_file *);
95 static void set_col_widths(capture_file *);
97 static gint tail_timeout_cb(gpointer);
100 open_cap_file(char *fname, capture_file *cf) {
103 char err_str[PCAP_ERRBUF_SIZE];
107 /* First, make sure the file is valid */
108 if (stat(fname, &cf_stat))
110 if (! S_ISREG(cf_stat.st_mode) && ! S_ISFIFO(cf_stat.st_mode))
111 return (OPEN_CAP_FILE_NOT_REGULAR);
113 /* Next, try to open the file */
114 cf->fh = fopen(fname, "r");
118 fseek(cf->fh, 0L, SEEK_END);
119 cf->f_len = ftell(cf->fh);
121 fseek(cf->fh, 0L, SEEK_SET);
122 fread(magic, sizeof(guint32), 2, cf->fh);
123 fseek(cf->fh, 0L, SEEK_SET);
127 /* set the file name beacuse we need it to set the follow stream filter */
128 cf->filename = g_strdup( fname );
130 /* Next, find out what type of file we're dealing with */
132 cf->cd_t = WTAP_FILE_UNKNOWN;
134 cf->cd_t = CD_UNKNOWN;
135 cf->lnk_t = DLT_NULL;
143 firstsec = 0, firstusec = 0;
144 lastsec = 0, lastusec = 0;
147 if (magic[0] == PCAP_MAGIC || magic[0] == SWAP32(PCAP_MAGIC)) {
149 /* Pcap/Tcpdump file */
150 cf->pfh = pcap_open_offline(fname, err_str);
151 if (cf->pfh == NULL) {
153 cf->wth = wtap_open_offline(fname);
154 if (cf->wth == NULL) {
157 /* XXX - we assume that, because we were able to open it above,
158 this must have failed because it's not a capture file in
159 a format we can read. */
160 return (OPEN_CAP_FILE_UNKNOWN_FORMAT);
165 if (pcap_compile(cf->pfh, &cf->fcode, cf->dfilter, 1, 0) < 0) {
166 simple_dialog(ESD_TYPE_WARN, NULL, "Unable to parse filter string "
167 "\"%s\".", cf->dfilter);
168 } else if (pcap_setfilter(cf->pfh, &cf->fcode) < 0) {
169 simple_dialog(ESD_TYPE_WARN, NULL, "Can't install filter.");
173 cf->fh = pcap_file(cf->pfh);
174 cf->swap = pcap_is_swapped(cf->pfh);
175 if ((cf->swap && BYTE_ORDER == BIG_ENDIAN) ||
176 (!cf->swap && BYTE_ORDER == LITTLE_ENDIAN)) {
177 /* Data is big-endian */
178 cf->cd_t = CD_PCAP_BE;
180 cf->cd_t = CD_PCAP_LE;
182 cf->vers = ( ((pcap_major_version(cf->pfh) & 0x0000ffff) << 16) |
183 pcap_minor_version(cf->pfh) );
184 cf->snap = pcap_snapshot(cf->pfh);
185 cf->lnk_t = pcap_datalink(cf->pfh);
186 } else if (ntohl(magic[0]) == SNOOP_MAGIC_1 && ntohl(magic[1]) == SNOOP_MAGIC_2) {
187 return (OPEN_CAP_FILE_UNKNOWN_FORMAT);
190 if (cf->cd_t == CD_UNKNOWN)
191 return (OPEN_CAP_FILE_UNKNOWN_FORMAT);
194 if (wtap_offline_filter(cf->wth, cf->dfilter) < 0) {
195 simple_dialog(ESD_TYPE_WARN, NULL, "Unable to parse filter string "
196 "\"%s\".", cf->dfilter);
199 cf->fh = wtap_file(cf->wth);
200 cf->cd_t = wtap_file_type(cf->wth);
201 cf->snap = wtap_snapshot_length(cf->wth);
208 free_packets_cb(gpointer data, gpointer user_data)
213 /* Reset everything to a pristine state */
215 close_cap_file(capture_file *cf, void *w, guint context) {
232 g_list_foreach(cf->plist, free_packets_cb, NULL);
233 g_list_free(cf->plist);
236 gtk_text_freeze(GTK_TEXT(byte_view));
237 gtk_text_set_point(GTK_TEXT(byte_view), 0);
238 gtk_text_forward_delete(GTK_TEXT(byte_view),
239 gtk_text_get_length(GTK_TEXT(byte_view)));
240 gtk_text_thaw(GTK_TEXT(byte_view));
241 gtk_tree_clear_items(GTK_TREE(tree_view), 0,
242 g_list_length(GTK_TREE(tree_view)->children));
244 gtk_clist_freeze(GTK_CLIST(packet_list));
245 gtk_clist_clear(GTK_CLIST(packet_list));
246 gtk_clist_thaw(GTK_CLIST(packet_list));
247 gtk_statusbar_pop(GTK_STATUSBAR(w), context);
251 load_cap_file(char *fname, capture_file *cf) {
252 gchar *name_ptr, *load_msg, *load_fmt = " Loading: %s...";
253 gchar *done_fmt = " File: %s Drops: %d";
254 gchar *err_fmt = " Error: Could not load '%s'";
259 close_cap_file(cf, info_bar, file_ctx);
261 /* Initialize protocol-specific variables */
264 if ((name_ptr = (gchar *) strrchr(fname, '/')) == NULL)
268 load_msg = g_malloc(strlen(name_ptr) + strlen(load_fmt) + 2);
269 sprintf(load_msg, load_fmt, name_ptr);
270 gtk_statusbar_push(GTK_STATUSBAR(info_bar), file_ctx, load_msg);
272 timeout = gtk_timeout_add(250, file_progress_cb, (gpointer) &cf);
274 err = open_cap_file(fname, cf);
276 if ((err == 0) && (cf->cd_t != WTAP_FILE_UNKNOWN)) {
278 if ((err == 0) && (cf->cd_t != CD_UNKNOWN)) {
280 gtk_clist_freeze(GTK_CLIST(packet_list));
283 wtap_loop(cf->wth, 0, wtap_dispatch_cb, (u_char *) cf);
287 pcap_loop(cf->pfh, 0, pcap_dispatch_cb, (u_char *) cf);
291 cf->fh = fopen(fname, "r");
294 gtk_clist_thaw(GTK_CLIST(packet_list));
297 gtk_timeout_remove(timeout);
298 gtk_progress_bar_update(GTK_PROGRESS_BAR(prog_bar), 0);
300 gtk_statusbar_pop(GTK_STATUSBAR(info_bar), file_ctx);
303 msg_len = strlen(name_ptr) + strlen(done_fmt) + 64;
304 load_msg = g_realloc(load_msg, msg_len);
306 if (cf->user_saved || !cf->save_file)
307 snprintf(load_msg, msg_len, done_fmt, name_ptr, cf->drops);
309 snprintf(load_msg, msg_len, done_fmt, "<none>", cf->drops);
311 gtk_statusbar_push(GTK_STATUSBAR(info_bar), file_ctx, load_msg);
314 /* name_ptr[-1] = '\0'; Why is this here? It causes problems with capture files */
316 set_menu_sensitivity("/File/Close", TRUE);
317 set_menu_sensitivity("/File/Reload", TRUE);
318 set_menu_sensitivity("/Tools/Summary", TRUE);
320 set_menu_sensitivity("<Main>/File/Close", TRUE);
321 set_menu_sensitivity("<Main>/File/Reload", TRUE);
322 set_menu_sensitivity("<Main>/Tools/Summary", TRUE);
325 msg_len = strlen(name_ptr) + strlen(err_fmt) + 2;
326 load_msg = g_realloc(load_msg, msg_len);
327 snprintf(load_msg, msg_len, err_fmt, name_ptr);
328 gtk_statusbar_push(GTK_STATUSBAR(info_bar), file_ctx, load_msg);
331 set_menu_sensitivity("/File/Close", FALSE);
332 set_menu_sensitivity("/File/Save", FALSE);
333 set_menu_sensitivity("/File/Save As...", FALSE);
334 set_menu_sensitivity("/File/Reload", FALSE);
335 set_menu_sensitivity("/Tools/Summary", FALSE);
338 set_menu_sensitivity("<Main>/File/Close", FALSE);
339 set_menu_sensitivity("<Main>/File/Save", FALSE);
340 set_menu_sensitivity("<Main>/File/Save As...", FALSE);
341 set_menu_sensitivity("<Main>/File/Reload", FALSE);
342 set_menu_sensitivity("<Main>/Tools/Summary", FALSE);
349 cap_file_input_cb (gpointer data, gint source, GdkInputCondition condition) {
351 capture_file *cf = (capture_file *)data;
354 /* avoid reentrancy problems and stack overflow */
355 gtk_input_remove(cap_input_id);
356 if (tail_timeout_id != -1) gtk_timeout_remove(tail_timeout_id);
358 if (read(sync_pipe[0], buffer, 256) <= 0) {
360 /* process data until end of file and stop capture (restore menu items) */
361 gtk_clist_freeze(GTK_CLIST(packet_list));
364 wtap_loop(cf->wth, 0, wtap_dispatch_cb, (u_char *) cf);
366 pcap_loop(cf->pfh, 0, pcap_dispatch_cb, (u_char *) cf);
370 gtk_clist_thaw(GTK_CLIST(packet_list));
380 set_menu_sensitivity("/File/Open...", TRUE);
381 set_menu_sensitivity("/File/Close", TRUE);
382 set_menu_sensitivity("/File/Save As...", TRUE);
383 set_menu_sensitivity("/File/Reload", TRUE);
384 set_menu_sensitivity("/Capture/Start...", TRUE);
385 set_menu_sensitivity("/Tools/Capture...", TRUE);
386 set_menu_sensitivity("/Tools/Summary", TRUE);
389 set_menu_sensitivity("<Main>/File/Open...", TRUE);
390 set_menu_sensitivity("<Main>/File/Close", TRUE);
391 set_menu_sensitivity("<Main>/File/Save As...", TRUE);
392 set_menu_sensitivity("<Main>/File/Reload", TRUE);
393 set_menu_sensitivity("<Main>/Capture/Start...", TRUE);
394 set_menu_sensitivity("<Main>/Tools/Capture...", TRUE);
395 set_menu_sensitivity("<Main>/Tools/Summary", TRUE);
397 gtk_statusbar_push(GTK_STATUSBAR(info_bar), file_ctx, " File: <none>");
401 gtk_clist_freeze(GTK_CLIST(packet_list));
404 wtap_loop(cf->wth, 0, wtap_dispatch_cb, (u_char *) cf);
406 pcap_loop(cf->pfh, 0, pcap_dispatch_cb, (u_char *) cf);
410 gtk_clist_thaw(GTK_CLIST(packet_list));
412 /* restore pipe handler */
413 cap_input_id = gtk_input_add_full (sync_pipe[0],
420 /* only useful in case of low amount of captured data */
421 tail_timeout_id = gtk_timeout_add(TAIL_TIMEOUT, tail_timeout_cb, (gpointer) cf);
426 tail_timeout_cb(gpointer data) {
428 capture_file *cf = (capture_file *)data;
430 /* avoid reentrancy problems and stack overflow */
431 gtk_input_remove(cap_input_id);
433 gtk_clist_freeze(GTK_CLIST(packet_list));
436 wtap_loop(cf->wth, 0, wtap_dispatch_cb, (u_char *) cf);
438 pcap_loop(cf->pfh, 0, pcap_dispatch_cb, (u_char *) cf);
442 gtk_clist_thaw(GTK_CLIST(packet_list));
444 cap_input_id = gtk_input_add_full (sync_pipe[0],
455 tail_cap_file(char *fname, capture_file *cf) {
458 close_cap_file(cf, info_bar, file_ctx);
460 /* Initialize protocol-speficic variables */
463 err = open_cap_file(fname, cf);
465 if ((err == 0) && (cf->cd_t != WTAP_FILE_UNKNOWN)) {
467 if ((err == 0) && (cf->cd_t != CD_UNKNOWN)) {
471 set_menu_sensitivity("/File/Open...", FALSE);
472 set_menu_sensitivity("/File/Close", FALSE);
473 set_menu_sensitivity("/File/Reload", FALSE);
474 set_menu_sensitivity("/Capture/Start...", FALSE);
475 set_menu_sensitivity("/Tools/Capture...", FALSE);
476 set_menu_sensitivity("/Tools/Summary", FALSE);
479 set_menu_sensitivity("<Main>/File/Open...", FALSE);
480 set_menu_sensitivity("<Main>/File/Close", FALSE);
481 set_menu_sensitivity("<Main>/File/Reload", FALSE);
482 set_menu_sensitivity("<Main>/Capture/Start...", FALSE);
483 set_menu_sensitivity("<Main>/Tools/Capture...", FALSE);
484 set_menu_sensitivity("<Main>/Tools/Summary", FALSE);
487 cf->fh = fopen(fname, "r");
488 tail_timeout_id = -1;
489 cap_input_id = gtk_input_add_full (sync_pipe[0],
495 gtk_statusbar_push(GTK_STATUSBAR(info_bar), file_ctx,
496 " <live capture in progress>");
500 set_menu_sensitivity("/File/Close", FALSE);
501 set_menu_sensitivity("/File/Save", FALSE);
502 set_menu_sensitivity("/File/Save As...", FALSE);
503 set_menu_sensitivity("/File/Reload", FALSE);
504 set_menu_sensitivity("/Tools/Summary", FALSE);
506 set_menu_sensitivity("<Main>/File/Close", FALSE);
507 set_menu_sensitivity("<Main>/File/Save", FALSE);
508 set_menu_sensitivity("<Main>/File/Save As...", FALSE);
509 set_menu_sensitivity("<Main>/File/Reload", FALSE);
510 set_menu_sensitivity("<Main>/Tools/Summary", FALSE);
518 compute_time_stamps(frame_data *fdata, capture_file *cf)
520 /* If we don't have the time stamp of the first packet, it's because this
521 is the first packet. Save the time stamp of this packet as the time
522 stamp of the first packet. */
523 if (!firstsec && !firstusec) {
524 firstsec = fdata->abs_secs;
525 firstusec = fdata->abs_usecs;
528 /* Do the same for the time stamp of the previous packet. */
529 if (!lastsec && !lastusec) {
530 lastsec = fdata->abs_secs;
531 lastusec = fdata->abs_usecs;
534 /* Get the time elapsed between the first packet and this packet. */
535 cf->esec = fdata->abs_secs - firstsec;
536 if (firstusec <= fdata->abs_usecs) {
537 cf->eusec = fdata->abs_usecs - firstusec;
539 cf->eusec = (fdata->abs_usecs + 1000000) - firstusec;
542 fdata->rel_secs = cf->esec;
543 fdata->rel_usecs = cf->eusec;
545 /* Do the same for the previous packet */
546 fdata->del_secs = fdata->abs_secs - lastsec;
547 if (lastusec <= fdata->abs_usecs) {
548 fdata->del_usecs = fdata->abs_usecs - lastusec;
550 fdata->del_usecs = (fdata->abs_usecs + 1000000) - lastusec;
553 lastsec = fdata->abs_secs;
554 lastusec = fdata->abs_usecs;
558 change_time_format_in_packet_list(frame_data *fdata, capture_file *cf)
562 /* XXX - there really should be a way of checking "cf->cinfo" for this;
563 the answer isn't going to change from packet to packet, so we should
564 simply skip all the "change_time_formats()" work if we're not
565 changing anything. */
566 fdata->cinfo = &cf->cinfo;
567 if (!check_col(fdata, COL_CLS_TIME)) {
568 /* There are no columns that show the time in the "command-line-specified"
569 format, so there's nothing we need to do. */
573 compute_time_stamps(fdata, cf);
575 for (i = 0; i < fdata->cinfo->num_cols; i++) {
576 fdata->cinfo->col_data[i][0] = '\0';
578 col_add_cls_time(fdata);
579 for (i = 0; i < fdata->cinfo->num_cols; i++) {
580 if (fdata->cinfo->fmt_matx[i][COL_CLS_TIME]) {
581 /* This is one of the columns that shows the time in
582 "command-line-specified" format; update it. */
583 col_width = gdk_string_width(pl_style->font, fdata->cinfo->col_data[i]);
584 if (col_width > fdata->cinfo->col_width[i])
585 fdata->cinfo->col_width[i] = col_width;
586 gtk_clist_set_text(GTK_CLIST(packet_list), cf->count - 1, i,
587 fdata->cinfo->col_data[i]);
594 add_packet_to_packet_list(frame_data *fdata, capture_file *cf, const u_char *buf)
596 gint i, row, col_width;
598 compute_time_stamps(fdata, cf);
600 fdata->cinfo = &cf->cinfo;
601 for (i = 0; i < fdata->cinfo->num_cols; i++) {
602 fdata->cinfo->col_data[i][0] = '\0';
604 if (check_col(fdata, COL_NUMBER))
605 col_add_fstr(fdata, COL_NUMBER, "%d", cf->count);
606 dissect_packet(buf, fdata, NULL);
607 for (i = 0; i < fdata->cinfo->num_cols; i++) {
608 col_width = gdk_string_width(pl_style->font, fdata->cinfo->col_data[i]);
609 if (col_width > fdata->cinfo->col_width[i])
610 fdata->cinfo->col_width[i] = col_width;
612 row = gtk_clist_append(GTK_CLIST(packet_list), fdata->cinfo->col_data);
618 wtap_dispatch_cb(u_char *user, const struct wtap_pkthdr *phdr, int offset,
620 pcap_dispatch_cb(u_char *user, const struct pcap_pkthdr *phdr,
624 capture_file *cf = (capture_file *) user;
626 while (gtk_events_pending())
627 gtk_main_iteration();
629 /* Allocate the next list entry, and add it to the list. */
630 fdata = (frame_data *) g_malloc(sizeof(frame_data));
631 cf->plist = g_list_append(cf->plist, (gpointer) fdata);
636 fdata->pkt_len = phdr->len;
637 fdata->cap_len = phdr->caplen;
639 fdata->file_off = offset;
640 fdata->lnk_t = phdr->pkt_encap;
642 fdata->file_off = ftell(pcap_file(cf->pfh)) - phdr->caplen;
644 fdata->abs_secs = phdr->ts.tv_sec;
645 fdata->abs_usecs = phdr->ts.tv_usec;
647 add_packet_to_packet_list(fdata, cf, buf);
651 filter_packets_cb(gpointer data, gpointer user_data)
653 frame_data *fd = data;
654 capture_file *cf = user_data;
659 fseek(cf->fh, fd->file_off, SEEK_SET);
660 fread(cf->pd, sizeof(guint8), fd->cap_len, cf->fh);
662 add_packet_to_packet_list(fd, cf, cf->pd);
666 filter_packets(capture_file *cf)
668 /* Freeze the packet list while we redo it, so we don't get any
669 screen updates while it happens. */
670 gtk_clist_freeze(GTK_CLIST(packet_list));
673 gtk_clist_clear(GTK_CLIST(packet_list));
676 * Iterate through the list of packets, calling a routine
677 * to run the filter on the packet, see if it matches, and
678 * put it in the display list if so.
680 * XXX - we don't yet have anything to run a filter on a packet;
681 * this code awaits the arrival of display filter code.
688 g_list_foreach(cf->plist, filter_packets_cb, cf);
690 /* Unfreeze the packet list. */
691 gtk_clist_thaw(GTK_CLIST(packet_list));
695 change_time_formats_cb(gpointer data, gpointer user_data)
697 frame_data *fd = data;
698 capture_file *cf = user_data;
703 change_time_format_in_packet_list(fd, cf);
706 /* Scan through the packet list and change all columns that use the
707 "command-line-specified" time stamp format to use the current
708 value of that format. */
710 change_time_formats(capture_file *cf)
714 /* Freeze the packet list while we redo it, so we don't get any
715 screen updates while it happens. */
716 gtk_clist_freeze(GTK_CLIST(packet_list));
718 /* Zero out the column widths. */
722 * Iterate through the list of packets, calling a routine
723 * to run the filter on the packet, see if it matches, and
724 * put it in the display list if so.
731 g_list_foreach(cf->plist, change_time_formats_cb, cf);
733 /* Set the column widths of those columns that show the time in
734 "command-line-specified" format. */
735 for (i = 0; i < cf->cinfo.num_cols; i++) {
736 if (cf->cinfo.fmt_matx[i][COL_CLS_TIME]) {
737 gtk_clist_set_column_width(GTK_CLIST(packet_list), i,
738 cf->cinfo.col_width[i]);
742 /* Unfreeze the packet list. */
743 gtk_clist_thaw(GTK_CLIST(packet_list));
746 /* Initialize the maximum widths of the columns to the widths of their
749 init_col_widths(capture_file *cf)
753 /* XXX - this should use the column *title* font, not the font for
754 the items in the list.
756 Unfortunately, it's not clear how to get that font - it'd be
757 the font used for buttons; there doesn't seem to be a way to get
758 that from a clist, or to get one of the buttons in that clist from
759 the clist in order to get its font. */
760 for (i = 0; i < cf->cinfo.num_cols; i++)
761 cf->cinfo.col_width[i] = gdk_string_width(pl_style->font,
762 cf->cinfo.col_title[i]);
765 /* Set the widths of the columns to the maximum widths we found. */
767 set_col_widths(capture_file *cf)
771 for (i = 0; i < cf->cinfo.num_cols; i++) {
772 gtk_clist_set_column_width(GTK_CLIST(packet_list), i,
773 cf->cinfo.col_width[i]);
777 /* Tries to mv a file. If unsuccessful, tries to cp the file.
778 * Returns 0 on failure to do either, 1 on success of either
781 file_mv(char *from, char *to)
784 #define COPY_BUFFER_SIZE 8192
788 /* try a hard link */
789 retval = link(from, to);
793 retval = file_cp(from, to);
804 * Returns 0 on failure to do either, 1 on success of either
807 file_cp(char *from, char *to)
810 #define COPY_BUFFER_SIZE 8192
812 int from_fd, to_fd, nread, nwritten;
814 gint dialogue_button = ESD_BTN_OK;
816 buffer = g_malloc(COPY_BUFFER_SIZE);
818 from_fd = open(from, O_RDONLY);
820 simple_dialog(ESD_TYPE_WARN, &dialogue_button,
821 file_open_error_message(errno, TRUE), from);
825 to_fd = creat(to, 0644);
827 simple_dialog(ESD_TYPE_WARN, &dialogue_button,
828 file_open_error_message(errno, TRUE), to);
833 while( (nread = read(from_fd, buffer, COPY_BUFFER_SIZE)) > 0) {
834 nwritten = write(to_fd, buffer, nread);
835 if (nwritten < nread) {
837 simple_dialog(ESD_TYPE_WARN, &dialogue_button,
838 file_write_error_message(errno), to);
840 simple_dialog(ESD_TYPE_WARN, &dialogue_button,
841 "The file \"%s\" could not be saved: tried writing %d, wrote %d.\n",
842 to, nread, nwritten);
850 simple_dialog(ESD_TYPE_WARN, &dialogue_button,
851 file_read_error_message(errno), from);
863 file_open_error_message(int err, int for_writing)
866 static char errmsg_errno[1024+1];
870 case OPEN_CAP_FILE_NOT_REGULAR:
871 errmsg = "The file \"%s\" is invalid.";
874 case OPEN_CAP_FILE_UNKNOWN_FORMAT:
875 errmsg = "The file \"%s\" is not a capture file in a format Ethereal understands.";
880 errmsg = "The path to the file \"%s\" does not exist.";
882 errmsg = "The file \"%s\" does not exist.";
887 errmsg = "You do not have permission to create or write to the file \"%s\".";
889 errmsg = "You do not have permission to open the file \"%s\".";
893 sprintf(errmsg_errno, "The file \"%%s\" could not be opened: %s.", strerror(err));
894 errmsg = errmsg_errno;
901 file_read_error_message(int err)
903 static char errmsg_errno[1024+1];
905 sprintf(errmsg_errno, "An error occurred while reading from the file \"%%s\": %s.", strerror(err));
910 file_write_error_message(int err)
913 static char errmsg_errno[1024+1];
918 errmsg = "The file \"%s\" could not be saved because there is no space left on the file system.";
923 errmsg = "The file \"%s\" could not be saved because you are too close to, or over, your disk quota.";
928 sprintf(errmsg_errno, "An error occurred while writing to the file \"%%s\": %s.", strerror(err));
929 errmsg = errmsg_errno;