defs.c revision 59084
1/*-
2 * Copyright (c) 1997 Brian Somers <brian@Awfulhak.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $FreeBSD: head/usr.sbin/ppp/defs.c 59084 2000-04-07 23:46:14Z brian $
27 */
28
29
30#include <sys/types.h>
31#include <netdb.h>
32#include <netinet/in.h>
33#include <arpa/inet.h>
34#include <sys/socket.h>
35
36#include <ctype.h>
37#include <errno.h>
38#include <stdio.h>
39#include <stdlib.h>
40#include <string.h>
41#include <termios.h>
42#if !defined(__FreeBSD__) || __FreeBSD__ < 3
43#include <time.h>
44#endif
45#include <unistd.h>
46
47#include "defs.h"
48
49#define	issep(c)	((c) == '\t' || (c) == ' ')
50
51void
52randinit()
53{
54#if __FreeBSD__ >= 3
55  static int initdone;		/* srandomdev() call is only required once */
56
57  if (!initdone) {
58    initdone = 1;
59    srandomdev();
60  }
61#else
62  srandom((time(NULL)^getpid())+random());
63#endif
64}
65
66ssize_t
67fullread(int fd, void *v, size_t n)
68{
69  size_t got, total;
70
71  for (total = 0; total < n; total += got)
72    switch ((got = read(fd, (char *)v + total, n - total))) {
73      case 0:
74        return total;
75      case -1:
76        if (errno == EINTR)
77          got = 0;
78        else
79          return -1;
80    }
81  return total;
82}
83
84static struct {
85  int mode;
86  const char *name;
87} modes[] = {
88  { PHYS_INTERACTIVE, "interactive" },
89  { PHYS_AUTO, "auto" },
90  { PHYS_DIRECT, "direct" },
91  { PHYS_DEDICATED, "dedicated" },
92  { PHYS_DDIAL, "ddial" },
93  { PHYS_BACKGROUND, "background" },
94  { PHYS_FOREGROUND, "foreground" },
95  { PHYS_ALL, "*" },
96  { 0, 0 }
97};
98
99const char *
100mode2Nam(int mode)
101{
102  int m;
103
104  for (m = 0; modes[m].mode; m++)
105    if (modes[m].mode == mode)
106      return modes[m].name;
107
108  return "unknown";
109}
110
111int
112Nam2mode(const char *name)
113{
114  int m, got, len;
115
116  len = strlen(name);
117  got = -1;
118  for (m = 0; modes[m].mode; m++)
119    if (!strncasecmp(name, modes[m].name, len)) {
120      if (modes[m].name[len] == '\0')
121	return modes[m].mode;
122      if (got != -1)
123        return 0;
124      got = m;
125    }
126
127  return got == -1 ? 0 : modes[got].mode;
128}
129
130struct in_addr
131GetIpAddr(const char *cp)
132{
133  struct in_addr ipaddr;
134
135  if (!strcasecmp(cp, "default"))
136    ipaddr.s_addr = INADDR_ANY;
137  else if (inet_aton(cp, &ipaddr) == 0) {
138    const char *ptr;
139
140    /* Any illegal characters ? */
141    for (ptr = cp; *ptr != '\0'; ptr++)
142      if (!isalnum(*ptr) && strchr("-.", *ptr) == NULL)
143        break;
144
145    if (*ptr == '\0') {
146      struct hostent *hp;
147
148      hp = gethostbyname(cp);
149      if (hp && hp->h_addrtype == AF_INET)
150        memcpy(&ipaddr, hp->h_addr, hp->h_length);
151      else
152        ipaddr.s_addr = INADDR_NONE;
153    } else
154      ipaddr.s_addr = INADDR_NONE;
155  }
156
157  return ipaddr;
158}
159
160static const struct speeds {
161  int nspeed;
162  speed_t speed;
163} speeds[] = {
164#ifdef B50
165  { 50, B50, },
166#endif
167#ifdef B75
168  { 75, B75, },
169#endif
170#ifdef B110
171  { 110, B110, },
172#endif
173#ifdef B134
174  { 134, B134, },
175#endif
176#ifdef B150
177  { 150, B150, },
178#endif
179#ifdef B200
180  { 200, B200, },
181#endif
182#ifdef B300
183  { 300, B300, },
184#endif
185#ifdef B600
186  { 600, B600, },
187#endif
188#ifdef B1200
189  { 1200, B1200, },
190#endif
191#ifdef B1800
192  { 1800, B1800, },
193#endif
194#ifdef B2400
195  { 2400, B2400, },
196#endif
197#ifdef B4800
198  { 4800, B4800, },
199#endif
200#ifdef B9600
201  { 9600, B9600, },
202#endif
203#ifdef B19200
204  { 19200, B19200, },
205#endif
206#ifdef B38400
207  { 38400, B38400, },
208#endif
209#ifndef _POSIX_SOURCE
210#ifdef B7200
211  { 7200, B7200, },
212#endif
213#ifdef B14400
214  { 14400, B14400, },
215#endif
216#ifdef B28800
217  { 28800, B28800, },
218#endif
219#ifdef B57600
220  { 57600, B57600, },
221#endif
222#ifdef B76800
223  { 76800, B76800, },
224#endif
225#ifdef B115200
226  { 115200, B115200, },
227#endif
228#ifdef B230400
229  { 230400, B230400, },
230#endif
231#ifdef EXTA
232  { 19200, EXTA, },
233#endif
234#ifdef EXTB
235  { 38400, EXTB, },
236#endif
237#endif				/* _POSIX_SOURCE */
238  { 0, 0 }
239};
240
241int
242SpeedToInt(speed_t speed)
243{
244  const struct speeds *sp;
245
246  for (sp = speeds; sp->nspeed; sp++) {
247    if (sp->speed == speed) {
248      return sp->nspeed;
249    }
250  }
251  return 0;
252}
253
254speed_t
255IntToSpeed(int nspeed)
256{
257  const struct speeds *sp;
258
259  for (sp = speeds; sp->nspeed; sp++) {
260    if (sp->nspeed == nspeed) {
261      return sp->speed;
262    }
263  }
264  return B0;
265}
266
267char *
268findblank(char *p, int flags)
269{
270  int instring;
271
272  instring = 0;
273  while (*p) {
274    if (*p == '\\') {
275      if (flags & PARSE_REDUCE) {
276        memmove(p, p + 1, strlen(p));
277        if (!*p)
278          break;
279      } else
280        p++;
281    } else if (*p == '"') {
282      memmove(p, p + 1, strlen(p));
283      instring = !instring;
284      continue;
285    } else if (!instring && (issep(*p) ||
286                             (*p == '#' && !(flags & PARSE_NOHASH))))
287      return p;
288    p++;
289  }
290
291  return instring ? NULL : p;
292}
293
294int
295MakeArgs(char *script, char **pvect, int maxargs, int flags)
296{
297  int nargs;
298
299  nargs = 0;
300  while (*script && (*script != '#' || (flags & PARSE_NOHASH))) {
301    script += strspn(script, " \t");
302    if (*script) {
303      if (nargs >= maxargs - 1)
304	break;
305      *pvect++ = script;
306      nargs++;
307      script = findblank(script, flags);
308      if (script == NULL)
309        return -1;
310      else if (!(flags & PARSE_NOHASH) && *script == '#')
311	*script = '\0';
312      else if (*script)
313	*script++ = '\0';
314    }
315  }
316  *pvect = NULL;
317  return nargs;
318}
319
320const char *
321NumStr(long val, char *buf, size_t sz)
322{
323  static char result[23];		/* handles 64 bit numbers */
324
325  if (buf == NULL || sz == 0) {
326    buf = result;
327    sz = sizeof result;
328  }
329  snprintf(buf, sz, "<%ld>", val);
330  return buf;
331}
332
333const char *
334HexStr(long val, char *buf, size_t sz)
335{
336  static char result[21];		/* handles 64 bit numbers */
337
338  if (buf == NULL || sz == 0) {
339    buf = result;
340    sz = sizeof result;
341  }
342  snprintf(buf, sz, "<0x%lx>", val);
343  return buf;
344}
345
346const char *
347ex_desc(int ex)
348{
349  static char num[12];		/* Used immediately if returned */
350  static const char * const desc[] = {
351    "normal", "start", "sock", "modem", "dial", "dead", "done",
352    "reboot", "errdead", "hangup", "term", "nodial", "nologin",
353    "redial", "reconnect"
354  };
355
356  if (ex >= 0 && ex < sizeof desc / sizeof *desc)
357    return desc[ex];
358  snprintf(num, sizeof num, "%d", ex);
359  return num;
360}
361