4 * $Id: util.c,v 1.56 2002/08/02 23:36:07 jmayer 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_STAT_H
44 #ifdef NEED_SNPRINTF_H
45 # include "snprintf.h"
54 typedef int mode_t; /* for win32 */
60 * Collect command-line arguments as a string consisting of the arguments,
61 * separated by spaces.
64 get_args_as_string(int argc, char **argv, int optind)
71 * Find out how long the string will be.
74 for (i = optind; i < argc; i++) {
75 len += strlen(argv[i]);
76 len++; /* space, or '\0' if this is the last argument */
80 * Allocate the buffer for the string.
82 argstring = g_malloc(len);
85 * Now construct the string.
87 strcpy(argstring, "");
90 strcat(argstring, argv[i]);
94 strcat(argstring, " ");
100 setup_tmpdir(char *dir)
102 int len = strlen(dir);
105 /* Append slash if necessary */
106 if (dir[len - 1] == '/') {
110 newdir = g_malloc(len + 2);
118 try_tempfile(char *namebuf, int namebuflen, const char *dir, const char *pfx)
120 static const char suffix[] = "XXXXXXXXXX";
121 int namelen = strlen(dir) + strlen(pfx) + sizeof suffix;
125 if (namebuflen < namelen) {
126 /* Stick in a truncated name, so that if this error is
127 reported with the file name, you at least get
129 snprintf(namebuf, namebuflen, "%s%s%s", dir, pfx, suffix);
130 errno = ENAMETOOLONG;
133 strcpy(namebuf, dir);
134 strcat(namebuf, pfx);
135 strcat(namebuf, suffix);
137 /* The Single UNIX Specification doesn't say that "mkstemp()"
138 creates the temporary file with mode rw-------, so we
139 won't assume that all UNIXes will do so; instead, we set
140 the umask to 0077 to take away all group and other
141 permissions, attempt to create the file, and then put
143 old_umask = umask(0077);
144 tmp_fd = mkstemp(namebuf);
149 static char *tmpdir = NULL;
151 static char *temp = NULL;
153 static char *E_tmpdir;
156 #define P_tmpdir "/var/tmp"
160 create_tempfile(char *namebuf, int namebuflen, const char *pfx)
164 static gboolean initialized;
167 if ((dir = getenv("TMPDIR")) != NULL)
168 tmpdir = setup_tmpdir(dir);
170 if ((dir = getenv("TEMP")) != NULL)
171 temp = setup_tmpdir(dir);
174 E_tmpdir = setup_tmpdir(P_tmpdir);
178 if (tmpdir != NULL) {
179 fd = try_tempfile(namebuf, namebuflen, tmpdir, pfx);
186 fd = try_tempfile(namebuf, namebuflen, temp, pfx);
192 fd = try_tempfile(namebuf, namebuflen, E_tmpdir, pfx);
196 return try_tempfile(namebuf, namebuflen, "/tmp", pfx);
199 /* ASCII/EBCDIC conversion tables from
200 * http://www.room42.com/store/computer_center/code_tables.shtml
203 static guint8 ASCII_translate_EBCDIC [ 256 ] = {
204 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
205 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
206 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
207 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
208 0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D, 0x4D,
209 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
210 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8,
211 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F,
212 0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8,
213 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
214 0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
215 0xE8, 0xE9, 0xAD, 0xE0, 0xBD, 0x5F, 0x6D,
216 0x7D, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
217 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
218 0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
219 0xA8, 0xA9, 0xC0, 0x6A, 0xD0, 0xA1, 0x4B,
220 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
221 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
222 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
223 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 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
239 ASCII_to_EBCDIC(guint8 *buf, guint bytes)
246 for (i = 0; i < bytes; i++, bufptr++) {
247 *bufptr = ASCII_translate_EBCDIC[*bufptr];
252 ASCII_to_EBCDIC1(guint8 c)
254 return ASCII_translate_EBCDIC[c];
258 static guint8 EBCDIC_translate_ASCII [ 256 ] = {
259 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
260 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
261 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
262 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
263 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
264 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
265 0x2E, 0x2E, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
266 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x2E, 0x3F,
267 0x20, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
268 0x2E, 0x2E, 0x2E, 0x3C, 0x28, 0x2B, 0x7C,
269 0x26, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
270 0x2E, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0x5E,
271 0x2D, 0x2F, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
272 0x2E, 0x7C, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
273 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
274 0x2E, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
275 0x2E, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
276 0x69, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
277 0x2E, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71,
278 0x72, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
279 0x2E, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
280 0x7A, 0x2E, 0x2E, 0x2E, 0x5B, 0x2E, 0x2E,
281 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
282 0x2E, 0x2E, 0x2E, 0x2E, 0x5D, 0x2E, 0x2E,
283 0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
284 0x49, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
285 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51,
286 0x52, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
287 0x5C, 0x2E, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
288 0x5A, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
289 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
290 0x39, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E
294 EBCDIC_to_ASCII(guint8 *buf, guint bytes)
301 for (i = 0; i < bytes; i++, bufptr++) {
302 *bufptr = EBCDIC_translate_ASCII[*bufptr];
307 EBCDIC_to_ASCII1(guint8 c)
309 return EBCDIC_translate_ASCII[c];
312 /* Compute the difference between two seconds/microseconds time stamps. */
314 compute_timestamp_diff(gint *diffsec, gint *diffusec,
315 guint32 sec1, guint32 usec1, guint32 sec2, guint32 usec2)
318 /* The seconds part of the first time is the same as the seconds
319 part of the second time, so if the microseconds part of the first
320 time is less than the microseconds part of the second time, the
321 first time is before the second time. The microseconds part of
322 the delta should just be the difference between the microseconds
323 part of the first time and the microseconds part of the second
324 time; don't adjust the seconds part of the delta, as it's OK if
325 the microseconds part is negative. */
327 *diffsec = sec1 - sec2;
328 *diffusec = usec1 - usec2;
329 } else if (sec1 <= sec2) {
330 /* The seconds part of the first time is less than the seconds part
331 of the second time, so the first time is before the second time.
333 Both the "seconds" and "microseconds" value of the delta
334 should have the same sign, so if the difference between the
335 microseconds values would be *positive*, subtract 1,000,000
336 from it, and add one to the seconds value. */
337 *diffsec = sec1 - sec2;
338 if (usec2 >= usec1) {
339 *diffusec = usec1 - usec2;
341 *diffusec = (usec1 - 1000000) - usec2;
345 /* Oh, good, we're not caught in a chronosynclastic infindibulum. */
346 *diffsec = sec1 - sec2;
347 if (usec2 <= usec1) {
348 *diffusec = usec1 - usec2;
350 *diffusec = (usec1 + 1000000) - usec2;