util.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2007, Novell Inc.
00003  *
00004  * This program is licensed under the BSD license, read LICENSE.BSD
00005  * for further information
00006  */
00007 
00008 #define _GNU_SOURCE
00009 
00010 #include <stdio.h>
00011 #include <stdlib.h>
00012 #include <unistd.h>
00013 #include <string.h>
00014 #include <sys/time.h>
00015 
00016 #include "util.h"
00017 
00018 void
00019 sat_oom(size_t num, size_t len)
00020 {
00021   if (num)
00022     fprintf(stderr, "Out of memory allocating %zu*%zu bytes!\n", num, len);
00023   else
00024     fprintf(stderr, "Out of memory allocating %zu bytes!\n", len);
00025   abort();
00026   exit(1);
00027 }
00028 
00029 void *
00030 sat_malloc(size_t len)
00031 {
00032   void *r = malloc(len ? len : 1);
00033   if (!r)
00034     sat_oom(0, len);
00035   return r;
00036 }
00037 
00038 void *
00039 sat_malloc2(size_t num, size_t len)
00040 {
00041   if (len && (num * len) / len != num)
00042     sat_oom(num, len);
00043   return sat_malloc(num * len);
00044 }
00045 
00046 void *
00047 sat_realloc(void *old, size_t len)
00048 {
00049   if (old == 0)
00050     old = malloc(len ? len : 1);
00051   else
00052     old = realloc(old, len ? len : 1);
00053   if (!old)
00054     sat_oom(0, len);
00055   return old;
00056 }
00057 
00058 void *
00059 sat_realloc2(void *old, size_t num, size_t len)
00060 {
00061   if (len && (num * len) / len != num)
00062     sat_oom(num, len);
00063   return sat_realloc(old, num * len);
00064 }
00065 
00066 void *
00067 sat_calloc(size_t num, size_t len)
00068 {
00069   void *r;
00070   if (num == 0 || len == 0)
00071     r = malloc(1);
00072   else
00073     r = calloc(num, len);
00074   if (!r)
00075     sat_oom(num, len);
00076   return r;
00077 }
00078 
00079 void *
00080 sat_free(void *mem)
00081 {
00082   if (mem)
00083     free(mem);
00084   return 0;
00085 }
00086 
00087 unsigned int
00088 sat_timems(unsigned int subtract)
00089 {
00090   struct timeval tv;
00091   unsigned int r;
00092 
00093   if (gettimeofday(&tv, 0))
00094     return 0;
00095   r = (((unsigned int)tv.tv_sec >> 16) * 1000) << 16;
00096   r += ((unsigned int)tv.tv_sec & 0xffff) * 1000;
00097   r += (unsigned int)tv.tv_usec / 1000;
00098   return r - subtract;
00099 }
00100 
00101 /* bsd's qsort_r has different arguments, so we define our
00102    own version in case we need to do some clever mapping
00103 
00104    see also: http://sources.redhat.com/ml/libc-alpha/2008-12/msg00003.html
00105  */
00106 #if defined(__GLIBC__)
00107 
00108 # if HAVE_QSORT_R || HAVE___QSORT_R
00109 void
00110 sat_sort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *, void *), void *compard)
00111 {
00112 # if HAVE_QSORT_R
00113   qsort_r(base, nmemb, size, compar, compard);
00114 # else
00115   /* backported for SLE10-SP2 */
00116   __qsort_r(base, nmemb, size, compar, compard);
00117 # endif
00118 
00119 }
00120 #else /* qsort_r or __qsort_r on glibc */
00121 /* use own version of qsort if none available */
00122 #include "qsort_r.c"
00123 #endif
00124 
00125 #else /* not glibc */
00126 
00127 struct sat_sort_data {
00128   int (*compar)(const void *, const void *, void *);
00129   void *compard;
00130 };
00131 
00132 static int
00133 sat_sort_helper(void *compard, const void *a, const void *b)
00134 {
00135   struct sat_sort_data *d = compard;
00136   return (*d->compar)(a, b, d->compard);
00137 }
00138 
00139 void
00140 sat_sort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *, void *), void *compard)
00141 {
00142   struct sat_sort_data d;
00143   d.compar = compar;
00144   d.compard = compard;
00145   qsort_r(base, nmemb, size, &d, sat_sort_helper);
00146 }
00147 
00148 #endif
00149 
00150 char *
00151 sat_dupjoin(const char *str1, const char *str2, const char *str3)
00152 {
00153   int l1, l2, l3;
00154   char *s, *str;
00155   l1 = str1 ? strlen(str1) : 0;
00156   l2 = str2 ? strlen(str2) : 0;
00157   l3 = str3 ? strlen(str3) : 0;
00158   s = str = sat_malloc(l1 + l2 + l3 + 1);
00159   if (l1)
00160     {
00161       strcpy(s, str1);
00162       s += l1;
00163     }
00164   if (l2)
00165     {
00166       strcpy(s, str2);
00167       s += l2;
00168     }
00169   if (l3)
00170     {
00171       strcpy(s, str3);
00172       s += l3;
00173     }
00174   *s = 0;
00175   return str;
00176 }
00177 
00178 char *
00179 sat_dupappend(const char *str1, const char *str2, const char *str3)
00180 {
00181   char *str = sat_dupjoin(str1, str2, str3);
00182   sat_free((void *)str1);
00183   return str;
00184 }
00185 
00186 int
00187 sat_hex2bin(const char **strp, unsigned char *buf, int bufl)
00188 {
00189   const char *str = *strp;
00190   int i;
00191 
00192   for (i = 0; i < bufl; i++)
00193     {
00194       int c = *str;
00195       int d;
00196       if (c >= '0' && c <= '9')
00197         d = c - '0';
00198       else if (c >= 'a' && c <= 'f')
00199         d = c - ('a' - 10);
00200       else if (c >= 'A' && c <= 'F')
00201         d = c - ('A' - 10);
00202       else
00203         break;
00204       c = *++str;
00205       d <<= 4;
00206       if (c >= '0' && c <= '9')
00207         d |= c - '0';
00208       else if (c >= 'a' && c <= 'f')
00209         d |= c - ('a' - 10);
00210       else if (c >= 'A' && c <= 'F')
00211         d |= c - ('A' - 10);
00212       else
00213         break;
00214       buf[i] = d;
00215       ++str;
00216     }
00217   *strp = str;
00218   return i;
00219 }
00220 
00221 char *
00222 sat_bin2hex(const unsigned char *buf, int l, char *str)
00223 {
00224   int i;
00225   for (i = 0; i < l; i++, buf++)
00226     {
00227       int c = *buf >> 4;
00228       *str++ = c < 10 ? c + '0' : c + ('a' - 10);
00229       c = *buf & 15;
00230       *str++ = c < 10 ? c + '0' : c + ('a' - 10);
00231     }
00232   *str = 0;
00233   return str;
00234 }
00235 
00236 

doxygen