Pre-ci test passed git-svn-id: http://svn.eurecom.fr/openair4G/trunk@4000 818b1a75-f10b-46b9-bf7c-635c3b92a50f
350 lines
6.1 KiB
C
350 lines
6.1 KiB
C
/*
|
|
* $Id: util.c,v 1.9 2008/02/11 06:54:23 sobomax Exp $
|
|
*
|
|
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
|
*
|
|
* Copyright (C) 1995,1996,1997 Lars Fenneberg
|
|
*
|
|
* Copyright 1992 Livingston Enterprises, Inc.
|
|
*
|
|
* Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan
|
|
* and Merit Network, Inc. All Rights Reserved
|
|
*
|
|
* See the file COPYRIGHT for the respective terms and conditions.
|
|
* If the file is missing contact me at lf@elemental.net
|
|
* and I'll send you a copy.
|
|
*
|
|
*/
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <config.h>
|
|
#include <includes.h>
|
|
#include <freeradius-client.h>
|
|
|
|
#define RC_BUFSIZ 1024
|
|
|
|
/*
|
|
* Function: rc_str2tm
|
|
*
|
|
* Purpose: Turns printable string into correct tm struct entries.
|
|
*
|
|
*/
|
|
|
|
static const char * months[] =
|
|
{
|
|
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
|
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
|
};
|
|
|
|
void rc_str2tm (char *valstr, struct tm *tm)
|
|
{
|
|
int i;
|
|
|
|
/* Get the month */
|
|
for (i = 0; i < 12; i++)
|
|
{
|
|
if (strncmp (months[i], valstr, 3) == 0)
|
|
{
|
|
tm->tm_mon = i;
|
|
i = 13;
|
|
}
|
|
}
|
|
|
|
/* Get the Day */
|
|
tm->tm_mday = atoi (&valstr[4]);
|
|
|
|
/* Now the year */
|
|
tm->tm_year = atoi (&valstr[7]) - 1900;
|
|
}
|
|
|
|
/*
|
|
* Function: rc_getifname
|
|
*
|
|
* Purpose: get the network interface name associated with this tty
|
|
*
|
|
*/
|
|
|
|
char *rc_getifname(rc_handle *rh, char *tty)
|
|
{
|
|
#if defined(BSD4_4) || defined(linux)
|
|
int fd;
|
|
|
|
if ((fd = open(tty, O_RDWR|O_NDELAY)) < 0) {
|
|
rc_log(LOG_ERR, "rc_getifname: can't open %s: %s", tty, strerror(errno));
|
|
return NULL;
|
|
}
|
|
#endif
|
|
|
|
#ifdef BSD4_4
|
|
strcpy(rh->ifname,ttyname(fd));
|
|
if (strlen(rh->ifname) < 1) {
|
|
rc_log(LOG_ERR, "rc_getifname: can't get attached interface of %s: %s", tty, strerror(errno));
|
|
close(fd);
|
|
return NULL;
|
|
}
|
|
#elif linux
|
|
if (ioctl(fd, SIOCGIFNAME, rh->ifname) < 0) {
|
|
rc_log(LOG_ERR, "rc_getifname: can't ioctl %s: %s", tty, strerror(errno));
|
|
close(fd);
|
|
return NULL;
|
|
}
|
|
#else
|
|
return NULL;
|
|
#endif
|
|
|
|
#if defined(BSD4_4) || defined(linux)
|
|
close(fd);
|
|
return rh->ifname;
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
* Function: rc_getstr
|
|
*
|
|
* Purpose: Reads in a string from the user (with or witout echo)
|
|
*
|
|
*/
|
|
#ifndef _MSC_VER
|
|
char *rc_getstr (rc_handle *rh, char *prompt, int do_echo)
|
|
{
|
|
int in, out;
|
|
char *p;
|
|
struct termios term_old, term_new;
|
|
int is_term, flags, old_flags;
|
|
char c;
|
|
int flushed = 0;
|
|
sigset_t newset;
|
|
sigset_t oldset;
|
|
|
|
in = fileno(stdin);
|
|
out = fileno(stdout);
|
|
|
|
(void) sigemptyset (&newset);
|
|
(void) sigaddset (&newset, SIGINT);
|
|
(void) sigaddset (&newset, SIGTSTP);
|
|
(void) sigaddset (&newset, SIGQUIT);
|
|
|
|
(void) sigprocmask (SIG_BLOCK, &newset, &oldset);
|
|
|
|
if ((is_term = isatty(in)))
|
|
{
|
|
|
|
(void) tcgetattr (in, &term_old);
|
|
term_new = term_old;
|
|
if (do_echo)
|
|
term_new.c_lflag |= ECHO;
|
|
else
|
|
term_new.c_lflag &= ~ECHO;
|
|
|
|
if (tcsetattr (in, TCSAFLUSH, &term_new) == 0)
|
|
flushed = 1;
|
|
|
|
}
|
|
else
|
|
{
|
|
is_term = 0;
|
|
if ((flags = fcntl(in, F_GETFL, 0)) >= 0) {
|
|
old_flags = flags;
|
|
flags |= O_NONBLOCK;
|
|
|
|
fcntl(in, F_SETFL, flags);
|
|
|
|
while (read(in, &c, 1) > 0)
|
|
/* nothing */;
|
|
|
|
fcntl(in, F_SETFL, old_flags);
|
|
|
|
flushed = 1;
|
|
}
|
|
}
|
|
|
|
write(out, prompt, strlen(prompt));
|
|
|
|
/* well, this looks ugly, but it handles the following end of line
|
|
markers: \r \r\0 \r\n \n \n\r, at least at a second pass */
|
|
|
|
p = rh->buf;
|
|
for (;;)
|
|
{
|
|
if (read(in, &c, 1) <= 0)
|
|
return NULL;
|
|
|
|
if (!flushed && ((c == '\0') || (c == '\r') || (c == '\n'))) {
|
|
flushed = 1;
|
|
continue;
|
|
}
|
|
|
|
if ((c == '\r') || (c == '\n'))
|
|
break;
|
|
|
|
flushed = 1;
|
|
|
|
if (p < rh->buf + GETSTR_LENGTH)
|
|
{
|
|
if (do_echo && !is_term)
|
|
write(out, &c, 1);
|
|
*p++ = c;
|
|
}
|
|
}
|
|
|
|
*p = '\0';
|
|
|
|
if (!do_echo || !is_term) write(out, "\r\n", 2);
|
|
|
|
if (is_term)
|
|
tcsetattr (in, TCSAFLUSH, &term_old);
|
|
else {
|
|
if ((flags = fcntl(in, F_GETFL, 0)) >= 0) {
|
|
old_flags = flags;
|
|
flags |= O_NONBLOCK;
|
|
|
|
fcntl(in, F_SETFL, flags);
|
|
|
|
while (read(in, &c, 1) > 0)
|
|
/* nothing */;
|
|
|
|
fcntl(in, F_SETFL, old_flags);
|
|
}
|
|
}
|
|
|
|
(void) sigprocmask (SIG_SETMASK, &oldset, NULL);
|
|
|
|
return rh->buf;
|
|
}
|
|
#endif
|
|
void rc_mdelay(int msecs)
|
|
{
|
|
struct timeval tv;
|
|
|
|
tv.tv_sec = (int) msecs / 1000;
|
|
tv.tv_usec = (msecs % 1000) * 1000;
|
|
|
|
select(0, NULL, NULL, NULL, &tv);
|
|
}
|
|
|
|
/*
|
|
* Function: rc_mksid
|
|
*
|
|
* Purpose: generate a quite unique string
|
|
*
|
|
* Remarks: not that unique at all...
|
|
*
|
|
*/
|
|
|
|
char *
|
|
rc_mksid (rc_handle *rh)
|
|
{
|
|
sprintf (rh->buf1, "%08lX%04X", (unsigned long int) time (NULL), (unsigned int) getpid ());
|
|
return rh->buf1;
|
|
}
|
|
|
|
/*
|
|
* Function: rc_new
|
|
*
|
|
* Purpose: Initialises new Radius Client handle
|
|
*
|
|
*/
|
|
|
|
rc_handle *
|
|
rc_new(void)
|
|
{
|
|
rc_handle *rh;
|
|
|
|
rh = malloc(sizeof(*rh));
|
|
if (rh == NULL) {
|
|
rc_log(LOG_CRIT, "rc_new: out of memory");
|
|
return NULL;
|
|
}
|
|
memset(rh, 0, sizeof(*rh));
|
|
return rh;
|
|
}
|
|
|
|
/*
|
|
* Function: rc_destroy
|
|
*
|
|
* Purpose: Destroys Radius Client handle reclaiming all memory
|
|
*
|
|
*/
|
|
|
|
void
|
|
rc_destroy(rc_handle *rh)
|
|
{
|
|
|
|
rc_map2id_free(rh);
|
|
rc_dict_free(rh);
|
|
rc_config_free(rh);
|
|
if (rh->this_host_bind_ipaddr != NULL)
|
|
free(rh->this_host_bind_ipaddr);
|
|
if (rh->ppbuf != NULL)
|
|
free(rh->ppbuf);
|
|
free(rh);
|
|
}
|
|
|
|
/*
|
|
* Function: rc_fgetln
|
|
*
|
|
* Purpose: Get next line from the stream.
|
|
*
|
|
*/
|
|
|
|
char *
|
|
rc_fgetln(FILE *fp, size_t *len)
|
|
{
|
|
static char *buf = NULL;
|
|
static size_t bufsiz = 0;
|
|
char *ptr;
|
|
|
|
if (buf == NULL) {
|
|
bufsiz = RC_BUFSIZ;
|
|
if ((buf = malloc(bufsiz)) == NULL)
|
|
return NULL;
|
|
}
|
|
|
|
if (fgets(buf, (int)bufsiz, fp) == NULL)
|
|
return NULL;
|
|
*len = 0;
|
|
|
|
while ((ptr = strchr(&buf[*len], '\n')) == NULL) {
|
|
size_t nbufsiz = bufsiz + RC_BUFSIZ;
|
|
char *nbuf = realloc(buf, nbufsiz);
|
|
|
|
if (nbuf == NULL) {
|
|
int oerrno = errno;
|
|
free(buf);
|
|
errno = oerrno;
|
|
buf = NULL;
|
|
return NULL;
|
|
} else
|
|
buf = nbuf;
|
|
|
|
*len = bufsiz;
|
|
if (fgets(&buf[bufsiz], RC_BUFSIZ, fp) == NULL)
|
|
return buf;
|
|
|
|
bufsiz = nbufsiz;
|
|
}
|
|
|
|
*len = (ptr - buf) + 1;
|
|
return buf;
|
|
}
|
|
|
|
/*
|
|
* Function: rc_getctime
|
|
*
|
|
* Purpose: Get current time (seconds since epoch) expressed as
|
|
* double-precision floating point number.
|
|
*
|
|
*/
|
|
|
|
double
|
|
rc_getctime(void)
|
|
{
|
|
struct timeval timev;
|
|
|
|
if (gettimeofday(&timev, NULL) == -1)
|
|
return -1;
|
|
|
|
return timev.tv_sec + ((double)timev.tv_usec) / 1000000.0;
|
|
}
|