| Commit | Line | Data |
|---|---|---|
| 984263bc MD |
1 | /* |
| 2 | * Copyright (c) 1989, 1993 | |
| 3 | * The Regents of the University of California. 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 | * 3. All advertising materials mentioning features or use of this software | |
| 14 | * must display the following acknowledgement: | |
| 15 | * This product includes software developed by the University of | |
| 16 | * California, Berkeley and its contributors. | |
| 17 | * 4. Neither the name of the University nor the names of its contributors | |
| 18 | * may be used to endorse or promote products derived from this software | |
| 19 | * without specific prior written permission. | |
| 20 | * | |
| 21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
| 22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
| 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
| 24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
| 25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
| 26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
| 27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
| 29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
| 30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
| 31 | * SUCH DAMAGE. | |
| 32 | * | |
| 2bc1b80e | 33 | * $FreeBSD: src/lib/libc/gen/getttyent.c,v 1.13 2005/07/25 17:57:15 mdodd Exp $ |
| 1de703da MD |
34 | * |
| 35 | * @(#)getttyent.c 8.1 (Berkeley) 6/4/93 | |
| 984263bc MD |
36 | */ |
| 37 | ||
| 984263bc MD |
38 | #include <ttyent.h> |
| 39 | #include <stdio.h> | |
| 40 | #include <stdlib.h> | |
| 41 | #include <ctype.h> | |
| 42 | #include <string.h> | |
| f4f08bf8 AH |
43 | #include <dirent.h> |
| 44 | #include <paths.h> | |
| 984263bc MD |
45 | |
| 46 | static char zapchar; | |
| 47 | static FILE *tf; | |
| f4f08bf8 AH |
48 | static int maxpts = -1; |
| 49 | static int curpts = 0; | |
| 984263bc MD |
50 | static size_t lbsize; |
| 51 | static char *line; | |
| 52 | ||
| f4f08bf8 | 53 | #define PTS "pts/" |
| 984263bc MD |
54 | #define MALLOCCHUNK 100 |
| 55 | ||
| 064e1fb3 EN |
56 | static char *skip (char *); |
| 57 | static char *value (char *); | |
| 984263bc MD |
58 | |
| 59 | struct ttyent * | |
| 0f52d283 | 60 | getttynam(const char *tty) |
| 984263bc | 61 | { |
| e27dad4e | 62 | struct ttyent *t; |
| 984263bc MD |
63 | |
| 64 | if (strncmp(tty, "/dev/", 5) == 0) | |
| 65 | tty += 5; | |
| 66 | setttyent(); | |
| 67 | while ( (t = getttyent()) ) | |
| 68 | if (!strcmp(tty, t->ty_name)) | |
| 69 | break; | |
| 70 | endttyent(); | |
| 71 | return (t); | |
| 72 | } | |
| 73 | ||
| 74 | struct ttyent * | |
| 0f52d283 | 75 | getttyent(void) |
| 984263bc MD |
76 | { |
| 77 | static struct ttyent tty; | |
| f4f08bf8 | 78 | static char devpts_name[] = "pts/9999999999"; |
| e27dad4e HP |
79 | char *p; |
| 80 | int c; | |
| 984263bc MD |
81 | size_t i; |
| 82 | ||
| 83 | if (!tf && !setttyent()) | |
| 84 | return (NULL); | |
| 85 | for (;;) { | |
| f4f08bf8 AH |
86 | if (!fgets(p = line, lbsize, tf)) { |
| 87 | if (curpts <= maxpts) { | |
| 88 | sprintf(devpts_name, "pts/%d", curpts++); | |
| 89 | tty.ty_name = devpts_name; | |
| 90 | tty.ty_getty = NULL; | |
| 91 | tty.ty_type = NULL; | |
| 92 | tty.ty_status = TTY_NETWORK; | |
| 93 | tty.ty_window = NULL; | |
| 94 | tty.ty_comment = NULL; | |
| 95 | tty.ty_group = _TTYS_NOGROUP; | |
| 96 | return (&tty); | |
| 97 | } | |
| 984263bc | 98 | return (NULL); |
| f4f08bf8 | 99 | } |
| 984263bc | 100 | /* extend buffer if line was too big, and retry */ |
| 2bc1b80e | 101 | while (!index(p, '\n') && !feof(tf)) { |
| 984263bc MD |
102 | i = strlen(p); |
| 103 | lbsize += MALLOCCHUNK; | |
| 104 | if ((p = realloc(line, lbsize)) == NULL) { | |
| 0f52d283 | 105 | endttyent(); |
| 984263bc MD |
106 | return (NULL); |
| 107 | } | |
| 108 | line = p; | |
| 109 | if (!fgets(&line[i], lbsize - i, tf)) | |
| 110 | return (NULL); | |
| 111 | } | |
| 112 | while (isspace((unsigned char)*p)) | |
| 113 | ++p; | |
| 114 | if (*p && *p != '#') | |
| 115 | break; | |
| 116 | } | |
| 117 | ||
| 118 | #define scmp(e) !strncmp(p, e, sizeof(e) - 1) && isspace((unsigned char)p[sizeof(e) - 1]) | |
| 119 | #define vcmp(e) !strncmp(p, e, sizeof(e) - 1) && p[sizeof(e) - 1] == '=' | |
| 120 | ||
| 121 | zapchar = 0; | |
| 122 | tty.ty_name = p; | |
| 2bc1b80e PA |
123 | tty.ty_status = 0; |
| 124 | tty.ty_window = NULL; | |
| 125 | tty.ty_group = _TTYS_NOGROUP; | |
| 126 | ||
| 984263bc MD |
127 | p = skip(p); |
| 128 | if (!*(tty.ty_getty = p)) | |
| 129 | tty.ty_getty = tty.ty_type = NULL; | |
| 130 | else { | |
| 131 | p = skip(p); | |
| 132 | if (!*(tty.ty_type = p)) | |
| 133 | tty.ty_type = NULL; | |
| 134 | else { | |
| 135 | /* compatibility kludge: handle network/dialup specially */ | |
| 136 | if (scmp(_TTYS_DIALUP)) | |
| 137 | tty.ty_status |= TTY_DIALUP; | |
| 138 | else if (scmp(_TTYS_NETWORK)) | |
| 139 | tty.ty_status |= TTY_NETWORK; | |
| 140 | p = skip(p); | |
| 141 | } | |
| 142 | } | |
| 984263bc MD |
143 | |
| 144 | for (; *p; p = skip(p)) { | |
| 145 | if (scmp(_TTYS_OFF)) | |
| 146 | tty.ty_status &= ~TTY_ON; | |
| 147 | else if (scmp(_TTYS_ON)) | |
| 148 | tty.ty_status |= TTY_ON; | |
| 149 | else if (scmp(_TTYS_SECURE)) | |
| 150 | tty.ty_status |= TTY_SECURE; | |
| 151 | else if (scmp(_TTYS_INSECURE)) | |
| 152 | tty.ty_status &= ~TTY_SECURE; | |
| 153 | else if (scmp(_TTYS_DIALUP)) | |
| 154 | tty.ty_status |= TTY_DIALUP; | |
| 155 | else if (scmp(_TTYS_NETWORK)) | |
| 156 | tty.ty_status |= TTY_NETWORK; | |
| 157 | else if (vcmp(_TTYS_WINDOW)) | |
| 158 | tty.ty_window = value(p); | |
| 159 | else if (vcmp(_TTYS_GROUP)) | |
| 160 | tty.ty_group = value(p); | |
| 161 | else | |
| 162 | break; | |
| 163 | } | |
| 164 | ||
| 165 | if (zapchar == '#' || *p == '#') | |
| 166 | while ((c = *++p) == ' ' || c == '\t') | |
| 167 | ; | |
| 168 | tty.ty_comment = p; | |
| 169 | if (*p == 0) | |
| 170 | tty.ty_comment = 0; | |
| 171 | if ( (p = index(p, '\n')) ) | |
| 172 | *p = '\0'; | |
| 173 | return (&tty); | |
| 174 | } | |
| 175 | ||
| 176 | #define QUOTED 1 | |
| 177 | ||
| 178 | /* | |
| 179 | * Skip over the current field, removing quotes, and return a pointer to | |
| 180 | * the next field. | |
| 181 | */ | |
| 182 | static char * | |
| 0f52d283 | 183 | skip(char *p) |
| 984263bc | 184 | { |
| e27dad4e HP |
185 | char *t; |
| 186 | int c, q; | |
| 984263bc MD |
187 | |
| 188 | for (q = 0, t = p; (c = *p) != '\0'; p++) { | |
| 189 | if (c == '"') { | |
| 190 | q ^= QUOTED; /* obscure, but nice */ | |
| 191 | continue; | |
| 192 | } | |
| 193 | if (q == QUOTED && *p == '\\' && *(p+1) == '"') | |
| 194 | p++; | |
| 195 | *t++ = *p; | |
| 196 | if (q == QUOTED) | |
| 197 | continue; | |
| 198 | if (c == '#') { | |
| 199 | zapchar = c; | |
| 200 | *p = 0; | |
| 201 | break; | |
| 202 | } | |
| 203 | if (c == '\t' || c == ' ' || c == '\n') { | |
| 204 | zapchar = c; | |
| 205 | *p++ = 0; | |
| 206 | while ((c = *p) == '\t' || c == ' ' || c == '\n') | |
| 207 | p++; | |
| 208 | break; | |
| 209 | } | |
| 210 | } | |
| 211 | *--t = '\0'; | |
| 212 | return (p); | |
| 213 | } | |
| 214 | ||
| 215 | static char * | |
| 0f52d283 | 216 | value(char *p) |
| 984263bc MD |
217 | { |
| 218 | ||
| 219 | return ((p = index(p, '=')) ? ++p : NULL); | |
| 220 | } | |
| 221 | ||
| 222 | int | |
| 0f52d283 | 223 | setttyent(void) |
| 984263bc | 224 | { |
| f4f08bf8 AH |
225 | DIR *devpts_dir; |
| 226 | struct dirent *dp; | |
| 227 | int unit; | |
| 984263bc MD |
228 | |
| 229 | if (line == NULL) { | |
| 230 | if ((line = malloc(MALLOCCHUNK)) == NULL) | |
| 231 | return (0); | |
| 232 | lbsize = MALLOCCHUNK; | |
| 233 | } | |
| f4f08bf8 AH |
234 | devpts_dir = opendir(_PATH_DEV PTS); |
| 235 | if (devpts_dir) { | |
| 236 | maxpts = -1; | |
| 237 | while ((dp = readdir(devpts_dir))) { | |
| 238 | if (strcmp(dp->d_name, ".") == 0 || | |
| 239 | strcmp(dp->d_name, "..") == 0) | |
| 240 | continue; | |
| 241 | ||
| 242 | unit = (int)strtol(dp->d_name, NULL, 10); | |
| 243 | ||
| 244 | if (unit > maxpts) { | |
| 245 | maxpts = unit; | |
| 246 | curpts = 0; | |
| 247 | } | |
| 248 | } | |
| 249 | closedir(devpts_dir); | |
| 250 | } | |
| 984263bc MD |
251 | if (tf) { |
| 252 | rewind(tf); | |
| 253 | return (1); | |
| 254 | } else if ( (tf = fopen(_PATH_TTYS, "r")) ) | |
| 255 | return (1); | |
| 256 | return (0); | |
| 257 | } | |
| 258 | ||
| 259 | int | |
| 0f52d283 | 260 | endttyent(void) |
| 984263bc MD |
261 | { |
| 262 | int rval; | |
| 263 | ||
| f4f08bf8 | 264 | maxpts = -1; |
| 984263bc MD |
265 | /* |
| 266 | * NB: Don't free `line' because getttynam() | |
| 267 | * may still be referencing it | |
| 268 | */ | |
| 269 | if (tf) { | |
| 270 | rval = (fclose(tf) != EOF); | |
| 271 | tf = NULL; | |
| 272 | return (rval); | |
| 273 | } | |
| 274 | return (1); | |
| 275 | } | |
| 276 | ||
| 277 | static int | |
| 0f52d283 | 278 | isttystat(const char *tty, int flag) |
| 984263bc | 279 | { |
| e27dad4e | 280 | struct ttyent *t; |
| 984263bc MD |
281 | |
| 282 | return ((t = getttynam(tty)) == NULL) ? 0 : !!(t->ty_status & flag); | |
| 283 | } | |
| 284 | ||
| 285 | ||
| 286 | int | |
| 0f52d283 | 287 | isdialuptty(const char *tty) |
| 984263bc MD |
288 | { |
| 289 | ||
| 290 | return isttystat(tty, TTY_DIALUP); | |
| 291 | } | |
| 292 | ||
| 0f52d283 SW |
293 | int |
| 294 | isnettty(const char *tty) | |
| 984263bc MD |
295 | { |
| 296 | ||
| 297 | return isttystat(tty, TTY_NETWORK); | |
| 298 | } |