1 /*
2 * Copyright (c) 1985 Regents of the University of California.
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 */
6
7 #pragma ident "%Z%%M% %I% %E% SMI"
8
9
10 #include <stdio.h>
11 #include <strings.h>
12 #include <ttyent.h>
13
14 static char *TTYFILE = "/etc/ttytab";
15 #define LINE 256
16 static struct _ttyentjunk {
17 char zapchar;
18 FILE *tf;
19 char line[LINE];
20 struct ttyent tty;
21 } *__ttyentjunk, *_ttyentjunk(void);
22
23 static struct _ttyentjunk *
_ttyentjunk(void)24 _ttyentjunk(void)
25 {
26
27 if (__ttyentjunk == 0)
28 __ttyentjunk = (struct _ttyentjunk *)calloc(1, sizeof (struct _ttyentjunk));
29 return (__ttyentjunk);
30 }
31
32 void
setttyent(void)33 setttyent(void)
34 {
35 struct _ttyentjunk *t = _ttyentjunk();
36
37 if (t == 0)
38 return;
39 if (t->tf == NULL)
40 t->tf = fopen(TTYFILE, "r");
41 else
42 rewind(t->tf);
43 }
44
45 void
endttyent(void)46 endttyent(void)
47 {
48 struct _ttyentjunk *t = _ttyentjunk();
49
50 if (t == 0)
51 return;
52 if (t->tf != NULL) {
53 (void) fclose(t->tf);
54 t->tf = NULL;
55 }
56 }
57
58 #define QUOTED 1
59
60 /*
61 * Skip over the current field, removing quotes,
62 * and return a pointer to the next field.
63 */
64 static char *
skip(char * p)65 skip(char *p)
66 {
67 struct _ttyentjunk *t = _ttyentjunk();
68 char *cp = p;
69 int c;
70 int q = 0;
71
72 if (t == 0)
73 return (0);
74 for (; (c = *p) != '\0'; p++) {
75 if (c == '"') {
76 q ^= QUOTED; /* obscure, but nice */
77 continue;
78 }
79 if (q == QUOTED && *p == '\\' && *(p+1) == '"')
80 p++;
81 *cp++ = *p;
82 if (q == QUOTED)
83 continue;
84 if (c == '#') {
85 t->zapchar = c;
86 *p = 0;
87 break;
88 }
89 if (c == '\t' || c == ' ' || c == '\n') {
90 t->zapchar = c;
91 *p++ = 0;
92 while ((c = *p) == '\t' || c == ' ' || c == '\n')
93 p++;
94 break;
95 }
96 }
97 *--cp = '\0';
98 return (p);
99 }
100
101 static char *
value(char * p)102 value(char *p)
103 {
104 if ((p = index(p,'=')) == 0)
105 return (NULL);
106 p++; /* get past the = sign */
107 return (p);
108 }
109
110 struct ttyent *
getttyent(void)111 getttyent(void)
112 {
113 struct _ttyentjunk *t = _ttyentjunk();
114 char *p;
115 int c;
116
117 if (t == 0)
118 return (NULL);
119 if (t->tf == NULL) {
120 if ((t->tf = fopen(TTYFILE, "r")) == NULL)
121 return (NULL);
122 }
123 do {
124 p = fgets(t->line, LINE, t->tf);
125 if (p == NULL)
126 return (NULL);
127 while ((c = *p) == '\t' || c == ' ' || c == '\n')
128 p++;
129 } while (c == '\0' || c == '#');
130 t->zapchar = 0;
131 t->tty.ty_name = p;
132 p = skip(p);
133 t->tty.ty_getty = p;
134 p = skip(p);
135 t->tty.ty_type = p;
136 p = skip(p);
137 t->tty.ty_status = 0;
138 t->tty.ty_window = NULL;
139 for (; *p; p = skip(p)) {
140 #define space(x) ((c = p[x]) == ' ' || c == '\t' || c == '\n')
141 if (strncmp(p, "on", 2) == 0 && space(2))
142 t->tty.ty_status |= TTY_ON;
143 else if (strncmp(p, "off", 3) == 0 && space(3))
144 t->tty.ty_status &= ~TTY_ON;
145 else if (strncmp(p, "secure", 6) == 0 && space(6))
146 t->tty.ty_status |= TTY_SECURE;
147 else if (strncmp(p, "local", 5) == 0 && space(5))
148 t->tty.ty_status |= TTY_LOCAL;
149 else if (strncmp(p, "window=", 7) == 0)
150 t->tty.ty_window = value(p);
151 else
152 break;
153 }
154 if (t->zapchar == '#' || *p == '#')
155 while ((c = *++p) == ' ' || c == '\t')
156 ;
157 t->tty.ty_comment = p;
158 if (*p == 0)
159 t->tty.ty_comment = 0;
160 if (p = index(p, '\n'))
161 *p = '\0';
162 return (&t->tty);
163 }
164