4 * $Id: util.c,v 1.55 2002/04/08 20:23:55 gram 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
207 static guint8 ASCII_translate_EBCDIC [ 256 ] = {
208 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
209 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
210 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
211 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
212 0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D, 0x4D,
213 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
214 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8,
215 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F,
216 0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8,
217 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
218 0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
219 0xE8, 0xE9, 0xAD, 0xE0, 0xBD, 0x5F, 0x6D,
220 0x7D, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
221 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
222 0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
223 0xA8, 0xA9, 0xC0, 0x6A, 0xD0, 0xA1, 0x4B,
224 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
225 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
226 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
227 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
228 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
229 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
230 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
231 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
232 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
233 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
234 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
235 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
236 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
237 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
238 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
239 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B
243 ASCII_to_EBCDIC(guint8 *buf, guint bytes)
250 for (i = 0; i < bytes; i++, bufptr++) {
251 *bufptr = ASCII_translate_EBCDIC[*bufptr];
256 ASCII_to_EBCDIC1(guint8 c)
258 return ASCII_translate_EBCDIC[c];
262 static guint8 EBCDIC_translate_ASCII [ 256 ] = {
263 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
264 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
265 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
266 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
267 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
268 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
269 0x2E, 0x2E, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
270 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x2E, 0x3F,
271 0x20, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
272 0x2E, 0x2E, 0x2E, 0x3C, 0x28, 0x2B, 0x7C,
273 0x26, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
274 0x2E, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0x5E,
275 0x2D, 0x2F, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
276 0x2E, 0x7C, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
277 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
278 0x2E, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
279 0x2E, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
280 0x69, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
281 0x2E, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71,
282 0x72, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
283 0x2E, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
284 0x7A, 0x2E, 0x2E, 0x2E, 0x5B, 0x2E, 0x2E,
285 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
286 0x2E, 0x2E, 0x2E, 0x2E, 0x5D, 0x2E, 0x2E,
287 0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
288 0x49, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
289 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51,
290 0x52, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
291 0x5C, 0x2E, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
292 0x5A, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
293 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
294 0x39, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E
298 EBCDIC_to_ASCII(guint8 *buf, guint bytes)
305 for (i = 0; i < bytes; i++, bufptr++) {
306 *bufptr = EBCDIC_translate_ASCII[*bufptr];
311 EBCDIC_to_ASCII1(guint8 c)
313 return EBCDIC_translate_ASCII[c];
316 /* Compute the difference between two seconds/microseconds time stamps. */
318 compute_timestamp_diff(gint *diffsec, gint *diffusec,
319 guint32 sec1, guint32 usec1, guint32 sec2, guint32 usec2)
322 /* The seconds part of the first time is the same as the seconds
323 part of the second time, so if the microseconds part of the first
324 time is less than the microseconds part of the second time, the
325 first time is before the second time. The microseconds part of
326 the delta should just be the difference between the microseconds
327 part of the first time and the microseconds part of the second
328 time; don't adjust the seconds part of the delta, as it's OK if
329 the microseconds part is negative. */
331 *diffsec = sec1 - sec2;
332 *diffusec = usec1 - usec2;
333 } else if (sec1 <= sec2) {
334 /* The seconds part of the first time is less than the seconds part
335 of the second time, so the first time is before the second time.
337 Both the "seconds" and "microseconds" value of the delta
338 should have the same sign, so if the difference between the
339 microseconds values would be *positive*, subtract 1,000,000
340 from it, and add one to the seconds value. */
341 *diffsec = sec1 - sec2;
342 if (usec2 >= usec1) {
343 *diffusec = usec1 - usec2;
345 *diffusec = (usec1 - 1000000) - usec2;
349 /* Oh, good, we're not caught in a chronosynclastic infindibulum. */
350 *diffsec = sec1 - sec2;
351 if (usec2 <= usec1) {
352 *diffusec = usec1 - usec2;
354 *diffusec = (usec1 + 1000000) - usec2;