Moved the server to using ctime_r, instead of ctime, to help
[freeradius.git] / src / lib / missing.c
1 /*
2  * missing.c    Replacements for functions that are or can be
3  *              missing on some platforms.
4  *
5  * Version:     $Id$
6  *
7  */
8
9 static const char rcsid[] = "$Id$";
10
11 #include        "autoconf.h"
12
13 #include        <stdio.h>
14 #include        <stdlib.h>
15 #include        <sys/types.h>
16 #include        <sys/socket.h>
17 #include        <netinet/in.h>
18 #include        <arpa/inet.h>
19 #include        <ctype.h>
20
21 #include        "libradius.h"
22 #include        "missing.h"
23
24 #ifndef HAVE_CRYPT
25 char *crypt(char *key, char *salt)
26 {
27         /*log(L_ERR, "crypt() called but not implemented");*/
28         return "____fnord____";
29 }
30 #endif
31
32 #ifndef HAVE_STRNCASECMP
33 int strncasecmp(char *s1, char *s2, int n)
34 {
35         int             dif;
36         unsigned char   *p1, *p2;
37         int             c1, c2;
38
39         p1 = (unsigned char *)s1;
40         p2 = (unsigned char *)s2;
41         dif = 0;
42
43         while (n != 0) {
44                 if (*p1 == 0 && *p2 == 0)
45                         break;
46                 c1 = *p1;
47                 c2 = *p2;
48
49                 if (islower(c1)) c1 = toupper(c1);
50                 if (islower(c2)) c2 = toupper(c2);
51
52                 if ((dif = c1 - c2) != 0)
53                         break;
54                 p1++;
55                 p2++;
56                 n--;
57         }
58         return dif;
59 }
60 #endif
61
62 #ifndef HAVE_STRCASECMP
63 int strcasecmp(char *s1, char *s2)
64 {
65         int             l1, l2;
66
67         l1 = strlen(s1);
68         l2 = strlen(s2);
69         if (l2 > l1) l1 = l2;
70
71         return strncasecmp(s1, s2, l1);
72 }
73 #endif
74
75 #ifndef HAVE_INET_ATON
76 int inet_aton(char *cp, struct in_addr *inp)
77 {
78         int     a1, a2, a3, a4;
79
80         if (sscanf(cp, "%d.%d.%d.%d", &a1, &a2, &a3, &a4) != 4)
81                 return 0;
82
83         inp->s_addr = htonl((a1 << 24) + (a2 << 16) + (a3 << 8) + a4);
84         return 1;
85 }
86 #endif
87
88 #ifndef HAVE_GETHOSTNAME
89 int gethostname(char *name, int len)
90 {
91         char            *h;
92
93         h = getenv("HOSTNAME");
94         if (strlen(h) + 1 > len)
95                 return -1;
96         strcpy(name, h);
97         return 0;
98 }
99 #endif
100
101 #ifndef HAVE_STRSEP
102 /*
103  *      Get next token from string *stringp, where tokens are
104  *      possibly-empty strings separated by characters from delim.
105  *
106  *      Writes NULs into the string at *stringp to end tokens.
107  *      delim need not remain constant from call to call.  On
108  *      return, *stringp points past the last NUL written (if there
109  *      might be further tokens), or is NULL (if there are
110  *      definitely no more tokens).
111  *
112  *      If *stringp is NULL, strsep returns NULL.
113  */
114 char *
115 strsep(char **stringp, const char *delim)
116 {
117         char *s;
118         const char *spanp;
119         int c, sc;
120         char *tok;
121
122         if ((s = *stringp) == NULL)
123                 return (NULL);
124
125         for (tok = s;;) {
126                 c = *s++;
127                 spanp = delim;
128                 do {
129                         if ((sc = *spanp++) == c) {
130                                 if (c == 0)
131                                         s = NULL;
132                                 else
133                                         s[-1] = 0;
134                                 *stringp = s;
135                                 return (tok);
136                         }
137                 } while (sc != 0);
138         }
139
140         return NULL;            /* NOTREACHED, but the compiler complains */
141 }
142 #endif
143
144 #ifndef HAVE_LOCALTIME_R
145 /*
146  *      We use localtime_r() by default in the server.
147  *
148  *      For systems which do NOT have localtime_r(), we make the
149  *      assumption that localtime() is re-entrant, and returns a
150  *      per-thread data structure.
151  *
152  *      Even if localtime is NOT re-entrant, this function will
153  *      lower the possibility of race conditions.
154  */
155 struct tm *localtime_r(const time_t *l_clock, struct tm *result)
156 {
157   memcpy(result, localtime(l_clock), sizeof(*result));
158
159   return result;
160 }
161 #endif
162
163 #ifndef HAVE_CTIME_R
164 /*
165  *      We use ctime_r() by default in the server.
166  *
167  *      For systems which do NOT have ctime_r(), we make the
168  *      assumption that ctime() is re-entrant, and returns a
169  *      per-thread data structure.
170  *
171  *      Even if ctime is NOT re-entrant, this function will
172  *      lower the possibility of race conditions.
173  */
174 char *ctime_r(const time_t *l_clock, char *l_buf)
175 {
176   strcpy(l_buf, ctime(l_clock));
177
178   return l_buf;
179 }
180 #endif