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