main.c revision 1.9.2.2 1 1.9.2.2 mycroft /*-
2 1.9.2.2 mycroft * Copyright (c) 1980, 1993
3 1.9.2.2 mycroft * The Regents of the University of California. All rights reserved.
4 1.9.2.2 mycroft *
5 1.9.2.2 mycroft * Redistribution and use in source and binary forms, with or without
6 1.9.2.2 mycroft * modification, are permitted provided that the following conditions
7 1.9.2.2 mycroft * are met:
8 1.9.2.2 mycroft * 1. Redistributions of source code must retain the above copyright
9 1.9.2.2 mycroft * notice, this list of conditions and the following disclaimer.
10 1.9.2.2 mycroft * 2. Redistributions in binary form must reproduce the above copyright
11 1.9.2.2 mycroft * notice, this list of conditions and the following disclaimer in the
12 1.9.2.2 mycroft * documentation and/or other materials provided with the distribution.
13 1.9.2.2 mycroft * 3. All advertising materials mentioning features or use of this software
14 1.9.2.2 mycroft * must display the following acknowledgement:
15 1.9.2.2 mycroft * This product includes software developed by the University of
16 1.9.2.2 mycroft * California, Berkeley and its contributors.
17 1.9.2.2 mycroft * 4. Neither the name of the University nor the names of its contributors
18 1.9.2.2 mycroft * may be used to endorse or promote products derived from this software
19 1.9.2.2 mycroft * without specific prior written permission.
20 1.9.2.2 mycroft *
21 1.9.2.2 mycroft * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 1.9.2.2 mycroft * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 1.9.2.2 mycroft * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 1.9.2.2 mycroft * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 1.9.2.2 mycroft * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 1.9.2.2 mycroft * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 1.9.2.2 mycroft * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 1.9.2.2 mycroft * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 1.9.2.2 mycroft * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 1.9.2.2 mycroft * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 1.9.2.2 mycroft * SUCH DAMAGE.
32 1.9.2.2 mycroft */
33 1.9.2.2 mycroft
34 1.9.2.2 mycroft #ifndef lint
35 1.9.2.2 mycroft static char copyright[] =
36 1.9.2.2 mycroft "@(#) Copyright (c) 1980, 1993\n\
37 1.9.2.2 mycroft The Regents of the University of California. All rights reserved.\n";
38 1.9.2.2 mycroft #endif /* not lint */
39 1.9.2.2 mycroft
40 1.9.2.2 mycroft #ifndef lint
41 1.9.2.2 mycroft /*static char sccsid[] = "from: @(#)main.c 8.1 (Berkeley) 6/20/93";*/
42 1.9.2.2 mycroft static char rcsid[] = "$Id: main.c,v 1.9.2.2 1994/08/24 17:12:38 mycroft Exp $";
43 1.9.2.2 mycroft #endif /* not lint */
44 1.9.2.2 mycroft
45 1.9.2.2 mycroft #include <sys/param.h>
46 1.9.2.2 mycroft #include <sys/stat.h>
47 1.9.2.2 mycroft #include <sys/termios.h>
48 1.9.2.2 mycroft #include <sys/ioctl.h>
49 1.9.2.2 mycroft #include <sys/resource.h>
50 1.9.2.2 mycroft #include <sys/utsname.h>
51 1.9.2.2 mycroft #include <signal.h>
52 1.9.2.2 mycroft #include <fcntl.h>
53 1.9.2.2 mycroft #include <time.h>
54 1.9.2.2 mycroft #include <ctype.h>
55 1.9.2.2 mycroft #include <fcntl.h>
56 1.9.2.2 mycroft #include <setjmp.h>
57 1.9.2.2 mycroft #include <signal.h>
58 1.9.2.2 mycroft #include <stdlib.h>
59 1.9.2.2 mycroft #include <string.h>
60 1.9.2.2 mycroft #include <syslog.h>
61 1.9.2.2 mycroft #include <time.h>
62 1.9.2.2 mycroft #include <unistd.h>
63 1.9.2.2 mycroft
64 1.9.2.2 mycroft #include "gettytab.h"
65 1.9.2.2 mycroft #include "pathnames.h"
66 1.9.2.2 mycroft #include "extern.h"
67 1.9.2.2 mycroft
68 1.9.2.2 mycroft /*
69 1.9.2.2 mycroft * Set the amount of running time that getty should accumulate
70 1.9.2.2 mycroft * before deciding that something is wrong and exit.
71 1.9.2.2 mycroft */
72 1.9.2.2 mycroft #define GETTY_TIMEOUT 60 /* seconds */
73 1.9.2.2 mycroft
74 1.9.2.2 mycroft struct termios tmode, omode;
75 1.9.2.2 mycroft
76 1.9.2.2 mycroft int crmod, digit, lower, upper;
77 1.9.2.2 mycroft
78 1.9.2.2 mycroft char hostname[MAXHOSTNAMELEN];
79 1.9.2.2 mycroft struct utsname kerninfo;
80 1.9.2.2 mycroft char name[16];
81 1.9.2.2 mycroft char dev[] = _PATH_DEV;
82 1.9.2.2 mycroft char ttyn[32];
83 1.9.2.2 mycroft char *portselector();
84 1.9.2.2 mycroft char *ttyname();
85 1.9.2.2 mycroft
86 1.9.2.2 mycroft #define OBUFSIZ 128
87 1.9.2.2 mycroft #define TABBUFSIZ 512
88 1.9.2.2 mycroft
89 1.9.2.2 mycroft char defent[TABBUFSIZ];
90 1.9.2.2 mycroft char tabent[TABBUFSIZ];
91 1.9.2.2 mycroft
92 1.9.2.2 mycroft char *env[128];
93 1.9.2.2 mycroft
94 1.9.2.2 mycroft char partab[] = {
95 1.9.2.2 mycroft 0001,0201,0201,0001,0201,0001,0001,0201,
96 1.9.2.2 mycroft 0202,0004,0003,0205,0005,0206,0201,0001,
97 1.9.2.2 mycroft 0201,0001,0001,0201,0001,0201,0201,0001,
98 1.9.2.2 mycroft 0001,0201,0201,0001,0201,0001,0001,0201,
99 1.9.2.2 mycroft 0200,0000,0000,0200,0000,0200,0200,0000,
100 1.9.2.2 mycroft 0000,0200,0200,0000,0200,0000,0000,0200,
101 1.9.2.2 mycroft 0000,0200,0200,0000,0200,0000,0000,0200,
102 1.9.2.2 mycroft 0200,0000,0000,0200,0000,0200,0200,0000,
103 1.9.2.2 mycroft 0200,0000,0000,0200,0000,0200,0200,0000,
104 1.9.2.2 mycroft 0000,0200,0200,0000,0200,0000,0000,0200,
105 1.9.2.2 mycroft 0000,0200,0200,0000,0200,0000,0000,0200,
106 1.9.2.2 mycroft 0200,0000,0000,0200,0000,0200,0200,0000,
107 1.9.2.2 mycroft 0000,0200,0200,0000,0200,0000,0000,0200,
108 1.9.2.2 mycroft 0200,0000,0000,0200,0000,0200,0200,0000,
109 1.9.2.2 mycroft 0200,0000,0000,0200,0000,0200,0200,0000,
110 1.9.2.2 mycroft 0000,0200,0200,0000,0200,0000,0000,0201
111 1.9.2.2 mycroft };
112 1.9.2.2 mycroft
113 1.9.2.2 mycroft #define ERASE tmode.c_cc[VERASE]
114 1.9.2.2 mycroft #define KILL tmode.c_cc[VKILL]
115 1.9.2.2 mycroft #define EOT tmode.c_cc[VEOF]
116 1.9.2.2 mycroft
117 1.9.2.2 mycroft jmp_buf timeout;
118 1.9.2.2 mycroft
119 1.9.2.2 mycroft static void
120 1.9.2.2 mycroft dingdong()
121 1.9.2.2 mycroft {
122 1.9.2.2 mycroft
123 1.9.2.2 mycroft alarm(0);
124 1.9.2.2 mycroft signal(SIGALRM, SIG_DFL);
125 1.9.2.2 mycroft longjmp(timeout, 1);
126 1.9.2.2 mycroft }
127 1.9.2.2 mycroft
128 1.9.2.2 mycroft jmp_buf intrupt;
129 1.9.2.2 mycroft
130 1.9.2.2 mycroft static void
131 1.9.2.2 mycroft interrupt()
132 1.9.2.2 mycroft {
133 1.9.2.2 mycroft
134 1.9.2.2 mycroft signal(SIGINT, interrupt);
135 1.9.2.2 mycroft longjmp(intrupt, 1);
136 1.9.2.2 mycroft }
137 1.9.2.2 mycroft
138 1.9.2.2 mycroft /*
139 1.9.2.2 mycroft * Action to take when getty is running too long.
140 1.9.2.2 mycroft */
141 1.9.2.2 mycroft void
142 1.9.2.2 mycroft timeoverrun(signo)
143 1.9.2.2 mycroft int signo;
144 1.9.2.2 mycroft {
145 1.9.2.2 mycroft
146 1.9.2.2 mycroft syslog(LOG_ERR, "getty exiting due to excessive running time\n");
147 1.9.2.2 mycroft exit(1);
148 1.9.2.2 mycroft }
149 1.9.2.2 mycroft
150 1.9.2.2 mycroft static int getname __P((void));
151 1.9.2.2 mycroft static void oflush __P((void));
152 1.9.2.2 mycroft static void prompt __P((void));
153 1.9.2.2 mycroft static void putchr __P((int));
154 1.9.2.2 mycroft static void putf __P((char *));
155 1.9.2.2 mycroft static void putpad __P((char *));
156 1.9.2.2 mycroft static void puts __P((char *));
157 1.9.2.2 mycroft
158 1.9.2.2 mycroft int
159 1.9.2.2 mycroft main(argc, argv)
160 1.9.2.2 mycroft int argc;
161 1.9.2.2 mycroft char *argv[];
162 1.9.2.2 mycroft {
163 1.9.2.2 mycroft extern char **environ;
164 1.9.2.2 mycroft char *tname;
165 1.9.2.2 mycroft long allflags;
166 1.9.2.2 mycroft int repcnt = 0;
167 1.9.2.2 mycroft struct rlimit limit;
168 1.9.2.2 mycroft
169 1.9.2.2 mycroft signal(SIGINT, SIG_IGN);
170 1.9.2.2 mycroft /*
171 1.9.2.2 mycroft signal(SIGQUIT, SIG_DFL);
172 1.9.2.2 mycroft */
173 1.9.2.2 mycroft openlog("getty", LOG_ODELAY|LOG_CONS, LOG_AUTH);
174 1.9.2.2 mycroft gethostname(hostname, sizeof(hostname));
175 1.9.2.2 mycroft if (hostname[0] == '\0')
176 1.9.2.2 mycroft strcpy(hostname, "Amnesiac");
177 1.9.2.2 mycroft uname(&kerninfo);
178 1.9.2.2 mycroft
179 1.9.2.2 mycroft /*
180 1.9.2.2 mycroft * Limit running time to deal with broken or dead lines.
181 1.9.2.2 mycroft */
182 1.9.2.2 mycroft (void)signal(SIGXCPU, timeoverrun);
183 1.9.2.2 mycroft limit.rlim_max = RLIM_INFINITY;
184 1.9.2.2 mycroft limit.rlim_cur = GETTY_TIMEOUT;
185 1.9.2.2 mycroft (void)setrlimit(RLIMIT_CPU, &limit);
186 1.9.2.2 mycroft
187 1.9.2.2 mycroft /*
188 1.9.2.2 mycroft * The following is a work around for vhangup interactions
189 1.9.2.2 mycroft * which cause great problems getting window systems started.
190 1.9.2.2 mycroft * If the tty line is "-", we do the old style getty presuming
191 1.9.2.2 mycroft * that the file descriptors are already set up for us.
192 1.9.2.2 mycroft * J. Gettys - MIT Project Athena.
193 1.9.2.2 mycroft */
194 1.9.2.2 mycroft if (argc <= 2 || strcmp(argv[2], "-") == 0)
195 1.9.2.2 mycroft strcpy(ttyn, ttyname(0));
196 1.9.2.2 mycroft else {
197 1.9.2.2 mycroft int i;
198 1.9.2.2 mycroft
199 1.9.2.2 mycroft strcpy(ttyn, dev);
200 1.9.2.2 mycroft strncat(ttyn, argv[2], sizeof(ttyn)-sizeof(dev));
201 1.9.2.2 mycroft if (strcmp(argv[0], "+") != 0) {
202 1.9.2.2 mycroft chown(ttyn, 0, 0);
203 1.9.2.2 mycroft chmod(ttyn, 0600);
204 1.9.2.2 mycroft revoke(ttyn);
205 1.9.2.2 mycroft /*
206 1.9.2.2 mycroft * Delay the open so DTR stays down long enough to be detected.
207 1.9.2.2 mycroft */
208 1.9.2.2 mycroft sleep(2);
209 1.9.2.2 mycroft while ((i = open(ttyn, O_RDWR)) == -1) {
210 1.9.2.2 mycroft if (repcnt % 10 == 0) {
211 1.9.2.2 mycroft syslog(LOG_ERR, "%s: %m", ttyn);
212 1.9.2.2 mycroft closelog();
213 1.9.2.2 mycroft }
214 1.9.2.2 mycroft repcnt++;
215 1.9.2.2 mycroft sleep(60);
216 1.9.2.2 mycroft }
217 1.9.2.2 mycroft login_tty(i);
218 1.9.2.2 mycroft }
219 1.9.2.2 mycroft }
220 1.9.2.2 mycroft
221 1.9.2.2 mycroft /* Start with default tty settings */
222 1.9.2.2 mycroft if (tcgetattr(0, &tmode) < 0) {
223 1.9.2.2 mycroft syslog(LOG_ERR, "%s: %m", ttyn);
224 1.9.2.2 mycroft exit(1);
225 1.9.2.2 mycroft }
226 1.9.2.2 mycroft omode = tmode;
227 1.9.2.2 mycroft
228 1.9.2.2 mycroft gettable("default", defent);
229 1.9.2.2 mycroft gendefaults();
230 1.9.2.2 mycroft tname = "default";
231 1.9.2.2 mycroft if (argc > 1)
232 1.9.2.2 mycroft tname = argv[1];
233 1.9.2.2 mycroft for (;;) {
234 1.9.2.2 mycroft int off;
235 1.9.2.2 mycroft
236 1.9.2.2 mycroft gettable(tname, tabent);
237 1.9.2.2 mycroft if (OPset || EPset || APset)
238 1.9.2.2 mycroft APset++, OPset++, EPset++;
239 1.9.2.2 mycroft setdefaults();
240 1.9.2.2 mycroft off = 0;
241 1.9.2.2 mycroft ioctl(0, TIOCFLUSH, &off); /* clear out the crap */
242 1.9.2.2 mycroft ioctl(0, FIONBIO, &off); /* turn off non-blocking mode */
243 1.9.2.2 mycroft ioctl(0, FIOASYNC, &off); /* ditto for async mode */
244 1.9.2.2 mycroft
245 1.9.2.2 mycroft if (IS)
246 1.9.2.2 mycroft cfsetispeed(&tmode, IS);
247 1.9.2.2 mycroft else if (SP)
248 1.9.2.2 mycroft cfsetispeed(&tmode, SP);
249 1.9.2.2 mycroft if (OS)
250 1.9.2.2 mycroft cfsetospeed(&tmode, OS);
251 1.9.2.2 mycroft else if (SP)
252 1.9.2.2 mycroft cfsetospeed(&tmode, SP);
253 1.9.2.2 mycroft setflags(0);
254 1.9.2.2 mycroft setchars();
255 1.9.2.2 mycroft if (tcsetattr(0, TCSANOW, &tmode) < 0) {
256 1.9.2.2 mycroft syslog(LOG_ERR, "%s: %m", ttyn);
257 1.9.2.2 mycroft exit(1);
258 1.9.2.2 mycroft }
259 1.9.2.2 mycroft if (AB) {
260 1.9.2.2 mycroft extern char *autobaud();
261 1.9.2.2 mycroft
262 1.9.2.2 mycroft tname = autobaud();
263 1.9.2.2 mycroft continue;
264 1.9.2.2 mycroft }
265 1.9.2.2 mycroft if (PS) {
266 1.9.2.2 mycroft tname = portselector();
267 1.9.2.2 mycroft continue;
268 1.9.2.2 mycroft }
269 1.9.2.2 mycroft if (CL && *CL)
270 1.9.2.2 mycroft putpad(CL);
271 1.9.2.2 mycroft edithost(HE);
272 1.9.2.2 mycroft if (IM && *IM)
273 1.9.2.2 mycroft putf(IM);
274 1.9.2.2 mycroft if (setjmp(timeout)) {
275 1.9.2.2 mycroft tmode.c_ispeed = tmode.c_ospeed = 0;
276 1.9.2.2 mycroft (void)tcsetattr(0, TCSANOW, &tmode);
277 1.9.2.2 mycroft exit(1);
278 1.9.2.2 mycroft }
279 1.9.2.2 mycroft if (TO) {
280 1.9.2.2 mycroft signal(SIGALRM, dingdong);
281 1.9.2.2 mycroft alarm(TO);
282 1.9.2.2 mycroft }
283 1.9.2.2 mycroft if (getname()) {
284 1.9.2.2 mycroft register int i;
285 1.9.2.2 mycroft
286 1.9.2.2 mycroft oflush();
287 1.9.2.2 mycroft alarm(0);
288 1.9.2.2 mycroft signal(SIGALRM, SIG_DFL);
289 1.9.2.2 mycroft if (name[0] == '-') {
290 1.9.2.2 mycroft puts("user names may not start with '-'.");
291 1.9.2.2 mycroft continue;
292 1.9.2.2 mycroft }
293 1.9.2.2 mycroft if (!(upper || lower || digit))
294 1.9.2.2 mycroft continue;
295 1.9.2.2 mycroft setflags(2);
296 1.9.2.2 mycroft if (crmod) {
297 1.9.2.2 mycroft tmode.c_iflag |= ICRNL;
298 1.9.2.2 mycroft tmode.c_oflag |= ONLCR;
299 1.9.2.2 mycroft }
300 1.9.2.2 mycroft #if XXX
301 1.9.2.2 mycroft if (upper || UC)
302 1.9.2.2 mycroft tmode.sg_flags |= LCASE;
303 1.9.2.2 mycroft if (lower || LC)
304 1.9.2.2 mycroft tmode.sg_flags &= ~LCASE;
305 1.9.2.2 mycroft #endif
306 1.9.2.2 mycroft if (tcsetattr(0, TCSANOW, &tmode) < 0) {
307 1.9.2.2 mycroft syslog(LOG_ERR, "%s: %m", ttyn);
308 1.9.2.2 mycroft exit(1);
309 1.9.2.2 mycroft }
310 1.9.2.2 mycroft signal(SIGINT, SIG_DFL);
311 1.9.2.2 mycroft for (i = 0; environ[i] != (char *)0; i++)
312 1.9.2.2 mycroft env[i] = environ[i];
313 1.9.2.2 mycroft makeenv(&env[i]);
314 1.9.2.2 mycroft
315 1.9.2.2 mycroft limit.rlim_max = RLIM_INFINITY;
316 1.9.2.2 mycroft limit.rlim_cur = RLIM_INFINITY;
317 1.9.2.2 mycroft (void)setrlimit(RLIMIT_CPU, &limit);
318 1.9.2.2 mycroft execle(LO, "login", "-p", name, (char *) 0, env);
319 1.9.2.2 mycroft syslog(LOG_ERR, "%s: %m", LO);
320 1.9.2.2 mycroft exit(1);
321 1.9.2.2 mycroft }
322 1.9.2.2 mycroft alarm(0);
323 1.9.2.2 mycroft signal(SIGALRM, SIG_DFL);
324 1.9.2.2 mycroft signal(SIGINT, SIG_IGN);
325 1.9.2.2 mycroft if (NX && *NX)
326 1.9.2.2 mycroft tname = NX;
327 1.9.2.2 mycroft }
328 1.9.2.2 mycroft }
329 1.9.2.2 mycroft
330 1.9.2.2 mycroft static int
331 1.9.2.2 mycroft getname()
332 1.9.2.2 mycroft {
333 1.9.2.2 mycroft register int c;
334 1.9.2.2 mycroft register char *np;
335 1.9.2.2 mycroft char cs;
336 1.9.2.2 mycroft
337 1.9.2.2 mycroft /*
338 1.9.2.2 mycroft * Interrupt may happen if we use CBREAK mode
339 1.9.2.2 mycroft */
340 1.9.2.2 mycroft if (setjmp(intrupt)) {
341 1.9.2.2 mycroft signal(SIGINT, SIG_IGN);
342 1.9.2.2 mycroft return (0);
343 1.9.2.2 mycroft }
344 1.9.2.2 mycroft signal(SIGINT, interrupt);
345 1.9.2.2 mycroft setflags(1);
346 1.9.2.2 mycroft prompt();
347 1.9.2.2 mycroft if (PF > 0) {
348 1.9.2.2 mycroft oflush();
349 1.9.2.2 mycroft sleep(PF);
350 1.9.2.2 mycroft PF = 0;
351 1.9.2.2 mycroft }
352 1.9.2.2 mycroft if (tcsetattr(0, TCSANOW, &tmode) < 0) {
353 1.9.2.2 mycroft syslog(LOG_ERR, "%s: %m", ttyn);
354 1.9.2.2 mycroft exit(1);
355 1.9.2.2 mycroft }
356 1.9.2.2 mycroft crmod = digit = lower = upper = 0;
357 1.9.2.2 mycroft np = name;
358 1.9.2.2 mycroft for (;;) {
359 1.9.2.2 mycroft oflush();
360 1.9.2.2 mycroft if (read(STDIN_FILENO, &cs, 1) <= 0)
361 1.9.2.2 mycroft exit(0);
362 1.9.2.2 mycroft if ((c = cs&0177) == 0)
363 1.9.2.2 mycroft return (0);
364 1.9.2.2 mycroft if (c == EOT)
365 1.9.2.2 mycroft exit(1);
366 1.9.2.2 mycroft if (c == '\r' || c == '\n' || np >= &name[sizeof name]) {
367 1.9.2.2 mycroft putf("\r\n");
368 1.9.2.2 mycroft break;
369 1.9.2.2 mycroft }
370 1.9.2.2 mycroft if (islower(c))
371 1.9.2.2 mycroft lower = 1;
372 1.9.2.2 mycroft else if (isupper(c))
373 1.9.2.2 mycroft upper = 1;
374 1.9.2.2 mycroft else if (c == ERASE || c == '#' || c == '\b') {
375 1.9.2.2 mycroft if (np > name) {
376 1.9.2.2 mycroft np--;
377 1.9.2.2 mycroft if (cfgetospeed(&tmode) >= 1200)
378 1.9.2.2 mycroft puts("\b \b");
379 1.9.2.2 mycroft else
380 1.9.2.2 mycroft putchr(cs);
381 1.9.2.2 mycroft }
382 1.9.2.2 mycroft continue;
383 1.9.2.2 mycroft } else if (c == KILL || c == '@') {
384 1.9.2.2 mycroft putchr(cs);
385 1.9.2.2 mycroft putchr('\r');
386 1.9.2.2 mycroft if (cfgetospeed(&tmode) < 1200)
387 1.9.2.2 mycroft putchr('\n');
388 1.9.2.2 mycroft /* this is the way they do it down under ... */
389 1.9.2.2 mycroft else if (np > name)
390 1.9.2.2 mycroft puts(" \r");
391 1.9.2.2 mycroft prompt();
392 1.9.2.2 mycroft np = name;
393 1.9.2.2 mycroft continue;
394 1.9.2.2 mycroft } else if (isdigit(c))
395 1.9.2.2 mycroft digit++;
396 1.9.2.2 mycroft if (IG && (c <= ' ' || c > 0176))
397 1.9.2.2 mycroft continue;
398 1.9.2.2 mycroft *np++ = c;
399 1.9.2.2 mycroft putchr(cs);
400 1.9.2.2 mycroft }
401 1.9.2.2 mycroft signal(SIGINT, SIG_IGN);
402 1.9.2.2 mycroft *np = 0;
403 1.9.2.2 mycroft if (c == '\r')
404 1.9.2.2 mycroft crmod = 1;
405 1.9.2.2 mycroft if (upper && !lower && !LC || UC)
406 1.9.2.2 mycroft for (np = name; *np; np++)
407 1.9.2.2 mycroft if (isupper(*np))
408 1.9.2.2 mycroft *np = tolower(*np);
409 1.9.2.2 mycroft return (1);
410 1.9.2.2 mycroft }
411 1.9.2.2 mycroft
412 1.9.2.2 mycroft static void
413 1.9.2.2 mycroft putpad(s)
414 1.9.2.2 mycroft register char *s;
415 1.9.2.2 mycroft {
416 1.9.2.2 mycroft register pad = 0;
417 1.9.2.2 mycroft speed_t ospeed = cfgetospeed(&tmode);
418 1.9.2.2 mycroft
419 1.9.2.2 mycroft if (isdigit(*s)) {
420 1.9.2.2 mycroft while (isdigit(*s)) {
421 1.9.2.2 mycroft pad *= 10;
422 1.9.2.2 mycroft pad += *s++ - '0';
423 1.9.2.2 mycroft }
424 1.9.2.2 mycroft pad *= 10;
425 1.9.2.2 mycroft if (*s == '.' && isdigit(s[1])) {
426 1.9.2.2 mycroft pad += s[1] - '0';
427 1.9.2.2 mycroft s += 2;
428 1.9.2.2 mycroft }
429 1.9.2.2 mycroft }
430 1.9.2.2 mycroft
431 1.9.2.2 mycroft puts(s);
432 1.9.2.2 mycroft /*
433 1.9.2.2 mycroft * If no delay needed, or output speed is
434 1.9.2.2 mycroft * not comprehensible, then don't try to delay.
435 1.9.2.2 mycroft */
436 1.9.2.2 mycroft if (pad == 0 || ospeed <= 0)
437 1.9.2.2 mycroft return;
438 1.9.2.2 mycroft
439 1.9.2.2 mycroft /*
440 1.9.2.2 mycroft * Round up by a half a character frame, and then do the delay.
441 1.9.2.2 mycroft * Too bad there are no user program accessible programmed delays.
442 1.9.2.2 mycroft * Transmitting pad characters slows many terminals down and also
443 1.9.2.2 mycroft * loads the system.
444 1.9.2.2 mycroft */
445 1.9.2.2 mycroft pad = (pad * ospeed + 50000) / 100000;
446 1.9.2.2 mycroft while (pad--)
447 1.9.2.2 mycroft putchr(*PC);
448 1.9.2.2 mycroft }
449 1.9.2.2 mycroft
450 1.9.2.2 mycroft static void
451 1.9.2.2 mycroft puts(s)
452 1.9.2.2 mycroft register char *s;
453 1.9.2.2 mycroft {
454 1.9.2.2 mycroft while (*s)
455 1.9.2.2 mycroft putchr(*s++);
456 1.9.2.2 mycroft }
457 1.9.2.2 mycroft
458 1.9.2.2 mycroft char outbuf[OBUFSIZ];
459 1.9.2.2 mycroft int obufcnt = 0;
460 1.9.2.2 mycroft
461 1.9.2.2 mycroft static void
462 1.9.2.2 mycroft putchr(cc)
463 1.9.2.2 mycroft int cc;
464 1.9.2.2 mycroft {
465 1.9.2.2 mycroft char c;
466 1.9.2.2 mycroft
467 1.9.2.2 mycroft c = cc;
468 1.9.2.2 mycroft if (!NP) {
469 1.9.2.2 mycroft c |= partab[c&0177] & 0200;
470 1.9.2.2 mycroft if (OP)
471 1.9.2.2 mycroft c ^= 0200;
472 1.9.2.2 mycroft }
473 1.9.2.2 mycroft if (!UB) {
474 1.9.2.2 mycroft outbuf[obufcnt++] = c;
475 1.9.2.2 mycroft if (obufcnt >= OBUFSIZ)
476 1.9.2.2 mycroft oflush();
477 1.9.2.2 mycroft } else
478 1.9.2.2 mycroft write(STDOUT_FILENO, &c, 1);
479 1.9.2.2 mycroft }
480 1.9.2.2 mycroft
481 1.9.2.2 mycroft static void
482 1.9.2.2 mycroft oflush()
483 1.9.2.2 mycroft {
484 1.9.2.2 mycroft if (obufcnt)
485 1.9.2.2 mycroft write(STDOUT_FILENO, outbuf, obufcnt);
486 1.9.2.2 mycroft obufcnt = 0;
487 1.9.2.2 mycroft }
488 1.9.2.2 mycroft
489 1.9.2.2 mycroft static void
490 1.9.2.2 mycroft prompt()
491 1.9.2.2 mycroft {
492 1.9.2.2 mycroft
493 1.9.2.2 mycroft putf(LM);
494 1.9.2.2 mycroft if (CO)
495 1.9.2.2 mycroft putchr('\n');
496 1.9.2.2 mycroft }
497 1.9.2.2 mycroft
498 1.9.2.2 mycroft static void
499 1.9.2.2 mycroft putf(cp)
500 1.9.2.2 mycroft register char *cp;
501 1.9.2.2 mycroft {
502 1.9.2.2 mycroft extern char editedhost[];
503 1.9.2.2 mycroft time_t t;
504 1.9.2.2 mycroft char *slash, db[100];
505 1.9.2.2 mycroft
506 1.9.2.2 mycroft while (*cp) {
507 1.9.2.2 mycroft if (*cp != '%') {
508 1.9.2.2 mycroft putchr(*cp++);
509 1.9.2.2 mycroft continue;
510 1.9.2.2 mycroft }
511 1.9.2.2 mycroft switch (*++cp) {
512 1.9.2.2 mycroft
513 1.9.2.2 mycroft case 't':
514 1.9.2.2 mycroft slash = strrchr(ttyn, '/');
515 1.9.2.2 mycroft if (slash == (char *) 0)
516 1.9.2.2 mycroft puts(ttyn);
517 1.9.2.2 mycroft else
518 1.9.2.2 mycroft puts(&slash[1]);
519 1.9.2.2 mycroft break;
520 1.9.2.2 mycroft
521 1.9.2.2 mycroft case 'h':
522 1.9.2.2 mycroft puts(editedhost);
523 1.9.2.2 mycroft break;
524 1.9.2.2 mycroft
525 1.9.2.2 mycroft case 'd': {
526 1.9.2.2 mycroft static char fmt[] = "%l:% %P on %A, %d %B %Y";
527 1.9.2.2 mycroft
528 1.9.2.2 mycroft fmt[4] = 'M'; /* I *hate* SCCS... */
529 1.9.2.2 mycroft (void)time(&t);
530 1.9.2.2 mycroft (void)strftime(db, sizeof(db), fmt, localtime(&t));
531 1.9.2.2 mycroft puts(db);
532 1.9.2.2 mycroft break;
533 1.9.2.2 mycroft
534 1.9.2.2 mycroft case 's':
535 1.9.2.2 mycroft puts(kerninfo.sysname);
536 1.9.2.2 mycroft break;
537 1.9.2.2 mycroft
538 1.9.2.2 mycroft case 'm':
539 1.9.2.2 mycroft puts(kerninfo.machine);
540 1.9.2.2 mycroft break;
541 1.9.2.2 mycroft
542 1.9.2.2 mycroft case 'r':
543 1.9.2.2 mycroft puts(kerninfo.release);
544 1.9.2.2 mycroft break;
545 1.9.2.2 mycroft
546 1.9.2.2 mycroft case 'v':
547 1.9.2.2 mycroft puts(kerninfo.version);
548 1.9.2.2 mycroft break;
549 1.9.2.2 mycroft }
550 1.9.2.2 mycroft
551 1.9.2.2 mycroft case '%':
552 1.9.2.2 mycroft putchr('%');
553 1.9.2.2 mycroft break;
554 1.9.2.2 mycroft }
555 1.9.2.2 mycroft cp++;
556 1.9.2.2 mycroft }
557 1.9.2.2 mycroft }
558