--- libpcap-2004.05.20/pcap-int.h Wed Apr 07 20:41:00 2004 +++ pcap-int.h Thu May 27 16:51:35 2004 @@ -111,6 +111,7 @@ int offset; /* offset for proper alignment */ int break_loop; /* flag set to force break from packet-reading loop */ + long filemode; /* previous translation mode for stdin/stdout */ struct pcap_sf sf; struct pcap_md md; --- libpcap-2004.05.20/savefile.c Tue Mar 23 21:18:08 2004 +++ savefile.c Thu May 27 17:04:24 2004 @@ -52,6 +52,12 @@ #define TCPDUMP_MAGIC 0xa1b2c3d4 #define PATCHED_TCPDUMP_MAGIC 0xa1b2cd34 +#if defined(WIN32) || defined(MSDOS) +#define SETMODE(file,mode) setmode(file,mode) +#else +#define SETMODE(file,mode) (-1) +#endif + /* * We use the "receiver-makes-right" approach to byte order, * because time is at a premium when we are writing the file. @@ -515,6 +521,20 @@ return linktype; } +/* + * Close dump/save-file or restore old translation mode of stdin/stdout. + */ +static int +file_close(FILE *fil, long filemode) +{ + if (fil != stdin && fil != stdout) + return fclose (fil); + + (void) SETMODE (fileno(fil), filemode > -1L ? filemode : O_TEXT); + return (0); +} + + static int sf_write_header(FILE *fp, int linktype, int thiszone, int snaplen) { @@ -585,8 +605,7 @@ static void sf_close(pcap_t *p) { - if (p->sf.rfile != stdin) - (void)fclose(p->sf.rfile); + file_close(p->sf.rfile, p->filemode); if (p->sf.base != NULL) free(p->sf.base); } @@ -602,20 +621,18 @@ p = (pcap_t *)malloc(sizeof(*p)); if (p == NULL) { - strlcpy(errbuf, "out of swap", PCAP_ERRBUF_SIZE); + strlcpy(errbuf, "out of memory", PCAP_ERRBUF_SIZE); return (NULL); } memset((char *)p, 0, sizeof(*p)); - - if (fname[0] == '-' && fname[1] == '\0') + if (fname[0] == '-' && fname[1] == '\0') { fp = stdin; + p->filemode = SETMODE(fileno(fp), O_BINARY); + } else { -#ifndef WIN32 - fp = fopen(fname, "r"); -#else + p->filemode = -1L; /* Always binary, but we don't need this */ fp = fopen(fname, "rb"); -#endif if (fp == NULL) { snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", fname, pcap_strerror(errno)); @@ -726,13 +743,15 @@ break; } -#ifndef WIN32 +#if !defined(WIN32) && !defined(MSDOS) /* * You can do "select()" and "poll()" on plain files on most * platforms, and should be able to do so on pipes. * * You can't do "select()" on anything other than sockets in * Windows, so, on Win32 systems, we don't have "selectable_fd". + * But one could use 'WaitForSingleObject()' on HANDLE obtained + * from '_get_osfhandle(p->selectable_fd)'. */ p->selectable_fd = fileno(fp); #endif @@ -749,7 +768,7 @@ return (p); bad: if(fp) - fclose(fp); + file_close(fp, p->filemode); free(p); return (NULL); } @@ -985,26 +1004,22 @@ if (fname[0] == '-' && fname[1] == '\0') { f = stdout; -#ifdef WIN32 - _setmode(_fileno(f), _O_BINARY); -#endif + p->filemode = SETMODE(fileno(f), O_BINARY); } else { -#ifndef WIN32 - f = fopen(fname, "w"); -#else + p->filemode = -1L; f = fopen(fname, "wb"); -#endif - if (f == NULL) { + /* setbuf(f, NULL); */ /* XXX - why? */ + } + + if (!f || sf_write_header(f, linktype, p->tzoff, p->snapshot) < 0) { snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s", fname, pcap_strerror(errno)); - return (NULL); - } -#ifdef WIN32 - setbuf(f, NULL); /* XXX - why? */ -#endif + if (f) + file_close(f, p->filemode); + p->filemode = -1L; + f = NULL; } - (void)sf_write_header(f, linktype, p->tzoff, p->snapshot); - return ((pcap_dumper_t *)f); + return (pcap_dumper_t*)f; } FILE * @@ -1026,11 +1041,13 @@ void pcap_dump_close(pcap_dumper_t *p) { + FILE *fil = (FILE*)p; #ifdef notyet - if (ferror((FILE *)p)) + if (ferror(fil)) return-an-error; /* XXX should check return from fclose() too */ #endif - (void)fclose((FILE *)p); + /* We don't know the old stdout mode. Guess it was O_TEXT. */ + file_close(fil, O_TEXT); }