131921Sbrian/*- 231921Sbrian * Copyright (c) 1997 Brian Somers <brian@Awfulhak.org> 331921Sbrian * All rights reserved. 431921Sbrian * 531921Sbrian * Redistribution and use in source and binary forms, with or without 631921Sbrian * modification, are permitted provided that the following conditions 731921Sbrian * are met: 831921Sbrian * 1. Redistributions of source code must retain the above copyright 931921Sbrian * notice, this list of conditions and the following disclaimer. 1031921Sbrian * 2. Redistributions in binary form must reproduce the above copyright 1131921Sbrian * notice, this list of conditions and the following disclaimer in the 1231921Sbrian * documentation and/or other materials provided with the distribution. 1331921Sbrian * 1431921Sbrian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1531921Sbrian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1631921Sbrian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1731921Sbrian * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1831921Sbrian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1931921Sbrian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2031921Sbrian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2131921Sbrian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2231921Sbrian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2331921Sbrian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2431921Sbrian * SUCH DAMAGE. 2531921Sbrian * 2650479Speter * $FreeBSD$ 2730715Sbrian */ 2830715Sbrian 2931196Sbrian 3093418Sbrian#include <sys/param.h> 3144279Sbrian#include <netdb.h> 3244279Sbrian#include <netinet/in.h> 3344279Sbrian#include <arpa/inet.h> 3444279Sbrian#include <sys/socket.h> 3544279Sbrian 3644279Sbrian#include <ctype.h> 3746085Sbrian#include <errno.h> 3893418Sbrian#include <stdarg.h> 3958034Sbrian#include <stdio.h> 4030715Sbrian#include <stdlib.h> 4131121Sbrian#include <string.h> 4293418Sbrian#if defined(__FreeBSD__) && !defined(NOKLDLOAD) 4393418Sbrian#include <sys/module.h> 4493418Sbrian#endif 4546686Sbrian#include <termios.h> 46252826Srmh#ifndef __FreeBSD__ 4734539Sbrian#include <time.h> 4837192Sbrian#endif 4931196Sbrian#include <unistd.h> 5030715Sbrian 5193418Sbrian#if defined(__FreeBSD__) && !defined(NOKLDLOAD) 5293418Sbrian#include "id.h" 5393418Sbrian#include "log.h" 5493418Sbrian#endif 5530715Sbrian#include "defs.h" 5630715Sbrian 5746686Sbrian#define issep(c) ((c) == '\t' || (c) == ' ') 5846686Sbrian 59252826Srmh#ifdef __NetBSD__ 6030715Sbrianvoid 6130715Sbrianrandinit() 6230715Sbrian{ 6336285Sbrian srandom((time(NULL)^getpid())+random()); 6430715Sbrian} 6565269Sbrian#endif 6631196Sbrian 6736285Sbrianssize_t 6836285Sbrianfullread(int fd, void *v, size_t n) 6936285Sbrian{ 7036285Sbrian size_t got, total; 7131196Sbrian 7236285Sbrian for (total = 0; total < n; total += got) 7336285Sbrian switch ((got = read(fd, (char *)v + total, n - total))) { 7436285Sbrian case 0: 7536285Sbrian return total; 7636285Sbrian case -1: 7736285Sbrian if (errno == EINTR) 7836285Sbrian got = 0; 7936285Sbrian else 8036285Sbrian return -1; 8136285Sbrian } 8236285Sbrian return total; 8336285Sbrian} 8436285Sbrian 8536285Sbrianstatic struct { 8636285Sbrian int mode; 8736285Sbrian const char *name; 8836285Sbrian} modes[] = { 8936465Sbrian { PHYS_INTERACTIVE, "interactive" }, 9036465Sbrian { PHYS_AUTO, "auto" }, 9136285Sbrian { PHYS_DIRECT, "direct" }, 9236285Sbrian { PHYS_DEDICATED, "dedicated" }, 9336465Sbrian { PHYS_DDIAL, "ddial" }, 9436465Sbrian { PHYS_BACKGROUND, "background" }, 9553830Sbrian { PHYS_FOREGROUND, "foreground" }, 9636285Sbrian { PHYS_ALL, "*" }, 9736285Sbrian { 0, 0 } 9836285Sbrian}; 9936285Sbrian 10036285Sbrianconst char * 10136285Sbrianmode2Nam(int mode) 10231196Sbrian{ 10336285Sbrian int m; 10431196Sbrian 10536285Sbrian for (m = 0; modes[m].mode; m++) 10636285Sbrian if (modes[m].mode == mode) 10736285Sbrian return modes[m].name; 10831196Sbrian 10936285Sbrian return "unknown"; 11031196Sbrian} 11131203Sbrian 11236285Sbrianint 11336285SbrianNam2mode(const char *name) 11431203Sbrian{ 11536285Sbrian int m, got, len; 11631203Sbrian 11736285Sbrian len = strlen(name); 11836285Sbrian got = -1; 11936285Sbrian for (m = 0; modes[m].mode; m++) 12036285Sbrian if (!strncasecmp(name, modes[m].name, len)) { 12136285Sbrian if (modes[m].name[len] == '\0') 12236285Sbrian return modes[m].mode; 12336285Sbrian if (got != -1) 12436285Sbrian return 0; 12536285Sbrian got = m; 12636285Sbrian } 12736285Sbrian 12836285Sbrian return got == -1 ? 0 : modes[got].mode; 12931203Sbrian} 13044279Sbrian 13144279Sbrianstruct in_addr 13244279SbrianGetIpAddr(const char *cp) 13344279Sbrian{ 13444279Sbrian struct in_addr ipaddr; 13544279Sbrian 13644279Sbrian if (!strcasecmp(cp, "default")) 13744279Sbrian ipaddr.s_addr = INADDR_ANY; 13844279Sbrian else if (inet_aton(cp, &ipaddr) == 0) { 13944279Sbrian const char *ptr; 14044279Sbrian 14144279Sbrian /* Any illegal characters ? */ 14244279Sbrian for (ptr = cp; *ptr != '\0'; ptr++) 14344279Sbrian if (!isalnum(*ptr) && strchr("-.", *ptr) == NULL) 14444279Sbrian break; 14544279Sbrian 14644279Sbrian if (*ptr == '\0') { 14744279Sbrian struct hostent *hp; 14844279Sbrian 14944279Sbrian hp = gethostbyname(cp); 15044279Sbrian if (hp && hp->h_addrtype == AF_INET) 15144279Sbrian memcpy(&ipaddr, hp->h_addr, hp->h_length); 15244279Sbrian else 15344279Sbrian ipaddr.s_addr = INADDR_NONE; 15444279Sbrian } else 15544279Sbrian ipaddr.s_addr = INADDR_NONE; 15644279Sbrian } 15744279Sbrian 15844279Sbrian return ipaddr; 15944279Sbrian} 16046686Sbrian 16146686Sbrianstatic const struct speeds { 162134789Sbrian unsigned nspeed; 16346686Sbrian speed_t speed; 16446686Sbrian} speeds[] = { 16546686Sbrian#ifdef B50 16646686Sbrian { 50, B50, }, 16746686Sbrian#endif 16846686Sbrian#ifdef B75 16946686Sbrian { 75, B75, }, 17046686Sbrian#endif 17146686Sbrian#ifdef B110 17246686Sbrian { 110, B110, }, 17346686Sbrian#endif 17446686Sbrian#ifdef B134 17546686Sbrian { 134, B134, }, 17646686Sbrian#endif 17746686Sbrian#ifdef B150 17846686Sbrian { 150, B150, }, 17946686Sbrian#endif 18046686Sbrian#ifdef B200 18146686Sbrian { 200, B200, }, 18246686Sbrian#endif 18346686Sbrian#ifdef B300 18446686Sbrian { 300, B300, }, 18546686Sbrian#endif 18646686Sbrian#ifdef B600 18746686Sbrian { 600, B600, }, 18846686Sbrian#endif 18946686Sbrian#ifdef B1200 19046686Sbrian { 1200, B1200, }, 19146686Sbrian#endif 19246686Sbrian#ifdef B1800 19346686Sbrian { 1800, B1800, }, 19446686Sbrian#endif 19546686Sbrian#ifdef B2400 19646686Sbrian { 2400, B2400, }, 19746686Sbrian#endif 19846686Sbrian#ifdef B4800 19946686Sbrian { 4800, B4800, }, 20046686Sbrian#endif 20146686Sbrian#ifdef B9600 20246686Sbrian { 9600, B9600, }, 20346686Sbrian#endif 20446686Sbrian#ifdef B19200 20546686Sbrian { 19200, B19200, }, 20646686Sbrian#endif 20746686Sbrian#ifdef B38400 20846686Sbrian { 38400, B38400, }, 20946686Sbrian#endif 21046686Sbrian#ifndef _POSIX_SOURCE 21146686Sbrian#ifdef B7200 21246686Sbrian { 7200, B7200, }, 21346686Sbrian#endif 21446686Sbrian#ifdef B14400 21546686Sbrian { 14400, B14400, }, 21646686Sbrian#endif 21746686Sbrian#ifdef B28800 21846686Sbrian { 28800, B28800, }, 21946686Sbrian#endif 22046686Sbrian#ifdef B57600 22146686Sbrian { 57600, B57600, }, 22246686Sbrian#endif 22346686Sbrian#ifdef B76800 22446686Sbrian { 76800, B76800, }, 22546686Sbrian#endif 22646686Sbrian#ifdef B115200 22746686Sbrian { 115200, B115200, }, 22846686Sbrian#endif 22946686Sbrian#ifdef B230400 23046686Sbrian { 230400, B230400, }, 23146686Sbrian#endif 23292142Sbrian#ifdef B460800 23392142Sbrian { 460800, B460800, }, 23492142Sbrian#endif 23592142Sbrian#ifdef B921600 23692142Sbrian { 921600, B921600, }, 23792142Sbrian#endif 23846686Sbrian#ifdef EXTA 23946686Sbrian { 19200, EXTA, }, 24046686Sbrian#endif 24146686Sbrian#ifdef EXTB 24246686Sbrian { 38400, EXTB, }, 24346686Sbrian#endif 24446686Sbrian#endif /* _POSIX_SOURCE */ 24546686Sbrian { 0, 0 } 24646686Sbrian}; 24746686Sbrian 248134789Sbrianunsigned 249134789SbrianSpeedToUnsigned(speed_t speed) 25046686Sbrian{ 25146686Sbrian const struct speeds *sp; 25246686Sbrian 25346686Sbrian for (sp = speeds; sp->nspeed; sp++) { 25446686Sbrian if (sp->speed == speed) { 25546686Sbrian return sp->nspeed; 25646686Sbrian } 25746686Sbrian } 25846686Sbrian return 0; 25946686Sbrian} 26046686Sbrian 26146686Sbrianspeed_t 262134789SbrianUnsignedToSpeed(unsigned nspeed) 26346686Sbrian{ 26446686Sbrian const struct speeds *sp; 26546686Sbrian 26646686Sbrian for (sp = speeds; sp->nspeed; sp++) { 26746686Sbrian if (sp->nspeed == nspeed) { 26846686Sbrian return sp->speed; 26946686Sbrian } 27046686Sbrian } 27146686Sbrian return B0; 27246686Sbrian} 27346686Sbrian 27454915Sbrianchar * 27555145Sbrianfindblank(char *p, int flags) 27646686Sbrian{ 27755065Sbrian int instring; 27855065Sbrian 27955065Sbrian instring = 0; 28054915Sbrian while (*p) { 28154915Sbrian if (*p == '\\') { 28255145Sbrian if (flags & PARSE_REDUCE) { 28355013Sbrian memmove(p, p + 1, strlen(p)); 28455013Sbrian if (!*p) 28555013Sbrian break; 28655013Sbrian } else 28755013Sbrian p++; 28855065Sbrian } else if (*p == '"') { 28955065Sbrian memmove(p, p + 1, strlen(p)); 29055065Sbrian instring = !instring; 29155065Sbrian continue; 29255145Sbrian } else if (!instring && (issep(*p) || 29355145Sbrian (*p == '#' && !(flags & PARSE_NOHASH)))) 29454915Sbrian return p; 29554915Sbrian p++; 29646686Sbrian } 29746686Sbrian 29854915Sbrian return instring ? NULL : p; 29946686Sbrian} 30046686Sbrian 30146686Sbrianint 30255145SbrianMakeArgs(char *script, char **pvect, int maxargs, int flags) 30346686Sbrian{ 30455065Sbrian int nargs; 30546686Sbrian 30646686Sbrian nargs = 0; 30765264Sbrian while (*script) { 30855065Sbrian script += strspn(script, " \t"); 30967825Sbrian if (*script == '#' && !(flags & PARSE_NOHASH)) { 31065264Sbrian *script = '\0'; 31165264Sbrian break; 31265264Sbrian } 31346686Sbrian if (*script) { 31446686Sbrian if (nargs >= maxargs - 1) 31565264Sbrian break; 31646686Sbrian *pvect++ = script; 31746686Sbrian nargs++; 31855145Sbrian script = findblank(script, flags); 31954914Sbrian if (script == NULL) 32054914Sbrian return -1; 32178275Sbrian else if (!(flags & PARSE_NOHASH) && *script == '#') 32265264Sbrian *script = '\0'; 32378275Sbrian else if (*script) 32465264Sbrian *script++ = '\0'; 32546686Sbrian } 32646686Sbrian } 32746686Sbrian *pvect = NULL; 32846686Sbrian return nargs; 32946686Sbrian} 33058034Sbrian 33158034Sbrianconst char * 33258034SbrianNumStr(long val, char *buf, size_t sz) 33358034Sbrian{ 33458034Sbrian static char result[23]; /* handles 64 bit numbers */ 33558034Sbrian 33658034Sbrian if (buf == NULL || sz == 0) { 33758034Sbrian buf = result; 33858034Sbrian sz = sizeof result; 33958034Sbrian } 34058034Sbrian snprintf(buf, sz, "<%ld>", val); 34158034Sbrian return buf; 34258034Sbrian} 34358034Sbrian 34458034Sbrianconst char * 34558034SbrianHexStr(long val, char *buf, size_t sz) 34658034Sbrian{ 34758034Sbrian static char result[21]; /* handles 64 bit numbers */ 34858034Sbrian 34958034Sbrian if (buf == NULL || sz == 0) { 35058034Sbrian buf = result; 35158034Sbrian sz = sizeof result; 35258034Sbrian } 35358034Sbrian snprintf(buf, sz, "<0x%lx>", val); 35458034Sbrian return buf; 35558034Sbrian} 35659084Sbrian 35759084Sbrianconst char * 35859084Sbrianex_desc(int ex) 35959084Sbrian{ 36059084Sbrian static char num[12]; /* Used immediately if returned */ 36159084Sbrian static const char * const desc[] = { 36259084Sbrian "normal", "start", "sock", "modem", "dial", "dead", "done", 36359084Sbrian "reboot", "errdead", "hangup", "term", "nodial", "nologin", 36459084Sbrian "redial", "reconnect" 36559084Sbrian }; 36659084Sbrian 367134789Sbrian if (ex >= 0 && ex < (int)(sizeof desc / sizeof *desc)) 36859084Sbrian return desc[ex]; 36959084Sbrian snprintf(num, sizeof num, "%d", ex); 37059084Sbrian return num; 37159084Sbrian} 37264698Sbrian 37364698Sbrianvoid 37464698SbrianSetTitle(const char *title) 37564698Sbrian{ 37664698Sbrian if (title == NULL) 37764698Sbrian setproctitle(NULL); 37864698Sbrian else if (title[0] == '-' && title[1] != '\0') 37964698Sbrian setproctitle("-%s", title + 1); 38064698Sbrian else 38164698Sbrian setproctitle("%s", title); 38264698Sbrian} 38366898Sbrian 38466898Sbrianfd_set * 38566898Sbrianmkfdset() 38666898Sbrian{ 38766898Sbrian return (fd_set *)malloc(howmany(getdtablesize(), NFDBITS) * sizeof (fd_mask)); 38866898Sbrian} 38966898Sbrian 39066898Sbrianvoid 39166898Sbrianzerofdset(fd_set *s) 39266898Sbrian{ 39366898Sbrian memset(s, '\0', howmany(getdtablesize(), NFDBITS) * sizeof (fd_mask)); 39466898Sbrian} 39585991Sbrian 39685991Sbrianvoid 39785991SbrianConcatinate(char *buf, size_t sz, int argc, const char *const *argv) 39885991Sbrian{ 399134789Sbrian int i, n; 400134789Sbrian unsigned pos; 40185991Sbrian 40285991Sbrian *buf = '\0'; 40385991Sbrian for (pos = i = 0; i < argc; i++) { 40485991Sbrian n = snprintf(buf + pos, sz - pos, "%s%s", i ? " " : "", argv[i]); 40585991Sbrian if (n < 0) { 40685991Sbrian buf[pos] = '\0'; 40785991Sbrian break; 40885991Sbrian } 40985991Sbrian if ((pos += n) >= sz) 41085991Sbrian break; 41185991Sbrian } 41285991Sbrian} 41393418Sbrian 414134789Sbrian#if defined(__FreeBSD__) && !defined(NOKLDLOAD) 41594698Sbrianint 41693418Sbrianloadmodules(int how, const char *module, ...) 41793418Sbrian{ 41894698Sbrian int loaded = 0; 41993418Sbrian va_list ap; 42093418Sbrian 42193418Sbrian va_start(ap, module); 42293418Sbrian while (module != NULL) { 42394698Sbrian if (modfind(module) == -1) { 42494698Sbrian if (ID0kldload(module) == -1) { 42594698Sbrian if (how == LOAD_VERBOSLY) 42694698Sbrian log_Printf(LogWARN, "%s: Cannot load module\n", module); 42794698Sbrian } else 42894698Sbrian loaded++; 42994698Sbrian } 43093418Sbrian module = va_arg(ap, const char *); 43193418Sbrian } 43293418Sbrian va_end(ap); 43394698Sbrian return loaded; 43493418Sbrian} 435134789Sbrian#else 436134789Sbrianint 437134789Sbrianloadmodules(int how __unused, const char *module __unused, ...) 438134789Sbrian{ 439134789Sbrian return 0; 440134789Sbrian} 441134789Sbrian#endif 442