Squelch a "signed vs. unsigned comparison" warning (which warned of a
[obnox/wireshark/wip.git] / util.c
1 /* util.c
2  * Utility routines
3  *
4  * $Id: util.c,v 1.52 2001/08/21 06:39:15 guy Exp $
5  *
6  * Ethereal - Network traffic analyzer
7  * By Gerald Combs <gerald@ethereal.com>
8  * Copyright 1998 Gerald Combs
9  * 
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.
14  * 
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.
19  * 
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.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #include <glib.h>
30
31 #include <stdlib.h>
32 #include <string.h>
33 #include <stdio.h>
34 #include <errno.h>
35
36 #ifdef HAVE_UNISTD_H
37 #include <unistd.h>
38 #endif
39
40 #ifdef HAVE_SYS_TYPES_H
41 #include <sys/types.h>
42 #endif
43
44 #ifdef HAVE_SYS_STAT_H
45 #include <sys/stat.h>
46 #endif
47
48 #ifdef NEED_SNPRINTF_H
49 # include "snprintf.h"
50 #endif
51
52 #ifndef WIN32
53 #include <pwd.h>
54 #endif
55
56 #ifdef NEED_MKSTEMP
57 #include "mkstemp.h"
58 #endif
59
60 #include "util.h"
61
62 #ifdef HAVE_IO_H
63 #include <io.h>
64 typedef int mode_t;     /* for win32 */
65 #endif
66
67 #ifdef HAVE_LIBPCAP
68
69 #ifdef HAVE_SYS_SOCKET_H
70 #include <sys/socket.h>
71 #endif
72
73 #ifdef HAVE_SYS_IOCTL_H
74 #include <sys/ioctl.h>
75 #endif
76
77 #include <pcap.h>
78
79 #ifndef WIN32
80 #include <net/if.h>
81 #endif
82
83 #ifdef HAVE_SYS_SOCKIO_H
84 # include <sys/sockio.h>
85 #endif
86
87 #include "globals.h"
88
89 #endif
90
91 /*
92  * Collect command-line arguments as a string consisting of the arguments,
93  * separated by spaces.
94  */
95 char *
96 get_args_as_string(int argc, char **argv, int optind)
97 {
98         int len;
99         int i;
100         char *argstring;
101
102         /*
103          * Find out how long the string will be.
104          */
105         len = 0;
106         for (i = optind; i < argc; i++) {
107                 len += strlen(argv[i]);
108                 len++;  /* space, or '\0' if this is the last argument */
109         }
110
111         /*
112          * Allocate the buffer for the string.
113          */
114         argstring = g_malloc(len);
115
116         /*
117          * Now construct the string.
118          */
119         strcpy(argstring, "");
120         i = optind;
121         for (;;) {
122                 strcat(argstring, argv[i]);
123                 i++;
124                 if (i == argc)
125                         break;
126                 strcat(argstring, " ");
127         }
128         return argstring;
129 }
130
131 static char *
132 setup_tmpdir(char *dir)
133 {
134         int len = strlen(dir);
135         char *newdir;
136
137         /* Append slash if necessary */
138         if (dir[len - 1] == '/') {
139                 newdir = dir;
140         }
141         else {
142                 newdir = g_malloc(len + 2);
143                 strcpy(newdir, dir);
144                 strcat(newdir, "/");
145         }
146         return newdir;
147 }
148
149 static int
150 try_tempfile(char *namebuf, int namebuflen, const char *dir, const char *pfx)
151 {
152         static const char suffix[] = "XXXXXXXXXX";
153         int namelen = strlen(dir) + strlen(pfx) + sizeof suffix;
154         mode_t old_umask;
155         int tmp_fd;
156
157         if (namebuflen < namelen) {
158                 /* Stick in a truncated name, so that if this error is
159                    reported with the file name, you at least get
160                    something. */
161                 snprintf(namebuf, namebuflen, "%s%s%s", dir, pfx, suffix);
162                 errno = ENAMETOOLONG;
163                 return -1;
164         }
165         strcpy(namebuf, dir);
166         strcat(namebuf, pfx);
167         strcat(namebuf, suffix);
168
169         /* The Single UNIX Specification doesn't say that "mkstemp()"
170            creates the temporary file with mode rw-------, so we
171            won't assume that all UNIXes will do so; instead, we set
172            the umask to 0077 to take away all group and other
173            permissions, attempt to create the file, and then put
174            the umask back. */
175         old_umask = umask(0077);
176         tmp_fd = mkstemp(namebuf);
177         umask(old_umask);
178         return tmp_fd;
179 }
180
181 static char *tmpdir = NULL;
182 #ifdef WIN32
183 static char *temp = NULL;
184 #endif
185 static char *E_tmpdir;
186
187 #ifndef P_tmpdir
188 #define P_tmpdir "/var/tmp"
189 #endif
190
191 int
192 create_tempfile(char *namebuf, int namebuflen, const char *pfx)
193 {
194         char *dir;
195         int fd;
196         static gboolean initialized;
197
198         if (!initialized) {
199                 if ((dir = getenv("TMPDIR")) != NULL)
200                         tmpdir = setup_tmpdir(dir);
201 #ifdef WIN32
202                 if ((dir = getenv("TEMP")) != NULL)
203                         temp = setup_tmpdir(dir);
204 #endif
205
206                 E_tmpdir = setup_tmpdir(P_tmpdir);
207                 initialized = TRUE;
208         }
209
210         if (tmpdir != NULL) {
211                 fd = try_tempfile(namebuf, namebuflen, tmpdir, pfx);
212                 if (fd != -1)
213                         return fd;
214         }
215
216 #ifdef WIN32
217         if (temp != NULL) {
218                 fd = try_tempfile(namebuf, namebuflen, temp, pfx);
219                 if (fd != -1)
220                         return fd;
221         }
222 #endif
223
224         fd = try_tempfile(namebuf, namebuflen, E_tmpdir, pfx);
225         if (fd != -1)
226                 return fd;
227
228         return try_tempfile(namebuf, namebuflen, "/tmp", pfx);
229 }
230
231 /* ASCII/EBCDIC conversion tables from
232  * http://www.room42.com/store/computer_center/code_tables.shtml
233  */
234 static guint8 ASCII_translate_EBCDIC [ 256 ] = {
235     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
236     0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
237     0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
238     0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
239     0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D, 0x4D,
240     0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
241     0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8,
242     0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F,
243     0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8,
244     0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
245     0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
246     0xE8, 0xE9, 0xAD, 0xE0, 0xBD, 0x5F, 0x6D,
247     0x7D, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
248     0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
249     0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
250     0xA8, 0xA9, 0xC0, 0x6A, 0xD0, 0xA1, 0x4B,
251     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
252     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
253     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
254     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
255     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
256     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
257     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
258     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
259     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
260     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
261     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
262     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
263     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
264     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
265     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
266     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B
267 };
268
269 void
270 ASCII_to_EBCDIC(guint8 *buf, guint bytes)
271 {
272         guint   i;
273         guint8  *bufptr;
274
275         bufptr = buf;
276
277         for (i = 0; i < bytes; i++, bufptr++) {
278                 *bufptr = ASCII_translate_EBCDIC[*bufptr];
279         }
280 }
281
282 guint8
283 ASCII_to_EBCDIC1(guint8 c)
284 {
285         return ASCII_translate_EBCDIC[c];
286 }
287
288 static guint8 EBCDIC_translate_ASCII [ 256 ] = {
289     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
290     0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
291     0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
292     0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
293     0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
294     0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
295     0x2E, 0x2E, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
296     0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x2E, 0x3F,
297     0x20, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
298     0x2E, 0x2E, 0x2E, 0x3C, 0x28, 0x2B, 0x7C,
299     0x26, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
300     0x2E, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0x5E,
301     0x2D, 0x2F, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
302     0x2E, 0x7C, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
303     0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
304     0x2E, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
305     0x2E, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
306     0x69, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
307     0x2E, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71,
308     0x72, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
309     0x2E, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
310     0x7A, 0x2E, 0x2E, 0x2E, 0x5B, 0x2E, 0x2E,
311     0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
312     0x2E, 0x2E, 0x2E, 0x2E, 0x5D, 0x2E, 0x2E,
313     0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
314     0x49, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
315     0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51,                                             
316     0x52, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
317     0x5C, 0x2E, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
318     0x5A, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
319     0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,                 
320     0x39, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E
321 };
322
323 void
324 EBCDIC_to_ASCII(guint8 *buf, guint bytes)
325 {
326         guint   i;
327         guint8  *bufptr;
328
329         bufptr = buf;
330
331         for (i = 0; i < bytes; i++, bufptr++) {
332                 *bufptr = EBCDIC_translate_ASCII[*bufptr];
333         }
334 }
335
336 guint8
337 EBCDIC_to_ASCII1(guint8 c)
338 {
339         return EBCDIC_translate_ASCII[c];
340 }
341
342 #ifdef HAVE_LIBPCAP
343
344 /*
345  * If the ability to capture packets is added to Wiretap, these
346  * routines should be moved to the Wiretap source (with
347  * "get_interface_list()" and "free_interface_list()" renamed to
348  * "wtap_get_interface_list()" and "wtap_free_interface_list()",
349  * and modified to use Wiretap routines to attempt to open the
350  * interface.
351  */
352
353 struct search_user_data {
354         char    *name;
355         int     found;
356 };
357
358 static void
359 search_for_if_cb(gpointer data, gpointer user_data);
360
361 static void
362 free_if_cb(gpointer data, gpointer user_data);
363
364 #ifndef WIN32
365 GList *
366 get_interface_list(int *err, char *err_str)
367 {
368         GList  *il = NULL;
369         gint    nonloopback_pos = 0;
370         struct  ifreq *ifr, *last;
371         struct  ifconf ifc;
372         struct  ifreq ifrflags;
373         int     sock = socket(AF_INET, SOCK_DGRAM, 0);
374         struct search_user_data user_data;
375         pcap_t *pch;
376         int len, lastlen;
377         char *buf;
378
379         if (sock < 0) {
380                 sprintf(err_str, "Error opening socket: %s",
381                     strerror(errno));
382                 return NULL;
383         }
384
385         /*
386          * This code came from: W. Richard Stevens: "UNIX Network Programming",
387          * Networking APIs: Sockets and XTI, Vol 1, page 434.
388          */
389         lastlen = 0;
390         len = 100 * sizeof(struct ifreq);
391         for ( ; ; ) {
392                 buf = g_malloc(len);
393                 ifc.ifc_len = len;
394                 ifc.ifc_buf = buf;
395                 memset (buf, 0, len);
396                 if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) {
397                         if (errno != EINVAL || lastlen != 0) {
398                                 sprintf(err_str,
399                                         "SIOCGIFCONF ioctl error getting list of interfaces: %s",
400                                         strerror(errno));
401                                 goto fail;
402                         }
403                 } else {
404                         if (ifc.ifc_len < sizeof(struct ifreq)) {
405                                 sprintf(err_str,
406                                         "SIOCGIFCONF ioctl gave too small return buffer");
407                                 goto fail;
408                         }
409                         if (ifc.ifc_len == lastlen)
410                                 break;                  /* success, len has not changed */
411                         lastlen = ifc.ifc_len;
412                 }
413                 len += 10 * sizeof(struct ifreq);       /* increment */
414                 g_free(buf);
415         }
416         ifr = (struct ifreq *) ifc.ifc_req;
417         last = (struct ifreq *) ((char *) ifr + ifc.ifc_len);
418         while (ifr < last) {
419                 /*
420                  * Skip addresses that begin with "dummy", or that include
421                  * a ":" (the latter are Solaris virtuals).
422                  */
423                 if (strncmp(ifr->ifr_name, "dummy", 5) == 0 ||
424                     strchr(ifr->ifr_name, ':') != NULL)
425                         goto next;
426
427                 /*
428                  * If we already have this interface name on the list,
429                  * don't add it (SIOCGIFCONF returns, at least on
430                  * BSD-flavored systems, one entry per interface *address*;
431                  * if an interface has multiple addresses, we get multiple
432                  * entries for it).
433                  */
434                 user_data.name = ifr->ifr_name;
435                 user_data.found = FALSE;
436                 g_list_foreach(il, search_for_if_cb, &user_data);
437                 if (user_data.found)
438                         goto next;
439
440                 /*
441                  * Get the interface flags.
442                  */
443                 memset(&ifrflags, 0, sizeof ifrflags);
444                 strncpy(ifrflags.ifr_name, ifr->ifr_name,
445                     sizeof ifrflags.ifr_name);
446                 if (ioctl(sock, SIOCGIFFLAGS, (char *)&ifrflags) < 0) {
447                         if (errno == ENXIO)
448                                 goto next;
449                         sprintf(err_str, "SIOCGIFFLAGS error getting flags for interface %s: %s",
450                             ifr->ifr_name, strerror(errno));
451                         goto fail;
452                 }
453
454                 /*
455                  * Skip interfaces that aren't up.
456                  */
457                 if (!(ifrflags.ifr_flags & IFF_UP))
458                         goto next;
459
460                 /*
461                  * Skip interfaces that we can't open with "libpcap".
462                  * Open with the minimum packet size - it appears that the
463                  * IRIX SIOCSNOOPLEN "ioctl" may fail if the capture length
464                  * supplied is too large, rather than just truncating it.
465                  */
466                 pch = pcap_open_live(ifr->ifr_name, MIN_PACKET_SIZE, 0, 0,
467                     err_str);
468                 if (pch == NULL)
469                         goto next;
470                 pcap_close(pch);
471
472                 /*
473                  * If it's a loopback interface, add it at the end of the
474                  * list, otherwise add it after the last non-loopback
475                  * interface, so all loopback interfaces go at the end - we
476                  * don't want a loopback interface to be the default capture
477                  * device unless there are no non-loopback devices.
478                  */
479                 if ((ifrflags.ifr_flags & IFF_LOOPBACK) ||
480                     strncmp(ifr->ifr_name, "lo", 2) == 0)
481                         il = g_list_insert(il, g_strdup(ifr->ifr_name), -1);
482                 else {
483                         il = g_list_insert(il, g_strdup(ifr->ifr_name),
484                             nonloopback_pos);
485                         /*
486                          * Insert the next non-loopback interface after this
487                          * one.
488                          */
489                         nonloopback_pos++;
490                 }
491
492         next:
493 #ifdef HAVE_SA_LEN
494                 ifr = (struct ifreq *) ((char *) ifr + ifr->ifr_addr.sa_len + IFNAMSIZ);
495 #else
496                 ifr = (struct ifreq *) ((char *) ifr + sizeof(struct ifreq));
497 #endif
498         }
499
500 #ifdef linux
501         /*
502          * OK, maybe we have support for the "any" device, to do a cooked
503          * capture on all interfaces at once.
504          * Try opening it and, if that succeeds, add it to the end of
505          * the list of interfaces.
506          */
507         pch = pcap_open_live("any", MIN_PACKET_SIZE, 0, 0, err_str);
508         if (pch != NULL) {
509                 /*
510                  * It worked; we can use the "any" device.
511                  */
512                 il = g_list_insert(il, g_strdup("any"), -1);
513                 pcap_close(pch);
514         }
515 #endif
516
517         g_free(ifc.ifc_buf);
518         close(sock);
519
520         if (il == NULL) {
521                 /*
522                  * No interfaces found.
523                  */
524                 *err = NO_INTERFACES_FOUND;
525         }
526         return il;
527
528 fail:
529         if (il != NULL) {
530                 g_list_foreach(il, free_if_cb, NULL);
531                 g_list_free(il);
532         }
533         g_free(ifc.ifc_buf);
534         close(sock);
535         *err = CANT_GET_INTERFACE_LIST;
536         return NULL;
537 }
538
539 static void
540 search_for_if_cb(gpointer data, gpointer user_data)
541 {
542         struct search_user_data *search_user_data = user_data;
543
544         if (strcmp((char *)data, search_user_data->name) == 0)
545                 search_user_data->found = TRUE;
546 }
547 #else
548 GList *
549 get_interface_list(int *err, char *err_str) {
550   GList  *il = NULL;
551   wchar_t *names;
552   char *win95names; 
553   char newname[255];
554   int i, j, done;
555   
556   names = (wchar_t *)pcap_lookupdev(err_str);
557   i = done = 0;
558
559   if (names) {
560           if (names[0]<256) { 
561                   /* If names[0] is less than 256 it means the first byte is 0
562                      This implies that we are using unicode characters */
563                   do 
564                   { 
565                           j = 0; 
566                           while (names[i] != 0) 
567                                   newname[j++] = names[i++]; 
568                           i++; 
569                           if (names[i] == 0) 
570                                   done = 1; 
571                           newname[j++] = 0; 
572                           il = g_list_append(il, g_strdup(newname)); 
573                   } while (!done); 
574           } 
575           else { 
576                   /* Otherwise we are in Windows 95/98 and using ascii(8 bit)
577                      characters */
578                   do 
579                   { 
580                           win95names=(char *)names; 
581                           j = 0; 
582                           while (win95names[i] != 0) 
583                                   newname[j++] = win95names[i++]; 
584                           i++; 
585                           if (win95names[i] == 0) 
586                                   done = 1; 
587                           newname[j++] = 0; 
588                           il = g_list_append(il, g_strdup(newname)); 
589                   } while (!done); 
590           } 
591   }
592   return(il);
593 }
594 #endif
595
596 static void
597 free_if_cb(gpointer data, gpointer user_data)
598 {
599         g_free(data);
600 }
601
602 void
603 free_interface_list(GList *if_list)
604 {
605         while (if_list != NULL) {
606                 g_free(if_list->data);
607                 if_list = g_list_remove_link(if_list, if_list);
608         }
609 }
610
611 #endif /* HAVE_LIBPCAP */
612
613
614 /* Compute the difference between two seconds/microseconds time stamps. */
615 void
616 compute_timestamp_diff(gint *diffsec, gint *diffusec,
617         guint32 sec1, guint32 usec1, guint32 sec2, guint32 usec2)
618 {
619   if (sec1 == sec2) {
620     /* The seconds part of the first time is the same as the seconds
621        part of the second time, so if the microseconds part of the first
622        time is less than the microseconds part of the second time, the
623        first time is before the second time.  The microseconds part of
624        the delta should just be the difference between the microseconds
625        part of the first time and the microseconds part of the second
626        time; don't adjust the seconds part of the delta, as it's OK if
627        the microseconds part is negative. */
628
629     *diffsec = sec1 - sec2;
630     *diffusec = usec1 - usec2;
631   } else if (sec1 <= sec2) {
632     /* The seconds part of the first time is less than the seconds part
633        of the second time, so the first time is before the second time.
634
635        Both the "seconds" and "microseconds" value of the delta
636        should have the same sign, so if the difference between the
637        microseconds values would be *positive*, subtract 1,000,000
638        from it, and add one to the seconds value. */
639     *diffsec = sec1 - sec2;
640     if (usec2 >= usec1) {
641       *diffusec = usec1 - usec2;
642     } else {
643       *diffusec = (usec1 - 1000000) - usec2;
644       (*diffsec)++;
645     }
646   } else {
647     /* Oh, good, we're not caught in a chronosynclastic infindibulum. */
648     *diffsec = sec1 - sec2;
649     if (usec2 <= usec1) {
650       *diffusec = usec1 - usec2;
651     } else {
652       *diffusec = (usec1 + 1000000) - usec2;
653       (*diffsec)--;
654     }
655   }
656 }