All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
misc.c
Go to the documentation of this file.
1 /*
2  * misc.c Various miscellaneous functions.
3  *
4  * Version: $Id: c598f38d450e6c0402db4c39678aef7478fa71d6 $
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  *
20  * Copyright 2000,2006 The FreeRADIUS server project
21  */
22 
23 RCSID("$Id: c598f38d450e6c0402db4c39678aef7478fa71d6 $")
24 
25 #include <freeradius-devel/libradius.h>
26 
27 #include <ctype.h>
28 #include <sys/file.h>
29 #include <fcntl.h>
30 #include <grp.h>
31 #include <pwd.h>
32 #include <sys/uio.h>
33 
34 #define FR_PUT_LE16(a, val)\
35  do {\
36  a[1] = ((uint16_t) (val)) >> 8;\
37  a[0] = ((uint16_t) (val)) & 0xff;\
38  } while (0)
39 
40 int fr_debug_lvl = 0;
41 
42 static char const *months[] = {
43  "jan", "feb", "mar", "apr", "may", "jun",
44  "jul", "aug", "sep", "oct", "nov", "dec" };
45 
46 typedef struct fr_talloc_link {
47  bool armed;
48  TALLOC_CTX *child;
50 
51 /** Sets a signal handler using sigaction if available, else signal
52  *
53  * @param sig to set handler for.
54  * @param func handler to set.
55  */
56 int fr_set_signal(int sig, sig_t func)
57 {
58 #ifdef HAVE_SIGACTION
59  struct sigaction act;
60 
61  memset(&act, 0, sizeof(act));
62  act.sa_flags = 0;
63  sigemptyset(&act.sa_mask);
64  act.sa_handler = func;
65 
66  if (sigaction(sig, &act, NULL) < 0) {
67  fr_strerror_printf("Failed setting signal %i handler via sigaction(): %s", sig, fr_syserror(errno));
68  return -1;
69  }
70 #else
71  if (signal(sig, func) < 0) {
72  fr_strerror_printf("Failed setting signal %i handler via signal(): %s", sig, fr_syserror(errno));
73  return -1;
74  }
75 #endif
76  return 0;
77 }
78 
80 {
81  if (trigger->armed) talloc_free(trigger->child);
82 
83  return 0;
84 }
85 
86 static int _fr_disarm_talloc_ctx_free(bool **armed)
87 {
88  **armed = false;
89  return 0;
90 }
91 
92 /** Link a parent and a child context, so the child is freed before the parent
93  *
94  * @note This is not thread safe. Do not free parent before threads are joined, do not call from a
95  * child thread.
96  * @note It's OK to free the child before threads are joined, but this will leak memory until the
97  * parent is freed.
98  *
99  * @param parent who's fate the child should share.
100  * @param child bound to parent's lifecycle.
101  * @return
102  * - 0 on success.
103  * - -1 on failure.
104  */
105 int fr_talloc_link_ctx(TALLOC_CTX *parent, TALLOC_CTX *child)
106 {
107  fr_talloc_link_t *trigger;
108  bool **disarm;
109 
110  trigger = talloc(parent, fr_talloc_link_t);
111  if (!trigger) return -1;
112 
113  disarm = talloc(child, bool *);
114  if (!disarm) {
115  talloc_free(trigger);
116  return -1;
117  }
118 
119  trigger->child = child;
120  trigger->armed = true;
121  *disarm = &trigger->armed;
122 
123  talloc_set_destructor(trigger, _fr_trigger_talloc_ctx_free);
124  talloc_set_destructor(disarm, _fr_disarm_talloc_ctx_free);
125 
126  return 0;
127 }
128 
129 /*
130  * cppcheck apparently can't pick this up from the system headers.
131  */
132 #ifdef CPPCHECK
133 #define F_WRLCK
134 #endif
135 
136 /*
137  * Internal wrapper for locking, to minimize the number of ifdef's
138  *
139  * Use fcntl or error
140  */
141 int rad_lockfd(int fd, int lock_len)
142 {
143 #ifdef F_WRLCK
144  struct flock fl;
145 
146  fl.l_start = 0;
147  fl.l_len = lock_len;
148  fl.l_pid = getpid();
149  fl.l_type = F_WRLCK;
150  fl.l_whence = SEEK_CUR;
151 
152  return fcntl(fd, F_SETLKW, (void *)&fl);
153 #else
154 #error "missing definition for F_WRLCK, all file locks will fail"
155 
156  return -1;
157 #endif
158 }
159 
160 /*
161  * Internal wrapper for locking, to minimize the number of ifdef's
162  *
163  * Lock an fd, prefer lockf() over flock()
164  * Nonblocking version.
165  */
166 int rad_lockfd_nonblock(int fd, int lock_len)
167 {
168 #ifdef F_WRLCK
169  struct flock fl;
170 
171  fl.l_start = 0;
172  fl.l_len = lock_len;
173  fl.l_pid = getpid();
174  fl.l_type = F_WRLCK;
175  fl.l_whence = SEEK_CUR;
176 
177  return fcntl(fd, F_SETLK, (void *)&fl);
178 #else
179 #error "missing definition for F_WRLCK, all file locks will fail"
180 
181  return -1;
182 #endif
183 }
184 
185 /*
186  * Internal wrapper for unlocking, to minimize the number of ifdef's
187  * in the source.
188  *
189  * Unlock an fd, prefer lockf() over flock()
190  */
191 int rad_unlockfd(int fd, int lock_len)
192 {
193 #ifdef F_WRLCK
194  struct flock fl;
195 
196  fl.l_start = 0;
197  fl.l_len = lock_len;
198  fl.l_pid = getpid();
199  fl.l_type = F_WRLCK;
200  fl.l_whence = SEEK_CUR;
201 
202  return fcntl(fd, F_UNLCK, (void *)&fl);
203 #else
204 #error "missing definition for F_WRLCK, all file locks will fail"
205 
206  return -1;
207 #endif
208 }
209 
210 static char const hextab[] = "0123456789abcdef";
211 
212 /** Convert hex strings to binary data
213  *
214  * @param bin Buffer to write output to.
215  * @param outlen length of output buffer (or length of input string / 2).
216  * @param hex input string.
217  * @param inlen length of the input string
218  * @return length of data written to buffer.
219  */
220 size_t fr_hex2bin(uint8_t *bin, size_t outlen, char const *hex, size_t inlen)
221 {
222  size_t i;
223  size_t len;
224  char *c1, *c2;
225 
226  /*
227  * Smartly truncate output, caller should check number of bytes
228  * written.
229  */
230  len = inlen >> 1;
231  if (len > outlen) len = outlen;
232 
233  for (i = 0; i < len; i++) {
234  if(!(c1 = memchr(hextab, tolower((int) hex[i << 1]), sizeof(hextab))) ||
235  !(c2 = memchr(hextab, tolower((int) hex[(i << 1) + 1]), sizeof(hextab))))
236  break;
237  bin[i] = ((c1-hextab)<<4) + (c2-hextab);
238  }
239 
240  return i;
241 }
242 
243 /** Convert binary data to a hex string
244  *
245  * Ascii encoded hex string will not be prefixed with '0x'
246  *
247  * @warning If the output buffer isn't long enough, we have a buffer overflow.
248  *
249  * @param[out] hex Buffer to write hex output.
250  * @param[in] bin input.
251  * @param[in] inlen of bin input.
252  * @return length of data written to buffer.
253  */
254 size_t fr_bin2hex(char *hex, uint8_t const *bin, size_t inlen)
255 {
256  size_t i;
257 
258  for (i = 0; i < inlen; i++) {
259  hex[0] = hextab[((*bin) >> 4) & 0x0f];
260  hex[1] = hextab[*bin & 0x0f];
261  hex += 2;
262  bin++;
263  }
264 
265  *hex = '\0';
266  return inlen * 2;
267 }
268 
269 /** Convert binary data to a hex string
270  *
271  * Ascii encoded hex string will not be prefixed with '0x'
272  *
273  * @param[in] ctx to alloc buffer in.
274  * @param[in] bin input.
275  * @param[in] inlen of bin input.
276  * @return length of data written to buffer.
277  */
278 char *fr_abin2hex(TALLOC_CTX *ctx, uint8_t const *bin, size_t inlen)
279 {
280  char *buff;
281 
282  buff = talloc_array(ctx, char, (inlen << 2));
283  if (!buff) return NULL;
284 
285  fr_bin2hex(buff, bin, inlen);
286 
287  return buff;
288 }
289 
290 /** Consume the integer (or hex) portion of a value string
291  *
292  * @param value string to parse.
293  * @param end pointer to the first non numeric char.
294  * @return integer value.
295  */
296 uint32_t fr_strtoul(char const *value, char **end)
297 {
298  if ((value[0] == '0') && (value[1] == 'x')) {
299  return strtoul(value, end, 16);
300  }
301 
302  return strtoul(value, end, 10);
303 }
304 
305 /** Check whether the string is all whitespace
306  *
307  * @return
308  * - true if the entirety of the string is whitespace.
309  * - false if the string contains non whitespace.
310  */
311 bool is_whitespace(char const *value)
312 {
313  do {
314  if (!isspace(*value)) return false;
315  } while (*++value);
316 
317  return true;
318 }
319 
320 /** Check whether the string is made up of printable UTF8 chars
321  *
322  * @param value to check.
323  * @param len of value.
324  *
325  * @return
326  * - true if the string is printable.
327  * - false if the string contains non printable chars
328  */
329  bool is_printable(void const *value, size_t len)
330  {
331  uint8_t const *p = value;
332  int clen;
333  size_t i;
334 
335  for (i = 0; i < len; i++) {
336  clen = fr_utf8_char(p, len - i);
337  if (clen == 0) return false;
338  i += (size_t)clen;
339  p += clen;
340  }
341  return true;
342  }
343 
344 /** Check whether the string is all numbers
345  *
346  * @return
347  * - true if the entirety of the string is number chars.
348  * - false if string contains no number chars.
349  */
350 bool is_integer(char const *value)
351 {
352  do {
353  if (!isdigit(*value)) return false;
354  } while (*++value);
355 
356  return true;
357 }
358 
359 /** Check whether the string is all zeros
360  *
361  * @return
362  * - true if the entirety of the string is all zeros.
363  * - false if string contains no zeros.
364  */
365 bool is_zero(char const *value)
366 {
367  do {
368  if (*value != '0') return false;
369  } while (*++value);
370 
371  return true;
372 }
373 
374 /*
375  * So we don't have ifdef's in the rest of the code
376  */
377 #ifndef HAVE_CLOSEFROM
378 int closefrom(int fd)
379 {
380  int i;
381  int maxfd = 256;
382 
383 #ifdef _SC_OPEN_MAX
384  maxfd = sysconf(_SC_OPEN_MAX);
385  if (maxfd < 0) {
386  maxfd = 256;
387  }
388 #endif
389 
390  if (fd > maxfd) return 0;
391 
392  /*
393  * FIXME: return EINTR?
394  *
395  * Use F_CLOSEM?
396  */
397  for (i = fd; i < maxfd; i++) {
398  close(i);
399  }
400 
401  return 0;
402 }
403 #endif
404 
405 #ifdef O_NONBLOCK
406 /** Set O_NONBLOCK on a socket
407  *
408  * @note O_NONBLOCK is POSIX.
409  *
410  * @param fd to set nonblocking flag on.
411  * @return
412  * - Flags set on the socket.
413  * - -1 on failure.
414  */
415 int fr_nonblock(int fd)
416 {
417  int flags;
418 
419  flags = fcntl(fd, F_GETFL, NULL);
420  if (flags < 0) {
421  fr_strerror_printf("Failure getting socket flags: %s", fr_syserror(errno));
422  return -1;
423  }
424 
425  flags |= O_NONBLOCK;
426  if (fcntl(fd, F_SETFL, flags) < 0) {
427  fr_strerror_printf("Failure setting socket flags: %s", fr_syserror(errno));
428  return -1;
429  }
430 
431  return flags;
432 }
433 
434 /** Unset O_NONBLOCK on a socket
435  *
436  * @note O_NONBLOCK is POSIX.
437  *
438  * @param fd to set nonblocking flag on.
439  * @return
440  * - Flags set on the socket.
441  * - -1 on failure.
442  */
443 int fr_blocking(int fd)
444 {
445  int flags;
446 
447  flags = fcntl(fd, F_GETFL, NULL);
448  if (flags < 0) {
449  fr_strerror_printf("Failure getting socket flags: %s", fr_syserror(errno));
450  return -1;
451  }
452 
453  flags ^= O_NONBLOCK;
454  if (fcntl(fd, F_SETFL, flags) < 0) {
455  fr_strerror_printf("Failure setting socket flags: %s", fr_syserror(errno));
456  return -1;
457  }
458 
459  return flags;
460 }
461 #else
462 int fr_nonblock(UNUSED int fd)
463 {
464  fr_strerror_printf("Non blocking sockets are not supported");
465  return -1;
466 }
467 int fr_blocking(UNUSED int fd)
468 {
469  fr_strerror_printf("Non blocking sockets are not supported");
470  return -1;
471 }
472 #endif
473 
474 /** Write out a vector to a file descriptor
475  *
476  * Wraps writev, calling it as necessary. If timeout is not NULL,
477  * timeout is applied to each call that returns EAGAIN or EWOULDBLOCK
478  *
479  * @note Should only be used on nonblocking file descriptors.
480  * @note Socket should likely be closed on timeout.
481  * @note iovec may be modified in such a way that it's not re-usable.
482  * @note Leaves errno set to the last error that occurred.
483  *
484  * @param fd to write to.
485  * @param vector to write.
486  * @param iovcnt number of elements in iovec.
487  * @param timeout how long to wait for fd to become writeable before timing out.
488  * @return
489  * - Number of bytes written.
490  * - -1 on failure.
491  */
492 ssize_t fr_writev(int fd, struct iovec vector[], int iovcnt, struct timeval *timeout)
493 {
494  struct iovec *vector_p = vector;
495  ssize_t total = 0;
496 
497  while (iovcnt > 0) {
498  ssize_t wrote;
499 
500  wrote = writev(fd, vector_p, iovcnt);
501  if (wrote > 0) {
502  total += wrote;
503  while (wrote > 0) {
504  /*
505  * An entire vector element was written
506  */
507  if (wrote >= (ssize_t)vector_p->iov_len) {
508  iovcnt--;
509  wrote -= vector_p->iov_len;
510  vector_p++;
511  continue;
512  }
513 
514  /*
515  * Partial vector element was written
516  */
517  vector_p->iov_len -= wrote;
518  vector_p->iov_base = ((char *)vector_p->iov_base) + wrote;
519  break;
520  }
521  continue;
522  } else if (wrote == 0) return total;
523 
524  switch (errno) {
525  /* Write operation would block, use select() to implement a timeout */
526 #if EWOULDBLOCK != EAGAIN
527  case EWOULDBLOCK:
528  case EAGAIN:
529 #else
530  case EAGAIN:
531 #endif
532  {
533  int ret;
534  fd_set write_set;
535 
536  FD_ZERO(&write_set);
537  FD_SET(fd, &write_set);
538 
539  /* Don't let signals mess up the select */
540  do {
541  ret = select(fd + 1, NULL, &write_set, NULL, timeout);
542  } while ((ret == -1) && (errno == EINTR));
543 
544  /* Select returned 0 which means it reached the timeout */
545  if (ret == 0) {
546  fr_strerror_printf("Write timed out");
547  return -1;
548  }
549 
550  /* Other select error */
551  if (ret < 0) {
552  fr_strerror_printf("Failed waiting on socket: %s", fr_syserror(errno));
553  return -1;
554  }
555 
556  /* select said a file descriptor was ready for writing */
557  if (!fr_assert(FD_ISSET(fd, &write_set))) return -1;
558 
559  break;
560  }
561 
562  default:
563  return -1;
564  }
565  }
566 
567  return total;
568 }
569 
570 /** Convert UTF8 string to UCS2 encoding
571  *
572  * @note Borrowed from src/crypto/ms_funcs.c of wpa_supplicant project (http://hostap.epitest.fi/wpa_supplicant/)
573  *
574  * @param[out] out Where to write the ucs2 string.
575  * @param[in] outlen Size of output buffer.
576  * @param[in] in UTF8 string to convert.
577  * @param[in] inlen length of UTF8 string.
578  * @return the size of the UCS2 string written to the output buffer (in bytes).
579  */
580 ssize_t fr_utf8_to_ucs2(uint8_t *out, size_t outlen, char const *in, size_t inlen)
581 {
582  size_t i;
583  uint8_t *start = out;
584 
585  for (i = 0; i < inlen; i++) {
586  uint8_t c, c2, c3;
587 
588  c = in[i];
589  if ((size_t)(out - start) >= outlen) {
590  /* input too long */
591  return -1;
592  }
593 
594  /* One-byte encoding */
595  if (c <= 0x7f) {
596  FR_PUT_LE16(out, c);
597  out += 2;
598  continue;
599  } else if ((i == (inlen - 1)) || ((size_t)(out - start) >= (outlen - 1))) {
600  /* Incomplete surrogate */
601  return -1;
602  }
603 
604  c2 = in[++i];
605  /* Two-byte encoding */
606  if ((c & 0xe0) == 0xc0) {
607  FR_PUT_LE16(out, ((c & 0x1f) << 6) | (c2 & 0x3f));
608  out += 2;
609  continue;
610  }
611  if ((i == inlen) || ((size_t)(out - start) >= (outlen - 1))) {
612  /* Incomplete surrogate */
613  return -1;
614  }
615 
616  /* Three-byte encoding */
617  c3 = in[++i];
618  FR_PUT_LE16(out, ((c & 0xf) << 12) | ((c2 & 0x3f) << 6) | (c3 & 0x3f));
619  out += 2;
620  }
621 
622  return out - start;
623 }
624 
625 /** Write 128bit unsigned integer to buffer
626  *
627  * @author Alexey Frunze
628  *
629  * @param out where to write result to.
630  * @param outlen size of out.
631  * @param num 128 bit integer.
632  */
633 size_t fr_snprint_uint128(char *out, size_t outlen, uint128_t const num)
634 {
635  char buff[128 / 3 + 1 + 1];
636  uint64_t n[2];
637  char *p = buff;
638  int i;
639 #ifndef WORDS_BIGENDIAN
640  const size_t l = 0;
641  const size_t h = 1;
642 #else
643  const size_t l = 1;
644  const size_t h = 0;
645 #endif
646 
647  memset(buff, '0', sizeof(buff) - 1);
648  buff[sizeof(buff) - 1] = '\0';
649 
650  memcpy(n, &num, sizeof(n));
651 
652  for (i = 0; i < 128; i++) {
653  ssize_t j;
654  int carry;
655 
656  carry = (n[h] >= 0x8000000000000000);
657 
658  // Shift n[] left, doubling it
659  n[h] = ((n[h] << 1) & 0xffffffffffffffff) + (n[l] >= 0x8000000000000000);
660  n[l] = ((n[l] << 1) & 0xffffffffffffffff);
661 
662  // Add s[] to itself in decimal, doubling it
663  for (j = sizeof(buff) - 2; j >= 0; j--) {
664  buff[j] += buff[j] - '0' + carry;
665  carry = (buff[j] > '9');
666  if (carry) {
667  buff[j] -= 10;
668  }
669  }
670  }
671 
672  while ((*p == '0') && (p < &buff[sizeof(buff) - 2])) {
673  p++;
674  }
675 
676  return strlcpy(out, p, outlen);
677 }
678 
679 /*
680  * Sort of strtok/strsep function.
681  */
682 static char *mystrtok(char **ptr, char const *sep)
683 {
684  char *res;
685 
686  if (**ptr == 0) {
687  return NULL;
688  }
689 
690  while (**ptr && strchr(sep, **ptr)) {
691  (*ptr)++;
692  }
693  if (**ptr == 0) {
694  return NULL;
695  }
696 
697  res = *ptr;
698  while (**ptr && strchr(sep, **ptr) == NULL) {
699  (*ptr)++;
700  }
701 
702  if (**ptr != 0) {
703  *(*ptr)++ = 0;
704  }
705  return res;
706 }
707 
708 /** Convert string in various formats to a time_t
709  *
710  * @param date_str input date string.
711  * @param date time_t to write result to.
712  * @return
713  * - 0 on success.
714  * - -1 on failure.
715  */
716 int fr_get_time(char const *date_str, time_t *date)
717 {
718  int i;
719  time_t t;
720  struct tm *tm, s_tm;
721  char buf[64];
722  char *p;
723  char *f[4];
724  char *tail = NULL;
725 
726  /*
727  * Test for unix timestamp date
728  */
729  *date = strtoul(date_str, &tail, 10);
730  if (*tail == '\0') {
731  return 0;
732  }
733 
734  tm = &s_tm;
735  memset(tm, 0, sizeof(*tm));
736  tm->tm_isdst = -1; /* don't know, and don't care about DST */
737 
738  strlcpy(buf, date_str, sizeof(buf));
739 
740  p = buf;
741  f[0] = mystrtok(&p, " \t");
742  f[1] = mystrtok(&p, " \t");
743  f[2] = mystrtok(&p, " \t");
744  f[3] = mystrtok(&p, " \t"); /* may, or may not, be present */
745  if (!f[0] || !f[1] || !f[2]) return -1;
746 
747  /*
748  * The time has a colon, where nothing else does.
749  * So if we find it, bubble it to the back of the list.
750  */
751  if (f[3]) {
752  for (i = 0; i < 3; i++) {
753  if (strchr(f[i], ':')) {
754  p = f[3];
755  f[3] = f[i];
756  f[i] = p;
757  break;
758  }
759  }
760  }
761 
762  /*
763  * The month is text, which allows us to find it easily.
764  */
765  tm->tm_mon = 12;
766  for (i = 0; i < 3; i++) {
767  if (isalpha( (int) *f[i])) {
768  /*
769  * Bubble the month to the front of the list
770  */
771  p = f[0];
772  f[0] = f[i];
773  f[i] = p;
774 
775  for (i = 0; i < 12; i++) {
776  if (strncasecmp(months[i], f[0], 3) == 0) {
777  tm->tm_mon = i;
778  break;
779  }
780  }
781  }
782  }
783 
784  /* month not found? */
785  if (tm->tm_mon == 12) return -1;
786 
787  /*
788  * The year may be in f[1], or in f[2]
789  */
790  tm->tm_year = atoi(f[1]);
791  tm->tm_mday = atoi(f[2]);
792 
793  if (tm->tm_year >= 1900) {
794  tm->tm_year -= 1900;
795 
796  } else {
797  /*
798  * We can't use 2-digit years any more, they make it
799  * impossible to tell what's the day, and what's the year.
800  */
801  if (tm->tm_mday < 1900) return -1;
802 
803  /*
804  * Swap the year and the day.
805  */
806  i = tm->tm_year;
807  tm->tm_year = tm->tm_mday - 1900;
808  tm->tm_mday = i;
809  }
810 
811  /*
812  * If the day is out of range, die.
813  */
814  if ((tm->tm_mday < 1) || (tm->tm_mday > 31)) {
815  return -1;
816  }
817 
818  /*
819  * There may be %H:%M:%S. Parse it in a hacky way.
820  */
821  if (f[3]) {
822  f[0] = f[3]; /* HH */
823  f[1] = strchr(f[0], ':'); /* find : separator */
824  if (!f[1]) return -1;
825 
826  *(f[1]++) = '\0'; /* nuke it, and point to MM:SS */
827 
828  f[2] = strchr(f[1], ':'); /* find : separator */
829  if (f[2]) {
830  *(f[2]++) = '\0'; /* nuke it, and point to SS */
831  tm->tm_sec = atoi(f[2]);
832  } /* else leave it as zero */
833 
834  tm->tm_hour = atoi(f[0]);
835  tm->tm_min = atoi(f[1]);
836  }
837 
838  /*
839  * Returns -1 on failure.
840  */
841  t = mktime(tm);
842  if (t == (time_t) -1) return -1;
843 
844  *date = t;
845 
846  return 0;
847 }
848 
849 #define USEC 1000000
850 /** Subtract one timeval from another
851  *
852  * @param[out] out Where to write difference.
853  * @param[in] end Time closest to the present.
854  * @param[in] start Time furthest in the past.
855  */
856 void fr_timeval_subtract(struct timeval *out, struct timeval const *end, struct timeval const *start)
857 {
858  out->tv_sec = end->tv_sec - start->tv_sec;
859  if (out->tv_sec > 0) {
860  out->tv_sec--;
861  out->tv_usec = USEC;
862  } else {
863  out->tv_usec = 0;
864  }
865  out->tv_usec += end->tv_usec;
866  out->tv_usec -= start->tv_usec;
867 
868  if (out->tv_usec >= USEC) {
869  out->tv_usec -= USEC;
870  out->tv_sec++;
871  }
872 }
873 
874 #define NSEC 1000000000
875 /** Subtract one timespec from another
876  *
877  * @param[out] out Where to write difference.
878  * @param[in] end Time closest to the present.
879  * @param[in] start Time furthest in the past.
880  */
881 void fr_timespec_subtract(struct timespec *out, struct timespec const *end, struct timespec const *start)
882 {
883  out->tv_sec = end->tv_sec - start->tv_sec;
884  if (out->tv_sec > 0) {
885  out->tv_sec--;
886  out->tv_nsec = NSEC;
887  } else {
888  out->tv_nsec = 0;
889  }
890  out->tv_nsec += end->tv_nsec;
891  out->tv_nsec -= start->tv_nsec;
892 
893  if (out->tv_nsec >= NSEC) {
894  out->tv_nsec -= NSEC;
895  out->tv_sec++;
896  }
897 }
898 
899 /** Create timeval from a string
900  *
901  * @param[out] out Where to write timeval.
902  * @param[in] in String to parse.
903  * @return
904  * - 0 on success.
905  * - -1 on failure.
906  */
907 int fr_timeval_from_str(struct timeval *out, char const *in)
908 {
909  int sec;
910  char *end;
911  struct timeval tv;
912 
913  sec = strtoul(in, &end, 10);
914  if (in == end) {
915  fr_strerror_printf("Failed parsing \"%s\" as decimal", in);
916  return -1;
917  }
918  tv.tv_sec = sec;
919  tv.tv_usec = 0;
920  if (*end == '.') {
921  size_t len;
922 
923  len = strlen(end + 1);
924 
925  if (len > 6) {
926  fr_strerror_printf("Too much precision for timeval");
927  return -1;
928  }
929 
930  /*
931  * If they write "0.1", that means
932  * "10000" microseconds.
933  */
934  sec = strtoul(end + 1, &end, 10);
935  if (in == end) {
936  fr_strerror_printf("Failed parsing fractional component \"%s\" of decimal ", in);
937  return -1;
938  }
939  while (len < 6) {
940  sec *= 10;
941  len++;
942  }
943  tv.tv_usec = sec;
944  }
945  *out = tv;
946  return 0;
947 }
948 
949 /** Compares two pointers
950  *
951  * @param a first pointer to compare.
952  * @param b second pointer to compare.
953  * @return
954  * - -1 if a < b.
955  * - +1 if b > a.
956  * - 0 if both equal.
957  */
958 int8_t fr_pointer_cmp(void const *a, void const *b)
959 {
960  if (a < b) return -1;
961  if (a == b) return 0;
962 
963  return 1;
964 }
965 
966 static int _quick_partition(void const *to_sort[], int min, int max, fr_cmp_t cmp) {
967  void const *pivot = to_sort[min];
968  int i = min;
969  int j = max + 1;
970  void const *tmp;
971 
972  for (;;) {
973  do ++i; while((cmp(to_sort[i], pivot) <= 0) && i <= max);
974  do --j; while(cmp(to_sort[j], pivot) > 0);
975 
976  if (i >= j) break;
977 
978  tmp = to_sort[i];
979  to_sort[i] = to_sort[j];
980  to_sort[j] = tmp;
981  }
982 
983  tmp = to_sort[min];
984  to_sort[min] = to_sort[j];
985  to_sort[j] = tmp;
986 
987  return j;
988 }
989 
990 /** Quick sort an array of pointers using a comparator
991  *
992  * @param to_sort array of pointers to sort.
993  * @param min_idx the lowest index (usually 0).
994  * @param max_idx the highest index (usually length of array - 1).
995  * @param cmp the comparison function to use to sort the array elements.
996  */
997 void fr_quick_sort(void const *to_sort[], int min_idx, int max_idx, fr_cmp_t cmp)
998 {
999  int part;
1000 
1001  if (min_idx >= max_idx) return;
1002 
1003  part = _quick_partition(to_sort, min_idx, max_idx, cmp);
1004  fr_quick_sort(to_sort, min_idx, part - 1, cmp);
1005  fr_quick_sort(to_sort, part + 1, max_idx, cmp);
1006 }
1007 
1008 #ifdef TALLOC_DEBUG
1009 void fr_talloc_verify_cb(UNUSED const void *ptr, UNUSED int depth,
1010  UNUSED int max_depth, UNUSED int is_ref,
1011  UNUSED void *private_data)
1012 {
1013  /* do nothing */
1014 }
1015 #endif
int8_t(* fr_cmp_t)(void const *a, void const *b)
Definition: pair.h:227
static char * mystrtok(char **ptr, char const *sep)
Definition: misc.c:682
struct fr_talloc_link fr_talloc_link_t
int rad_lockfd_nonblock(int fd, int lock_len)
Definition: misc.c:166
ssize_t fr_writev(int fd, struct iovec vector[], int iovcnt, struct timeval *timeout)
Write out a vector to a file descriptor.
Definition: misc.c:492
size_t fr_hex2bin(uint8_t *bin, size_t outlen, char const *hex, size_t inlen)
Convert hex strings to binary data.
Definition: misc.c:220
void fr_timeval_subtract(struct timeval *out, struct timeval const *end, struct timeval const *start)
Subtract one timeval from another.
Definition: misc.c:856
static struct cmp * cmp
Definition: pair.c:45
int closefrom(int fd)
Definition: misc.c:378
void(* sig_t)(int)
Definition: libradius.h:111
#define UNUSED
Definition: libradius.h:134
size_t fr_bin2hex(char *hex, uint8_t const *bin, size_t inlen)
Convert binary data to a hex string.
Definition: misc.c:254
static float timeout
Definition: radclient.c:43
static int _fr_disarm_talloc_ctx_free(bool **armed)
Definition: misc.c:86
#define USEC
Definition: misc.c:849
int fr_nonblock(UNUSED int fd)
Definition: misc.c:462
static char const hextab[]
Definition: misc.c:210
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
Definition: log.c:238
TALLOC_CTX * child
Definition: misc.c:48
int fr_debug_lvl
Definition: misc.c:40
int fr_get_time(char const *date_str, time_t *date)
Convert string in various formats to a time_t.
Definition: misc.c:716
uint32_t fr_strtoul(char const *value, char **end)
Consume the integer (or hex) portion of a value string.
Definition: misc.c:296
#define fr_assert(_x)
Definition: libradius.h:505
ssize_t fr_utf8_to_ucs2(uint8_t *out, size_t outlen, char const *in, size_t inlen)
Convert UTF8 string to UCS2 encoding.
Definition: misc.c:580
bool armed
Definition: misc.c:47
#define FR_PUT_LE16(a, val)
Definition: misc.c:34
void fr_quick_sort(void const *to_sort[], int min_idx, int max_idx, fr_cmp_t cmp)
Quick sort an array of pointers using a comparator.
Definition: misc.c:997
bool is_integer(char const *value)
Check whether the string is all numbers.
Definition: misc.c:350
size_t fr_snprint_uint128(char *out, size_t outlen, uint128_t const num)
Write 128bit unsigned integer to buffer.
Definition: misc.c:633
char * fr_abin2hex(TALLOC_CTX *ctx, uint8_t const *bin, size_t inlen)
Convert binary data to a hex string.
Definition: misc.c:278
bool is_zero(char const *value)
Check whether the string is all zeros.
Definition: misc.c:365
int fr_timeval_from_str(struct timeval *out, char const *in)
Create timeval from a string.
Definition: misc.c:907
int rad_unlockfd(int fd, int lock_len)
Definition: misc.c:191
int fr_talloc_link_ctx(TALLOC_CTX *parent, TALLOC_CTX *child)
Link a parent and a child context, so the child is freed before the parent.
Definition: misc.c:105
int fr_set_signal(int sig, sig_t func)
Sets a signal handler using sigaction if available, else signal.
Definition: misc.c:56
int strncasecmp(char *s1, char *s2, int n)
Definition: missing.c:43
int rad_lockfd(int fd, int lock_len)
Definition: misc.c:141
void fr_strerror_printf(char const *,...) CC_HINT(format(printf
static char const * months[]
Definition: misc.c:42
void fr_timespec_subtract(struct timespec *out, struct timespec const *end, struct timespec const *start)
Subtract one timespec from another.
Definition: misc.c:881
size_t strlcpy(char *dst, char const *src, size_t siz)
Definition: strlcpy.c:38
Definition: pair.c:37
int fr_utf8_char(uint8_t const *str, ssize_t inlen)
Checks for utf-8, taken from http://www.w3.org/International/questions/qa-forms-utf-8.
Definition: print.c:34
static int _fr_trigger_talloc_ctx_free(fr_talloc_link_t *trigger)
Definition: misc.c:79
static int _quick_partition(void const *to_sort[], int min, int max, fr_cmp_t cmp)
Definition: misc.c:966
static char const hex[]
Definition: smbencrypt.c:34
int fr_blocking(UNUSED int fd)
Definition: misc.c:467
#define RCSID(id)
Definition: build.h:135
bool is_printable(void const *value, size_t len)
Check whether the string is made up of printable UTF8 chars.
Definition: misc.c:329
bool is_whitespace(char const *value)
Check whether the string is all whitespace.
Definition: misc.c:311
int8_t fr_pointer_cmp(void const *a, void const *b)
Compares two pointers.
Definition: misc.c:958
#define NSEC
Definition: misc.c:874