2 * util.c Various utility functions.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 * Copyright 2000 The FreeRADIUS server project
23 static const char rcsid[] = "$Id$";
26 #include "libradius.h"
44 * The signal() function in Solaris 2.5.1 sets SA_NODEFER in
45 * sa_flags, which causes grief if signal() is called in the
46 * handler before the cause of the signal has been cleared.
47 * (Infinite recursion).
49 * The same problem appears on HPUX, so we avoid it, if we can.
51 * Using sigaction() to reset the signal handler fixes the problem,
52 * so where available, we prefer that solution.
54 void (*reset_signal(int signo, void (*func)(int)))(int)
57 struct sigaction act, oact;
59 act.sa_handler = func;
60 sigemptyset(&act.sa_mask);
62 #ifdef SA_INTERRUPT /* SunOS */
63 act.sa_flags |= SA_INTERRUPT;
65 if (sigaction(signo, &act, &oact) < 0)
67 return oact.sa_handler;
71 * re-set by calling the 'signal' function, which
72 * may cause infinite recursion and core dumps due to
75 * However, the system is too dumb to implement sigaction(),
76 * so we don't have a choice.
84 * Free a REQUEST struct.
86 void request_free(REQUEST **request_ptr)
90 if (request_ptr == NULL)
92 request = *request_ptr;
95 rad_free(&request->packet);
98 rad_free(&request->proxy);
101 rad_free(&request->reply);
103 if (request->proxy_reply)
104 rad_free(&request->proxy_reply);
106 if (request->config_items)
107 pairfree(&request->config_items);
110 request->magic = 0x01020304; /* set the request to be nonsense */
118 * Check a filename for sanity.
120 * Allow only uppercase/lowercase letters, numbers, and '-_/.'
122 int rad_checkfilename(const char *filename)
124 if (strspn(filename, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_/.") == strlen(filename)) {
132 * Create possibly many directories.
134 * Note that the input directory name is NOT a constant!
135 * This is so that IF an error is returned, the 'directory' ptr
136 * points to the name of the file which caused the error.
138 int rad_mkdir(char *directory, int mode)
145 * If the directory exists, don't do anything.
147 if (stat(directory, &st) == 0) {
152 * Look for the LAST directory name. Try to create that,
153 * failing on any error.
155 p = strrchr(directory, '/');
158 rcode = rad_mkdir(directory, mode);
161 * On error, we leave the directory name as the
162 * one which caused the error.
169 * Reset the directory delimiter, and go ask
170 * the system to make the directory.
178 * Having done everything successfully, we do the
179 * system call to actually go create the directory.
181 return mkdir(directory, mode);
186 * Module malloc() call, which does stuff if the malloc fails.
188 * This call ALWAYS succeeds!
190 void *rad_malloc(size_t size)
192 void *ptr = malloc(size);
195 radlog(L_ERR|L_CONS, "no memory");
202 void xfree(const char *ptr)