]>
git.saurik.com Git - apple/system_cmds.git/blob - getty.tproj/main.c
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.0 (the 'License'). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
22 * @APPLE_LICENSE_HEADER_END@
25 * Copyright (c) 1980, 1993
26 * The Regents of the University of California. All rights reserved.
28 * Redistribution and use in source and binary forms, with or without
29 * modification, are permitted provided that the following conditions
31 * 1. Redistributions of source code must retain the above copyright
32 * notice, this list of conditions and the following disclaimer.
33 * 2. Redistributions in binary form must reproduce the above copyright
34 * notice, this list of conditions and the following disclaimer in the
35 * documentation and/or other materials provided with the distribution.
36 * 3. All advertising materials mentioning features or use of this software
37 * must display the following acknowledgement:
38 * This product includes software developed by the University of
39 * California, Berkeley and its contributors.
40 * 4. Neither the name of the University nor the names of its contributors
41 * may be used to endorse or promote products derived from this software
42 * without specific prior written permission.
44 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
45 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
46 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
47 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
48 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
49 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
50 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
52 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
53 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 static char copyright
[] =
59 "@(#) Copyright (c) 1980, 1993\n\
60 The Regents of the University of California. All rights reserved.\n";
64 /*static char sccsid[] = "from: @(#)main.c 8.1 (Berkeley) 6/20/93";*/
65 static char rcsid
[] = "$Id: main.c,v 1.1.1.2 2000/01/11 02:10:14 wsanchez Exp $";
68 #include <sys/param.h>
70 #include <sys/termios.h>
71 #include <sys/ioctl.h>
72 #include <sys/resource.h>
73 #include <sys/utsname.h>
88 #include "pathnames.h"
92 * Set the amount of running time that getty should accumulate
93 * before deciding that something is wrong and exit.
95 #define GETTY_TIMEOUT 60 /* seconds */
97 struct termios tmode
, omode
;
99 int crmod
, digit
, lower
, upper
;
101 char hostname
[MAXHOSTNAMELEN
];
102 struct utsname kerninfo
;
104 char dev
[] = _PATH_DEV
;
106 char *portselector();
110 #define TABBUFSIZ 512
112 char defent
[TABBUFSIZ
];
113 char tabent
[TABBUFSIZ
];
118 0001,0201,0201,0001,0201,0001,0001,0201,
119 0202,0004,0003,0205,0005,0206,0201,0001,
120 0201,0001,0001,0201,0001,0201,0201,0001,
121 0001,0201,0201,0001,0201,0001,0001,0201,
122 0200,0000,0000,0200,0000,0200,0200,0000,
123 0000,0200,0200,0000,0200,0000,0000,0200,
124 0000,0200,0200,0000,0200,0000,0000,0200,
125 0200,0000,0000,0200,0000,0200,0200,0000,
126 0200,0000,0000,0200,0000,0200,0200,0000,
127 0000,0200,0200,0000,0200,0000,0000,0200,
128 0000,0200,0200,0000,0200,0000,0000,0200,
129 0200,0000,0000,0200,0000,0200,0200,0000,
130 0000,0200,0200,0000,0200,0000,0000,0200,
131 0200,0000,0000,0200,0000,0200,0200,0000,
132 0200,0000,0000,0200,0000,0200,0200,0000,
133 0000,0200,0200,0000,0200,0000,0000,0201
136 #define ERASE tmode.c_cc[VERASE]
137 #define KILL tmode.c_cc[VKILL]
138 #define EOT tmode.c_cc[VEOF]
147 signal(SIGALRM
, SIG_DFL
);
157 signal(SIGINT
, interrupt
);
162 * Action to take when getty is running too long.
169 syslog(LOG_ERR
, "getty exiting due to excessive running time\n");
173 static int getname
__P((void));
174 static void oflush
__P((void));
175 static void prompt
__P((void));
176 static void putchr
__P((int));
177 static void putf
__P((char *));
178 static void putpad
__P((char *));
179 static void puts
__P((char *));
186 extern char **environ
;
193 signal(SIGINT
, SIG_IGN
);
195 signal(SIGQUIT, SIG_DFL);
197 openlog("getty", LOG_ODELAY
|LOG_CONS
, LOG_AUTH
);
198 gethostname(hostname
, sizeof(hostname
));
199 if (hostname
[0] == '\0')
200 strcpy(hostname
, "Amnesiac");
204 * Limit running time to deal with broken or dead lines.
206 (void)signal(SIGXCPU
, timeoverrun
);
207 limit
.rlim_max
= RLIM_INFINITY
;
208 limit
.rlim_cur
= GETTY_TIMEOUT
;
209 (void)setrlimit(RLIMIT_CPU
, &limit
);
212 * The following is a work around for vhangup interactions
213 * which cause great problems getting window systems started.
214 * If the tty line is "-", we do the old style getty presuming
215 * that the file descriptors are already set up for us.
216 * J. Gettys - MIT Project Athena.
218 if (argc
<= 2 || strcmp(argv
[2], "-") == 0)
219 strcpy(ttyn
, ttyname(0));
224 strncat(ttyn
, argv
[2], sizeof(ttyn
)-sizeof(dev
));
225 if (strcmp(argv
[0], "+") != 0) {
230 * Delay the open so DTR stays down long enough to be detected.
234 ttyopenmode
= ((strcmp(ttyn
, _PATH_CONSOLE
)==0)
235 ? (O_RDWR
|O_POPUP
): O_RDWR
);
236 #else /* __APPLE __ */
237 ttyopenmode
= O_RDWR
;
238 #endif /* __APPLE__ */
240 while ((i
= open(ttyn
, ttyopenmode
)) == -1) {
241 if (repcnt
% 10 == 0) {
242 syslog(LOG_ERR
, "%s: %m", ttyn
);
252 /* Start with default tty settings */
253 if (tcgetattr(0, &tmode
) < 0) {
254 syslog(LOG_ERR
, "%s: %m", ttyn
);
259 gettable("default", defent
);
267 gettable(tname
, tabent
);
268 if (OPset
|| EPset
|| APset
)
269 APset
++, OPset
++, EPset
++;
272 ioctl(0, TIOCFLUSH
, &off
); /* clear out the crap */
273 ioctl(0, FIONBIO
, &off
); /* turn off non-blocking mode */
274 ioctl(0, FIOASYNC
, &off
); /* ditto for async mode */
277 cfsetispeed(&tmode
, IS
);
279 cfsetispeed(&tmode
, SP
);
281 cfsetospeed(&tmode
, OS
);
283 cfsetospeed(&tmode
, SP
);
286 if (tcsetattr(0, TCSANOW
, &tmode
) < 0) {
287 syslog(LOG_ERR
, "%s: %m", ttyn
);
291 extern char *autobaud();
297 tname
= portselector();
305 if (setjmp(timeout
)) {
306 tmode
.c_ispeed
= tmode
.c_ospeed
= 0;
307 (void)tcsetattr(0, TCSANOW
, &tmode
);
311 signal(SIGALRM
, dingdong
);
319 signal(SIGALRM
, SIG_DFL
);
320 if (name
[0] == '-') {
321 puts("user names may not start with '-'.");
324 if (!(upper
|| lower
|| digit
))
328 tmode
.c_iflag
|= ICRNL
;
329 tmode
.c_oflag
|= ONLCR
;
333 tmode
.sg_flags
|= LCASE
;
335 tmode
.sg_flags
&= ~LCASE
;
337 if (tcsetattr(0, TCSANOW
, &tmode
) < 0) {
338 syslog(LOG_ERR
, "%s: %m", ttyn
);
341 signal(SIGINT
, SIG_DFL
);
342 for (i
= 0; environ
[i
] != (char *)0; i
++)
346 limit
.rlim_max
= RLIM_INFINITY
;
347 limit
.rlim_cur
= RLIM_INFINITY
;
348 (void)setrlimit(RLIMIT_CPU
, &limit
);
349 execle(LO
, "login", "-p", name
, (char *) 0, env
);
350 syslog(LOG_ERR
, "%s: %m", LO
);
354 signal(SIGALRM
, SIG_DFL
);
355 signal(SIGINT
, SIG_IGN
);
369 * Interrupt may happen if we use CBREAK mode
371 if (setjmp(intrupt
)) {
372 signal(SIGINT
, SIG_IGN
);
375 signal(SIGINT
, interrupt
);
383 if (tcsetattr(0, TCSANOW
, &tmode
) < 0) {
384 syslog(LOG_ERR
, "%s: %m", ttyn
);
387 crmod
= digit
= lower
= upper
= 0;
391 if (read(STDIN_FILENO
, &cs
, 1) <= 0)
393 if ((c
= cs
&0177) == 0)
397 if (c
== '\r' || c
== '\n' || np
>= &name
[sizeof name
]) {
405 else if (c
== ERASE
|| c
== '#' || c
== '\b') {
408 if (cfgetospeed(&tmode
) >= 1200)
414 } else if (c
== KILL
|| c
== '@') {
417 if (cfgetospeed(&tmode
) < 1200)
419 /* this is the way they do it down under ... */
425 } else if (isdigit(c
))
427 if (IG
&& (c
<= ' ' || c
> 0176))
432 signal(SIGINT
, SIG_IGN
);
436 if (upper
&& !lower
&& !LC
|| UC
)
437 for (np
= name
; *np
; np
++)
448 speed_t ospeed
= cfgetospeed(&tmode
);
451 while (isdigit(*s
)) {
456 if (*s
== '.' && isdigit(s
[1])) {
464 * If no delay needed, or output speed is
465 * not comprehensible, then don't try to delay.
467 if (pad
== 0 || ospeed
<= 0)
471 * Round up by a half a character frame, and then do the delay.
472 * Too bad there are no user program accessible programmed delays.
473 * Transmitting pad characters slows many terminals down and also
476 pad
= (pad
* ospeed
+ 50000) / 100000;
489 char outbuf
[OBUFSIZ
];
500 c
|= partab
[c
&0177] & 0200;
505 outbuf
[obufcnt
++] = c
;
506 if (obufcnt
>= OBUFSIZ
)
509 write(STDOUT_FILENO
, &c
, 1);
516 write(STDOUT_FILENO
, outbuf
, obufcnt
);
533 extern char editedhost
[];
535 char *slash
, db
[100];
545 slash
= strrchr(ttyn
, '/');
546 if (slash
== (char *) 0)
557 static char fmt
[] = "%l:% %P on %A, %d %B %Y";
559 fmt
[4] = 'M'; /* I *hate* SCCS... */
561 (void)strftime(db
, sizeof(db
), fmt
, localtime(&t
));
566 puts(kerninfo
.sysname
);
570 puts(kerninfo
.machine
);
574 puts(kerninfo
.release
);
578 puts(kerninfo
.version
);