2 * missing.c Replacements for functions that are or can be
3 * missing on some platforms.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 * Copyright 2000,2006 The FreeRADIUS server project
26 #include <freeradius-devel/libradius.h>
31 char *crypt(UNUSED char *key, char *salt)
33 /*log(L_ERR, "crypt() called but not implemented");*/
38 #ifndef HAVE_STRNCASECMP
39 int strncasecmp(char *s1, char *s2, int n)
42 unsigned char *p1, *p2;
45 p1 = (unsigned char *)s1;
46 p2 = (unsigned char *)s2;
50 if (*p1 == 0 && *p2 == 0)
55 if (islower(c1)) c1 = toupper(c1);
56 if (islower(c2)) c2 = toupper(c2);
58 if ((dif = c1 - c2) != 0)
68 #ifndef HAVE_STRCASECMP
69 int strcasecmp(char *s1, char *s2)
77 return strncasecmp(s1, s2, l1);
81 #ifndef HAVE_INET_ATON
82 int inet_aton(char const *cp, struct in_addr *inp)
86 if (sscanf(cp, "%d.%d.%d.%d", &a1, &a2, &a3, &a4) != 4)
89 inp->s_addr = htonl((a1 << 24) + (a2 << 16) + (a3 << 8) + a4);
96 * Get next token from string *stringp, where tokens are
97 * possibly-empty strings separated by characters from delim.
99 * Writes NULs into the string at *stringp to end tokens.
100 * delim need not remain constant from call to call. On
101 * return, *stringp points past the last NUL written (if there
102 * might be further tokens), or is NULL (if there are
103 * definitely no more tokens).
105 * If *stringp is NULL, strsep returns NULL.
108 strsep(char **stringp, char const *delim)
115 if ((s = *stringp) == NULL)
122 if ((sc = *spanp++) == c) {
133 return NULL; /* NOTREACHED, but the compiler complains */
137 #ifndef HAVE_LOCALTIME_R
139 * We use localtime_r() by default in the server.
141 * For systems which do NOT have localtime_r(), we make the
142 * assumption that localtime() is re-entrant, and returns a
143 * per-thread data structure.
145 * Even if localtime is NOT re-entrant, this function will
146 * lower the possibility of race conditions.
148 struct tm *localtime_r(time_t const *l_clock, struct tm *result)
150 memcpy(result, localtime(l_clock), sizeof(*result));
158 * We use ctime_r() by default in the server.
160 * For systems which do NOT have ctime_r(), we make the
161 * assumption that ctime() is re-entrant, and returns a
162 * per-thread data structure.
164 * Even if ctime is NOT re-entrant, this function will
165 * lower the possibility of race conditions.
167 char *ctime_r(time_t const *l_clock, char *l_buf)
169 strcpy(l_buf, ctime(l_clock));
175 #ifndef HAVE_GMTIME_R
177 * We use gmtime_r() by default in the server.
179 * For systems which do NOT have gmtime_r(), we make the
180 * assumption that gmtime() is re-entrant, and returns a
181 * per-thread data structure.
183 * Even if gmtime is NOT re-entrant, this function will
184 * lower the possibility of race conditions.
186 struct tm *gmtime_r(time_t const *l_clock, struct tm *result)
188 memcpy(result, gmtime(l_clock), sizeof(*result));
194 #ifndef HAVE_VDPRINTF
195 int vdprintf (int fd, const char *format, va_list args)
202 if (dup_fd < 0) return -1;
204 fp = fdopen(fd, "w");
210 ret = vfprintf(fp, format, args);
211 fclose(fp); /* Also closes dup_fd */
217 #ifndef HAVE_GETTIMEOFDAY
220 * Number of micro-seconds between the beginning of the Windows epoch
221 * (Jan. 1, 1601) and the Unix epoch (Jan. 1, 1970).
223 * This assumes all Win32 compilers have 64-bit support.
225 #if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) || defined(__WATCOMC__)
226 #define DELTA_EPOCH_IN_USEC 11644473600000000Ui64
228 #define DELTA_EPOCH_IN_USEC 11644473600000000ULL
231 static uint64_t filetime_to_unix_epoch (FILETIME const *ft)
233 uint64_t res = (uint64_t) ft->dwHighDateTime << 32;
235 res |= ft->dwLowDateTime;
236 res /= 10; /* from 100 nano-sec periods to usec */
237 res -= DELTA_EPOCH_IN_USEC; /* from Win epoch to Unix epoch */
241 int gettimeofday (struct timeval *tv, UNUSED void *tz)
250 GetSystemTimeAsFileTime (&ft);
251 tim = filetime_to_unix_epoch (&ft);
252 tv->tv_sec = (long) (tim / 1000000L);
253 tv->tv_usec = (long) (tim % 1000000L);
259 #define NTP_EPOCH_OFFSET 2208988800ULL
262 * Convert 'struct timeval' into NTP format (32-bit integer
263 * of seconds, 32-bit integer of fractional seconds)
266 timeval2ntp(struct timeval const *tv, uint8_t *ntp)
270 sec = tv->tv_sec + NTP_EPOCH_OFFSET;
271 usec = tv->tv_usec * 4295; /* close enough to 2^32 / USEC */
272 usec -= ((tv->tv_usec * 2143) >> 16); /* */
277 memcpy(ntp, &sec, sizeof(sec));
278 memcpy(ntp + sizeof(sec), &usec, sizeof(usec));
282 * Inverse of timeval2ntp
285 ntp2timeval(struct timeval *tv, char const *ntp)
289 memcpy(&sec, ntp, sizeof(sec));
290 memcpy(&usec, ntp + sizeof(sec), sizeof(usec));
295 tv->tv_sec = sec - NTP_EPOCH_OFFSET;
296 tv->tv_usec = usec / 4295; /* close enough */
299 #if !defined(HAVE_128BIT_INTEGERS) && defined(FR_LITTLE_ENDIAN)
300 /** Swap byte order of 128 bit integer
302 * @param num 128bit integer to swap.
303 * @return 128bit integer reversed.
305 uint128_t ntohlll(uint128_t const num)
307 uint64_t const *p = (uint64_t const *) #
311 ret[1] = ntohll(p[0]);
312 ret[0] = ntohll(p[1]);
314 return *(uint128_t *)ret;
318 /** Call talloc strdup, setting the type on the new chunk correctly
320 * For some bizarre reason the talloc string functions don't set the
321 * memory chunk type to char, which causes all kinds of issues with
322 * verifying VALUE_PAIRs.
324 * @param[in] t The talloc context to hang the result off.
325 * @param[in] p The string you want to duplicate.
326 * @return The duplicated string, NULL on error.
328 char *talloc_typed_strdup(void const *t, char const *p)
332 n = talloc_strdup(t, p);
334 talloc_set_type(n, char);
339 /** Call talloc vasprintf, setting the type on the new chunk correctly
341 * For some bizarre reason the talloc string functions don't set the
342 * memory chunk type to char, which causes all kinds of issues with
343 * verifying VALUE_PAIRs.
345 * @param[in] t The talloc context to hang the result off.
346 * @param[in] fmt The format string.
347 * @return The formatted string, NULL on error.
349 char *talloc_typed_asprintf(void const *t, char const *fmt, ...)
355 n = talloc_vasprintf(t, fmt, ap);
358 talloc_set_type(n, char);
363 /** Binary safe strndup function
365 * @param[in] t The talloc context o allocate new buffer in.
366 * @param[in] in String to dup, may contain embedded '\0'.
367 * @param[in] inlen Number of bytes to dup.
368 * @return duped string.
370 char *talloc_bstrndup(void const *t, char const *in, size_t inlen)
374 p = talloc_array(t, char, inlen + 1);
376 memcpy(p, in, inlen);