#include "wtap.h"
-#ifdef NEED_GETOPT_H
-#include "getopt.h"
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#else
+#include "wsgetopt.h"
#endif
#ifdef _WIN32
static int find_dct2000_real_data(guint8 *buf);
+static gchar *
+abs_time_to_str_with_sec_resolution(const struct wtap_nstime *abs_time)
+{
+ struct tm *tmp;
+ gchar *buf = g_malloc(16);
+
+#ifdef _MSC_VER
+ /* calling localtime() on MSVC 2005 with huge values causes it to crash */
+ /* XXX - find the exact value that still does work */
+ /* XXX - using _USE_32BIT_TIME_T might be another way to circumvent this problem */
+ if(abs_time->secs > 2000000000) {
+ tmp = NULL;
+ } else
+#endif
+ tmp = localtime(&abs_time->secs);
+ if (tmp) {
+ g_snprintf(buf, 16, "%d%02d%02d%02d%02d%02d",
+ tmp->tm_year + 1900,
+ tmp->tm_mon+1,
+ tmp->tm_mday,
+ tmp->tm_hour,
+ tmp->tm_min,
+ tmp->tm_sec);
+ } else
+ strcpy(buf, "");
+
+ return buf;
+}
+
+static gchar*
+fileset_get_filename_by_pattern(guint idx, const struct wtap_nstime *time_val,
+ gchar *fprefix, gchar *fsuffix)
+{
+ gchar filenum[5+1];
+ gchar *timestr;
+ gchar *abs_str;
+
+ timestr = abs_time_to_str_with_sec_resolution(time_val);
+ g_snprintf(filenum, sizeof(filenum), "%05u", idx);
+ abs_str = g_strconcat(fprefix, "_", filenum, "_", timestr, fsuffix, NULL);
+ g_free(timestr);
+
+ return abs_str;
+}
+
+static gboolean
+fileset_extract_prefix_suffix(const char *fname, gchar **fprefix, gchar **fsuffix)
+{
+ char *pfx, *last_pathsep;
+ gchar *save_file;
+
+ save_file = g_strdup(fname);
+ if (save_file == NULL) {
+ fprintf(stderr, "editcap: Out of memory\n");
+ return FALSE;
+ }
+
+ last_pathsep = strrchr(save_file, G_DIR_SEPARATOR);
+ pfx = strrchr(save_file,'.');
+ if (pfx != NULL && (last_pathsep == NULL || pfx > last_pathsep)) {
+ /* The pathname has a "." in it, and it's in the last component
+ of the pathname (because there is either only one component,
+ i.e. last_pathsep is null as there are no path separators,
+ or the "." is after the path separator before the last
+ component.
+
+ Treat it as a separator between the rest of the file name and
+ the file name suffix, and arrange that the names given to the
+ ring buffer files have the specified suffix, i.e. put the
+ changing part of the name *before* the suffix. */
+ pfx[0] = '\0';
+ *fprefix = g_strdup(save_file);
+ pfx[0] = '.'; /* restore capfile_name */
+ *fsuffix = g_strdup(pfx);
+ } else {
+ /* Either there's no "." in the pathname, or it's in a directory
+ component, so the last component has no suffix. */
+ *fprefix = g_strdup(save_file);
+ *fsuffix = NULL;
+ }
+ g_free(save_file);
+ return TRUE;
+}
+
/* Add a selection item, a simple parser for now */
static gboolean
add_selection(char *sel)
}
static void
-set_time_adjustment(char *optarg)
+set_time_adjustment(char *optarg_str_p)
{
char *frac, *end;
long val;
size_t frac_digits;
- if (!optarg)
+ if (!optarg_str_p)
return;
/* skip leading whitespace */
- while (*optarg == ' ' || *optarg == '\t') {
- optarg++;
+ while (*optarg_str_p == ' ' || *optarg_str_p == '\t') {
+ optarg_str_p++;
}
/* check for a negative adjustment */
- if (*optarg == '-') {
+ if (*optarg_str_p == '-') {
time_adj.is_negative = 1;
- optarg++;
+ optarg_str_p++;
}
/* collect whole number of seconds, if any */
- if (*optarg == '.') { /* only fractional (i.e., .5 is ok) */
+ if (*optarg_str_p == '.') { /* only fractional (i.e., .5 is ok) */
val = 0;
- frac = optarg;
+ frac = optarg_str_p;
} else {
- val = strtol(optarg, &frac, 10);
- if (frac == NULL || frac == optarg || val == LONG_MIN || val == LONG_MAX) {
+ val = strtol(optarg_str_p, &frac, 10);
+ if (frac == NULL || frac == optarg_str_p || val == LONG_MIN || val == LONG_MAX) {
fprintf(stderr, "editcap: \"%s\" isn't a valid time adjustment\n",
- optarg);
+ optarg_str_p);
exit(1);
}
if (val < 0) { /* implies '--' since we caught '-' above */
fprintf(stderr, "editcap: \"%s\" isn't a valid time adjustment\n",
- optarg);
+ optarg_str_p);
exit(1);
}
}
/* now collect the partial seconds, if any */
if (*frac != '\0') { /* chars left, so get fractional part */
val = strtol(&(frac[1]), &end, 10);
+ /* if more than 6 fractional digits truncate to 6 */
+ if((end - &(frac[1])) > 6) {
+ frac[7] = 't'; /* 't' for truncate */
+ val = strtol(&(frac[1]), &end, 10);
+ }
if (*frac != '.' || end == NULL || end == frac
|| val < 0 || val > ONE_MILLION || val == LONG_MIN || val == LONG_MAX) {
fprintf(stderr, "editcap: \"%s\" isn't a valid time adjustment\n",
- optarg);
+ optarg_str_p);
exit(1);
}
}
}
static void
-set_rel_time(char *optarg)
+set_rel_time(char *optarg_str_p)
{
char *frac, *end;
long val;
- int frac_digits;
+ size_t frac_digits;
- if (!optarg)
+ if (!optarg_str_p)
return;
/* skip leading whitespace */
- while (*optarg == ' ' || *optarg == '\t') {
- optarg++;
+ while (*optarg_str_p == ' ' || *optarg_str_p == '\t') {
+ optarg_str_p++;
}
/* ignore negative adjustment */
- if (*optarg == '-') {
- optarg++;
+ if (*optarg_str_p == '-') {
+ optarg_str_p++;
}
/* collect whole number of seconds, if any */
- if (*optarg == '.') { /* only fractional (i.e., .5 is ok) */
+ if (*optarg_str_p == '.') { /* only fractional (i.e., .5 is ok) */
val = 0;
- frac = optarg;
+ frac = optarg_str_p;
} else {
- val = strtol(optarg, &frac, 10);
- if (frac == NULL || frac == optarg || val == LONG_MIN || val == LONG_MAX) {
+ val = strtol(optarg_str_p, &frac, 10);
+ if (frac == NULL || frac == optarg_str_p || val == LONG_MIN || val == LONG_MAX) {
fprintf(stderr, "1: editcap: \"%s\" isn't a valid rel time value\n",
- optarg);
+ optarg_str_p);
exit(1);
}
if (val < 0) { /* implies '--' since we caught '-' above */
fprintf(stderr, "2: editcap: \"%s\" isn't a valid rel time value\n",
- optarg);
+ optarg_str_p);
exit(1);
}
}
/* now collect the partial seconds, if any */
if (*frac != '\0') { /* chars left, so get fractional part */
val = strtol(&(frac[1]), &end, 10);
+ /* if more than 9 fractional digits truncate to 9 */
+ if((end - &(frac[1])) > 9) {
+ frac[10] = 't'; /* 't' for truncate */
+ val = strtol(&(frac[1]), &end, 10);
+ }
if (*frac != '.' || end == NULL || end == frac
|| val < 0 || val > ONE_BILLION || val == LONG_MIN || val == LONG_MAX) {
fprintf(stderr, "3: editcap: \"%s\" isn't a valid rel time value\n",
- optarg);
+ optarg_str_p);
exit(1);
}
}
}
static void
-usage(void)
+usage(gboolean is_error)
{
- fprintf(stderr, "Editcap %s"
+ FILE *output;
+
+ if (!is_error)
+ output = stdout;
+ else
+ output = stderr;
+
+ fprintf(output, "Editcap %s"
#ifdef SVNVERSION
- " (" SVNVERSION ")"
+ " (" SVNVERSION " from " SVNPATH ")"
#endif
"\n", VERSION);
- fprintf(stderr, "Edit and/or translate the format of capture files.\n");
- fprintf(stderr, "See http://www.wireshark.org for more information.\n");
- fprintf(stderr, "\n");
- fprintf(stderr, "Usage: editcap [options] ... <infile> <outfile> [ <packet#>[-<packet#>] ... ]\n");
- fprintf(stderr, "\n");
- fprintf(stderr, "A single packet or a range of packets can be selected.\n");
- fprintf(stderr, "\n");
- fprintf(stderr, "Packet selection:\n");
- fprintf(stderr, " -r keep the selected packets, default is to delete them\n");
- fprintf(stderr, " -A <start time> don't output packets whose timestamp is before the\n");
- fprintf(stderr, " given time (format as YYYY-MM-DD hh:mm:ss)\n");
- fprintf(stderr, " -B <stop time> don't output packets whose timestamp is after the\n");
- fprintf(stderr, " given time (format as YYYY-MM-DD hh:mm:ss)\n");
- fprintf(stderr, "\n");
- fprintf(stderr, "Duplicate packet removal:\n");
- fprintf(stderr, " -d remove packet if duplicate (window == %d).\n", DEFAULT_DUP_DEPTH);
- fprintf(stderr, " -D <dup window> remove packet if duplicate, configurable <dup window>.\n");
- fprintf(stderr, " Valid <dup window> values are 0 to %d.\n", MAX_DUP_DEPTH);
- fprintf(stderr, " NOTE: A <dup window> of 0 with -v (verbose option) is\n");
- fprintf(stderr, " useful to print MD5 hashes.\n");
- fprintf(stderr, " -w <dup time window> remove packet if duplicate packet is found EQUAL TO OR\n");
- fprintf(stderr, " LESS THAN <dup time window> prior to current packet.\n");
- fprintf(stderr, " A <dup time window> is specified in relative seconds\n");
- fprintf(stderr, " (e.g. 0.000001)\n");
- fprintf(stderr, "\n");
- fprintf(stderr, " NOTE: The use of the 'Duplicate packet removal' options with\n");
- fprintf(stderr, " other editcap options except -v may not always work as expected.\n");
- fprintf(stderr, " Specifically the -r and -t options will very likely NOT have the\n");
- fprintf(stderr, " desired effect if combined with the -d, -D or -w.\n");
- fprintf(stderr, "\n");
- fprintf(stderr, "Packet manipulation:\n");
- fprintf(stderr, " -s <snaplen> truncate each packet to max. <snaplen> bytes of data\n");
- fprintf(stderr, " -C <choplen> chop each packet at the end by <choplen> bytes\n");
- fprintf(stderr, " -t <time adjustment> adjust the timestamp of each packet,\n");
- fprintf(stderr, " <time adjustment> is in relative seconds (e.g. -0.5)\n");
- fprintf(stderr, " -E <error probability> set the probability (between 0.0 and 1.0 incl.)\n");
- fprintf(stderr, " that a particular packet byte will be randomly changed\n");
- fprintf(stderr, "\n");
- fprintf(stderr, "Output File(s):\n");
- fprintf(stderr, " -c <packets per file> split the packet output to different files,\n");
- fprintf(stderr, " based on uniform packet counts \n");
- fprintf(stderr, " with a maximum of <packets per file> each\n");
- fprintf(stderr, " -i <seconds per file> split the packet output to different files,\n");
- fprintf(stderr, " based on uniform time intervals \n");
- fprintf(stderr, " with a maximum of <seconds per file> each\n");
- fprintf(stderr, " -F <capture type> set the output file type, default is libpcap\n");
- fprintf(stderr, " an empty \"-F\" option will list the file types\n");
- fprintf(stderr, " -T <encap type> set the output file encapsulation type,\n");
- fprintf(stderr, " default is the same as the input file\n");
- fprintf(stderr, " an empty \"-T\" option will list the encapsulation types\n");
- fprintf(stderr, "\n");
- fprintf(stderr, "Miscellaneous:\n");
- fprintf(stderr, " -h display this help and exit\n");
- fprintf(stderr, " -v verbose output\n");
- fprintf(stderr, " If -v is used with any of the 'Duplicate Packet\n");
- fprintf(stderr, " Removal' options (-d, -D or -w) then Packet lengths\n");
- fprintf(stderr, " and MD5 hashes are printed to standard-out.\n");
- fprintf(stderr, "\n");
+ fprintf(output, "Edit and/or translate the format of capture files.\n");
+ fprintf(output, "See http://www.wireshark.org for more information.\n");
+ fprintf(output, "\n");
+ fprintf(output, "Usage: editcap [options] ... <infile> <outfile> [ <packet#>[-<packet#>] ... ]\n");
+ fprintf(output, "\n");
+ fprintf(output, "<infile> and <outfile> must both be present.\n");
+ fprintf(output, "A single packet or a range of packets can be selected.\n");
+ fprintf(output, "\n");
+ fprintf(output, "Packet selection:\n");
+ fprintf(output, " -r keep the selected packets; default is to delete them.\n");
+ fprintf(output, " -A <start time> don't output packets whose timestamp is before the\n");
+ fprintf(output, " given time (format as YYYY-MM-DD hh:mm:ss).\n");
+ fprintf(output, " -B <stop time> don't output packets whose timestamp is after the\n");
+ fprintf(output, " given time (format as YYYY-MM-DD hh:mm:ss).\n");
+ fprintf(output, "\n");
+ fprintf(output, "Duplicate packet removal:\n");
+ fprintf(output, " -d remove packet if duplicate (window == %d).\n", DEFAULT_DUP_DEPTH);
+ fprintf(output, " -D <dup window> remove packet if duplicate; configurable <dup window>\n");
+ fprintf(output, " Valid <dup window> values are 0 to %d.\n", MAX_DUP_DEPTH);
+ fprintf(output, " NOTE: A <dup window> of 0 with -v (verbose option) is\n");
+ fprintf(output, " useful to print MD5 hashes.\n");
+ fprintf(output, " -w <dup time window> remove packet if duplicate packet is found EQUAL TO OR\n");
+ fprintf(output, " LESS THAN <dup time window> prior to current packet.\n");
+ fprintf(output, " A <dup time window> is specified in relative seconds\n");
+ fprintf(output, " (e.g. 0.000001).\n");
+ fprintf(output, "\n");
+ fprintf(output, " NOTE: The use of the 'Duplicate packet removal' options with\n");
+ fprintf(output, " other editcap options except -v may not always work as expected.\n");
+ fprintf(output, " Specifically the -r and -t options will very likely NOT have the\n");
+ fprintf(output, " desired effect if combined with the -d, -D or -w.\n");
+ fprintf(output, "\n");
+ fprintf(output, "Packet manipulation:\n");
+ fprintf(output, " -s <snaplen> truncate each packet to max. <snaplen> bytes of data.\n");
+ fprintf(output, " -C <choplen> chop each packet at the end by <choplen> bytes.\n");
+ fprintf(output, " -t <time adjustment> adjust the timestamp of each packet;\n");
+ fprintf(output, " <time adjustment> is in relative seconds (e.g. -0.5).\n");
+ fprintf(output, " -E <error probability> set the probability (between 0.0 and 1.0 incl.)\n");
+ fprintf(output, " that a particular packet byte will be randomly changed.\n");
+ fprintf(output, "\n");
+ fprintf(output, "Output File(s):\n");
+ fprintf(output, " -c <packets per file> split the packet output to different files\n");
+ fprintf(output, " based on uniform packet counts\n");
+ fprintf(output, " with a maximum of <packets per file> each.\n");
+ fprintf(output, " -i <seconds per file> split the packet output to different files\n");
+ fprintf(output, " based on uniform time intervals\n");
+ fprintf(output, " with a maximum of <seconds per file> each.\n");
+ fprintf(output, " -F <capture type> set the output file type; default is libpcap.\n");
+ fprintf(output, " an empty \"-F\" option will list the file types.\n");
+ fprintf(output, " -T <encap type> set the output file encapsulation type;\n");
+ fprintf(output, " default is the same as the input file.\n");
+ fprintf(output, " an empty \"-T\" option will list the encapsulation types.\n");
+ fprintf(output, "\n");
+ fprintf(output, "Miscellaneous:\n");
+ fprintf(output, " -h display this help and exit.\n");
+ fprintf(output, " -v verbose output.\n");
+ fprintf(output, " If -v is used with any of the 'Duplicate Packet\n");
+ fprintf(output, " Removal' options (-d, -D or -w) then Packet lengths\n");
+ fprintf(output, " and MD5 hashes are printed to standard-out.\n");
+ fprintf(output, "\n");
}
static void
list_capture_types(void) {
int i;
- fprintf(stderr, "editcap: The available capture file types for \"F\":\n");
+ fprintf(stderr, "editcap: The available capture file types for the \"-F\" flag are:\n");
for (i = 0; i < WTAP_NUM_FILE_TYPES; i++) {
if (wtap_dump_can_open(i))
fprintf(stderr, " %s - %s\n",
int i;
const char *string;
- fprintf(stderr, "editcap: The available encapsulation types for \"T\":\n");
+ fprintf(stderr, "editcap: The available encapsulation types for the \"-T\" flag are:\n");
for (i = 0; i < WTAP_NUM_ENCAP_TYPES; i++) {
string = wtap_encap_short_string(i);
if (string != NULL)
wtap *wth;
int i, j, err;
gchar *err_info;
- extern char *optarg;
- extern int optind;
int opt;
char *p;
unsigned int snaplen = 0; /* No limit */
unsigned int choplen = 0; /* No chop */
- wtap_dumper *pdh;
+ wtap_dumper *pdh = NULL;
int count = 1;
unsigned duplicate_count = 0;
gint64 data_offset;
guint8 *buf;
int split_packet_count = 0;
int written_count = 0;
- char *filename;
- size_t filenamelen = 0;
+ char *filename = NULL;
gboolean check_ts;
int secs_per_block = 0;
int block_cnt = 0;
nstime_t block_start;
+ gchar *fprefix = NULL;
+ gchar *fsuffix = NULL;
#ifdef HAVE_PLUGINS
char* init_progfile_dir_error;
list_encap_types();
break;
default:
- usage();
+ usage(TRUE);
}
exit(1);
break;
case 'h':
- usage();
+ usage(FALSE);
exit(1);
break;
case 'i': /* break capture file based on time interval */
secs_per_block = atoi(optarg);
- nstime_set_unset(&block_start);
if(secs_per_block <= 0) {
fprintf(stderr, "editcap: \"%s\" isn't a valid time interval\n\n", optarg);
exit(1);
if ((argc - optind) < 1) {
- usage();
+ usage(TRUE);
exit(1);
}
stoptime = mktime(&stoptm);
}
+ nstime_set_unset(&block_start);
+
if (starttime > stoptime) {
fprintf(stderr, "editcap: start time is after the stop time\n");
exit(1);
g_free(err_info);
break;
}
- exit(1);
+ exit(2);
}
if (out_frame_type == -2)
out_frame_type = wtap_file_encap(wth);
- if (split_packet_count > 0) {
- filenamelen = strlen(argv[optind+1]) + 20;
- filename = (char *) g_malloc(filenamelen);
- if (!filename) {
- exit(5);
- }
- g_snprintf(filename, (gulong) filenamelen, "%s-%05d", argv[optind+1], 0);
- } else {
- if (secs_per_block > 0) {
- filenamelen = strlen(argv[optind+1]) + 7;
- filename = (char *) g_malloc(filenamelen);
- if (!filename) {
- exit(5);
- }
- g_snprintf(filename, (gulong) filenamelen, "%s-%05d", argv[optind+1], block_cnt);
- }
- else {
- filename = argv[optind+1];
- }
- }
-
- pdh = wtap_dump_open(filename, out_file_type,
- out_frame_type, wtap_snapshot_length(wth),
- FALSE /* compressed */, &err);
- if (pdh == NULL) {
-
- fprintf(stderr, "editcap: Can't open or create %s: %s\n", filename,
- wtap_strerror(err));
- exit(1);
- }
-
for (i = optind + 2; i < argc; i++)
if (add_selection(argv[i]) == FALSE)
break;
}
while (wtap_read(wth, &err, &err_info, &data_offset)) {
+ phdr = wtap_phdr(wth);
- if (secs_per_block > 0) {
- phdr = wtap_phdr(wth);
+ if (nstime_is_unset(&block_start)) { /* should only be the first packet */
+ block_start.secs = phdr->ts.secs;
+ block_start.nsecs = phdr->ts.nsecs;
- if (nstime_is_unset(&block_start)) { /* should only be the first packet */
- block_start.secs = phdr->ts.secs;
- block_start.nsecs = phdr->ts.nsecs;
- }
+ if (split_packet_count > 0 || secs_per_block > 0) {
+ if (!fileset_extract_prefix_suffix(argv[optind+1], &fprefix, &fsuffix))
+ exit(2);
- while ((phdr->ts.secs - block_start.secs > secs_per_block) ||
- (phdr->ts.secs - block_start.secs == secs_per_block &&
+ filename = fileset_get_filename_by_pattern(block_cnt++, &phdr->ts, fprefix, fsuffix);
+ } else
+ filename = g_strdup(argv[optind+1]);
+
+ pdh = wtap_dump_open(filename, out_file_type,
+ out_frame_type, wtap_snapshot_length(wth),
+ FALSE /* compressed */, &err);
+ if (pdh == NULL) {
+ fprintf(stderr, "editcap: Can't open or create %s: %s\n", filename,
+ wtap_strerror(err));
+ exit(2);
+ }
+ }
+
+ g_assert(filename);
+
+ if (secs_per_block > 0) {
+ while ((phdr->ts.secs - block_start.secs > secs_per_block) ||
+ (phdr->ts.secs - block_start.secs == secs_per_block &&
phdr->ts.nsecs >= block_start.nsecs )) { /* time for the next file */
if (!wtap_dump_close(pdh, &err)) {
fprintf(stderr, "editcap: Error writing to %s: %s\n", filename,
wtap_strerror(err));
- exit(1);
- }
+ exit(2);
+ }
block_start.secs = block_start.secs + secs_per_block; /* reset for next interval */
- g_snprintf(filename, (gulong) filenamelen, "%s-%05d",argv[optind+1], ++block_cnt);
+ g_free(filename);
+ filename = fileset_get_filename_by_pattern(block_cnt++, &phdr->ts, fprefix, fsuffix);
+ g_assert(filename);
if (verbose) {
fprintf(stderr, "Continuing writing in file %s\n", filename);
- }
+ }
pdh = wtap_dump_open(filename, out_file_type,
out_frame_type, wtap_snapshot_length(wth), FALSE /* compressed */, &err);
if (pdh == NULL) {
fprintf(stderr, "editcap: Can't open or create %s: %s\n", filename,
wtap_strerror(err));
- exit(1);
+ exit(2);
}
}
}
- if (split_packet_count > 0 && (written_count % split_packet_count == 0)) {
- if (!wtap_dump_close(pdh, &err)) {
+ if (split_packet_count > 0) {
- fprintf(stderr, "editcap: Error writing to %s: %s\n", filename,
- wtap_strerror(err));
- exit(1);
- }
+ /* time for the next file? */
+ if (written_count > 0 &&
+ written_count % split_packet_count == 0) {
+ if (!wtap_dump_close(pdh, &err)) {
+ fprintf(stderr, "editcap: Error writing to %s: %s\n", filename,
+ wtap_strerror(err));
+ exit(2);
+ }
- g_snprintf(filename, (gulong) filenamelen, "%s-%05d",argv[optind+1], count / split_packet_count);
+ g_free(filename);
+ filename = fileset_get_filename_by_pattern(block_cnt++, &phdr->ts, fprefix, fsuffix);
+ g_assert(filename);
- if (verbose) {
- fprintf(stderr, "Continuing writing in file %s\n", filename);
- }
-
- pdh = wtap_dump_open(filename, out_file_type,
- out_frame_type, wtap_snapshot_length(wth), FALSE /* compressed */, &err);
- if (pdh == NULL) {
+ if (verbose) {
+ fprintf(stderr, "Continuing writing in file %s\n", filename);
+ }
- fprintf(stderr, "editcap: Can't open or create %s: %s\n", filename,
- wtap_strerror(err));
- exit(1);
+ pdh = wtap_dump_open(filename, out_file_type,
+ out_frame_type, wtap_snapshot_length(wth), FALSE /* compressed */, &err);
+ if (pdh == NULL) {
+ fprintf(stderr, "editcap: Can't open or create %s: %s\n", filename,
+ wtap_strerror(err));
+ exit(2);
+ }
}
}
&err)) {
fprintf(stderr, "editcap: Error writing to %s: %s\n",
filename, wtap_strerror(err));
- exit(1);
+ exit(2);
}
written_count++;
}
count++;
}
+ g_free(fprefix);
+ g_free(fsuffix);
+
if (err != 0) {
/* Print a message noting that the read failed somewhere along the line. */
fprintf(stderr,
}
}
+ if (!pdh) {
+ /* No valid packages found, open the outfile so we can write an empty header */
+ g_free (filename);
+ filename = g_strdup(argv[optind+1]);
+
+ pdh = wtap_dump_open(filename, out_file_type,
+ out_frame_type, wtap_snapshot_length(wth), FALSE /* compressed */, &err);
+ if (pdh == NULL) {
+ fprintf(stderr, "editcap: Can't open or create %s: %s\n", filename,
+ wtap_strerror(err));
+ exit(2);
+ }
+ }
+
if (!wtap_dump_close(pdh, &err)) {
fprintf(stderr, "editcap: Error writing to %s: %s\n", filename,
wtap_strerror(err));
- exit(1);
+ exit(2);
}
+ g_free(filename);
}
if (dup_detect) {