Make work better the (hexdump) popup menus.
[obnox/wireshark/wip.git] / util.c
1 /* util.c
2  * Utility routines
3  *
4  * $Id: util.c,v 1.41 2000/08/11 13:34:53 deniel 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 # include "snprintf.h"
51 #endif
52
53 #ifndef WIN32
54 #include <pwd.h>
55 #endif
56
57 #ifdef NEED_MKSTEMP
58 #include "mkstemp.h"
59 #endif
60
61 #include "util.h"
62
63 #ifdef HAVE_IO_H
64 #include <io.h>
65 typedef int mode_t;     /* for win32 */
66 #endif
67
68 #ifdef HAVE_LIBPCAP
69
70 #ifdef HAVE_SYS_SOCKET_H
71 #include <sys/socket.h>
72 #endif
73
74 #ifdef HAVE_SYS_IOCTL_H
75 #include <sys/ioctl.h>
76 #endif
77
78 #ifdef HAVE_NET_IF_H
79 #include <net/if.h>
80 #endif
81
82 #ifdef HAVE_SYS_SOCKIO_H
83 # include <sys/sockio.h>
84 #endif
85
86 #include "globals.h"
87
88 #endif
89
90 /*
91  * Given a pathname, return:
92  *
93  *      the errno, if an attempt to "stat()" the file fails;
94  *
95  *      EISDIR, if the attempt succeeded and the file turned out
96  *      to be a directory;
97  *
98  *      0, if the attempt succeeded and the file turned out not
99  *      to be a directory.
100  */
101
102 /*
103  * Visual C++ on Win32 systems doesn't define these.  (Old UNIX systems don't
104  * define them either.)
105  *
106  * Visual C++ on Win32 systems doesn't define S_IFIFO, it defines _S_IFIFO.
107  */
108 #ifndef S_ISREG
109 #define S_ISREG(mode)   (((mode) & S_IFMT) == S_IFREG)
110 #endif
111 #ifndef S_IFIFO
112 #define S_IFIFO _S_IFIFO
113 #endif
114 #ifndef S_ISFIFO
115 #define S_ISFIFO(mode)  (((mode) & S_IFMT) == S_IFIFO)
116 #endif
117 #ifndef S_ISDIR
118 #define S_ISDIR(mode)   (((mode) & S_IFMT) == S_IFDIR)
119 #endif
120
121 int
122 test_for_directory(const char *path)
123 {
124         struct stat statb;
125
126         if (stat(path, &statb) < 0)
127                 return errno;
128
129         if (S_ISDIR(statb.st_mode))
130                 return EISDIR;
131         else
132                 return 0;
133 }
134
135 /*
136  * Given a pathname, return a pointer to the last pathname separator
137  * character in the pathname, or NULL if the pathname contains no
138  * separators.
139  */
140 static char *
141 find_last_pathname_separator(char *path)
142 {
143         char *separator;
144
145 #ifdef WIN32
146         char c;
147
148         /*
149          * We have to scan for '\' or '/'.
150          * Get to the end of the string.
151          */
152         separator = path + strlen(path);        /* points to ending '\0' */
153         while (separator > path) {
154                 c = *--separator;
155                 if (c == '\\' || c == '/')
156                         return separator;       /* found it */
157         }
158
159         /*
160          * OK, we didn't find any, so no directories - but there might
161          * be a drive letter....
162          */
163         return strchr(path, ':');
164 #else
165         separator = strrchr(path, '/');
166 #endif
167         return separator;
168 }
169
170 /*
171  * Given a pathname, return the last component.
172  */
173 char *
174 get_basename(char *path)
175 {
176         char *filename;
177
178         filename = find_last_pathname_separator(path);
179         if (filename == NULL) {
180                 /*
181                  * There're no directories, drive letters, etc. in the
182                  * name; the pathname *is* the file name.
183                  */
184                 filename = path;
185         } else {
186                 /*
187                  * Skip past the pathname or drive letter separator.
188                  */
189                 filename++;
190         }
191         return filename;
192 }
193
194 /*
195  * Given a pathname, return a string containing everything but the
196  * last component.  NOTE: this overwrites the pathname handed into
197  * it....
198  */
199 char *
200 get_dirname(char *path)
201 {
202         char *separator;
203
204         separator = find_last_pathname_separator(path);
205         if (separator == NULL) {
206                 /*
207                  * There're no directories, drive letters, etc. in the
208                  * name; there is no directory path to return.
209                  */
210                 return NULL;
211         }
212
213         /*
214          * Get rid of the last pathname separator and the final file
215          * name following it.
216          */
217         *separator = '\0';
218
219         /*
220          * "path" now contains the pathname of the directory containing
221          * the file/directory to which it referred.
222          */
223         return path;
224 }
225
226 /*
227  * Collect command-line arguments as a string consisting of the arguments,
228  * separated by spaces.
229  */
230 char *
231 get_args_as_string(int argc, char **argv, int optind)
232 {
233         int len;
234         int i;
235         char *argstring;
236
237         /*
238          * Find out how long the string will be.
239          */
240         len = 0;
241         for (i = optind; i < argc; i++) {
242                 len += strlen(argv[i]);
243                 len++;  /* space, or '\0' if this is the last argument */
244         }
245
246         /*
247          * Allocate the buffer for the string.
248          */
249         argstring = g_malloc(len);
250
251         /*
252          * Now construct the string.
253          */
254         strcpy(argstring, "");
255         i = optind;
256         for (;;) {
257                 strcat(argstring, argv[i]);
258                 i++;
259                 if (i == argc)
260                         break;
261                 strcat(argstring, " ");
262         }
263         return argstring;
264 }
265
266 static char *
267 setup_tmpdir(char *dir)
268 {
269         int len = strlen(dir);
270         char *newdir;
271
272         /* Append slash if necessary */
273         if (dir[len - 1] == '/') {
274                 newdir = dir;
275         }
276         else {
277                 newdir = g_malloc(len + 2);
278                 strcpy(newdir, dir);
279                 strcat(newdir, "/");
280         }
281         return newdir;
282 }
283
284 static int
285 try_tempfile(char *namebuf, int namebuflen, const char *dir, const char *pfx)
286 {
287         static const char suffix[] = "XXXXXXXXXX";
288         int namelen = strlen(dir) + strlen(pfx) + sizeof suffix;
289         mode_t old_umask;
290         int tmp_fd;
291
292         if (namebuflen < namelen) {
293                 /* Stick in a truncated name, so that if this error is
294                    reported with the file name, you at least get
295                    something. */
296                 snprintf(namebuf, namebuflen, "%s%s%s", dir, pfx, suffix);
297                 errno = ENAMETOOLONG;
298                 return -1;
299         }
300         strcpy(namebuf, dir);
301         strcat(namebuf, pfx);
302         strcat(namebuf, suffix);
303
304         /* The Single UNIX Specification doesn't say that "mkstemp()"
305            creates the temporary file with mode rw-------, so we
306            won't assume that all UNIXes will do so; instead, we set
307            the umask to 0077 to take away all group and other
308            permissions, attempt to create the file, and then put
309            the umask back. */
310         old_umask = umask(0077);
311         tmp_fd = mkstemp(namebuf);
312         umask(old_umask);
313         return tmp_fd;
314 }
315
316 static char *tmpdir = NULL;
317 #ifdef WIN32
318 static char *temp = NULL;
319 #endif
320 static char *E_tmpdir;
321
322 #ifndef P_tmpdir
323 #define P_tmpdir "/var/tmp"
324 #endif
325
326 int
327 create_tempfile(char *namebuf, int namebuflen, const char *pfx)
328 {
329         char *dir;
330         int fd;
331         static gboolean initialized;
332
333         if (!initialized) {
334                 if ((dir = getenv("TMPDIR")) != NULL)
335                         tmpdir = setup_tmpdir(dir);
336 #ifdef WIN32
337                 if ((dir = getenv("TEMP")) != NULL)
338                         temp = setup_tmpdir(dir);
339 #endif
340
341                 E_tmpdir = setup_tmpdir(P_tmpdir);
342                 initialized = TRUE;
343         }
344
345         if (tmpdir != NULL) {
346                 fd = try_tempfile(namebuf, namebuflen, tmpdir, pfx);
347                 if (fd != -1)
348                         return fd;
349         }
350
351 #ifdef WIN32
352         if (temp != NULL) {
353                 fd = try_tempfile(namebuf, namebuflen, temp, pfx);
354                 if (fd != -1)
355                         return fd;
356         }
357 #endif
358
359         fd = try_tempfile(namebuf, namebuflen, E_tmpdir, pfx);
360         if (fd != -1)
361                 return fd;
362
363         return try_tempfile(namebuf, namebuflen, "/tmp", pfx);
364 }
365
366 /* ASCII/EBCDIC conversion tables from
367  * http://www.room42.com/store/computer_center/code_tables.shtml
368  */
369 static guint8 ASCII_translate_EBCDIC [ 256 ] = {
370     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
371     0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
372     0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
373     0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
374     0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D, 0x4D,
375     0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
376     0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8,
377     0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F,
378     0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8,
379     0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
380     0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
381     0xE8, 0xE9, 0xAD, 0xE0, 0xBD, 0x5F, 0x6D,
382     0x7D, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
383     0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
384     0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
385     0xA8, 0xA9, 0xC0, 0x6A, 0xD0, 0xA1, 0x4B,
386     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
387     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
388     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
389     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
390     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
391     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
392     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
393     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
394     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
395     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
396     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
397     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
398     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
399     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
400     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
401     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B
402 };
403
404 void
405 ASCII_to_EBCDIC(guint8 *buf, guint bytes)
406 {
407         guint   i;
408         guint8  *bufptr;
409
410         bufptr = buf;
411
412         for (i = 0; i < bytes; i++, bufptr++) {
413                 *bufptr = ASCII_translate_EBCDIC[*bufptr];
414         }
415 }
416
417 guint8
418 ASCII_to_EBCDIC1(guint8 c)
419 {
420         return ASCII_translate_EBCDIC[c];
421 }
422
423 static guint8 EBCDIC_translate_ASCII [ 256 ] = {
424     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
425     0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
426     0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
427     0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
428     0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
429     0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
430     0x2E, 0x2E, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
431     0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x2E, 0x3F,
432     0x20, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
433     0x2E, 0x2E, 0x2E, 0x3C, 0x28, 0x2B, 0x7C,
434     0x26, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
435     0x2E, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0x5E,
436     0x2D, 0x2F, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
437     0x2E, 0x7C, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
438     0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
439     0x2E, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
440     0x2E, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
441     0x69, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
442     0x2E, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71,
443     0x72, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
444     0x2E, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
445     0x7A, 0x2E, 0x2E, 0x2E, 0x5B, 0x2E, 0x2E,
446     0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
447     0x2E, 0x2E, 0x2E, 0x2E, 0x5D, 0x2E, 0x2E,
448     0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
449     0x49, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
450     0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51,                                             
451     0x52, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
452     0x5C, 0x2E, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
453     0x5A, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
454     0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,                 
455     0x39, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E
456 };
457
458 void
459 EBCDIC_to_ASCII(guint8 *buf, guint bytes)
460 {
461         guint   i;
462         guint8  *bufptr;
463
464         bufptr = buf;
465
466         for (i = 0; i < bytes; i++, bufptr++) {
467                 *bufptr = EBCDIC_translate_ASCII[*bufptr];
468         }
469 }
470
471 guint8
472 EBCDIC_to_ASCII1(guint8 c)
473 {
474         return EBCDIC_translate_ASCII[c];
475 }
476
477 #ifdef HAVE_LIBPCAP
478
479 /*
480  * If the ability to capture packets is added to Wiretap, these
481  * routines should be moved to the Wiretap source (with
482  * "get_interface_list()" and "free_interface_list()" renamed to
483  * "wtap_get_interface_list()" and "wtap_free_interface_list()",
484  * and modified to use Wiretap routines to attempt to open the
485  * interface.
486  */
487
488 struct search_user_data {
489         char    *name;
490         int     found;
491 };
492
493 static void
494 search_for_if_cb(gpointer data, gpointer user_data);
495
496 static void
497 free_if_cb(gpointer data, gpointer user_data);
498
499 #ifndef WIN32
500 GList *
501 get_interface_list(int *err, char *err_str)
502 {
503         GList  *il = NULL;
504         gint    nonloopback_pos = 0;
505         struct  ifreq *ifr, *last;
506         struct  ifconf ifc;
507         struct  ifreq ifrflags;
508         int     sock = socket(AF_INET, SOCK_DGRAM, 0);
509         struct search_user_data user_data;
510         pcap_t *pch;
511
512         if (sock < 0) {
513                 sprintf(err_str, "Error opening socket: %s",
514                     strerror(errno));
515                 return NULL;
516         }
517
518         /*
519          * Since we have to grab the interface list all at once, we'll
520          * make plenty of room.
521          */
522         ifc.ifc_len = 1024 * sizeof(struct ifreq);
523         ifc.ifc_buf = malloc(ifc.ifc_len);
524
525         if (ioctl(sock, SIOCGIFCONF, &ifc) < 0 ||
526             ifc.ifc_len < sizeof(struct ifreq)) {
527                 sprintf(err_str, "SIOCGIFCONF error getting list of interfaces: %s",
528                     strerror(errno));
529                 goto fail;
530          }
531
532         ifr = (struct ifreq *) ifc.ifc_req;
533         last = (struct ifreq *) ((char *) ifr + ifc.ifc_len);
534         while (ifr < last) {
535                 /*
536                  * Skip addresses that begin with "dummy", or that include
537                  * a ":" (the latter are Solaris virtuals).
538                  */
539                 if (strncmp(ifr->ifr_name, "dummy", 5) == 0 ||
540                     strchr(ifr->ifr_name, ':') != NULL)
541                         goto next;
542
543                 /*
544                  * If we already have this interface name on the list,
545                  * don't add it (SIOCGIFCONF returns, at least on
546                  * BSD-flavored systems, one entry per interface *address*;
547                  * if an interface has multiple addresses, we get multiple
548                  * entries for it).
549                  */
550                 user_data.name = ifr->ifr_name;
551                 user_data.found = FALSE;
552                 g_list_foreach(il, search_for_if_cb, &user_data);
553                 if (user_data.found)
554                         goto next;
555
556                 /*
557                  * Get the interface flags.
558                  */
559                 memset(&ifrflags, 0, sizeof ifrflags);
560                 strncpy(ifrflags.ifr_name, ifr->ifr_name,
561                     sizeof ifrflags.ifr_name);
562                 if (ioctl(sock, SIOCGIFFLAGS, (char *)&ifrflags) < 0) {
563                         if (errno == ENXIO)
564                                 goto next;
565                         sprintf(err_str, "SIOCGIFFLAGS error getting flags for interface %s: %s",
566                             ifr->ifr_name, strerror(errno));
567                         goto fail;
568                 }
569
570                 /*
571                  * Skip interfaces that aren't up.
572                  */
573                 if (!(ifrflags.ifr_flags & IFF_UP))
574                         goto next;
575
576                 /*
577                  * Skip interfaces that we can't open with "libpcap".
578                  * Open with the minimum packet size - it appears that the
579                  * IRIX SIOCSNOOPLEN "ioctl" may fail if the capture length
580                  * supplied is too large, rather than just truncating it.
581                  */
582                 pch = pcap_open_live(ifr->ifr_name, MIN_PACKET_SIZE, 0, 0,
583                     err_str);
584                 if (pch == NULL)
585                         goto next;
586                 pcap_close(pch);
587
588                 /*
589                  * If it's a loopback interface, add it at the end of the
590                  * list, otherwise add it after the last non-loopback
591                  * interface, so all loopback interfaces go at the end - we
592                  * don't want a loopback interface to be the default capture
593                  * device unless there are no non-loopback devices.
594                  */
595                 if ((ifrflags.ifr_flags & IFF_LOOPBACK) ||
596                     strncmp(ifr->ifr_name, "lo", 2) == 0)
597                         il = g_list_insert(il, g_strdup(ifr->ifr_name), -1);
598                 else {
599                         il = g_list_insert(il, g_strdup(ifr->ifr_name),
600                             nonloopback_pos);
601                         /*
602                          * Insert the next non-loopback interface after this
603                          * one.
604                          */
605                         nonloopback_pos++;
606                 }
607
608         next:
609 #ifdef HAVE_SA_LEN
610                 ifr = (struct ifreq *) ((char *) ifr + ifr->ifr_addr.sa_len + IFNAMSIZ);
611 #else
612                 ifr = (struct ifreq *) ((char *) ifr + sizeof(struct ifreq));
613 #endif
614         }
615
616         free(ifc.ifc_buf);
617         close(sock);
618
619         if (il == NULL) {
620                 /*
621                  * No interfaces found.
622                  */
623                 *err = NO_INTERFACES_FOUND;
624         }
625         return il;
626
627 fail:
628         if (il != NULL) {
629                 g_list_foreach(il, free_if_cb, NULL);
630                 g_list_free(il);
631         }
632         free(ifc.ifc_buf);
633         close(sock);
634         *err = CANT_GET_INTERFACE_LIST;
635         return NULL;
636 }
637
638 static void
639 search_for_if_cb(gpointer data, gpointer user_data)
640 {
641         struct search_user_data *search_user_data = user_data;
642
643         if (strcmp((char *)data, search_user_data->name) == 0)
644                 search_user_data->found = TRUE;
645 }
646 #else
647 GList *
648 get_interface_list(int *err, char *err_str) {
649   GList  *il = NULL;
650   wchar_t *names;
651   char *win95names; 
652   char newname[255];
653   int i, j, done;
654   
655   names = (wchar_t *)pcap_lookupdev(err_str);
656   i = done = 0;
657
658   if (names) {
659           if (names[0]<256) { 
660                   /* If names[0] is less than 256 it means the first byte is 0
661                      This implies that we are using unicode characters */
662                   do 
663                   { 
664                           j = 0; 
665                           while (names[i] != 0) 
666                                   newname[j++] = names[i++]; 
667                           i++; 
668                           if (names[i] == 0) 
669                                   done = 1; 
670                           newname[j++] = 0; 
671                           il = g_list_append(il, g_strdup(newname)); 
672                   } while (!done); 
673           } 
674           else { 
675                   /* Otherwise we are in Windows 95/98 and using ascii(8 bit)
676                      characters */
677                   do 
678                   { 
679                           win95names=names; 
680                           j = 0; 
681                           while (win95names[i] != 0) 
682                                   newname[j++] = win95names[i++]; 
683                           i++; 
684                           if (win95names[i] == 0) 
685                                   done = 1; 
686                           newname[j++] = 0; 
687                           il = g_list_append(il, g_strdup(newname)); 
688                   } while (!done); 
689           } 
690   }
691   return(il);
692 }
693 #endif
694
695 static void
696 free_if_cb(gpointer data, gpointer user_data)
697 {
698         g_free(data);
699 }
700
701 void
702 free_interface_list(GList *if_list)
703 {
704         while (if_list != NULL) {
705                 g_free(if_list->data);
706                 if_list = g_list_remove_link(if_list, if_list);
707         }
708 }
709
710 #endif /* HAVE_LIBPCAP */
711
712 const char*
713 get_home_dir(void)
714 {
715         static const char *home = NULL;
716 #ifdef WIN32
717         char *homedrive, *homepath;
718         char *homestring;
719         char *lastsep;
720 #else
721         struct passwd *pwd;
722 #endif
723
724         /* Return the cached value, if available */
725         if (home)
726                 return home;
727 #ifdef WIN32
728         /*
729          * XXX - should we use USERPROFILE anywhere in this process?
730          * Is there a chance that it might be set but one or more of
731          * HOMEDRIVE or HOMEPATH isn't set?
732          */
733         homedrive = getenv("HOMEDRIVE");
734         if (homedrive != NULL) {
735                 homepath = getenv("HOMEPATH");
736                 if (homepath != NULL) {
737                         /*
738                          * This is cached, so we don't need to worry about
739                          * allocating multiple ones of them.
740                          */
741                         homestring =
742                             g_malloc(strlen(homedrive) + strlen(homepath) + 1);
743                         strcpy(homestring, homedrive);
744                         strcat(homestring, homepath);
745
746                         /*
747                          * Trim off any trailing slash or backslash.
748                          */
749                         lastsep = find_last_pathname_separator(homestring);
750                         if (lastsep != NULL && *(lastsep + 1) == '\0') {
751                                 /*
752                                  * Last separator is the last character
753                                  * in the string.  Nuke it.
754                                  */
755                                 *lastsep = '\0';
756                         }
757                         home = homestring;
758                 } else
759                         home = homedrive;
760         } else {
761                 /*
762                  * Try using "windir?
763                  */
764                 home = "C:";
765         }
766 #else
767         home = getenv("HOME");
768         if (home == NULL) {
769                 /*
770                  * Get their home directory from the password file.
771                  * If we can't even find a password file entry for them,
772                  * use "/tmp".
773                  */
774                 pwd = getpwuid(getuid());
775                 if (pwd != NULL) {
776                         /*
777                          * This is cached, so we don't need to worry
778                          * about allocating multiple ones of them.
779                          */
780                         home = g_strdup(pwd->pw_dir);
781                 } else
782                         home = "/tmp";
783         }
784 #endif
785
786         return home;
787 }