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