]>
git.saurik.com Git - apple/system_cmds.git/blob - getty.tproj/main.c
cafc07dd18d7d84ac52d3d01ba40684aee847b83
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
26 * Copyright (c) 1980, 1993
27 * The Regents of the University of California. All rights reserved.
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
32 * 1. Redistributions of source code must retain the above copyright
33 * notice, this list of conditions and the following disclaimer.
34 * 2. Redistributions in binary form must reproduce the above copyright
35 * notice, this list of conditions and the following disclaimer in the
36 * documentation and/or other materials provided with the distribution.
37 * 3. All advertising materials mentioning features or use of this software
38 * must display the following acknowledgement:
39 * This product includes software developed by the University of
40 * California, Berkeley and its contributors.
41 * 4. Neither the name of the University nor the names of its contributors
42 * may be used to endorse or promote products derived from this software
43 * without specific prior written permission.
45 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 static char copyright
[] =
60 "@(#) Copyright (c) 1980, 1993\n\
61 The Regents of the University of California. All rights reserved.\n";
65 /*static char sccsid[] = "from: @(#)main.c 8.1 (Berkeley) 6/20/93";*/
66 static char rcsid
[] = "$Id: main.c,v 1.1.1.2 2000/01/11 02:10:14 wsanchez Exp $";
69 #include <sys/param.h>
71 #include <sys/termios.h>
72 #include <sys/ioctl.h>
73 #include <sys/resource.h>
74 #include <sys/utsname.h>
89 #include "pathnames.h"
93 * Set the amount of running time that getty should accumulate
94 * before deciding that something is wrong and exit.
96 #define GETTY_TIMEOUT 60 /* seconds */
98 struct termios tmode
, omode
;
100 int crmod
, digit
, lower
, upper
;
102 char hostname
[MAXHOSTNAMELEN
];
103 struct utsname kerninfo
;
105 char dev
[] = _PATH_DEV
;
107 char *portselector();
111 #define TABBUFSIZ 512
113 char defent
[TABBUFSIZ
];
114 char tabent
[TABBUFSIZ
];
119 0001,0201,0201,0001,0201,0001,0001,0201,
120 0202,0004,0003,0205,0005,0206,0201,0001,
121 0201,0001,0001,0201,0001,0201,0201,0001,
122 0001,0201,0201,0001,0201,0001,0001,0201,
123 0200,0000,0000,0200,0000,0200,0200,0000,
124 0000,0200,0200,0000,0200,0000,0000,0200,
125 0000,0200,0200,0000,0200,0000,0000,0200,
126 0200,0000,0000,0200,0000,0200,0200,0000,
127 0200,0000,0000,0200,0000,0200,0200,0000,
128 0000,0200,0200,0000,0200,0000,0000,0200,
129 0000,0200,0200,0000,0200,0000,0000,0200,
130 0200,0000,0000,0200,0000,0200,0200,0000,
131 0000,0200,0200,0000,0200,0000,0000,0200,
132 0200,0000,0000,0200,0000,0200,0200,0000,
133 0200,0000,0000,0200,0000,0200,0200,0000,
134 0000,0200,0200,0000,0200,0000,0000,0201
137 #define ERASE tmode.c_cc[VERASE]
138 #define KILL tmode.c_cc[VKILL]
139 #define EOT tmode.c_cc[VEOF]
148 signal(SIGALRM
, SIG_DFL
);
158 signal(SIGINT
, interrupt
);
163 * Action to take when getty is running too long.
170 syslog(LOG_ERR
, "getty exiting due to excessive running time\n");
174 static int getname
__P((void));
175 static void oflush
__P((void));
176 static void prompt
__P((void));
177 static void putchr
__P((int));
178 static void putf
__P((char *));
179 static void putpad
__P((char *));
180 static void puts
__P((char *));
187 extern char **environ
;
194 signal(SIGINT
, SIG_IGN
);
196 signal(SIGQUIT, SIG_DFL);
198 openlog("getty", LOG_ODELAY
|LOG_CONS
, LOG_AUTH
);
199 gethostname(hostname
, sizeof(hostname
));
200 if (hostname
[0] == '\0')
201 strcpy(hostname
, "Amnesiac");
205 * Limit running time to deal with broken or dead lines.
207 (void)signal(SIGXCPU
, timeoverrun
);
208 limit
.rlim_max
= RLIM_INFINITY
;
209 limit
.rlim_cur
= GETTY_TIMEOUT
;
210 (void)setrlimit(RLIMIT_CPU
, &limit
);
213 * The following is a work around for vhangup interactions
214 * which cause great problems getting window systems started.
215 * If the tty line is "-", we do the old style getty presuming
216 * that the file descriptors are already set up for us.
217 * J. Gettys - MIT Project Athena.
219 if (argc
<= 2 || strcmp(argv
[2], "-") == 0)
220 strcpy(ttyn
, ttyname(0));
225 strncat(ttyn
, argv
[2], sizeof(ttyn
)-sizeof(dev
));
226 if (strcmp(argv
[0], "+") != 0) {
231 * Delay the open so DTR stays down long enough to be detected.
235 ttyopenmode
= ((strcmp(ttyn
, _PATH_CONSOLE
)==0)
236 ? (O_RDWR
|O_POPUP
): O_RDWR
);
237 #else /* __APPLE __ */
238 ttyopenmode
= O_RDWR
;
239 #endif /* __APPLE__ */
241 while ((i
= open(ttyn
, ttyopenmode
)) == -1) {
242 if (repcnt
% 10 == 0) {
243 syslog(LOG_ERR
, "%s: %m", ttyn
);
253 /* Start with default tty settings */
254 if (tcgetattr(0, &tmode
) < 0) {
255 syslog(LOG_ERR
, "%s: %m", ttyn
);
260 gettable("default", defent
);
268 gettable(tname
, tabent
);
269 if (OPset
|| EPset
|| APset
)
270 APset
++, OPset
++, EPset
++;
273 ioctl(0, TIOCFLUSH
, &off
); /* clear out the crap */
274 ioctl(0, FIONBIO
, &off
); /* turn off non-blocking mode */
275 ioctl(0, FIOASYNC
, &off
); /* ditto for async mode */
278 cfsetispeed(&tmode
, IS
);
280 cfsetispeed(&tmode
, SP
);
282 cfsetospeed(&tmode
, OS
);
284 cfsetospeed(&tmode
, SP
);
287 if (tcsetattr(0, TCSANOW
, &tmode
) < 0) {
288 syslog(LOG_ERR
, "%s: %m", ttyn
);
292 extern char *autobaud();
298 tname
= portselector();
306 if (setjmp(timeout
)) {
307 tmode
.c_ispeed
= tmode
.c_ospeed
= 0;
308 (void)tcsetattr(0, TCSANOW
, &tmode
);
312 signal(SIGALRM
, dingdong
);
320 signal(SIGALRM
, SIG_DFL
);
321 if (name
[0] == '-') {
322 puts("user names may not start with '-'.");
325 if (!(upper
|| lower
|| digit
))
329 tmode
.c_iflag
|= ICRNL
;
330 tmode
.c_oflag
|= ONLCR
;
334 tmode
.sg_flags
|= LCASE
;
336 tmode
.sg_flags
&= ~LCASE
;
338 if (tcsetattr(0, TCSANOW
, &tmode
) < 0) {
339 syslog(LOG_ERR
, "%s: %m", ttyn
);
342 signal(SIGINT
, SIG_DFL
);
343 for (i
= 0; environ
[i
] != (char *)0; i
++)
347 limit
.rlim_max
= RLIM_INFINITY
;
348 limit
.rlim_cur
= RLIM_INFINITY
;
349 (void)setrlimit(RLIMIT_CPU
, &limit
);
350 execle(LO
, "login", "-p", name
, (char *) 0, env
);
351 syslog(LOG_ERR
, "%s: %m", LO
);
355 signal(SIGALRM
, SIG_DFL
);
356 signal(SIGINT
, SIG_IGN
);
370 * Interrupt may happen if we use CBREAK mode
372 if (setjmp(intrupt
)) {
373 signal(SIGINT
, SIG_IGN
);
376 signal(SIGINT
, interrupt
);
384 if (tcsetattr(0, TCSANOW
, &tmode
) < 0) {
385 syslog(LOG_ERR
, "%s: %m", ttyn
);
388 crmod
= digit
= lower
= upper
= 0;
392 if (read(STDIN_FILENO
, &cs
, 1) <= 0)
394 if ((c
= cs
&0177) == 0)
398 if (c
== '\r' || c
== '\n' || np
>= &name
[sizeof name
]) {
406 else if (c
== ERASE
|| c
== '#' || c
== '\b') {
409 if (cfgetospeed(&tmode
) >= 1200)
415 } else if (c
== KILL
|| c
== '@') {
418 if (cfgetospeed(&tmode
) < 1200)
420 /* this is the way they do it down under ... */
426 } else if (isdigit(c
))
428 if (IG
&& (c
<= ' ' || c
> 0176))
433 signal(SIGINT
, SIG_IGN
);
437 if (upper
&& !lower
&& !LC
|| UC
)
438 for (np
= name
; *np
; np
++)
449 speed_t ospeed
= cfgetospeed(&tmode
);
452 while (isdigit(*s
)) {
457 if (*s
== '.' && isdigit(s
[1])) {
465 * If no delay needed, or output speed is
466 * not comprehensible, then don't try to delay.
468 if (pad
== 0 || ospeed
<= 0)
472 * Round up by a half a character frame, and then do the delay.
473 * Too bad there are no user program accessible programmed delays.
474 * Transmitting pad characters slows many terminals down and also
477 pad
= (pad
* ospeed
+ 50000) / 100000;
490 char outbuf
[OBUFSIZ
];
501 c
|= partab
[c
&0177] & 0200;
506 outbuf
[obufcnt
++] = c
;
507 if (obufcnt
>= OBUFSIZ
)
510 write(STDOUT_FILENO
, &c
, 1);
517 write(STDOUT_FILENO
, outbuf
, obufcnt
);
534 extern char editedhost
[];
536 char *slash
, db
[100];
546 slash
= strrchr(ttyn
, '/');
547 if (slash
== (char *) 0)
558 static char fmt
[] = "%l:% %P on %A, %d %B %Y";
560 fmt
[4] = 'M'; /* I *hate* SCCS... */
562 (void)strftime(db
, sizeof(db
), fmt
, localtime(&t
));
567 puts(kerninfo
.sysname
);
571 puts(kerninfo
.machine
);
575 puts(kerninfo
.release
);
579 puts(kerninfo
.version
);