Merge in the final code to make Ethereal run on Win32, compiled
[metze/wireshark/wip.git] / util.c
1 /* util.c
2  * Utility routines
3  *
4  * $Id: util.c,v 1.26 2000/01/15 00:22:34 gram Exp $
5  *
6  * Ethereal - Network traffic analyzer
7  * By Gerald Combs <gerald@zing.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * 
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  * 
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  * 
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  */
25
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #include <glib.h>
31
32 #include <stdlib.h>
33 #include <string.h>
34 #include <stdio.h>
35 #include <errno.h>
36
37 #ifdef HAVE_UNISTD_H
38 #include <unistd.h>
39 #endif
40
41 #ifdef HAVE_SYS_TYPES_H
42 #include <sys/types.h>
43 #endif
44
45 #ifdef HAVE_SYS_STAT_H
46 #include <sys/stat.h>
47 #endif
48
49 #ifdef NEED_SNPRINTF_H
50 # ifdef HAVE_STDARG_H
51 #  include <stdarg.h>
52 # else
53 #  include <varargs.h>
54 # endif
55 # include "snprintf.h"
56 #endif
57
58 #ifdef NEED_MKSTEMP
59 #include "mkstemp.h"
60 #endif
61
62 #include "util.h"
63
64 #ifdef HAVE_IO_H
65 #include <io.h>
66 typedef int mode_t;     /* for win32 */
67 #endif
68
69 static char *
70 setup_tmpdir(char *dir)
71 {
72         int len = strlen(dir);
73         char *newdir;
74
75         /* Append slash if necessary */
76         if (dir[len - 1] == '/') {
77                 newdir = dir;
78         }
79         else {
80                 newdir = g_malloc(len + 2);
81                 strcpy(newdir, dir);
82                 strcat(newdir, "/");
83         }
84         return newdir;
85 }
86
87 static int
88 try_tempfile(char *namebuf, int namebuflen, const char *dir, const char *pfx)
89 {
90         static const char suffix[] = "XXXXXXXXXX";
91         int namelen = strlen(dir) + strlen(pfx) + sizeof suffix;
92         mode_t old_umask;
93         int tmp_fd;
94
95         if (namebuflen < namelen) {
96                 /* Stick in a truncated name, so that if this error is
97                    reported with the file name, you at least get
98                    something. */
99                 snprintf(namebuf, namebuflen, "%s%s%s", dir, pfx, suffix);
100                 errno = ENAMETOOLONG;
101                 return -1;
102         }
103         strcpy(namebuf, dir);
104         strcat(namebuf, pfx);
105         strcat(namebuf, suffix);
106
107         /* The Single UNIX Specification doesn't say that "mkstemp()"
108            creates the temporary file with mode rw-------, so we
109            won't assume that all UNIXes will do so; instead, we set
110            the umask to 0077 to take away all group and other
111            permissions, attempt to create the file, and then put
112            the umask back. */
113         old_umask = umask(0077);
114         tmp_fd = mkstemp(namebuf);
115         umask(old_umask);
116         return tmp_fd;
117 }
118
119 static char *tmpdir = NULL;
120 #ifdef WIN32
121 static char *temp = NULL;
122 #endif
123 static char *E_tmpdir;
124
125 #ifndef P_tmpdir
126 #define P_tmpdir "/var/tmp"
127 #endif
128
129 int
130 create_tempfile(char *namebuf, int namebuflen, const char *pfx)
131 {
132         char *dir;
133         int fd;
134         static gboolean initialized;
135
136         if (!initialized) {
137                 if ((dir = getenv("TMPDIR")) != NULL)
138                         tmpdir = setup_tmpdir(dir);
139 #ifdef WIN32
140                 if ((dir = getenv("TEMP")) != NULL)
141                         temp = setup_tmpdir(dir);
142 #endif
143
144                 E_tmpdir = setup_tmpdir(P_tmpdir);
145                 initialized = TRUE;
146         }
147
148         if (tmpdir != NULL) {
149                 fd = try_tempfile(namebuf, namebuflen, tmpdir, pfx);
150                 if (fd != -1)
151                         return fd;
152         }
153
154 #ifdef WIN32
155         if (temp != NULL) {
156                 fd = try_tempfile(namebuf, namebuflen, temp, pfx);
157                 if (fd != -1)
158                         return fd;
159         }
160 #endif
161
162         fd = try_tempfile(namebuf, namebuflen, E_tmpdir, pfx);
163         if (fd != -1)
164                 return fd;
165
166         return try_tempfile(namebuf, namebuflen, "/tmp", pfx);
167 }
168
169 /* ASCII/EBCDIC conversion tables from
170  * http://www.room42.com/store/computer_center/code_tables.shtml
171  */
172 static guint8 ASCII_translate_EBCDIC [ 256 ] = {
173     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
174     0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
175     0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
176     0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
177     0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D, 0x4D,
178     0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
179     0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8,
180     0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F,
181     0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8,
182     0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
183     0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
184     0xE8, 0xE9, 0xAD, 0xE0, 0xBD, 0x5F, 0x6D,
185     0x7D, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
186     0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
187     0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
188     0xA8, 0xA9, 0xC0, 0x6A, 0xD0, 0xA1, 0x4B,
189     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
190     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
191     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
192     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
193     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
194     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
195     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
196     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
197     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
198     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
199     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
200     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
201     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
202     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
203     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
204     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B
205 };
206
207 void
208 ASCII_to_EBCDIC(guint8 *buf, guint bytes)
209 {
210         guint   i;
211         guint8  *bufptr;
212
213         bufptr = buf;
214
215         for (i = 0; i < bytes; i++, bufptr++) {
216                 *bufptr = ASCII_translate_EBCDIC[*bufptr];
217         }
218 }
219
220 guint8
221 ASCII_to_EBCDIC1(guint8 c)
222 {
223         return ASCII_translate_EBCDIC[c];
224 }
225
226 static guint8 EBCDIC_translate_ASCII [ 256 ] = {
227     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
228     0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
229     0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
230     0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
231     0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
232     0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
233     0x2E, 0x2E, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
234     0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x2E, 0x3F,
235     0x20, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
236     0x2E, 0x2E, 0x2E, 0x3C, 0x28, 0x2B, 0x7C,
237     0x26, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
238     0x2E, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0x5E,
239     0x2D, 0x2F, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
240     0x2E, 0x7C, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
241     0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
242     0x2E, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
243     0x2E, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
244     0x69, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
245     0x2E, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71,
246     0x72, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
247     0x2E, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
248     0x7A, 0x2E, 0x2E, 0x2E, 0x5B, 0x2E, 0x2E,
249     0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
250     0x2E, 0x2E, 0x2E, 0x2E, 0x5D, 0x2E, 0x2E,
251     0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
252     0x49, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
253     0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51,                                             
254     0x52, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
255     0x5C, 0x2E, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
256     0x5A, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
257     0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,                 
258     0x39, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E
259 };
260
261 void
262 EBCDIC_to_ASCII(guint8 *buf, guint bytes)
263 {
264         guint   i;
265         guint8  *bufptr;
266
267         bufptr = buf;
268
269         for (i = 0; i < bytes; i++, bufptr++) {
270                 *bufptr = EBCDIC_translate_ASCII[*bufptr];
271         }
272 }
273
274 guint8
275 EBCDIC_to_ASCII1(guint8 c)
276 {
277         return EBCDIC_translate_ASCII[c];
278 }