4 * $Id: util.c,v 1.54 2001/11/09 07:44:48 guy Exp $
6 * Ethereal - Network traffic analyzer
7 * By Gerald Combs <gerald@ethereal.com>
8 * Copyright 1998 Gerald Combs
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
40 #ifdef HAVE_SYS_TYPES_H
41 #include <sys/types.h>
44 #ifdef HAVE_SYS_STAT_H
48 #ifdef NEED_SNPRINTF_H
49 # include "snprintf.h"
58 typedef int mode_t; /* for win32 */
64 * Collect command-line arguments as a string consisting of the arguments,
65 * separated by spaces.
68 get_args_as_string(int argc, char **argv, int optind)
75 * Find out how long the string will be.
78 for (i = optind; i < argc; i++) {
79 len += strlen(argv[i]);
80 len++; /* space, or '\0' if this is the last argument */
84 * Allocate the buffer for the string.
86 argstring = g_malloc(len);
89 * Now construct the string.
91 strcpy(argstring, "");
94 strcat(argstring, argv[i]);
98 strcat(argstring, " ");
104 setup_tmpdir(char *dir)
106 int len = strlen(dir);
109 /* Append slash if necessary */
110 if (dir[len - 1] == '/') {
114 newdir = g_malloc(len + 2);
122 try_tempfile(char *namebuf, int namebuflen, const char *dir, const char *pfx)
124 static const char suffix[] = "XXXXXXXXXX";
125 int namelen = strlen(dir) + strlen(pfx) + sizeof suffix;
129 if (namebuflen < namelen) {
130 /* Stick in a truncated name, so that if this error is
131 reported with the file name, you at least get
133 snprintf(namebuf, namebuflen, "%s%s%s", dir, pfx, suffix);
134 errno = ENAMETOOLONG;
137 strcpy(namebuf, dir);
138 strcat(namebuf, pfx);
139 strcat(namebuf, suffix);
141 /* The Single UNIX Specification doesn't say that "mkstemp()"
142 creates the temporary file with mode rw-------, so we
143 won't assume that all UNIXes will do so; instead, we set
144 the umask to 0077 to take away all group and other
145 permissions, attempt to create the file, and then put
147 old_umask = umask(0077);
148 tmp_fd = mkstemp(namebuf);
153 static char *tmpdir = NULL;
155 static char *temp = NULL;
157 static char *E_tmpdir;
160 #define P_tmpdir "/var/tmp"
164 create_tempfile(char *namebuf, int namebuflen, const char *pfx)
168 static gboolean initialized;
171 if ((dir = getenv("TMPDIR")) != NULL)
172 tmpdir = setup_tmpdir(dir);
174 if ((dir = getenv("TEMP")) != NULL)
175 temp = setup_tmpdir(dir);
178 E_tmpdir = setup_tmpdir(P_tmpdir);
182 if (tmpdir != NULL) {
183 fd = try_tempfile(namebuf, namebuflen, tmpdir, pfx);
190 fd = try_tempfile(namebuf, namebuflen, temp, pfx);
196 fd = try_tempfile(namebuf, namebuflen, E_tmpdir, pfx);
200 return try_tempfile(namebuf, namebuflen, "/tmp", pfx);
203 /* ASCII/EBCDIC conversion tables from
204 * http://www.room42.com/store/computer_center/code_tables.shtml
206 static guint8 ASCII_translate_EBCDIC [ 256 ] = {
207 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
208 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
209 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
210 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
211 0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D, 0x4D,
212 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
213 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8,
214 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F,
215 0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8,
216 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
217 0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
218 0xE8, 0xE9, 0xAD, 0xE0, 0xBD, 0x5F, 0x6D,
219 0x7D, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
220 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
221 0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
222 0xA8, 0xA9, 0xC0, 0x6A, 0xD0, 0xA1, 0x4B,
223 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
224 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
225 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
226 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
227 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
228 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
229 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
230 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
231 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
232 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
233 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
234 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
235 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
236 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
237 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
238 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B
242 ASCII_to_EBCDIC(guint8 *buf, guint bytes)
249 for (i = 0; i < bytes; i++, bufptr++) {
250 *bufptr = ASCII_translate_EBCDIC[*bufptr];
255 ASCII_to_EBCDIC1(guint8 c)
257 return ASCII_translate_EBCDIC[c];
260 static guint8 EBCDIC_translate_ASCII [ 256 ] = {
261 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
262 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
263 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
264 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
265 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
266 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
267 0x2E, 0x2E, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
268 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x2E, 0x3F,
269 0x20, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
270 0x2E, 0x2E, 0x2E, 0x3C, 0x28, 0x2B, 0x7C,
271 0x26, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
272 0x2E, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0x5E,
273 0x2D, 0x2F, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
274 0x2E, 0x7C, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
275 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
276 0x2E, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
277 0x2E, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
278 0x69, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
279 0x2E, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71,
280 0x72, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
281 0x2E, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
282 0x7A, 0x2E, 0x2E, 0x2E, 0x5B, 0x2E, 0x2E,
283 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
284 0x2E, 0x2E, 0x2E, 0x2E, 0x5D, 0x2E, 0x2E,
285 0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
286 0x49, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
287 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51,
288 0x52, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
289 0x5C, 0x2E, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
290 0x5A, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
291 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
292 0x39, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E
296 EBCDIC_to_ASCII(guint8 *buf, guint bytes)
303 for (i = 0; i < bytes; i++, bufptr++) {
304 *bufptr = EBCDIC_translate_ASCII[*bufptr];
309 EBCDIC_to_ASCII1(guint8 c)
311 return EBCDIC_translate_ASCII[c];
314 /* Compute the difference between two seconds/microseconds time stamps. */
316 compute_timestamp_diff(gint *diffsec, gint *diffusec,
317 guint32 sec1, guint32 usec1, guint32 sec2, guint32 usec2)
320 /* The seconds part of the first time is the same as the seconds
321 part of the second time, so if the microseconds part of the first
322 time is less than the microseconds part of the second time, the
323 first time is before the second time. The microseconds part of
324 the delta should just be the difference between the microseconds
325 part of the first time and the microseconds part of the second
326 time; don't adjust the seconds part of the delta, as it's OK if
327 the microseconds part is negative. */
329 *diffsec = sec1 - sec2;
330 *diffusec = usec1 - usec2;
331 } else if (sec1 <= sec2) {
332 /* The seconds part of the first time is less than the seconds part
333 of the second time, so the first time is before the second time.
335 Both the "seconds" and "microseconds" value of the delta
336 should have the same sign, so if the difference between the
337 microseconds values would be *positive*, subtract 1,000,000
338 from it, and add one to the seconds value. */
339 *diffsec = sec1 - sec2;
340 if (usec2 >= usec1) {
341 *diffusec = usec1 - usec2;
343 *diffusec = (usec1 - 1000000) - usec2;
347 /* Oh, good, we're not caught in a chronosynclastic infindibulum. */
348 *diffsec = sec1 - sec2;
349 if (usec2 <= usec1) {
350 *diffusec = usec1 - usec2;
352 *diffusec = (usec1 + 1000000) - usec2;