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$ 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 51 void 52 randinit() 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 66 ssize_t 67 fullread(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 84 static 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 99 const char * 100 mode2Nam(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 111 int 112 Nam2mode(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 130 struct in_addr 131 GetIpAddr(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 160 static 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 241 int 242 SpeedToInt(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 254 speed_t 255 IntToSpeed(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 267 char * 268 findblank(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 294 int 295 MakeArgs(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 320 const char * 321 NumStr(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 333 const char * 334 HexStr(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 346 const char * 347 ex_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