getttyent.c revision 90045
180219Swpaul/* 280219Swpaul * Copyright (c) 1989, 1993 380219Swpaul * The Regents of the University of California. All rights reserved. 480219Swpaul * 580219Swpaul * Redistribution and use in source and binary forms, with or without 680219Swpaul * modification, are permitted provided that the following conditions 780219Swpaul * are met: 880219Swpaul * 1. Redistributions of source code must retain the above copyright 980219Swpaul * notice, this list of conditions and the following disclaimer. 1080219Swpaul * 2. Redistributions in binary form must reproduce the above copyright 1180219Swpaul * notice, this list of conditions and the following disclaimer in the 1280219Swpaul * documentation and/or other materials provided with the distribution. 1380219Swpaul * 3. All advertising materials mentioning features or use of this software 1480219Swpaul * must display the following acknowledgement: 1580219Swpaul * This product includes software developed by the University of 1680219Swpaul * California, Berkeley and its contributors. 1780219Swpaul * 4. Neither the name of the University nor the names of its contributors 1880219Swpaul * may be used to endorse or promote products derived from this software 1980219Swpaul * without specific prior written permission. 2080219Swpaul * 2180219Swpaul * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2280219Swpaul * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2380219Swpaul * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2480219Swpaul * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2580219Swpaul * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2680219Swpaul * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2780219Swpaul * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2880219Swpaul * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2980219Swpaul * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3080219Swpaul * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3180219Swpaul * SUCH DAMAGE. 3280219Swpaul */ 3380219Swpaul 3480219Swpaul#if defined(LIBC_SCCS) && !defined(lint) 3580219Swpaulstatic char sccsid[] = "@(#)getttyent.c 8.1 (Berkeley) 6/4/93"; 3680219Swpaul#endif /* LIBC_SCCS and not lint */ 3780219Swpaul#include <sys/cdefs.h> 3880219Swpaul__FBSDID("$FreeBSD: head/lib/libc/gen/getttyent.c 90045 2002-02-01 01:32:19Z obrien $"); 3980219Swpaul 4080219Swpaul#include <ttyent.h> 4180219Swpaul#include <stdio.h> 4280219Swpaul#include <stdlib.h> 4380219Swpaul#include <ctype.h> 4480219Swpaul#include <string.h> 4580219Swpaul 4680219Swpaulstatic char zapchar; 4780219Swpaulstatic FILE *tf; 4880219Swpaulstatic size_t lbsize; 4980219Swpaulstatic char *line; 5080219Swpaul 5180219Swpaul#define MALLOCCHUNK 100 5280219Swpaul 5380219Swpaulstatic char *skip(char *); 5480219Swpaulstatic char *value(char *); 5583115Sbrooks 5680219Swpaulstruct ttyent * 5780219Swpaulgetttynam(tty) 5880219Swpaul const char *tty; 5980219Swpaul{ 6080219Swpaul struct ttyent *t; 6180219Swpaul 6280219Swpaul if (strncmp(tty, "/dev/", 5) == 0) 6380219Swpaul tty += 5; 6480219Swpaul setttyent(); 6580219Swpaul while ( (t = getttyent()) ) 6680219Swpaul if (!strcmp(tty, t->ty_name)) 6780219Swpaul break; 6880219Swpaul endttyent(); 6980219Swpaul return (t); 7080219Swpaul} 7180219Swpaul 7280219Swpaulstruct ttyent * 7380219Swpaulgetttyent() 7480219Swpaul{ 7580219Swpaul static struct ttyent tty; 7680219Swpaul char *p; 7780219Swpaul int c; 7880219Swpaul size_t i; 7980219Swpaul 8080219Swpaul if (!tf && !setttyent()) 8180219Swpaul return (NULL); 8280219Swpaul for (;;) { 8380219Swpaul if (!fgets(p = line, lbsize, tf)) 8480229Swpaul return (NULL); 8580219Swpaul /* extend buffer if line was too big, and retry */ 8680219Swpaul while (!index(p, '\n')) { 8780219Swpaul i = strlen(p); 8880219Swpaul lbsize += MALLOCCHUNK; 8980219Swpaul if ((p = realloc(line, lbsize)) == NULL) { 9080219Swpaul (void)endttyent(); 9180219Swpaul return (NULL); 9280219Swpaul } 9380219Swpaul line = p; 9480219Swpaul if (!fgets(&line[i], lbsize - i, tf)) 9580219Swpaul return (NULL); 9680219Swpaul } 9780219Swpaul while (isspace((unsigned char)*p)) 9880219Swpaul ++p; 9980219Swpaul if (*p && *p != '#') 10080219Swpaul break; 10180219Swpaul } 10280219Swpaul 10380219Swpaul#define scmp(e) !strncmp(p, e, sizeof(e) - 1) && isspace((unsigned char)p[sizeof(e) - 1]) 10480219Swpaul#define vcmp(e) !strncmp(p, e, sizeof(e) - 1) && p[sizeof(e) - 1] == '=' 10580219Swpaul 10680219Swpaul zapchar = 0; 10780219Swpaul tty.ty_name = p; 10880219Swpaul p = skip(p); 10980219Swpaul if (!*(tty.ty_getty = p)) 11080219Swpaul tty.ty_getty = tty.ty_type = NULL; 11180219Swpaul else { 11280219Swpaul p = skip(p); 11380219Swpaul if (!*(tty.ty_type = p)) 11480219Swpaul tty.ty_type = NULL; 11580219Swpaul else { 11680219Swpaul /* compatibility kludge: handle network/dialup specially */ 11780219Swpaul if (scmp(_TTYS_DIALUP)) 11880219Swpaul tty.ty_status |= TTY_DIALUP; 11980219Swpaul else if (scmp(_TTYS_NETWORK)) 12080219Swpaul tty.ty_status |= TTY_NETWORK; 12180219Swpaul p = skip(p); 12280219Swpaul } 12380219Swpaul } 12480219Swpaul tty.ty_status = 0; 12580219Swpaul tty.ty_window = NULL; 12680219Swpaul tty.ty_group = _TTYS_NOGROUP; 12780219Swpaul 12880219Swpaul for (; *p; p = skip(p)) { 12980219Swpaul if (scmp(_TTYS_OFF)) 13080219Swpaul tty.ty_status &= ~TTY_ON; 13180219Swpaul else if (scmp(_TTYS_ON)) 13280219Swpaul tty.ty_status |= TTY_ON; 13380219Swpaul else if (scmp(_TTYS_SECURE)) 13480219Swpaul tty.ty_status |= TTY_SECURE; 13580219Swpaul else if (scmp(_TTYS_INSECURE)) 13680219Swpaul tty.ty_status &= ~TTY_SECURE; 13780219Swpaul else if (scmp(_TTYS_DIALUP)) 13880219Swpaul tty.ty_status |= TTY_DIALUP; 13980219Swpaul else if (scmp(_TTYS_NETWORK)) 14080219Swpaul tty.ty_status |= TTY_NETWORK; 14180219Swpaul else if (vcmp(_TTYS_WINDOW)) 14280219Swpaul tty.ty_window = value(p); 14380219Swpaul else if (vcmp(_TTYS_GROUP)) 14480219Swpaul tty.ty_group = value(p); 14580219Swpaul else 14680219Swpaul break; 14780219Swpaul } 14880219Swpaul 14980219Swpaul if (zapchar == '#' || *p == '#') 15080219Swpaul while ((c = *++p) == ' ' || c == '\t') 15180219Swpaul ; 15280219Swpaul tty.ty_comment = p; 15380219Swpaul if (*p == 0) 15480219Swpaul tty.ty_comment = 0; 15580219Swpaul if ( (p = index(p, '\n')) ) 15680219Swpaul *p = '\0'; 15780219Swpaul return (&tty); 15880219Swpaul} 15980219Swpaul 16080219Swpaul#define QUOTED 1 16180219Swpaul 16280219Swpaul/* 16380219Swpaul * Skip over the current field, removing quotes, and return a pointer to 16480219Swpaul * the next field. 16580219Swpaul */ 16680219Swpaulstatic char * 16780219Swpaulskip(p) 16880219Swpaul char *p; 16980219Swpaul{ 17080219Swpaul char *t; 17180219Swpaul int c, q; 17280219Swpaul 17380219Swpaul for (q = 0, t = p; (c = *p) != '\0'; p++) { 17480219Swpaul if (c == '"') { 17580219Swpaul q ^= QUOTED; /* obscure, but nice */ 17680219Swpaul continue; 17780219Swpaul } 17880219Swpaul if (q == QUOTED && *p == '\\' && *(p+1) == '"') 17980219Swpaul p++; 18080219Swpaul *t++ = *p; 18180219Swpaul if (q == QUOTED) 18280219Swpaul continue; 18380219Swpaul if (c == '#') { 18480219Swpaul zapchar = c; 18580219Swpaul *p = 0; 18680219Swpaul break; 18780219Swpaul } 18880219Swpaul if (c == '\t' || c == ' ' || c == '\n') { 18980219Swpaul zapchar = c; 19080219Swpaul *p++ = 0; 19180219Swpaul while ((c = *p) == '\t' || c == ' ' || c == '\n') 19280219Swpaul p++; 19380219Swpaul break; 19480219Swpaul } 19580219Swpaul } 19680219Swpaul *--t = '\0'; 19780219Swpaul return (p); 19880219Swpaul} 19980219Swpaul 20080219Swpaulstatic char * 20180219Swpaulvalue(p) 20280219Swpaul char *p; 20380219Swpaul{ 20480219Swpaul 20580219Swpaul return ((p = index(p, '=')) ? ++p : NULL); 20680219Swpaul} 20780219Swpaul 20880219Swpaulint 20980219Swpaulsetttyent() 21080219Swpaul{ 21180219Swpaul 21280219Swpaul if (line == NULL) { 21380219Swpaul if ((line = malloc(MALLOCCHUNK)) == NULL) 21480219Swpaul return (0); 21580219Swpaul lbsize = MALLOCCHUNK; 21680219Swpaul } 21780219Swpaul if (tf) { 21880219Swpaul rewind(tf); 21980219Swpaul return (1); 22080219Swpaul } else if ( (tf = fopen(_PATH_TTYS, "r")) ) 22180219Swpaul return (1); 22280219Swpaul return (0); 22380219Swpaul} 22480219Swpaul 22580219Swpaulint 22680219Swpaulendttyent() 22780219Swpaul{ 22880219Swpaul int rval; 22980219Swpaul 23080219Swpaul /* 23180219Swpaul * NB: Don't free `line' because getttynam() 23280219Swpaul * may still be referencing it 23380219Swpaul */ 23480219Swpaul if (tf) { 23580219Swpaul rval = (fclose(tf) != EOF); 23680219Swpaul tf = NULL; 23780219Swpaul return (rval); 23880219Swpaul } 23980219Swpaul return (1); 24080219Swpaul} 24180219Swpaul 24280219Swpaulstatic int 24380219Swpaulisttystat(tty, flag) 24480219Swpaul const char *tty; 24580219Swpaul int flag; 24680219Swpaul{ 24780219Swpaul struct ttyent *t; 24880219Swpaul 24980219Swpaul return ((t = getttynam(tty)) == NULL) ? 0 : !!(t->ty_status & flag); 25080219Swpaul} 25180219Swpaul 25280219Swpaul 25380219Swpaulint 25480219Swpaulisdialuptty(tty) 25580219Swpaul const char *tty; 25680455Swpaul{ 25780219Swpaul 25880219Swpaul return isttystat(tty, TTY_DIALUP); 25980219Swpaul} 26080219Swpaul 26180219Swpaulint isnettty(tty) 26280455Swpaul const char *tty; 26380219Swpaul{ 26480219Swpaul 26580219Swpaul return isttystat(tty, TTY_NETWORK); 26680219Swpaul} 26780219Swpaul