1/*
2 * $Id: util.c,v 1.1.1.1 2008/10/15 03:30:50 james26_jang Exp $
3 *
4 * Copyright (C) 1995,1996,1997 Lars Fenneberg
5 *
6 * Copyright 1992 Livingston Enterprises, Inc.
7 *
8 * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan
9 * and Merit Network, Inc. All Rights Reserved
10 *
11 * See the file COPYRIGHT for the respective terms and conditions.
12 * If the file is missing contact me at lf@elemental.net
13 * and I'll send you a copy.
14 *
15 */
16
17#include <config.h>
18#include <includes.h>
19#include <radiusclient.h>
20
21/*
22 * Function: rc_str2tm
23 *
24 * Purpose: Turns printable string into correct tm struct entries.
25 *
26 */
27
28static const char * months[] =
29		{
30			"Jan", "Feb", "Mar", "Apr", "May", "Jun",
31			"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
32		};
33
34void rc_str2tm (char *valstr, struct tm *tm)
35{
36	int             i;
37
38	/* Get the month */
39	for (i = 0; i < 12; i++)
40	{
41		if (strncmp (months[i], valstr, 3) == 0)
42		{
43			tm->tm_mon = i;
44			i = 13;
45		}
46	}
47
48	/* Get the Day */
49	tm->tm_mday = atoi (&valstr[4]);
50
51	/* Now the year */
52	tm->tm_year = atoi (&valstr[7]) - 1900;
53}
54
55/*
56 * Function: rc_getifname
57 *
58 * Purpose: get the network interface name associated with this tty
59 *
60 */
61
62char *rc_getifname(char *tty)
63{
64#if defined(BSD4_4) || defined(linux)
65	static char	name[512];
66	int		fd;
67
68	if ((fd = open(tty, O_RDWR|O_NDELAY)) < 0) {
69		rc_log(LOG_ERR, "rc_getifname: can't open %s: %s", tty, strerror(errno));
70		return NULL;
71	}
72#endif
73
74#ifdef BSD4_4
75	strcpy(name,ttyname(fd));
76	if (strlen(name) < 1) {
77		rc_log(LOG_ERR, "rc_getifname: can't get attached interface of %s: %s", tty, strerror(errno));
78		close(fd);
79		return NULL;
80	}
81#elif linux
82	if (ioctl(fd, SIOCGIFNAME, name) < 0) {
83		rc_log(LOG_ERR, "rc_getifname: can't ioctl %s: %s", tty, strerror(errno));
84		close(fd);
85		return NULL;
86	}
87#else
88	return NULL;
89#endif
90
91#if defined(BSD4_4) || defined(linux)
92	close(fd);
93	return name;
94#endif
95}
96
97/*
98 * Function: rc_getstr
99 *
100 * Purpose: Reads in a string from the user (with or witout echo)
101 *
102 */
103
104char *rc_getstr (char *prompt, int do_echo)
105{
106	int             in, out;
107	char           *p;
108	sigset_t        newset;
109	sigset_t        oldset;
110	struct termios  term_old, term_new;
111	static char     buf[GETSTR_LENGTH];
112	int		is_term, flags, old_flags;
113	char		c;
114	int		flushed = 0;
115
116	in = fileno(stdin);
117	out = fileno(stdout);
118
119	(void) sigemptyset (&newset);
120	(void) sigaddset (&newset, SIGINT);
121	(void) sigaddset (&newset, SIGTSTP);
122	(void) sigaddset (&newset, SIGQUIT);
123
124	(void) sigprocmask (SIG_BLOCK, &newset, &oldset);
125
126	if ((is_term = isatty(in)))
127	{
128
129		(void) tcgetattr (in, &term_old);
130		term_new = term_old;
131		if (do_echo)
132			term_new.c_lflag |= ECHO;
133		else
134			term_new.c_lflag &= ~ECHO;
135
136		if (tcsetattr (in, TCSAFLUSH, &term_new) == 0)
137			flushed = 1;
138
139	}
140	else
141	{
142		is_term = 0;
143		if ((flags = fcntl(in, F_GETFL, 0)) >= 0) {
144			old_flags = flags;
145			flags |= O_NONBLOCK;
146
147			fcntl(in, F_SETFL, flags);
148
149			while (read(in, &c, 1) > 0)
150				/* nothing */;
151
152			fcntl(in, F_SETFL, old_flags);
153
154			flushed = 1;
155		}
156	}
157
158	write(out, prompt, strlen(prompt));
159
160	/* well, this looks ugly, but it handles the following end of line
161	   markers: \r \r\0 \r\n \n \n\r, at least at a second pass */
162
163	p = buf;
164	for (;;)
165	{
166		if (read(in, &c, 1) <= 0)
167			return NULL;
168
169		if (!flushed && ((c == '\0') || (c == '\r') || (c == '\n'))) {
170			flushed = 1;
171			continue;
172		}
173
174		if ((c == '\r') || (c == '\n'))
175			break;
176
177		flushed = 1;
178
179		if (p < buf + GETSTR_LENGTH)
180		{
181			if (do_echo && !is_term)
182				write(out, &c, 1);
183			*p++ = c;
184		}
185	}
186
187	*p = '\0';
188
189	if (!do_echo || !is_term) write(out, "\r\n", 2);
190
191	if (is_term)
192		tcsetattr (in, TCSAFLUSH, &term_old);
193	else {
194		if ((flags = fcntl(in, F_GETFL, 0)) >= 0) {
195			old_flags = flags;
196			flags |= O_NONBLOCK;
197
198			fcntl(in, F_SETFL, flags);
199
200			while (read(in, &c, 1) > 0)
201				/* nothing */;
202
203			fcntl(in, F_SETFL, old_flags);
204		}
205	}
206
207	(void) sigprocmask (SIG_SETMASK, &oldset, NULL);
208
209	return (buf);
210}
211
212void rc_mdelay(int msecs)
213{
214	struct timeval tv;
215
216	tv.tv_sec = (int) msecs / 1000;
217	tv.tv_usec = (msecs % 1000) * 1000;
218
219	select(0,(fd_set *)NULL,(fd_set *)NULL,(fd_set *)NULL, &tv);
220}
221
222/*
223 * Function: rc_mksid
224 *
225 * Purpose: generate a quite unique string
226 *
227 * Remarks: not that unique at all...
228 *
229 */
230
231char *
232rc_mksid (void)
233{
234  static char buf[14];
235  sprintf (buf, "%08lX%04X", (unsigned long int) time (NULL), (unsigned int) getpid ());
236  return buf;
237}
238