1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 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__ 62 void 63 randinit() 64 { 65 srandom((time(NULL)^getpid())+random()); 66 } 67 #endif 68 69 ssize_t 70 fullread(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 87 static 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 102 const char * 103 mode2Nam(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 114 int 115 Nam2mode(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 133 struct in_addr 134 GetIpAddr(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 163 static 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 250 unsigned 251 SpeedToUnsigned(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 263 speed_t 264 UnsignedToSpeed(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 276 char * 277 findblank(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 303 int 304 MakeArgs(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 333 const char * 334 NumStr(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 346 const char * 347 HexStr(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 359 const char * 360 ex_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 375 void 376 SetTitle(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 386 fd_set * 387 mkfdset(void) 388 { 389 return (fd_set *)malloc(howmany(getdtablesize(), NFDBITS) * sizeof (fd_mask)); 390 } 391 392 void 393 zerofdset(fd_set *s) 394 { 395 memset(s, '\0', howmany(getdtablesize(), NFDBITS) * sizeof (fd_mask)); 396 } 397 398 void 399 Concatinate(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) 417 int 418 loadmodules(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 438 int 439 loadmodules(int how __unused, const char *module __unused, ...) 440 { 441 return 0; 442 } 443 #endif 444