Home | History | Annotate | Download | only in src
      1 /*-
      2  * Copyright (c) 1997 Brian Somers <brian (at) 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: src/usr.sbin/ppp/defs.c,v 1.48.26.1 2010/12/21 17:10:29 kensmith Exp $
     27  */
     28 
     29 
     30 #include <sys/param.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 <stdarg.h>
     39 #include <stdio.h>
     40 #include <stdlib.h>
     41 #include <string.h>
     42 #if defined(__FreeBSD__) && !defined(NOKLDLOAD)
     43 #include <sys/module.h>
     44 #endif
     45 #include <termios.h>
     46 #if !defined(__FreeBSD__) || __FreeBSD__ < 3
     47 #include <time.h>
     48 #endif
     49 #include <unistd.h>
     50 
     51 #if defined(__FreeBSD__) && !defined(NOKLDLOAD)
     52 #include "id.h"
     53 #include "log.h"
     54 #endif
     55 #include "defs.h"
     56 
     57 #define	issep(c)	((c) == '\t' || (c) == ' ')
     58 
     59 #if defined(__NetBSD__) || __FreeBSD__ < 3
     60 void
     61 randinit()
     62 {
     63 #if defined(__FreeBSD__)
     64   static int initdone;		/* srandomdev() call is only required once */
     65 
     66   if (!initdone) {
     67     initdone = 1;
     68     srandomdev();
     69   }
     70 #else
     71   srandom((time(NULL)^getpid())+random());
     72 #endif
     73 }
     74 #endif
     75 
     76 ssize_t
     77 fullread(int fd, void *v, size_t n)
     78 {
     79   size_t got, total;
     80 
     81   for (total = 0; total < n; total += got)
     82     switch ((got = read(fd, (char *)v + total, n - total))) {
     83       case 0:
     84         return total;
     85       case -1:
     86         if (errno == EINTR)
     87           got = 0;
     88         else
     89           return -1;
     90     }
     91   return total;
     92 }
     93 
     94 static struct {
     95   int mode;
     96   const char *name;
     97 } modes[] = {
     98   { PHYS_INTERACTIVE, "interactive" },
     99   { PHYS_AUTO, "auto" },
    100   { PHYS_DIRECT, "direct" },
    101   { PHYS_DEDICATED, "dedicated" },
    102   { PHYS_DDIAL, "ddial" },
    103   { PHYS_BACKGROUND, "background" },
    104   { PHYS_FOREGROUND, "foreground" },
    105   { PHYS_ALL, "*" },
    106   { 0, 0 }
    107 };
    108 
    109 const char *
    110 mode2Nam(int mode)
    111 {
    112   int m;
    113 
    114   for (m = 0; modes[m].mode; m++)
    115     if (modes[m].mode == mode)
    116       return modes[m].name;
    117 
    118   return "unknown";
    119 }
    120 
    121 int
    122 Nam2mode(const char *name)
    123 {
    124   int m, got, len;
    125 
    126   len = strlen(name);
    127   got = -1;
    128   for (m = 0; modes[m].mode; m++)
    129     if (!strncasecmp(name, modes[m].name, len)) {
    130       if (modes[m].name[len] == '\0')
    131 	return modes[m].mode;
    132       if (got != -1)
    133         return 0;
    134       got = m;
    135     }
    136 
    137   return got == -1 ? 0 : modes[got].mode;
    138 }
    139 
    140 struct in_addr
    141 GetIpAddr(const char *cp)
    142 {
    143   struct in_addr ipaddr;
    144 
    145   if (!strcasecmp(cp, "default"))
    146     ipaddr.s_addr = INADDR_ANY;
    147   else if (inet_aton(cp, &ipaddr) == 0) {
    148     const char *ptr;
    149 
    150     /* Any illegal characters ? */
    151     for (ptr = cp; *ptr != '\0'; ptr++)
    152       if (!isalnum(*ptr) && strchr("-.", *ptr) == NULL)
    153         break;
    154 
    155     if (*ptr == '\0') {
    156       struct hostent *hp;
    157 
    158       hp = gethostbyname(cp);
    159       if (hp && hp->h_addrtype == AF_INET)
    160         memcpy(&ipaddr, hp->h_addr, hp->h_length);
    161       else
    162         ipaddr.s_addr = INADDR_NONE;
    163     } else
    164       ipaddr.s_addr = INADDR_NONE;
    165   }
    166 
    167   return ipaddr;
    168 }
    169 
    170 static const struct speeds {
    171   unsigned nspeed;
    172   speed_t speed;
    173 } speeds[] = {
    174 #ifdef B50
    175   { 50, B50, },
    176 #endif
    177 #ifdef B75
    178   { 75, B75, },
    179 #endif
    180 #ifdef B110
    181   { 110, B110, },
    182 #endif
    183 #ifdef B134
    184   { 134, B134, },
    185 #endif
    186 #ifdef B150
    187   { 150, B150, },
    188 #endif
    189 #ifdef B200
    190   { 200, B200, },
    191 #endif
    192 #ifdef B300
    193   { 300, B300, },
    194 #endif
    195 #ifdef B600
    196   { 600, B600, },
    197 #endif
    198 #ifdef B1200
    199   { 1200, B1200, },
    200 #endif
    201 #ifdef B1800
    202   { 1800, B1800, },
    203 #endif
    204 #ifdef B2400
    205   { 2400, B2400, },
    206 #endif
    207 #ifdef B4800
    208   { 4800, B4800, },
    209 #endif
    210 #ifdef B9600
    211   { 9600, B9600, },
    212 #endif
    213 #ifdef B19200
    214   { 19200, B19200, },
    215 #endif
    216 #ifdef B38400
    217   { 38400, B38400, },
    218 #endif
    219 #ifndef _POSIX_SOURCE
    220 #ifdef B7200
    221   { 7200, B7200, },
    222 #endif
    223 #ifdef B14400
    224   { 14400, B14400, },
    225 #endif
    226 #ifdef B28800
    227   { 28800, B28800, },
    228 #endif
    229 #ifdef B57600
    230   { 57600, B57600, },
    231 #endif
    232 #ifdef B76800
    233   { 76800, B76800, },
    234 #endif
    235 #ifdef B115200
    236   { 115200, B115200, },
    237 #endif
    238 #ifdef B230400
    239   { 230400, B230400, },
    240 #endif
    241 #ifdef B460800
    242   { 460800, B460800, },
    243 #endif
    244 #ifdef B921600
    245   { 921600, B921600, },
    246 #endif
    247 #ifdef EXTA
    248   { 19200, EXTA, },
    249 #endif
    250 #ifdef EXTB
    251   { 38400, EXTB, },
    252 #endif
    253 #endif				/* _POSIX_SOURCE */
    254   { 0, 0 }
    255 };
    256 
    257 unsigned
    258 SpeedToUnsigned(speed_t speed)
    259 {
    260   const struct speeds *sp;
    261 
    262   for (sp = speeds; sp->nspeed; sp++) {
    263     if (sp->speed == speed) {
    264       return sp->nspeed;
    265     }
    266   }
    267   return 0;
    268 }
    269 
    270 speed_t
    271 UnsignedToSpeed(unsigned nspeed)
    272 {
    273   const struct speeds *sp;
    274 
    275   for (sp = speeds; sp->nspeed; sp++) {
    276     if (sp->nspeed == nspeed) {
    277       return sp->speed;
    278     }
    279   }
    280   return B0;
    281 }
    282 
    283 char *
    284 findblank(char *p, int flags)
    285 {
    286   int instring;
    287 
    288   instring = 0;
    289   while (*p) {
    290     if (*p == '\\') {
    291       if (flags & PARSE_REDUCE) {
    292         memmove(p, p + 1, strlen(p));
    293         if (!*p)
    294           break;
    295       } else
    296         p++;
    297     } else if (*p == '"') {
    298       memmove(p, p + 1, strlen(p));
    299       instring = !instring;
    300       continue;
    301     } else if (!instring && (issep(*p) ||
    302                              (*p == '#' && !(flags & PARSE_NOHASH))))
    303       return p;
    304     p++;
    305   }
    306 
    307   return instring ? NULL : p;
    308 }
    309 
    310 int
    311 MakeArgs(char *script, char **pvect, int maxargs, int flags)
    312 {
    313   int nargs;
    314 
    315   nargs = 0;
    316   while (*script) {
    317     script += strspn(script, " \t");
    318     if (*script == '#' && !(flags & PARSE_NOHASH)) {
    319       *script = '\0';
    320       break;
    321     }
    322     if (*script) {
    323       if (nargs >= maxargs - 1)
    324         break;
    325       *pvect++ = script;
    326       nargs++;
    327       script = findblank(script, flags);
    328       if (script == NULL)
    329         return -1;
    330       else if (!(flags & PARSE_NOHASH) && *script == '#')
    331         *script = '\0';
    332       else if (*script)
    333         *script++ = '\0';
    334     }
    335   }
    336   *pvect = NULL;
    337   return nargs;
    338 }
    339 
    340 const char *
    341 NumStr(long val, char *buf, size_t sz)
    342 {
    343   static char result[23];		/* handles 64 bit numbers */
    344 
    345   if (buf == NULL || sz == 0) {
    346     buf = result;
    347     sz = sizeof result;
    348   }
    349   snprintf(buf, sz, "<%ld>", val);
    350   return buf;
    351 }
    352 
    353 const char *
    354 HexStr(long val, char *buf, size_t sz)
    355 {
    356   static char result[21];		/* handles 64 bit numbers */
    357 
    358   if (buf == NULL || sz == 0) {
    359     buf = result;
    360     sz = sizeof result;
    361   }
    362   snprintf(buf, sz, "<0x%lx>", val);
    363   return buf;
    364 }
    365 
    366 const char *
    367 ex_desc(int ex)
    368 {
    369   static char num[12];		/* Used immediately if returned */
    370   static const char * const desc[] = {
    371     "normal", "start", "sock", "modem", "dial", "dead", "done",
    372     "reboot", "errdead", "hangup", "term", "nodial", "nologin",
    373     "redial", "reconnect"
    374   };
    375 
    376   if (ex >= 0 && ex < (int)(sizeof desc / sizeof *desc))
    377     return desc[ex];
    378   snprintf(num, sizeof num, "%d", ex);
    379   return num;
    380 }
    381 
    382 void
    383 SetTitle(const char *title)
    384 {
    385   if (title == NULL)
    386     setproctitle(NULL);
    387   else if (title[0] == '-' && title[1] != '\0')
    388     setproctitle("-%s", title + 1);
    389   else
    390     setproctitle("%s", title);
    391 }
    392 
    393 fd_set *
    394 mkfdset()
    395 {
    396   return (fd_set *)malloc(howmany(getdtablesize(), NFDBITS) * sizeof (fd_mask));
    397 }
    398 
    399 void
    400 zerofdset(fd_set *s)
    401 {
    402   memset(s, '\0', howmany(getdtablesize(), NFDBITS) * sizeof (fd_mask));
    403 }
    404 
    405 void
    406 Concatinate(char *buf, size_t sz, int argc, const char *const *argv)
    407 {
    408   int i, n;
    409   unsigned pos;
    410 
    411   *buf = '\0';
    412   for (pos = i = 0; i < argc; i++) {
    413     n = snprintf(buf + pos, sz - pos, "%s%s", i ? " " : "", argv[i]);
    414     if (n < 0) {
    415       buf[pos] = '\0';
    416       break;
    417     }
    418     if ((pos += n) >= sz)
    419       break;
    420   }
    421 }
    422 
    423 #if defined(__FreeBSD__) && !defined(NOKLDLOAD)
    424 int
    425 loadmodules(int how, const char *module, ...)
    426 {
    427   int loaded = 0;
    428   va_list ap;
    429 
    430   va_start(ap, module);
    431   while (module != NULL) {
    432     if (modfind(module) == -1) {
    433       if (ID0kldload(module) == -1) {
    434         if (how == LOAD_VERBOSLY)
    435           log_Printf(LogWARN, "%s: Cannot load module\n", module);
    436       } else
    437         loaded++;
    438     }
    439     module = va_arg(ap, const char *);
    440   }
    441   va_end(ap);
    442   return loaded;
    443 }
    444 #else
    445 int
    446 loadmodules(int how __unused, const char *module __unused, ...)
    447 {
    448   return 0;
    449 }
    450 #endif
    451