diff --git a/file.c b/file.c index f54a520e76..4e3149cbbb 100644 --- a/file.c +++ b/file.c @@ -493,11 +493,12 @@ cf_read(capture_file *cf) snprintf(errmsg_errno, sizeof(errmsg_errno), "The capture file has a packet with a network type that Ethereal doesn't support.\n(%s)", err_info); + g_free(err_info); errmsg = errmsg_errno; break; case WTAP_ERR_CANT_READ: - errmsg = "An attempt to read from the file failed for" + errmsg = "An attempt to read from the capture file failed for" " some unknown reason."; break; @@ -510,6 +511,7 @@ cf_read(capture_file *cf) snprintf(errmsg_errno, sizeof(errmsg_errno), "The capture file appears to be damaged or corrupt.\n(%s)", err_info); + g_free(err_info); errmsg = errmsg_errno; break; @@ -977,7 +979,11 @@ cf_merge_files(const char *out_filename, int out_fd, int in_file_count, int err, close_err; gchar *err_info; int err_fileno; - gboolean ret; + merge_status_e status; + int i; + char errmsg_errno[1024+1]; + gchar err_str[2048+1]; + char *errmsg; /* open the input files */ if (!merge_open_in_files(in_file_count, in_filenames, &in_files, @@ -998,19 +1004,76 @@ cf_merge_files(const char *out_filename, int out_fd, int in_file_count, /* do the merge (or append) */ if (do_append) - ret = merge_append_files(in_file_count, in_files, &out_file, &err); + status = merge_append_files(in_file_count, in_files, &out_file, &err); else - ret = merge_files(in_file_count, in_files, &out_file, &err); + status = merge_files(in_file_count, in_files, &out_file, &err); merge_close_in_files(in_file_count, in_files); - if (ret) - ret = merge_close_outfile(&out_file, &err); - else - merge_close_outfile(&out_file, &close_err); + if (status == MERGE_SUCCESS) { + if (!merge_close_outfile(&out_file, &err)) + status = MERGE_WRITE_ERROR; + } else + merge_close_outfile(&out_file, &close_err); - if (!ret) + switch (status) { + + case MERGE_SUCCESS: + break; + + case MERGE_READ_ERROR: + /* + * Find the file on which we got the error, and report the error. + */ + for (i = 0; i < in_file_count; i++) { + if (!in_files[i].ok) { + /* Put up a message box noting that the read failed somewhere along + the line. */ + switch (err) { + + case WTAP_ERR_UNSUPPORTED_ENCAP: + snprintf(errmsg_errno, sizeof(errmsg_errno), + "The capture file %%s has a packet with a network type that Ethereal doesn't support.\n(%s)", + err_info); + g_free(err_info); + errmsg = errmsg_errno; + break; + + case WTAP_ERR_CANT_READ: + errmsg = "An attempt to read from the capture file %s failed for" + " some unknown reason."; + break; + + case WTAP_ERR_SHORT_READ: + errmsg = "The capture file %s appears to have been cut short" + " in the middle of a packet."; + break; + + case WTAP_ERR_BAD_RECORD: + snprintf(errmsg_errno, sizeof(errmsg_errno), + "The capture file %%sappears to be damaged or corrupt.\n(%s)", + err_info); + g_free(err_info); + errmsg = errmsg_errno; + break; + + default: + snprintf(errmsg_errno, sizeof(errmsg_errno), + "An error occurred while reading the" + " capture file %%s: %s.", wtap_strerror(err)); + errmsg = errmsg_errno; + break; + } + snprintf(err_str, sizeof err_str, errmsg, in_files[i].filename); + simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, err_str); + } + } + break; + + case MERGE_WRITE_ERROR: cf_write_failure_alert_box(out_filename, err); - return ret; + break; + } + return (status == MERGE_SUCCESS); } gboolean diff --git a/merge.c b/merge.c index 5d5f88298b..81f2a78ec2 100644 --- a/merge.c +++ b/merge.c @@ -217,7 +217,7 @@ earliest(int count, merge_in_file_t in_files[]) { /* * actually merge the files */ -gboolean +merge_status_e merge_files(int count, merge_in_file_t in_files[], merge_out_file_t *out_file, int *err) { int i; @@ -227,10 +227,8 @@ merge_files(int count, merge_in_file_t in_files[], merge_out_file_t *out_file, i in_files[i].ok = wtap_read(in_files[i].wth, &(in_files[i].err), &(in_files[i].err_info), &(in_files[i].data_offset)); - if (!in_files[i].ok) { - /* Read failure, not write failure. */ - return TRUE; - } + if (!in_files[i].ok) + return MERGE_READ_ERROR; } /* now keep writing the earliest frame until we're out of frames */ @@ -240,20 +238,18 @@ merge_files(int count, merge_in_file_t in_files[], merge_out_file_t *out_file, i * input file */ if(!write_frame(in_files[i].wth, out_file, err)) - return FALSE; + return MERGE_WRITE_ERROR; in_files[i].ok = wtap_read(in_files[i].wth, &(in_files[i].err), &(in_files[i].err_info), &(in_files[i].data_offset)); - if (!in_files[i].ok) { - /* Read failure, not write failure. */ - return TRUE; - } + if (!in_files[i].ok) + return MERGE_READ_ERROR; } - return TRUE; + return MERGE_SUCCESS; } -static gboolean +static merge_status_e append_loop(merge_in_file_t in_files[], int i, int count, merge_out_file_t *out_file, int *err) { @@ -266,33 +262,35 @@ append_loop(merge_in_file_t in_files[], int i, int count, while ( (wtap_read(in_files[i].wth, err, &err_info, &data_offset)) ) { if(!write_frame(in_files[i].wth, out_file, err)) - return FALSE; /* failure */ + return MERGE_WRITE_ERROR; if (count > 0 && ++loop >= count) break; } if (*err != 0) { - /* Read failure, not write failure. */ in_files[i].ok = FALSE; in_files[i].err = *err; in_files[i].err_info = err_info; + return MERGE_READ_ERROR; } - return TRUE; + return MERGE_SUCCESS; } /* * routine to concatenate files */ -gboolean +merge_status_e merge_append_files(int count, merge_in_file_t in_files[], merge_out_file_t *out_file, int *err) { int i; + merge_status_e status; for (i = 0; i < count; i++) { - if (!append_loop(in_files, i, 0, out_file, err)) - return FALSE; + status = append_loop(in_files, i, 0, out_file, err); + if (status != MERGE_SUCCESS) + return status; } - return TRUE; + return MERGE_SUCCESS; } diff --git a/merge.h b/merge.h index e48942c071..fe7bf296e6 100644 --- a/merge.h +++ b/merge.h @@ -114,15 +114,25 @@ merge_select_frame_type(int in_file_count, merge_in_file_t in_files[]); extern int merge_max_snapshot_length(int in_file_count, merge_in_file_t in_files[]); +/* + * Status from the merge-files routines. + */ +typedef enum { + MERGE_SUCCESS, + MERGE_READ_ERROR, + MERGE_WRITE_ERROR +} merge_status_e; + /** Merge the packets from the input files into the output file sorted chronologically. * * @param in_file_count number of entries in in_files * @param in_files input file array * @param out_file the output file array * @param err wiretap error, if failed - * @return TRUE on success or read failure, FALSE on write failure + * @return MERGE_SUCCESS on success, MERGE_READ_ERROR on read error, + * MERGE_WRITE_ERROR on write error */ -extern gboolean +extern merge_status_e merge_files(int in_file_count, merge_in_file_t in_files[], merge_out_file_t *out_file, int *err); /** Append the packets from the input files into the output file. @@ -131,9 +141,10 @@ merge_files(int in_file_count, merge_in_file_t in_files[], merge_out_file_t *out * @param in_files input file array * @param out_file the output file array * @param err wiretap error, if failed - * @return TRUE on success or read failure, FALSE on write failure + * @return MERGE_SUCCESS on success, MERGE_READ_ERROR on read error, + * MERGE_WRITE_ERROR on write error */ -extern gboolean +extern merge_status_e merge_append_files(int in_file_count, merge_in_file_t in_files[], merge_out_file_t *out_file, int *err); diff --git a/mergecap.c b/mergecap.c index 74c41a7918..19116a42ee 100644 --- a/mergecap.c +++ b/mergecap.c @@ -142,7 +142,7 @@ main(int argc, char *argv[]) gchar *err_info; int err_fileno; char *out_filename = NULL; - gboolean ret; + merge_status_e status; /* Process the options first */ while ((opt = getopt(argc, argv, "hvas:T:F:w:")) != -1) { @@ -194,7 +194,7 @@ main(int argc, char *argv[]) case '?': /* Bad options if GNU getopt */ usage(); - exit(1); + return 1; break; } @@ -208,11 +208,11 @@ main(int argc, char *argv[]) if (!out_filename) { fprintf(stderr, "mergecap: an output filename must be set with -w\n"); fprintf(stderr, " run with -h for help\n"); - exit(1); + return 1; } if (in_file_count < 1) { fprintf(stderr, "mergecap: No input files were specified\n"); - exit(1); + return 1; } /* open the input files */ @@ -229,7 +229,7 @@ main(int argc, char *argv[]) g_free(err_info); break; } - exit(1); + return 2; } if (verbose) { @@ -309,21 +309,49 @@ main(int argc, char *argv[]) /* do the merge (or append) */ if (do_append) - ret = merge_append_files(in_file_count, in_files, &out_file, &err); + status = merge_append_files(in_file_count, in_files, &out_file, &err); else - ret = merge_files(in_file_count, in_files, &out_file, &err); + status = merge_files(in_file_count, in_files, &out_file, &err); merge_close_in_files(in_file_count, in_files); - if (ret) - ret = merge_close_outfile(&out_file, &err); - else + if (status == MERGE_SUCCESS) { + if (!merge_close_outfile(&out_file, &err)) + status = MERGE_WRITE_ERROR; + } else merge_close_outfile(&out_file, &close_err); - if (!ret) { + switch (status) { + + case MERGE_SUCCESS: + break; + + case MERGE_READ_ERROR: + /* + * Find the file on which we got the error, and report the error. + */ + for (i = 0; i < in_file_count; i++) { + if (!in_files[i].ok) { + fprintf(stderr, "mergecap: Error reading %s: %s\n", + in_files[i].filename, wtap_strerror(in_files[i].err)); + switch (err) { + + case WTAP_ERR_UNSUPPORTED: + case WTAP_ERR_UNSUPPORTED_ENCAP: + case WTAP_ERR_BAD_RECORD: + fprintf(stderr, "(%s)\n", in_files[i].err_info); + g_free(in_files[i].err_info); + break; + } + } + } + break; + + case MERGE_WRITE_ERROR: fprintf(stderr, "mergecap: Error writing to outfile: %s\n", wtap_strerror(err)); + break; } free(in_files); - return ret ? 0 : 2; + return (status == MERGE_SUCCESS) ? 0 : 2; }