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:
parent
dc2280bc1e
commit
66e85e4e43
83
file.c
83
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
|
||||
|
36
merge.c
36
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;
|
||||
}
|
||||
|
19
merge.h
19
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);
|
||||
|
||||
|
52
mergecap.c
52
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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user