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