1 /* 2 * Copyright (c) 2007, Novell Inc. 3 * 4 * This program is licensed under the BSD license, read LICENSE.BSD 5 * for further information 6 */ 7 8 #define _GNU_SOURCE 9 10 #include <stdio.h> 11 #include <stdlib.h> 12 #include <unistd.h> 13 #include <string.h> 14 #include <sys/time.h> 15 16 #include "util.h" 17 18 void 19 solv_oom(size_t num, size_t len) 20 { 21 if (num) 22 fprintf(stderr, "Out of memory allocating %zu*%zu bytes!\n", num, len); 23 else 24 fprintf(stderr, "Out of memory allocating %zu bytes!\n", len); 25 abort(); 26 exit(1); 27 } 28 29 void * 30 solv_malloc(size_t len) 31 { 32 void *r = malloc(len ? len : 1); 33 if (!r) 34 solv_oom(0, len); 35 return r; 36 } 37 38 void * 39 solv_malloc2(size_t num, size_t len) 40 { 41 if (len && (num * len) / len != num) 42 solv_oom(num, len); 43 return solv_malloc(num * len); 44 } 45 46 void * 47 solv_realloc(void *old, size_t len) 48 { 49 if (old == 0) 50 old = malloc(len ? len : 1); 51 else 52 old = realloc(old, len ? len : 1); 53 if (!old) 54 solv_oom(0, len); 55 return old; 56 } 57 58 void * 59 solv_realloc2(void *old, size_t num, size_t len) 60 { 61 if (len && (num * len) / len != num) 62 solv_oom(num, len); 63 return solv_realloc(old, num * len); 64 } 65 66 void * 67 solv_calloc(size_t num, size_t len) 68 { 69 void *r; 70 if (num == 0 || len == 0) 71 r = malloc(1); 72 else 73 r = calloc(num, len); 74 if (!r) 75 solv_oom(num, len); 76 return r; 77 } 78 79 void * 80 solv_free(void *mem) 81 { 82 if (mem) 83 free(mem); 84 return 0; 85 } 86 87 char * 88 solv_strdup(const char *s) 89 { 90 char *r; 91 if (!s) 92 return 0; 93 r = strdup(s); 94 if (!r) 95 solv_oom(0, strlen(s)); 96 return r; 97 } 98 99 unsigned int 100 solv_timems(unsigned int subtract) 101 { 102 struct timeval tv; 103 unsigned int r; 104 105 if (gettimeofday(&tv, 0)) 106 return 0; 107 r = (((unsigned int)tv.tv_sec >> 16) * 1000) << 16; 108 r += ((unsigned int)tv.tv_sec & 0xffff) * 1000; 109 r += (unsigned int)tv.tv_usec / 1000; 110 return r - subtract; 111 } 112 113 /* bsd's qsort_r has different arguments, so we define our 114 own version in case we need to do some clever mapping 115 116 see also: http://sources.redhat.com/ml/libc-alpha/2008-12/msg00003.html 117 */ 118 #if defined(__GLIBC__) && (defined(HAVE_QSORT_R) || defined(HAVE___QSORT_R)) 119 120 void 121 solv_sort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *, void *), void *compard) 122 { 123 # if defined(HAVE_QSORT_R) 124 qsort_r(base, nmemb, size, compar, compard); 125 # else 126 /* backported for SLE10-SP2 */ 127 __qsort_r(base, nmemb, size, compar, compard); 128 # endif 129 130 } 131 132 #elif defined(HAVE_QSORT_R) /* not glibc, but has qsort_r() */ 133 134 struct solv_sort_data { 135 int (*compar)(const void *, const void *, void *); 136 void *compard; 137 }; 138 139 static int 140 solv_sort_helper(void *compard, const void *a, const void *b) 141 { 142 struct solv_sort_data *d = compard; 143 return (*d->compar)(a, b, d->compard); 144 } 145 146 void 147 solv_sort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *, void *), void *compard) 148 { 149 struct solv_sort_data d; 150 d.compar = compar; 151 d.compard = compard; 152 qsort_r(base, nmemb, size, &d, solv_sort_helper); 153 } 154 155 #else /* not glibc and no qsort_r() */ 156 /* use own version of qsort if none available */ 157 #include "qsort_r.c" 158 #endif 159 160 char * 161 solv_dupjoin(const char *str1, const char *str2, const char *str3) 162 { 163 int l1, l2, l3; 164 char *s, *str; 165 l1 = str1 ? strlen(str1) : 0; 166 l2 = str2 ? strlen(str2) : 0; 167 l3 = str3 ? strlen(str3) : 0; 168 s = str = solv_malloc(l1 + l2 + l3 + 1); 169 if (l1) 170 { 171 strcpy(s, str1); 172 s += l1; 173 } 174 if (l2) 175 { 176 strcpy(s, str2); 177 s += l2; 178 } 179 if (l3) 180 { 181 strcpy(s, str3); 182 s += l3; 183 } 184 *s = 0; 185 return str; 186 } 187 188 char * 189 solv_dupappend(const char *str1, const char *str2, const char *str3) 190 { 191 char *str = solv_dupjoin(str1, str2, str3); 192 solv_free((void *)str1); 193 return str; 194 } 195 196 int 197 solv_hex2bin(const char **strp, unsigned char *buf, int bufl) 198 { 199 const char *str = *strp; 200 int i; 201 202 for (i = 0; i < bufl; i++) 203 { 204 int c = *str; 205 int d; 206 if (c >= '0' && c <= '9') 207 d = c - '0'; 208 else if (c >= 'a' && c <= 'f') 209 d = c - ('a' - 10); 210 else if (c >= 'A' && c <= 'F') 211 d = c - ('A' - 10); 212 else 213 break; 214 c = *++str; 215 d <<= 4; 216 if (c >= '0' && c <= '9') 217 d |= c - '0'; 218 else if (c >= 'a' && c <= 'f') 219 d |= c - ('a' - 10); 220 else if (c >= 'A' && c <= 'F') 221 d |= c - ('A' - 10); 222 else 223 break; 224 buf[i] = d; 225 ++str; 226 } 227 *strp = str; 228 return i; 229 } 230 231 char * 232 solv_bin2hex(const unsigned char *buf, int l, char *str) 233 { 234 int i; 235 for (i = 0; i < l; i++, buf++) 236 { 237 int c = *buf >> 4; 238 *str++ = c < 10 ? c + '0' : c + ('a' - 10); 239 c = *buf & 15; 240 *str++ = c < 10 ? c + '0' : c + ('a' - 10); 241 } 242 *str = 0; 243 return str; 244 } 245 246 247