Make "merge_files()" and "merge_append_files()" return a tri-state

indication - success, read failure, write failure - and have their
callers handle read failures by looking for the file that got the read
failure and reporting the failure in question.

Free up the err_info string returned by "wtap_read()" after using it.

svn path=/trunk/; revision=12423
This commit is contained in:
Guy Harris 2004-10-28 01:52:05 +00:00
parent dc2280bc1e
commit 66e85e4e43
4 changed files with 145 additions and 45 deletions

83
file.c
View File

@ -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

36
merge.c
View File

@ -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;
}

19
merge.h
View File

@ -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);

View File

@ -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;
}