#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pcap.h>
#include <err.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>

int
main(int argc, char *argv[])
{
    pcap_t *in = NULL;
    pcap_dumper_t *out = NULL;
    char errbuf[PCAP_ERRBUF_SIZE + 1];
    struct pcap_pkthdr hdr;
    const u_char *data;
    int i;
    char fifoname[256];

    if (argc < 2) {
	fprintf(stderr, "usage: tcpdump-join pcapfiles ...");
	exit(1);
    }
    for (i = 1; i < argc; i++) {
	char *inname = argv[i];
	fifoname[0] = '\0';
	int waitstatus;
	if (0 == strcmp(inname+strlen(inname)-3, ".gz")) {
		snprintf(fifoname, 256, "/tmp/fifo.%d.%d", getpid(), i);
		mkfifo(fifoname, 0600);
		if (0 == fork()) {
			close(1);
			open(fifoname, O_WRONLY);
			execl("/usr/bin/gzip", "/usr/bin/gzip", "-dc", inname, NULL);
			perror("gzip");
			abort();
		}
		inname = fifoname;
	}
	in = pcap_open_offline(inname, errbuf);
	if (fifoname[0])
		unlink(fifoname);
	if (NULL == in) {
	    fprintf(stderr, "%s: %s", argv[i], errbuf);
	    exit(1);
	}
	while ((data = pcap_next(in, &hdr))) {
	    if (!out) {
		out = pcap_dump_open(in, "-");
		if (NULL == out) {
		    perror("stdout");
		    exit(1);
		}
	    }
	    pcap_dump((void *)out, &hdr, data);
	}
	pcap_close(in);
	waitpid(-1, &waitstatus, 0);
    }
    if (out)
	pcap_dump_close(out);
    exit(0);
}
