1 /*
2  * utils.c
3  *
4  * $Id: utils.c,v 1.199 2021/08/22 08:11:53 mjl Exp $
5  *
6  * Copyright (C) 2003-2006 Matthew Luckie
7  * Copyright (C) 2006-2011 The University of Waikato
8  * Copyright (C) 2011      Matthew Luckie
9  * Copyright (C) 2012-2015 The Regents of the University of California
10  * Copyright (C) 2015-2021 Matthew Luckie
11  * Author: Matthew Luckie
12  *
13  * This program is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation, version 2.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25  *
26  */
27 
28 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
31 #include "internal.h"
32 #include "utils.h"
33 
34 #if defined(HAVE_STRUCT_SOCKADDR_SA_LEN)
sockaddr_len(const struct sockaddr * sa)35 int sockaddr_len(const struct sockaddr *sa)
36 {
37   return sa->sa_len;
38 }
39 #else
sockaddr_len(const struct sockaddr * sa)40 int sockaddr_len(const struct sockaddr *sa)
41 {
42   if(sa->sa_family == AF_INET)  return sizeof(struct sockaddr_in);
43   if(sa->sa_family == AF_INET6) return sizeof(struct sockaddr_in6);
44 
45 #if defined(AF_LINK)
46   if(sa->sa_family == AF_LINK)  return sizeof(struct sockaddr_dl);
47 #endif
48 
49 #if defined(AF_UNIX) && !defined(_WIN32)
50   if(sa->sa_family == AF_UNIX)  return sizeof(struct sockaddr_un);
51 #endif
52 
53   return -1;
54 }
55 #endif
56 
addr_dup(const int af,const void * addr_in)57 void *addr_dup(const int af, const void *addr_in)
58 {
59   void   *addr;
60   size_t  size;
61 
62   if(af == AF_INET)
63     {
64       size = sizeof(struct in_addr);
65     }
66   else if(af == AF_INET6)
67     {
68       size = sizeof(struct in6_addr);
69     }
70   else return NULL;
71 
72   if((addr = malloc(size)) != NULL)
73     {
74       memcpy(addr, addr_in, size);
75     }
76 
77   return addr;
78 }
79 
sockaddr_dup(const struct sockaddr * sa)80 struct sockaddr *sockaddr_dup(const struct sockaddr *sa)
81 {
82   struct sockaddr *addr;
83   int len;
84 
85   if((len = sockaddr_len(sa)) <= 0)
86     {
87       return NULL;
88     }
89 
90   if((addr = malloc((size_t)len)) != NULL)
91     {
92       memcpy(addr, sa, (size_t)len);
93     }
94 
95   return addr;
96 }
97 
sockaddr_compose(struct sockaddr * sa,const int af,const void * addr,const int port)98 int sockaddr_compose(struct sockaddr *sa,
99 		     const int af, const void *addr, const int port)
100 {
101   socklen_t len;
102   struct sockaddr_in  *sin4;
103   struct sockaddr_in6 *sin6;
104 
105   assert(port >= 0);
106   assert(port <= 65535);
107 
108   if(af == AF_INET)
109     {
110       len = sizeof(struct sockaddr_in);
111       memset(sa, 0, len);
112       sin4 = (struct sockaddr_in *)sa;
113       if(addr != NULL) memcpy(&sin4->sin_addr, addr, sizeof(struct in_addr));
114       sin4->sin_port = htons(port);
115     }
116   else if(af == AF_INET6)
117     {
118       len = sizeof(struct sockaddr_in6);
119       memset(sa, 0, len);
120       sin6 = (struct sockaddr_in6 *)sa;
121       if(addr != NULL) memcpy(&sin6->sin6_addr, addr, sizeof(struct in6_addr));
122       sin6->sin6_port = htons(port);
123     }
124   else return -1;
125 
126 #if defined(HAVE_STRUCT_SOCKADDR_SA_LEN)
127   sa->sa_len    = len;
128 #endif
129 
130   sa->sa_family = af;
131 
132   return 0;
133 }
134 
sockaddr_compose_un(struct sockaddr * sa,const char * file)135 int sockaddr_compose_un(struct sockaddr *sa, const char *file)
136 {
137 #if defined(AF_UNIX) && !defined(_WIN32)
138   struct sockaddr_un *sn = (struct sockaddr_un *)sa;
139 
140   if(strlen(file) + 1 > sizeof(sn->sun_path))
141     return -1;
142   memset(sn, 0, sizeof(struct sockaddr_un));
143   sn->sun_family = AF_UNIX;
144   snprintf(sn->sun_path, sizeof(sn->sun_path), "%s", file);
145 
146 #if defined(HAVE_STRUCT_SOCKADDR_SA_LEN)
147   sn->sun_len    = sizeof(struct sockaddr_un);
148 #endif
149 
150   return 0;
151 #else
152   errno = EINVAL;
153   return -1;
154 #endif
155 }
156 
sockaddr_compose_str(struct sockaddr * sa,const char * addr,const int port)157 int sockaddr_compose_str(struct sockaddr *sa, const char *addr, const int port)
158 {
159   struct addrinfo hints, *res, *res0;
160   int rc = -1;
161   void *va;
162 
163   memset(&hints, 0, sizeof(struct addrinfo));
164   hints.ai_flags    = AI_NUMERICHOST;
165   hints.ai_socktype = SOCK_DGRAM;
166   hints.ai_protocol = IPPROTO_UDP;
167   hints.ai_family   = AF_UNSPEC;
168 
169   if(getaddrinfo(addr, NULL, &hints, &res0) != 0 || res0 == NULL)
170     return rc;
171 
172   for(res = res0; res != NULL; res = res->ai_next)
173     {
174       if(res->ai_family == PF_INET)
175 	{
176 	  va = &((struct sockaddr_in *)res->ai_addr)->sin_addr;
177 	  sockaddr_compose(sa, AF_INET, va, port);
178 	  rc = 0;
179 	  break;
180 	}
181       else if(res->ai_family == PF_INET6)
182 	{
183 	  va = &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr;
184 	  sockaddr_compose(sa, AF_INET6, va, port);
185 	  rc = 0;
186 	  break;
187 	}
188     }
189 
190   freeaddrinfo(res0);
191   return rc;
192 }
193 
194 #if defined(AF_LINK) && !defined(_WIN32)
link_tostr(const struct sockaddr_dl * sdl,char * buf,const size_t len)195 static char *link_tostr(const struct sockaddr_dl *sdl,
196 			char *buf, const size_t len)
197 {
198   static const char hex[] = "01234567890abcdef";
199   size_t off = 0;
200   uint8_t *u8, i;
201 
202   if((off = snprintf(buf, len, "t%d", sdl->sdl_type)) + 1 > len)
203     {
204       return NULL;
205     }
206 
207   if(sdl->sdl_nlen == 0 && sdl->sdl_alen == 0)
208     {
209       return buf;
210     }
211   else
212     {
213       buf[off++] = '.';
214     }
215 
216   /* check for enough remaining space */
217   if((size_t)(sdl->sdl_nlen + 1 + (3 * sdl->sdl_alen)) > len-off)
218     {
219       return NULL;
220     }
221 
222   if(sdl->sdl_nlen > 0)
223     {
224       memcpy(buf+off, sdl->sdl_data, sdl->sdl_nlen);
225       off += sdl->sdl_nlen;
226       if(sdl->sdl_alen > 0)
227 	{
228 	  buf[off++] = '.';
229 	}
230       else
231 	{
232 	  buf[off] = '\0';
233 	  return buf;
234 	}
235     }
236 
237   if(sdl->sdl_alen > 0)
238     {
239       u8 = (uint8_t *)LLADDR(sdl);
240       for(i=0; i<sdl->sdl_alen; i++)
241 	{
242 	  buf[off++] = hex[u8[i] & 0xf];
243 	  buf[off++] = hex[(u8[i] >> 4) & 0xf];
244 	  buf[off++] = ':';
245 	}
246       buf[off-1] = '\0';
247     }
248 
249   return buf;
250 }
251 #endif
252 
sockaddr_tostr(const struct sockaddr * sa,char * buf,const size_t len)253 char *sockaddr_tostr(const struct sockaddr *sa, char *buf, const size_t len)
254 {
255   char addr[128];
256 
257   if(sa->sa_family == AF_INET)
258     {
259 #ifndef _WIN32
260       if(inet_ntop(AF_INET, &((const struct sockaddr_in *)sa)->sin_addr,
261 		   addr, sizeof(addr)) == NULL)
262 	{
263 	  return NULL;
264 	}
265 #else
266       if(getnameinfo(sa, sizeof(struct sockaddr_in), addr, sizeof(addr),
267 		     NULL, 0, NI_NUMERICHOST) != 0)
268 	{
269 	  return NULL;
270 	}
271 #endif
272 
273       snprintf(buf, len, "%s:%d", addr,
274 	       ntohs(((const struct sockaddr_in *)sa)->sin_port));
275     }
276   else if(sa->sa_family == AF_INET6)
277     {
278 #ifndef _WIN32
279       if(inet_ntop(AF_INET6, &((const struct sockaddr_in6 *)sa)->sin6_addr,
280 		   addr, sizeof(addr)) == NULL)
281 	{
282 	  return NULL;
283 	}
284 #else
285       if(getnameinfo(sa, sizeof(struct sockaddr_in6), addr, sizeof(addr),
286 		     NULL, 0, NI_NUMERICHOST) != 0)
287 	{
288 	  return NULL;
289 	}
290 #endif
291 
292       snprintf(buf, len, "%s.%d", addr,
293 	       ntohs(((const struct sockaddr_in6 *)sa)->sin6_port));
294     }
295 #if defined(AF_LINK) && !defined(_WIN32)
296   else if(sa->sa_family == AF_LINK)
297     {
298       return link_tostr((const struct sockaddr_dl *)sa, buf, len);
299     }
300 #endif
301 #if defined(AF_UNIX) && !defined(_WIN32)
302   else if(sa->sa_family == AF_UNIX)
303     {
304       snprintf(buf, len, "%s", ((const struct sockaddr_un *)sa)->sun_path);
305     }
306 #endif
307   else
308     {
309       return NULL;
310     }
311 
312   return buf;
313 }
314 
addr4_cmp(const void * va,const void * vb)315 int addr4_cmp(const void *va, const void *vb)
316 {
317   const struct in_addr *a = (const struct in_addr *)va;
318   const struct in_addr *b = (const struct in_addr *)vb;
319   if(a->s_addr < b->s_addr) return -1;
320   if(a->s_addr > b->s_addr) return  1;
321   return 0;
322 }
323 
addr4_human_cmp(const void * va,const void * vb)324 int addr4_human_cmp(const void *va, const void *vb)
325 {
326   const struct in_addr *a = (const struct in_addr *)va;
327   const struct in_addr *b = (const struct in_addr *)vb;
328   uint32_t ua = ntohl(a->s_addr);
329   uint32_t ub = ntohl(b->s_addr);
330   if(ua < ub) return -1;
331   if(ua > ub) return  1;
332   return 0;
333 }
334 
addr6_cmp(const void * va,const void * vb)335 int addr6_cmp(const void *va, const void *vb)
336 {
337   const struct in6_addr *a = (const struct in6_addr *)va;
338   const struct in6_addr *b = (const struct in6_addr *)vb;
339   int i;
340 
341 #ifndef _WIN32
342   for(i=0; i<4; i++)
343     {
344       if(a->s6_addr32[i] < b->s6_addr32[i]) return -1;
345       if(a->s6_addr32[i] > b->s6_addr32[i]) return  1;
346     }
347 #else
348   for(i=0; i<8; i++)
349     {
350       if(a->u.Word[i] < b->u.Word[i]) return -1;
351       if(a->u.Word[i] > b->u.Word[i]) return  1;
352     }
353 #endif
354 
355   return 0;
356 }
357 
addr6_human_cmp(const void * va,const void * vb)358 int addr6_human_cmp(const void *va, const void *vb)
359 {
360   const struct in6_addr *a = (const struct in6_addr *)va;
361   const struct in6_addr *b = (const struct in6_addr *)vb;
362   int i;
363 
364 #ifndef _WIN32
365   uint32_t ua, ub;
366   for(i=0; i<4; i++)
367     {
368       ua = ntohl(a->s6_addr32[i]);
369       ub = ntohl(b->s6_addr32[i]);
370       if(ua < ub) return -1;
371       if(ua > ub) return  1;
372     }
373 #else
374   uint16_t ua, ub;
375   for(i=0; i<8; i++)
376     {
377       ua = ntohs(a->u.Word[i]);
378       ub = ntohs(b->u.Word[i]);
379       if(ua < ub) return -1;
380       if(ua > ub) return  1;
381     }
382 #endif
383 
384   return 0;
385 }
386 
387 /*
388  * addr_cmp:
389  * this function is used to provide a sorting order, not for advising the
390  * numerical order of the addresses passed in.
391  */
addr_cmp(const int af,const void * a,const void * b)392 int addr_cmp(const int af, const void *a, const void *b)
393 {
394   if(af == AF_INET)  return addr4_cmp(a, b);
395   if(af == AF_INET6) return addr6_cmp(a, b);
396   return 0;
397 }
398 
399 #ifndef _WIN32
addr_tostr(int af,const void * addr,char * buf,size_t len)400 const char *addr_tostr(int af, const void *addr, char *buf, size_t len)
401 {
402   return inet_ntop(af, addr, buf, len);
403 }
404 #endif
405 
406 #ifdef _WIN32
addr_tostr(int af,const void * addr,char * buf,size_t len)407 const char *addr_tostr(int af, const void *addr, char *buf, size_t len)
408 {
409   struct sockaddr_storage sas;
410 
411   if(sockaddr_compose((struct sockaddr *)&sas, af, addr, 0) != 0)
412     return NULL;
413 
414   if(getnameinfo((const struct sockaddr *)&sas, sizeof(sas), buf, len,
415                  NULL, 0, NI_NUMERICHOST) != 0)
416     {
417       return NULL;
418     }
419 
420   return buf;
421 }
422 #endif
423 
424 /*
425  * memdup
426  *
427  * duplicate some memory.
428  */
429 #ifndef DMALLOC
memdup(const void * ptr,const size_t len)430 void *memdup(const void *ptr, const size_t len)
431 {
432   void *d;
433   assert(ptr != NULL);
434   if((d = malloc(len)) != NULL)
435     {
436       memcpy(d, ptr, len);
437     }
438   return d;
439 }
440 #endif
441 
442 /*
443  * malloc_zero
444  *
445  * allocate some memory, zero it, and return a pointer to it.
446  */
447 #if !defined(DMALLOC) && !defined(HAVE_CALLOC)
malloc_zero(const size_t size)448 void *malloc_zero(const size_t size)
449 {
450   void *ptr;
451   if((ptr = malloc(size)) != NULL)
452     {
453       memset(ptr, 0, size);
454     }
455   return ptr;
456 }
457 #endif
458 
459 #ifdef DMALLOC
malloc_zero_dm(const size_t size,const char * file,const int line)460 void *malloc_zero_dm(const size_t size, const char *file, const int line)
461 {
462   void *ptr;
463   if((ptr = dmalloc_malloc(file,line,size,DMALLOC_FUNC_MALLOC,0,0)) != NULL)
464     {
465       memset(ptr, 0, size);
466     }
467   return ptr;
468 }
469 #endif
470 
471 #ifndef DMALLOC
realloc_wrap(void ** ptr,size_t len)472 int realloc_wrap(void **ptr, size_t len)
473 {
474   void *tmp;
475 
476   if(len != 0)
477     {
478       if(*ptr != NULL)
479 	tmp = realloc(*ptr, len);
480       else
481 	tmp = malloc(len);
482 
483       if(tmp != NULL)
484 	{
485 	  *ptr = tmp;
486 	  return 0;
487 	}
488     }
489   else
490     {
491       if(*ptr != NULL)
492 	{
493 	  free(*ptr);
494 	  *ptr = NULL;
495 	}
496       return 0;
497     }
498 
499   return -1;
500 }
501 #endif
502 
503 #ifdef DMALLOC
realloc_wrap_dm(void ** ptr,size_t len,const char * file,const int line)504 int realloc_wrap_dm(void **ptr, size_t len, const char *file, const int line)
505 {
506   void *tmp;
507 
508   if(len != 0)
509     {
510       if(*ptr != NULL)
511 	tmp = dmalloc_realloc(file, line, *ptr, len, DMALLOC_FUNC_REALLOC, 0);
512       else
513 	tmp = dmalloc_malloc(file, line, len, DMALLOC_FUNC_MALLOC, 0, 0);
514 
515       if(tmp != NULL)
516 	{
517 	  *ptr = tmp;
518 	  return 0;
519 	}
520     }
521   else
522     {
523       if(*ptr != NULL)
524 	{
525 	  dmalloc_free(file, line, *ptr, DMALLOC_FUNC_FREE);
526 	  *ptr = NULL;
527 	}
528       return 0;
529     }
530 
531   return -1;
532 }
533 #endif
534 
array_findpos(void ** array,int nmemb,const void * item,array_cmp_t cmp)535 int array_findpos(void **array, int nmemb, const void *item, array_cmp_t cmp)
536 {
537   int l, r, k, i;
538 
539   if(nmemb == 0)
540     {
541       return -1;
542     }
543 
544   l = 0;
545   r = nmemb-1;
546 
547   if(r == 0)
548     {
549       if(cmp(array[0], item) == 0)
550 	return 0;
551       return -1;
552     }
553 
554   while(l <= r)
555     {
556       k = (l + r) / 2;
557       i = cmp(array[k], item);
558       if(i > 0)
559 	r = k-1;
560       else if(i < 0)
561 	l = k+1;
562       else
563 	return k;
564     }
565 
566   return -1;
567 }
568 
array_find(void ** array,int nmemb,const void * item,array_cmp_t cmp)569 void *array_find(void **array, int nmemb, const void *item, array_cmp_t cmp)
570 {
571   int k = array_findpos(array, nmemb, item, cmp);
572   if(k >= 0)
573     return array[k];
574   return NULL;
575 }
576 
577 /*
578  * array_insert_0
579  *
580  * handy function that deals with inserting an element into an array
581  * and then sorting the array, if necessary.  using mergesort because
582  * the array is likely to have pre-existing order.
583  */
array_insert_0(void ** array,int * nmemb,void * item,array_cmp_t cmp)584 static int array_insert_0(void **array,int *nmemb,void *item,array_cmp_t cmp)
585 {
586   assert(array != NULL);
587   array[*nmemb] = item;
588   *nmemb = *nmemb + 1;
589   if(cmp != NULL)
590     array_qsort(array, *nmemb, cmp);
591   return 0;
592 }
593 
594 #ifndef DMALLOC
array_insert(void *** array,int * nmemb,void * item,array_cmp_t cmp)595 int array_insert(void ***array, int *nmemb, void *item, array_cmp_t cmp)
596 {
597   size_t len;
598   assert(nmemb != NULL); assert(*nmemb >= 0);
599   len = ((*nmemb) + 1) * sizeof(void *);
600   if(realloc_wrap((void **)array, len) != 0)
601     return -1;
602   return array_insert_0(*array, nmemb, item, cmp);
603 }
604 
array_insert_gb(void *** array,int * nmemb,int * mmemb,int growby,void * item,array_cmp_t cmp)605 int array_insert_gb(void ***array, int *nmemb, int *mmemb, int growby,
606 		    void *item, array_cmp_t cmp)
607 {
608   size_t len;
609 
610   assert(nmemb != NULL && *nmemb >= 0);
611   if(*nmemb + 1 >= *mmemb)
612     {
613       assert(*mmemb + growby > *nmemb);
614       len = (*mmemb + growby) * sizeof(void *);
615       if(realloc_wrap((void **)array, len) != 0)
616 	return -1;
617       *mmemb += growby;
618     }
619 
620   return array_insert_0(*array, nmemb, item, cmp);
621 }
622 #endif
623 
624 #ifdef DMALLOC
array_insert_dm(void *** array,int * nmemb,void * item,array_cmp_t cmp,const char * file,const int line)625 int array_insert_dm(void ***array, int *nmemb, void *item,
626 		    array_cmp_t cmp, const char *file, const int line)
627 {
628   size_t len;
629 
630   assert(nmemb != NULL && *nmemb >= 0);
631   len = ((*nmemb) + 1) * sizeof(void *);
632   if(realloc_wrap_dm((void **)array, len, file, line) != 0)
633     return -1;
634 
635   return array_insert_0(*array, nmemb, item, cmp);
636 }
637 
array_insert_gb_dm(void *** array,int * nmemb,int * mmemb,int growby,void * item,array_cmp_t cmp,const char * file,const int line)638 int array_insert_gb_dm(void ***array, int *nmemb, int *mmemb, int growby,
639 		       void *item, array_cmp_t cmp,
640 		       const char *file, const int line)
641 {
642   size_t len;
643 
644   assert(nmemb != NULL && *nmemb >= 0);
645   if(*nmemb + 1 >= *mmemb)
646     {
647       assert(*mmemb + growby > *nmemb);
648       len = (*mmemb + growby) * sizeof(void *);
649       if(realloc_wrap_dm((void **)array, len, file, line) != 0)
650 	return -1;
651       *mmemb += growby;
652     }
653 
654   return array_insert_0(*array, nmemb, item, cmp);
655 }
656 #endif
657 
array_remove(void ** array,int * nmemb,int p)658 void array_remove(void **array, int *nmemb, int p)
659 {
660   assert(p >= 0 && p < *nmemb);
661   memmove(array+p, array+p+1, ((*nmemb)-p-1) * sizeof(void *));
662   *nmemb = *nmemb - 1;
663   return;
664 }
665 
array_swap(void ** a,int i,int j)666 static void array_swap(void **a, int i, int j)
667 {
668   void *item = a[i];
669   a[i] = a[j];
670   a[j] = item;
671   return;
672 }
673 
array_qsort_3(void ** a,array_cmp_t cmp,int l,int r)674 static void array_qsort_3(void **a, array_cmp_t cmp, int l, int r)
675 {
676   int lt, gt, i, rc;
677   void *c;
678 
679   if(l >= r)
680     return;
681 
682   lt = l;
683   gt = r;
684   i  = l;
685   c  = a[l];
686 
687   while(i <= gt)
688     {
689       rc = a[i] != c ? cmp(a[i], c) : 0;
690       if(rc < 0)
691 	array_swap(a, lt++, i++);
692       else if(rc > 0)
693 	array_swap(a, i, gt--);
694       else
695 	i++;
696     }
697 
698   array_qsort_3(a, cmp, l, lt-1);
699   array_qsort_3(a, cmp, gt+1, r);
700   return;
701 }
702 
array_qsort(void ** a,int n,array_cmp_t cmp)703 void array_qsort(void **a, int n, array_cmp_t cmp)
704 {
705   array_qsort_3(a, cmp, 0, n-1);
706   return;
707 }
708 
709 #ifndef _WIN32
gettimeofday_wrap(struct timeval * tv)710 void gettimeofday_wrap(struct timeval *tv)
711 {
712   struct timezone tz;
713   gettimeofday(tv, &tz);
714   return;
715 }
716 #endif
717 
718 #ifdef _WIN32
gettimeofday_wrap(struct timeval * tv)719 void gettimeofday_wrap(struct timeval *tv)
720 {
721   FILETIME ft;
722   uint64_t u64;
723   GetSystemTimeAsFileTime(&ft);
724   u64 = ft.dwHighDateTime;
725   u64 <<= 32;
726   u64 |= ft.dwLowDateTime;
727 
728   u64 /= 10;
729   u64 -= 11644473600000000LL;
730   tv->tv_sec = (long)(u64 / 1000000UL);
731   tv->tv_usec = (long)(u64 % 1000000UL);
732   return;
733 }
734 #endif
735 
timeval_cmp(const struct timeval * a,const struct timeval * b)736 int timeval_cmp(const struct timeval *a, const struct timeval *b)
737 {
738   if(a->tv_sec  < b->tv_sec)  return -1;
739   if(a->tv_sec  > b->tv_sec)  return  1;
740 
741   if(a->tv_usec < b->tv_usec) return -1;
742   if(a->tv_usec > b->tv_usec) return  1;
743 
744   return 0;
745 }
746 
timeval_handlewrap(struct timeval * tv)747 static void timeval_handlewrap(struct timeval *tv)
748 {
749   if(tv->tv_usec >= 1000000)
750     {
751       tv->tv_sec++;
752       tv->tv_usec -= 1000000;
753     }
754   else if(tv->tv_usec < 0)
755     {
756       tv->tv_sec--;
757       tv->tv_usec += 1000000;
758     }
759   return;
760 }
761 
timeval_add_cs(struct timeval * out,const struct timeval * in,int cs)762 void timeval_add_cs(struct timeval *out, const struct timeval *in, int cs)
763 {
764   out->tv_sec  = in->tv_sec  + (cs / 100);
765   out->tv_usec = in->tv_usec + ((cs % 100) * 10000);
766   timeval_handlewrap(out);
767   return;
768 }
769 
timeval_add_ms(struct timeval * out,const struct timeval * in,int msec)770 void timeval_add_ms(struct timeval *out, const struct timeval *in, int msec)
771 {
772   out->tv_sec  = in->tv_sec  + (msec / 1000);
773   out->tv_usec = in->tv_usec + ((msec % 1000) * 1000);
774   timeval_handlewrap(out);
775   return;
776 }
777 
timeval_add_us(struct timeval * out,const struct timeval * in,int us)778 void timeval_add_us(struct timeval *out, const struct timeval *in, int us)
779 {
780   out->tv_sec  = in->tv_sec  + (us / 1000000);
781   out->tv_usec = in->tv_usec + (us % 1000000);
782   timeval_handlewrap(out);
783   return;
784 }
785 
timeval_add_s(struct timeval * out,const struct timeval * in,int s)786 void timeval_add_s(struct timeval *out, const struct timeval *in, int s)
787 {
788   out->tv_sec  = in->tv_sec + s;
789   out->tv_usec = in->tv_usec;
790   return;
791 }
792 
timeval_sub_us(struct timeval * out,const struct timeval * in,int us)793 void timeval_sub_us(struct timeval *out, const struct timeval *in, int us)
794 {
795   out->tv_sec  = in->tv_sec  - (us / 1000000);
796   out->tv_usec = in->tv_usec - (us % 1000000);
797   timeval_handlewrap(out);
798   return;
799 }
800 
timeval_add_tv(struct timeval * tv,const struct timeval * add)801 void timeval_add_tv(struct timeval *tv, const struct timeval *add)
802 {
803   assert(add->tv_sec >= 0);
804   assert(add->tv_usec >= 0);
805 
806   tv->tv_sec += add->tv_sec;
807   tv->tv_usec += add->tv_usec;
808 
809   /* check for overflow */
810   if(tv->tv_usec > 1000000)
811     {
812       tv->tv_sec++;
813       tv->tv_usec -= 1000000;
814     }
815 
816   return;
817 }
818 
timeval_add_tv3(struct timeval * out,const struct timeval * a,const struct timeval * b)819 void timeval_add_tv3(struct timeval *out,
820 		     const struct timeval *a, const struct timeval *b)
821 {
822   assert(a->tv_sec >= 0);  assert(a->tv_usec >= 0);
823   assert(b->tv_sec >= 0);  assert(b->tv_usec >= 0);
824 
825   out->tv_sec = a->tv_sec + b->tv_sec;
826   out->tv_usec = a->tv_usec + b->tv_usec;
827   if(out->tv_usec > 1000000)
828     {
829       out->tv_sec++;
830       out->tv_usec -= 1000000;
831     }
832 
833   return;
834 }
835 
timeval_diff_tv(struct timeval * rtt,const struct timeval * from,const struct timeval * to)836 void timeval_diff_tv(struct timeval *rtt,
837 		     const struct timeval *from, const struct timeval *to)
838 {
839   rtt->tv_sec  = to->tv_sec  - from->tv_sec;
840   rtt->tv_usec = to->tv_usec - from->tv_usec;
841 
842   if(rtt->tv_usec < 0)
843     {
844       rtt->tv_sec--;
845       rtt->tv_usec += 1000000;
846     }
847 
848   return;
849 }
850 
851 /*
852  * timeval_diff_ms
853  * return the millisecond difference between the two timevals.
854  * a - b
855  */
timeval_diff_ms(const struct timeval * a,const struct timeval * b)856 int timeval_diff_ms(const struct timeval *a, const struct timeval *b)
857 {
858   struct timeval tv;
859   timeval_diff_tv(&tv, b, a);
860   return ((int)tv.tv_sec * 1000) + ((int)tv.tv_usec / 1000);
861 }
862 
863 /*
864  * timeval_diff_us
865  * return the microsecond difference between the two timevals.
866  * a - b
867  */
timeval_diff_us(const struct timeval * a,const struct timeval * b)868 int timeval_diff_us(const struct timeval *a, const struct timeval *b)
869 {
870   struct timeval tv;
871   timeval_diff_tv(&tv, b, a);
872   return ((int)tv.tv_sec * 1000000) + tv.tv_usec;
873 }
874 
timeval_cpy(struct timeval * dst,const struct timeval * src)875 void timeval_cpy(struct timeval *dst, const struct timeval *src)
876 {
877   memcpy(dst, src, sizeof(struct timeval));
878   return;
879 }
880 
timeval_inrange_us(const struct timeval * a,const struct timeval * b,int c)881 int timeval_inrange_us(const struct timeval *a, const struct timeval *b, int c)
882 {
883   struct timeval tv;
884   int rc = timeval_cmp(a, b);
885   if(rc < 0)
886     {
887       timeval_add_us(&tv, a, c);
888       if(timeval_cmp(&tv, b) < 0)
889 	return 0;
890     }
891   else if(rc > 0)
892     {
893       timeval_add_us(&tv, b, c);
894       if(timeval_cmp(&tv, a) < 0)
895 	return 0;
896     }
897   return 1;
898 }
899 
timeval_tostr_us(const struct timeval * rtt,char * str,size_t len)900 char *timeval_tostr_us(const struct timeval *rtt, char *str, size_t len)
901 {
902   uint32_t usec = (rtt->tv_sec * 1000000) + rtt->tv_usec;
903   snprintf(str, len, "%d.%03d", usec / 1000, usec % 1000);
904   return str;
905 }
906 
907 #ifndef _WIN32
fcntl_unset(const int fd,const int flags)908 int fcntl_unset(const int fd, const int flags)
909 {
910   int i;
911 
912   if((i = fcntl(fd, F_GETFL, 0)) == -1)
913     {
914       return -1;
915     }
916 
917   if(fcntl(fd, F_SETFL, i & (~flags)) == -1)
918     {
919       return -1;
920     }
921 
922   return 0;
923 }
924 
fcntl_set(const int fd,const int flags)925 int fcntl_set(const int fd, const int flags)
926 {
927   int i;
928 
929   if((i = fcntl(fd, F_GETFL, 0)) == -1)
930     {
931       return -1;
932     }
933 
934   if(fcntl(fd, F_SETFL, i | flags) == -1)
935     {
936       return -1;
937     }
938 
939   return 0;
940 }
941 #endif
942 
json_esc(const char * in,char * out,size_t len)943 char *json_esc(const char *in, char *out, size_t len)
944 {
945   size_t off = 0;
946 
947   while(*in != '\0')
948     {
949       if(isprint(*in) == 0)
950 	break;
951 
952       switch(*in)
953 	{
954 	case '"':
955 	  if(off + 2 >= len)
956 	    goto done;
957 	  out[off++] = '\\';
958 	  out[off++] = '"';
959 	  break;
960 
961 	case '\\':
962 	  if(off + 2 >= len)
963 	    goto done;
964 	  out[off++] = '\\';
965 	  out[off++] = '\\';
966 	  break;
967 
968 	default:
969 	  out[off++] = *in;
970 	  break;
971 	}
972       in++;
973     }
974   out[off++] = '\0';
975 
976  done:
977   return out;
978 }
979 
string_isprint(const char * str,const size_t len)980 int string_isprint(const char *str, const size_t len)
981 {
982   size_t i = 0;
983 
984   for(i=0; i<len; i++)
985     {
986       if(isprint((int)str[i]) != 0)
987 	{
988 	  continue;
989 	}
990       else if(str[i] == '\0')
991 	{
992 	  break;
993 	}
994       else return 0;
995     }
996 
997   return 1;
998 }
999 
string_toupper(char * buf,size_t len,const char * in)1000 char *string_toupper(char *buf, size_t len, const char *in)
1001 {
1002   size_t off = 0;
1003   while(in[off] != '\0' && len - off > 1)
1004     {
1005       buf[off] = toupper(in[off]);
1006       off++;
1007     }
1008   buf[off] = '\0';
1009   return buf;
1010 }
1011 
string_tolong(const char * str,long * l)1012 int string_tolong(const char *str, long *l)
1013 {
1014   char *endptr;
1015 
1016   errno = 0;
1017   *l = strtol(str, &endptr, 0);
1018   if(*l == 0)
1019     {
1020       if(errno == EINVAL)
1021 	return -1;
1022     }
1023   else if(*l == LONG_MIN || *l == LONG_MAX)
1024     {
1025       if(errno == ERANGE)
1026 	return -1;
1027     }
1028 
1029   return 0;
1030 }
1031 
string_tollong(const char * str,long long * l)1032 int string_tollong(const char *str, long long *l)
1033 {
1034   char *endptr;
1035 
1036   errno = 0;
1037   *l = strtoll(str, &endptr, 0);
1038   if(*l == 0)
1039     {
1040       if(errno == EINVAL)
1041 	return -1;
1042     }
1043   else if(*l == LLONG_MIN || *l == LLONG_MAX)
1044     {
1045       if(errno == ERANGE)
1046 	return -1;
1047     }
1048 
1049   return 0;
1050 }
1051 
1052 /*
1053  * string_isalnum
1054  *
1055  * scan the word to establish if it is made up entirely of
1056  * alphanumeric characters.
1057  */
string_isalnum(const char * str)1058 int string_isalnum(const char *str)
1059 {
1060   if(*str == '\0')
1061     return 0;
1062   while(isalnum(*str) != 0)
1063     str++;
1064   if(*str == '\0')
1065     return 1;
1066   return 0;
1067 }
1068 
1069 /*
1070  * string_isdigit
1071  *
1072  * scan the word to establish if it is made up entirely of digits,
1073  * with no + or - at the start.
1074  */
string_isdigit(const char * str)1075 int string_isdigit(const char *str)
1076 {
1077   if(*str == '\0')
1078     return 0;
1079   while(isdigit(*str) != 0)
1080     str++;
1081   if(*str == '\0')
1082     return 1;
1083   return 0;
1084 }
1085 
1086 /*
1087  * string_isalpha
1088  *
1089  * scan the string to establish if it is made up entirely of alphabetic
1090  * characters.
1091  */
string_isalpha(const char * str)1092 int string_isalpha(const char *str)
1093 {
1094   if(*str == '\0')
1095     return 0;
1096   while(isalpha(*str) != 0)
1097     str++;
1098   if(*str == '\0')
1099     return 1;
1100   return 0;
1101 }
1102 
1103 /*
1104  * string_isnumber
1105  *
1106  * scan the word to establish if it an integer.
1107  */
string_isnumber(const char * str)1108 int string_isnumber(const char *str)
1109 {
1110   int i = 1;
1111 
1112   if(str[0] != '-' && str[0] != '+' && isdigit((int)str[0]) == 0)
1113     {
1114       return 0;
1115     }
1116 
1117   while(str[i] != '\0')
1118     {
1119       if(isdigit((int)str[i]) != 0)
1120 	{
1121 	  i++;
1122 	  continue;
1123 	}
1124 
1125       return 0;
1126     }
1127 
1128   return 1;
1129 }
1130 
1131 /*
1132  * string_isfloat
1133  *
1134  * scan the word to establish if it is a float.
1135  */
string_isfloat(const char * str)1136 int string_isfloat(const char *str)
1137 {
1138   int seen_dp = 0;
1139   int i = 1;
1140 
1141   if(str[0] != '-' && str[0] != '+' && isdigit((int)str[0]) == 0)
1142     {
1143       if(str[0] == '.')
1144 	{
1145 	  seen_dp = 1;
1146 	}
1147       else return 0;
1148     }
1149 
1150   while(str[i] != '\0')
1151     {
1152       if(isdigit((int)str[i]) != 0)
1153 	{
1154 	  i++;
1155 	  continue;
1156 	}
1157       else if(str[i] == '.')
1158 	{
1159 	  /* if the decimal point has already been seen */
1160 	  if(seen_dp == 1)
1161 	    {
1162 	      return 0;
1163 	    }
1164 
1165 	  i++;
1166 	  seen_dp = 1;
1167 	  continue;
1168 	}
1169       return 0;
1170     }
1171 
1172   return 1;
1173 }
1174 
1175 /*
1176  * string_nextword
1177  *
1178  * scan for the next word occurance in the string, after the current
1179  * word.  if there is no other word after this one, return NULL.
1180  */
string_nextword(char * buf)1181 char *string_nextword(char *buf)
1182 {
1183   /* scan for a start of a word */
1184   while(*buf != '\0' && isspace((int)*buf) == 0)
1185     {
1186       buf++;
1187     }
1188 
1189   if(*buf == '\0')
1190     {
1191       return NULL;
1192     }
1193   *buf = '\0';
1194   buf++;
1195 
1196   /* now scan for the end of the word */
1197   while(*buf != '\0' && isspace((int)*buf) != 0)
1198     {
1199       buf++;
1200     }
1201 
1202   if(*buf == '\0')
1203     {
1204       return NULL;
1205     }
1206 
1207   return buf;
1208 }
1209 
string_findlc(const char * str,const char * find)1210 const char *string_findlc(const char *str, const char *find)
1211 {
1212   const char *sp = str;
1213   int i;
1214 
1215   assert(*find != '\0');
1216   for(;;)
1217     {
1218       for(i=0; find[i] != '\0'; i++)
1219 	if(tolower((int)sp[i]) != find[i])
1220 	  break;
1221       if(find[i] == '\0')
1222 	return sp;
1223       if(sp[i] == '\0')
1224 	break;
1225       sp++;
1226     }
1227 
1228   return NULL;
1229 }
1230 
1231 /*
1232  * string_nullterm
1233  *
1234  * null terminate the string pointed to by buf at the first occurance of
1235  * a character in the delim string.
1236  *
1237  * if null termination occurs, this function returns a pointer to the first
1238  * byte of the buf (i.e. the buf parameter passed)
1239  */
string_nullterm(char * buf,const char * delim,char ** next)1240 char *string_nullterm(char *buf, const char *delim, char **next)
1241 {
1242   const char *dtmp;
1243   char *tmp;
1244 
1245   if(delim == NULL || *delim == '\0' || (tmp = buf) == NULL)
1246     return NULL;
1247 
1248   while(*tmp != '\0')
1249     {
1250       dtmp = delim;
1251 
1252       while(*dtmp != '\0')
1253 	{
1254 	  if(*tmp != *dtmp)
1255 	    {
1256 	      dtmp++;
1257 	      continue;
1258 	    }
1259 
1260 	  *tmp = '\0';
1261 	  if(next != NULL)
1262 	    {
1263 	      tmp++;
1264 	      *next = tmp;
1265 	    }
1266 	  return buf;
1267 	}
1268 
1269       tmp++;
1270     }
1271 
1272   if(next != NULL)
1273     *next = NULL;
1274   return buf;
1275 }
1276 
string_nullterm_char(char * buf,const char delim,char ** next)1277 char *string_nullterm_char(char *buf, const char delim, char **next)
1278 {
1279   char *tmp;
1280 
1281   if((tmp = buf) == NULL)
1282     return NULL;
1283 
1284   while(*tmp != '\0')
1285     {
1286       if(*tmp == delim)
1287 	{
1288 	  *tmp = '\0';
1289 	  if(next != NULL)
1290 	    {
1291 	      tmp++;
1292 	      *next = tmp;
1293 	    }
1294 	  return buf;
1295 	}
1296 
1297       tmp++;
1298     }
1299 
1300   if(next != NULL)
1301     *next = NULL;
1302   return buf;
1303 }
1304 
string_lastof(char * str,const char * delim)1305 char *string_lastof(char *str, const char *delim)
1306 {
1307   char *lastof = NULL;
1308   const char *d;
1309   int i;
1310 
1311   if(delim == NULL || *delim == '\0' || str == NULL)
1312     return NULL;
1313 
1314   for(i=0; str[i] != '\0'; i++)
1315     {
1316       for(d = delim; *d != '\0'; d++)
1317 	{
1318 	  if(str[i] == *d)
1319 	    {
1320 	      lastof = &str[i];
1321 	      break;
1322 	    }
1323 	}
1324     }
1325 
1326   return lastof;
1327 }
1328 
string_lastof_char(char * str,const char delim)1329 char *string_lastof_char(char *str, const char delim)
1330 {
1331   char *lastof = NULL;
1332   int i;
1333 
1334   if(str == NULL)
1335     return NULL;
1336 
1337   for(i=0; str[i] != '\0'; i++)
1338     {
1339       if(str[i] == delim)
1340 	{
1341 	  lastof = &str[i];
1342 	}
1343     }
1344 
1345   return lastof;
1346 }
1347 
string_firstof_char(char * str,const char delim)1348 char *string_firstof_char(char *str, const char delim)
1349 {
1350   char *firstof = NULL;
1351   int i;
1352 
1353   if(str == NULL)
1354     return NULL;
1355 
1356   for(i=0; str[i] != '\0'; i++)
1357     {
1358       if(str[i] == delim)
1359 	{
1360 	  firstof = &str[i];
1361 	  break;
1362 	}
1363     }
1364 
1365   return firstof;
1366 }
1367 
string_concat(char * str,size_t len,size_t * off,const char * fs,...)1368 char *string_concat(char *str, size_t len, size_t *off, const char *fs, ...)
1369 {
1370   va_list ap;
1371   size_t left;
1372   int wc;
1373 
1374   if(len < *off)
1375     return NULL;
1376 
1377   if((left = len - *off) == 0)
1378     return str;
1379 
1380   va_start(ap, fs);
1381   wc = vsnprintf(str + *off, left, fs, ap);
1382   va_end(ap);
1383 
1384   if(wc < 0)
1385     return NULL;
1386 
1387   *off = *off + ((size_t)wc < left ? wc : left);
1388   return str;
1389 }
1390 
1391 /*
1392  * string_addrport
1393  *
1394  * given an input string, return the ip address / name in the first part
1395  * (if present) and the port number in the second.  do some basic sanity
1396  * checking as well.
1397  */
string_addrport(const char * in,char ** first,int * port)1398 int string_addrport(const char *in, char **first, int *port)
1399 {
1400   char *ptr, *dup = NULL, *first_tmp = NULL;
1401   long lo;
1402 
1403   if(string_isnumber(in))
1404     {
1405       if(string_tolong(in, &lo) == -1 || lo < 1 || lo > 65535)
1406 	goto err;
1407       *first = NULL;
1408       *port  = lo;
1409       return 0;
1410     }
1411 
1412   if((dup = strdup(in)) == NULL)
1413     goto err;
1414 
1415   if(dup[0] == '[')
1416     {
1417       string_nullterm_char(dup, ']', &ptr);
1418       if(ptr == NULL || *ptr != ':' || (first_tmp = strdup(dup+1)) == NULL)
1419 	goto err;
1420       ptr++;
1421     }
1422   else
1423     {
1424       string_nullterm_char(dup, ':', &ptr);
1425       if(ptr == NULL || (first_tmp = strdup(dup)) == NULL)
1426 	goto err;
1427     }
1428 
1429   if(string_tolong(ptr, &lo) != 0 || lo < 1 || lo > 65535)
1430     goto err;
1431 
1432   *first = first_tmp;
1433   *port  = lo;
1434   free(dup);
1435   return 0;
1436 
1437  err:
1438   if(first_tmp != NULL) free(first_tmp);
1439   if(dup != NULL) free(dup);
1440   return -1;
1441 }
1442 
1443 #ifndef NDEBUG
string_isdash(const char * str)1444 int string_isdash(const char *str)
1445 {
1446   if(str[0] == '-' && str[1] == '\0')
1447     return 1;
1448   return 0;
1449 }
1450 #endif
1451 
mem_concat(void * dst,const void * src,size_t len,size_t * off,size_t size)1452 void mem_concat(void *dst,const void *src,size_t len,size_t *off,size_t size)
1453 {
1454   assert(*off + len <= size);
1455   memcpy(((uint8_t *)dst) + *off, src, len);
1456   *off += len;
1457   return;
1458 }
1459 
ishex(char c)1460 int ishex(char c)
1461 {
1462   if((c >= '0' && c <= '9') ||
1463      (c >= 'a' && c <= 'f') ||
1464      (c >= 'A' && c <= 'F'))
1465     {
1466       return 1;
1467     }
1468   return 0;
1469 }
1470 
hex2byte(char a,char b)1471 uint8_t hex2byte(char a, char b)
1472 {
1473   uint8_t out;
1474 
1475   assert(ishex(a));
1476   assert(ishex(b));
1477 
1478   if(a <= '9')      out = (((int)a - (int)'0') << 4);
1479   else if(a <= 'F') out = (((int)a - (int)'A' + 10) << 4);
1480   else              out = (((int)a - (int)'a' + 10) << 4);
1481 
1482   if(b <= '9')      out |= ((int)b - (int)'0');
1483   else if(b <= 'F') out |= ((int)b - (int)'A' + 10);
1484   else              out |= ((int)b - (int)'a' + 10);
1485 
1486   return out;
1487 }
1488 
byte2hex(uint8_t byte,char * a)1489 void byte2hex(uint8_t byte, char *a)
1490 {
1491   static const char hex[] = "01234567890abcdef";
1492   a[0] = hex[(byte >> 4)];
1493   a[1] = hex[byte & 0x0f];
1494   return;
1495 }
1496 
bytes_ntohs(const uint8_t * bytes)1497 uint16_t bytes_ntohs(const uint8_t *bytes)
1498 {
1499   uint16_t u16;
1500   memcpy(&u16, bytes, 2);
1501   return ntohs(u16);
1502 }
1503 
bytes_ntohl(const uint8_t * bytes)1504 uint32_t bytes_ntohl(const uint8_t *bytes)
1505 {
1506   uint32_t u32;
1507   memcpy(&u32, bytes, 4);
1508   return ntohl(u32);
1509 }
1510 
bytes_htons(uint8_t * bytes,uint16_t u16)1511 void bytes_htons(uint8_t *bytes, uint16_t u16)
1512 {
1513   uint16_t tmp = htons(u16);
1514   memcpy(bytes, &tmp, 2);
1515   return;
1516 }
1517 
bytes_htonl(uint8_t * bytes,uint32_t u32)1518 void bytes_htonl(uint8_t *bytes, uint32_t u32)
1519 {
1520   uint32_t tmp = htonl(u32);
1521   memcpy(bytes, &tmp, 4);
1522   return;
1523 }
1524 
read_wrap(const int fd,void * ptr,size_t * rc_out,const size_t rt)1525 int read_wrap(const int fd, void *ptr, size_t *rc_out, const size_t rt)
1526 {
1527   uint8_t *buf;
1528   int      ret = 0;
1529   ssize_t  r;
1530   size_t   rc;
1531 
1532   assert(rt > 0);
1533   assert(ptr != NULL);
1534 
1535   buf = (uint8_t *)ptr;
1536 
1537   for(rc = 0; rc < rt; rc += r)
1538     {
1539       if((r = read(fd, buf+rc, rt-rc)) < 0)
1540 	{
1541 	  if(errno == EINTR)
1542 	    {
1543 	      r = 0;
1544 	      continue;
1545 	    }
1546 	  ret = -1;
1547 	  break;
1548 	}
1549       else if(r == 0)
1550 	{
1551 	  ret = -2;
1552 	  break;
1553 	}
1554     }
1555 
1556   if(rc_out != NULL)
1557     {
1558       *rc_out = rc;
1559     }
1560 
1561   return ret;
1562 }
1563 
write_wrap(const int fd,const void * ptr,size_t * wc_out,const size_t wt)1564 int write_wrap(const int fd, const void *ptr, size_t *wc_out, const size_t wt)
1565 {
1566   int      ret = 0;
1567   ssize_t  w;
1568   size_t   wc;
1569 
1570   assert(wt > 0);
1571   assert(ptr != NULL);
1572 
1573   for(wc = 0; wc < wt; wc += w)
1574     {
1575       if((w = write(fd, ((const uint8_t *)ptr)+wc, wt-wc)) < 0)
1576 	{
1577 	  if(errno == EINTR)
1578 	    {
1579 	      w = 0;
1580 	      continue;
1581 	    }
1582 	  ret = -1;
1583 	  break;
1584 	}
1585     }
1586 
1587   if(wc_out != NULL)
1588     {
1589       *wc_out = wc;
1590     }
1591 
1592   return ret;
1593 }
1594 
1595 /*
1596  * mkdir_wrap
1597  *
1598  * iteratively call mkdir until the full path has been created
1599  */
1600 #ifndef _WIN32
mkdir_wrap(const char * path,mode_t mode)1601 int mkdir_wrap(const char *path, mode_t mode)
1602 #else
1603 int mkdir_wrap(const char *path)
1604 #endif
1605 {
1606   char *d = NULL;
1607   char *ptr;
1608 
1609   /* ensure there is actually a path to create ... */
1610   if(path[0] == '\0' || (path[0] == '/' && path[1] == '\0'))
1611     {
1612       return 0;
1613     }
1614 
1615   /* make a duplicate copy of the path that we are going to create */
1616   if((d = strdup(path)) == NULL)
1617     {
1618       goto err;
1619     }
1620   ptr = d;
1621 
1622   /* don't need to create the root directory ... */
1623   if(ptr[0] == '/') ptr++;
1624 
1625   while(ptr[0] != '\0')
1626     {
1627       if(ptr[0] == '/')
1628 	{
1629 	  /* temporarily replace the path delimeter */
1630 	  ptr[0] = '\0';
1631 
1632 	  if(mkdir(d, mode) != 0 && errno != EEXIST)
1633 	    {
1634 	      goto err;
1635 	    }
1636 
1637 	  ptr[0] = '/';
1638 	}
1639 
1640       ptr++;
1641     }
1642 
1643   /* create the last directory in the path */
1644   if(ptr[-1] != '/')
1645     {
1646       if(mkdir(d, mode) != 0 && errno != EEXIST)
1647 	{
1648 	  goto err;
1649 	}
1650     }
1651 
1652   free(d);
1653   return 0;
1654 
1655  err:
1656   if(d != NULL) free(d);
1657   return -1;
1658 }
1659 
1660 /*
1661  * fstat_mtime
1662  *
1663  * simple utility function that gets the mtime field from
1664  * a fstat call as a time_t.
1665  */
fstat_mtime(int fd,time_t * mtime)1666 int fstat_mtime(int fd, time_t *mtime)
1667 {
1668   struct stat sb;
1669 
1670   if(fstat(fd, &sb) != 0)
1671     {
1672       return -1;
1673     }
1674 
1675   *mtime = sb.st_mtime;
1676   return 0;
1677 }
1678 
1679 /*
1680  * stat_mtime
1681  *
1682  * simple utility function that gets the mtime field from
1683  * a stat call as a time_t.
1684  */
stat_mtime(const char * filename,time_t * mtime)1685 int stat_mtime(const char *filename, time_t *mtime)
1686 {
1687   struct stat sb;
1688 
1689   if(stat(filename, &sb) != 0)
1690     {
1691       return -1;
1692     }
1693 
1694   *mtime = sb.st_mtime;
1695   return 0;
1696 }
1697 
1698 #if defined(HAVE_SYSCTL)
sysctl_wrap(int * mib,u_int len,void ** buf,size_t * size)1699 int sysctl_wrap(int *mib, u_int len, void **buf, size_t *size)
1700 {
1701   if(sysctl(mib, len, NULL, size, NULL, 0) != 0)
1702     {
1703       return -1;
1704     }
1705 
1706   if(*size == 0)
1707     {
1708       *buf = NULL;
1709       return 0;
1710     }
1711 
1712   if((*buf = malloc(*size)) == NULL)
1713     {
1714       return -1;
1715     }
1716 
1717   if(sysctl(mib, len, *buf, size, NULL, 0) != 0)
1718     {
1719       free(*buf);
1720       return -1;
1721     }
1722 
1723   return 0;
1724 }
1725 #endif
1726 
random_seed(void)1727 void random_seed(void)
1728 {
1729 #if defined(_WIN32) || defined(HAVE_ARC4RANDOM)
1730   return;
1731 #else
1732   struct timeval tv;
1733   gettimeofday_wrap(&tv);
1734   srandom(tv.tv_usec);
1735   return;
1736 #endif
1737 }
1738 
random_u32(uint32_t * r)1739 int random_u32(uint32_t *r)
1740 {
1741 #if defined(_WIN32)
1742   unsigned int ui;
1743   if(rand_s(&ui) != 0)
1744     return -1;
1745   *r = ui;
1746 #elif defined(HAVE_ARC4RANDOM)
1747   *r = arc4random();
1748 #else
1749   *r = random();
1750 #endif
1751   return 0;
1752 }
1753 
random_u16(uint16_t * r)1754 int random_u16(uint16_t *r)
1755 {
1756 #ifdef _WIN32
1757   unsigned int ui;
1758   if(rand_s(&ui) != 0)
1759     return -1;
1760   *r = ui;
1761 #elif defined(HAVE_ARC4RANDOM)
1762   *r = arc4random();
1763 #else
1764   *r = random();
1765 #endif
1766   return 0;
1767 }
1768 
random_u8(uint8_t * r)1769 int random_u8(uint8_t *r)
1770 {
1771 #ifdef _WIN32
1772   unsigned int ui;
1773   if(rand_s(&ui) != 0)
1774     return -1;
1775   *r = ui;
1776 #elif defined(HAVE_ARC4RANDOM)
1777   *r = arc4random();
1778 #else
1779   *r = random();
1780 #endif
1781   return 0;
1782 }
1783 
1784 /*
1785  * countbits32
1786  *
1787  * count the number of bits set in v.  first published by Peter Wegner in
1788  * CACM 3 (1960), 322.
1789  */
countbits32(uint32_t v)1790 int countbits32(uint32_t v)
1791 {
1792   int c;
1793   for(c=0; v != 0; c++)
1794     v &= v - 1;
1795   return c;
1796 }
1797 
1798 /* Fisher-Yates shuffle */
shuffle16(uint16_t * array,int len)1799 int shuffle16(uint16_t *array, int len)
1800 {
1801   int x, n = len;
1802   uint32_t k;
1803   uint16_t tmp;
1804 
1805   while(n > 1)
1806     {
1807       n--;
1808       if(random_u32(&k) != 0)
1809 	return -1;
1810 
1811       x = k % (n+1);
1812 
1813       tmp = array[x];
1814       array[x] = array[n];
1815       array[n] = tmp;
1816     }
1817 
1818   return 0;
1819 }
1820 
1821 /* Fisher-Yates shuffle */
shuffle32(uint32_t * array,int len)1822 int shuffle32(uint32_t *array, int len)
1823 {
1824   int n = len;
1825   uint32_t k, tmp;
1826 
1827   while(n > 1)
1828     {
1829       n--;
1830       if(random_u32(&k) != 0)
1831 	return -1;
1832       k %= n+1;
1833 
1834       tmp = array[k];
1835       array[k] = array[n];
1836       array[n] = tmp;
1837     }
1838 
1839   return 0;
1840 }
1841 
min_array(int * array,int len)1842 int min_array(int *array, int len)
1843 {
1844   int x, i;
1845   x = array[0];
1846   for(i=1; i<len; i++)
1847     if(x > array[i])
1848       x = array[i];
1849   return x;
1850 }
1851 
in_cksum(const void * buf,size_t len)1852 uint16_t in_cksum(const void *buf, size_t len)
1853 {
1854   uint16_t *w = (uint16_t *)buf;
1855   size_t l = len;
1856   int sum = 0;
1857 
1858   while(l > 1)
1859     {
1860       sum += *w++;
1861       l   -= 2;
1862     }
1863 
1864   if(l != 0)
1865     {
1866       sum += ((uint8_t *)w)[0];
1867     }
1868 
1869   sum  = (sum >> 16) + (sum & 0xffff);
1870   sum += (sum >> 16);
1871 
1872   return ~sum;
1873 }
1874 
1875 /*
1876  * uudecode_4
1877  *
1878  * decode four ascii characters to form up to 3 binary bytes.
1879  */
uudecode_4(uint8_t * out,const char * in,size_t c)1880 static int uudecode_4(uint8_t *out, const char *in, size_t c)
1881 {
1882   char a, b;
1883 
1884   if(c == 0)
1885     return -1;
1886 
1887   if(in[0] >= '!' && in[0] <= '`')
1888     a = in[0];
1889   else return -1;
1890 
1891   if(in[1] >= '!' && in[1] <= '`')
1892     b = in[1];
1893   else return -1;
1894 
1895   out[0] = (((a - 32) & 0x3f) << 2 & 0xfc) | (((b - 32) & 0x3f) >> 4 & 0x3);
1896 
1897   if(in[2] >= '!' && in[2] <= '`')
1898     a = in[2];
1899   else return -1;
1900 
1901   if(c > 1)
1902     out[1] = (((b - 32) & 0x3f) << 4 & 0xf0) | (((a - 32) & 0x3f) >> 2 & 0xf);
1903 
1904   if(in[3] >= '!' && in[3] <= '`')
1905     b = in[3];
1906   else return -1;
1907 
1908   if(c > 2)
1909     out[2] = (((a - 32) & 0x3f) << 6 & 0xc0) |  ((b - 32) & 0x3f);
1910 
1911   return 0;
1912 }
1913 
1914 /*
1915  * uudecode_line
1916  *
1917  * decode a uuencoded line into binary bytes.
1918  */
uudecode_line(const char * in,size_t ilen,uint8_t * out,size_t * olen)1919 int uudecode_line(const char *in, size_t ilen, uint8_t *out, size_t *olen)
1920 {
1921   size_t i, j, o;
1922 
1923   if(ilen == 0)
1924     goto err;
1925 
1926   /* EOF */
1927   if(in[0] == '`')
1928     {
1929       *olen = 0;
1930       return 0;
1931     }
1932 
1933   /* figure out the number of binary bytes that should be found */
1934   if(in[0] >= '!' && in[0] <= '`')
1935     o = in[0] - 32;
1936   else goto err;
1937 
1938   /* make sure we can uudecode to the buffer provided */
1939   if(o > *olen)
1940     goto err;
1941 
1942   i = 0;
1943   j = 1;
1944 
1945   for(;;)
1946     {
1947       /* there needs to be at least four characters remaining */
1948       if(ilen - j < 4)
1949 	goto err;
1950 
1951       /* decode 4 characters into 3 bytes */
1952       if(uudecode_4(out+i, in+j, o-i) != 0)
1953 	goto err;
1954 
1955       /* next block of 4 characters */
1956       j += 4;
1957 
1958       /* advance */
1959       if(o-i > 3)
1960 	i += 3;
1961       else break;
1962     }
1963 
1964   *olen = o;
1965   return 0;
1966 
1967  err:
1968   return -1;
1969 }
1970 
uudecode(const char * in,size_t len)1971 void *uudecode(const char *in, size_t len)
1972 {
1973   uint8_t *out = NULL;
1974   size_t i, j, k, x;
1975 
1976   /* if the first character is a ` (EOF) there is nothing to decode */
1977   if(in[0] == '`')
1978     return NULL;
1979 
1980   i = 0;
1981   x = 0;
1982 
1983   /* first, figure out how much memory to allocate */
1984   for(;;)
1985     {
1986       /* make sure character is valid */
1987       if(in[i] < '!' || in[i] > '`')
1988 	{
1989 	  goto err;
1990 	}
1991 
1992       /* check for EOF */
1993       if(in[i] == '`')
1994 	break;
1995 
1996       /* number of uuencoded bytes on this line */
1997       j = in[i++] - 32;
1998 
1999       /* number of ascii bytes required */
2000       k = j + (j/3);
2001       if((k % 4) != 0)
2002 	{
2003 	  k /= 4;
2004 	  k++;
2005 	  k *= 4;
2006 	}
2007 
2008       /* advance to the end of the line */
2009       if(len - i < k+1 || in[i+k] != '\n')
2010 	{
2011 	  goto err;
2012 	}
2013       i += k + 1;
2014       x += j;
2015     }
2016 
2017   /* make sure the uuencoded data ends with a new line */
2018   if(len - i < 1 || in[i+1] != '\n')
2019     {
2020       goto err;
2021     }
2022 
2023   if((out = malloc(x)) == NULL)
2024     goto err;
2025 
2026   i = 0;
2027   j = 0;
2028   for(;;)
2029     {
2030       /* number of uuencoded bytes on this line */
2031       k = in[i++] - 32;
2032       for(;;)
2033 	{
2034 	  /* there needs to be at least four characters remaining */
2035 	  if(len - i < 4)
2036 	    goto err;
2037 
2038 	  /* decode the next four */
2039 	  if(uudecode_4(out+j, in+i, x-j) != 0)
2040 	    goto err;
2041 
2042 	  i += 4;
2043 
2044 	  if(k > 3)
2045 	    {
2046 	      j += 3;
2047 	      k -= 3;
2048 	    }
2049 	  else
2050 	    {
2051 	      j += k;
2052 	      break;
2053 	    }
2054 	}
2055 
2056       /* advance to next line */
2057       if(in[i] != '\n')
2058 	goto err;
2059       i++;
2060 
2061       if(j == x)
2062 	break;
2063     }
2064 
2065   return out;
2066 
2067  err:
2068   if(out != NULL) free(out);
2069   return NULL;
2070 }
2071 
uuencode_3(uint8_t * out,uint8_t a,uint8_t b,uint8_t c)2072 static void uuencode_3(uint8_t *out, uint8_t a, uint8_t b, uint8_t c)
2073 {
2074   uint8_t t;
2075 
2076   out[0] = (t =  ((a >> 2)                     & 0x3f)) != 0 ? t + 32 : '`';
2077   out[1] = (t = (((a << 4) | ((b >> 4) & 0xf)) & 0x3f)) != 0 ? t + 32 : '`';
2078   out[2] = (t = (((b << 2) | ((c >> 6) & 0x3)) & 0x3f)) != 0 ? t + 32 : '`';
2079   out[3] = (t =   (c                           & 0x3f)) != 0 ? t + 32 : '`';
2080 
2081   return;
2082 }
2083 
uuencode_len(size_t ilen,size_t * complete,size_t * leftover)2084 size_t uuencode_len(size_t ilen, size_t *complete, size_t *leftover)
2085 {
2086   size_t len;
2087   size_t complete_lines;
2088   size_t leftover_bytes;
2089 
2090   assert(ilen != 0);
2091 
2092   /*
2093    * figure out how many complete lines there are,
2094    * and then how many leftover bytes there are
2095    */
2096   complete_lines = ilen / 45;
2097   leftover_bytes = ilen % 45;
2098 
2099   /*
2100    * an input line of 45 characters is transformed into an 60 character
2101    * sequence, with the length encoded as a character at the start, and
2102    * a new-line character at the end of the line
2103    */
2104   len = (complete_lines * 62);
2105 
2106   /*
2107    * if there are leftover bytes, then each group of three characters
2108    * will take four output bytes.  if the number of leftover bytes is not
2109    * a multiple of three, then they are encoded in a 4 character sequence.
2110    * finally, there's a length character at the start and a new line at the
2111    * end.
2112    */
2113   if(leftover_bytes != 0)
2114     {
2115       len += ((leftover_bytes / 3) * 4);
2116       if((leftover_bytes % 3) > 0)
2117 	{
2118 	  len += 4;
2119 	}
2120       len += 2;
2121     }
2122 
2123   /* allocate the end-of-data bytes */
2124   len += 2;
2125 
2126   if(complete != NULL) *complete = complete_lines;
2127   if(leftover != NULL) *leftover = leftover_bytes;
2128 
2129   return len;
2130 }
2131 
2132 /*
2133  * uuencode_bytes
2134  *
2135  * take an input buffer, and an offset into that buffer, and encode as
2136  * much of it as possible into the output buffer
2137  */
uuencode_bytes(const uint8_t * in,size_t len,size_t * off,uint8_t * out,size_t olen)2138 size_t uuencode_bytes(const uint8_t *in, size_t len, size_t *off,
2139 		      uint8_t *out, size_t olen)
2140 {
2141   static const uint8_t b[] = {
2142     2, 6,6,6, 10,10,10, 14,14,14, 18,18,18, 22,22,22, 26,26,26, 30,30,30,
2143     34,34,34, 38,38,38, 42,42,42, 46,46,46, 50,50,50, 54,54,54, 58,58,58,
2144     62,62,62};
2145   size_t ooff = 0, i, lc, bb;
2146 
2147   assert(*off < len);
2148 
2149   for(;;)
2150     {
2151       /* determine how many characters will be written out this time */
2152       if(len - *off >= 45)
2153 	lc = 45;
2154       else
2155 	lc = len - *off;
2156 
2157       /* determine how many bytes will be required */
2158       bb = b[lc];
2159       if(*off + lc == len)
2160 	bb += 2;
2161 
2162       /* if not enough space, then stop now */
2163       if(olen - ooff < bb)
2164 	break;
2165 
2166       /* write out the line */
2167       out[ooff++] = 32 + lc;
2168       for(i=0; i+3<=lc; i+=3)
2169 	{
2170 	  uuencode_3(out+ooff, in[*off], in[*off+1], in[*off+2]);
2171 	  *off += 3;
2172 	  ooff += 4;
2173 	}
2174       if(i != lc)
2175 	{
2176 	  lc -= i;
2177       	  uuencode_3(out+ooff, in[*off], lc == 2 ? in[*off+1] : 0, 0);
2178 	  *off += lc;
2179 	  ooff += 4;
2180 	}
2181       out[ooff++] = '\n';
2182 
2183       /* encode eof */
2184       if(*off == len)
2185 	{
2186 	  out[ooff++] = '`';
2187 	  out[ooff++] = '\n';
2188 	  break;
2189 	}
2190     }
2191 
2192   return ooff;
2193 }
2194 
uuencode(const uint8_t * in,size_t ilen,uint8_t ** out,size_t * olen)2195 int uuencode(const uint8_t *in, size_t ilen, uint8_t **out, size_t *olen)
2196 {
2197   uint8_t *ptr;
2198   size_t len;
2199   size_t complete_lines;
2200   size_t leftover_bytes;
2201   size_t i, j;
2202 
2203   /* figure out how large the allocated buffer needs to be */
2204   len = uuencode_len(ilen, &complete_lines, &leftover_bytes);
2205   assert(len != 0);
2206 
2207   /* allocate memory to encode the data to */
2208   if((ptr = malloc(len)) == NULL)
2209     return -1;
2210   *out  = ptr;
2211   *olen = len;
2212 
2213   /* encode all complete lines */
2214   for(i=0; i<complete_lines; i++)
2215     {
2216       *ptr = (32 + 45); ptr++;
2217       for(j=0; j<15; j++)
2218 	{
2219 	  uuencode_3(ptr, in[0], in[1], in[2]);
2220 	  in  += 3;
2221 	  ptr += 4;
2222 	}
2223       *ptr = '\n'; ptr++;
2224     }
2225 
2226   /* encode the last line */
2227   if(leftover_bytes != 0)
2228     {
2229       /* encode groups of 3 input bytes */
2230       *ptr = (32 + leftover_bytes); ptr++;
2231       for(j=0; j<leftover_bytes/3; j++)
2232 	{
2233 	  uuencode_3(ptr, in[0], in[1], in[2]);
2234 	  in  += 3;
2235 	  ptr += 4;
2236 	}
2237 
2238       /* if there are one or two straggling bytes left, encode those */
2239       if((leftover_bytes % 3) > 0)
2240 	{
2241 	  uuencode_3(ptr, in[0], (leftover_bytes % 3) == 2 ? in[1] : 0, 0);
2242 	  ptr += 4;
2243 	}
2244 
2245       *ptr = '\n'; ptr++;
2246     }
2247 
2248   /* this line has no data -- uuencode EOF */
2249   *ptr = '`'; ptr++;
2250   *ptr = '\n';
2251 
2252   return 0;
2253 }
2254 
byteswap16(const uint16_t word)2255 uint16_t byteswap16(const uint16_t word)
2256 {
2257   return ((word >> 8) | (word << 8));
2258 }
2259 
byteswap32(const uint32_t word)2260 uint32_t byteswap32(const uint32_t word)
2261 {
2262   return ((word << 24) | (word >> 24) |
2263 	  ((word & 0xff00) << 8) | ((word >> 8) & 0xff00));
2264 }
2265 
fd_lines(int fd,int (* func)(char *,void *),void * param)2266 int fd_lines(int fd, int (*func)(char *, void *), void *param)
2267 {
2268   char *readbuf = NULL;
2269   size_t readbuf_len, readbuf_off;
2270   size_t start, end, off;
2271   int rc = -1;
2272   ssize_t ss;
2273 
2274   readbuf_len = 8192; readbuf_off = 0;
2275   if((readbuf = malloc(readbuf_len)) == NULL)
2276     goto done;
2277 
2278   while((ss = read(fd, readbuf+readbuf_off, readbuf_len-readbuf_off-1)) >= 0)
2279     {
2280       start = 0; off = 0;
2281       end = readbuf_off + ss;
2282 
2283       while(off <= end)
2284 	{
2285 	  if(off == end && ss != 0)
2286 	    break;
2287 	  if(readbuf[off] == '\n' || (off == end && start < off))
2288 	    {
2289 	      readbuf[off] = '\0';
2290 	      if(func(readbuf+start, param) != 0)
2291 		goto done;
2292 	      start = ++off;
2293 	    }
2294 	  else
2295 	    {
2296 	      ++off;
2297 	    }
2298 	}
2299 
2300       if(ss == 0)
2301 	{
2302 	  rc = 0;
2303 	  break;
2304 	}
2305       else if(start == 0)
2306 	{
2307 	  readbuf_len += 8192;
2308 	  readbuf_off = off;
2309 	  if(realloc_wrap((void **)&readbuf, readbuf_len) != 0)
2310 	    goto done;
2311 	}
2312       else
2313 	{
2314 	  memmove(readbuf, readbuf+start, end - start);
2315 	  readbuf_off = end - start;
2316 	}
2317     }
2318 
2319  done:
2320   if(readbuf != NULL) free(readbuf);
2321   return rc;
2322 }
2323 
2324 /* process a text file, line by line */
file_lines(const char * filename,int (* func)(char *,void *),void * param)2325 int file_lines(const char *filename, int (*func)(char *, void *), void *param)
2326 {
2327   int rc, fd = -1;
2328   if((fd = open(filename, O_RDONLY)) < 0)
2329     return -1;
2330   rc = fd_lines(fd, func, param);
2331   close(fd);
2332   return rc;
2333 }
2334 
offt_tostr(char * buf,size_t len,off_t off,int lz,char c)2335 char *offt_tostr(char *buf, size_t len, off_t off, int lz, char c)
2336 {
2337   char sp[8];
2338 
2339   assert(lz >= 0);
2340 
2341   if(sizeof(int) == sizeof(off_t))
2342     {
2343       if(lz == 0)
2344 	snprintf(sp, sizeof(sp), "%%%c", c);
2345       else
2346 	snprintf(sp, sizeof(sp), "%%0%d%c", lz, c);
2347     }
2348   else if(sizeof(long int) == sizeof(off_t))
2349     {
2350       if(lz == 0)
2351 	snprintf(sp, sizeof(sp), "%%l%c", c);
2352       else
2353 	snprintf(sp, sizeof(sp), "%%0%dl%c", lz, c);
2354     }
2355   else if(sizeof(long long int) == sizeof(off_t))
2356     {
2357       if(lz == 0)
2358 	snprintf(sp, sizeof(sp), "%%ll%c", c);
2359       else
2360 	snprintf(sp, sizeof(sp), "%%0%dll%c", lz, c);
2361     }
2362   else
2363     {
2364       return NULL;
2365     }
2366 
2367   snprintf(buf, len, sp, off);
2368   return buf;
2369 }
2370