Introduction
Introduction Statistics Contact Development Disclaimer Help
getty.c - ubase - suckless linux base utils
git clone git://git.suckless.org/ubase
Log
Files
Refs
README
LICENSE
---
getty.c (2823B)
---
1 /* See LICENSE file for copyright and license details. */
2 #include <sys/ioctl.h>
3 #include <sys/stat.h>
4 #include <sys/types.h>
5
6 #include <fcntl.h>
7 #include <limits.h>
8 #include <signal.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <unistd.h>
13 #include <utmp.h>
14
15 #include "config.h"
16 #include "util.h"
17
18 static char *tty = "/dev/tty1";
19 static char *defaultterm = "linux";
20
21 static void
22 usage(void)
23 {
24 eprintf("usage: %s [tty] [term] [cmd] [args...]\n", argv0);
25 }
26
27 int
28 main(int argc, char *argv[])
29 {
30 char term[128], logname[LOGIN_NAME_MAX], c;
31 char hostname[HOST_NAME_MAX + 1];
32 struct utmp usr;
33 struct sigaction sa;
34 FILE *fp;
35 int fd;
36 unsigned int i = 0;
37 ssize_t n;
38 long pos;
39
40 ARGBEGIN {
41 default:
42 usage();
43 } ARGEND;
44
45 strlcpy(term, defaultterm, sizeof(term));
46 if (argc > 0) {
47 tty = argv[0];
48 if (argc > 1)
49 strlcpy(term, argv[1], sizeof(term));
50 }
51
52 sa.sa_handler = SIG_IGN;
53 sa.sa_flags = 0;
54 sigemptyset(&sa.sa_mask);
55 sigaction(SIGHUP, &sa, NULL);
56
57 setenv("TERM", term, 1);
58
59 setsid();
60
61 fd = open(tty, O_RDWR);
62 if (fd < 0)
63 eprintf("open %s:", tty);
64 if (isatty(fd) == 0)
65 eprintf("%s is not a tty\n", tty);
66
67 /* steal the controlling terminal if necessary */
68 if (ioctl(fd, TIOCSCTTY, (void *)1) != 0)
69 weprintf("TIOCSCTTY: could not set controlling tty\n");
70 vhangup();
71 close(fd);
72
73 fd = open(tty, O_RDWR);
74 if (fd < 0)
75 eprintf("open %s:", tty);
76 dup2(fd, 0);
77 dup2(fd, 1);
78 dup2(fd, 2);
79 if (fchown(fd, 0, 0) < 0)
80 weprintf("fchown %s:", tty);
81 if (fchmod(fd, 0600) < 0)
82 weprintf("fchmod %s:", tty);
83 if (fd > 2)
84 close(fd);
85
86 sa.sa_handler = SIG_DFL;
87 sa.sa_flags = 0;
88 sigemptyset(&sa.sa_mask);
89 sigaction(SIGHUP, &sa, NULL);
90
91 /* Clear all utmp entries for this tty */
92 fp = fopen(UTMP_PATH, "r+");
93 if (fp) {
94 do {
95 pos = ftell(fp);
96 if (fread(&usr, sizeof(usr), 1, fp) != 1)
97 break;
98 if (usr.ut_line[0] == '\0')
99 continue;
100 if (strcmp(usr.ut_line, tty) != 0)
101 continue;
102 memset(&usr, 0, sizeof(usr));
103 fseek(fp, pos, SEEK_SET);
104 if (fwrite(&usr, sizeof(usr), 1, fp) != 1)
105 break;
106 } while (1);
107 if (ferror(fp))
108 weprintf("%s: I/O error:", UTMP_PATH);
109 fclose(fp);
110 }
111
112 if (argc > 2)
113 return execvp(argv[2], argv + 2);
114
115 if (gethostname(hostname, sizeof(hostname)) == 0)
116 printf("%s ", hostname);
117 printf("login: ");
118 fflush(stdout);
119
120 /* Flush pending input */
121 ioctl(0, TCFLSH, (void *)0);
122 memset(logname, 0, sizeof(logname));
123 while (1) {
124 n = read(0, &c, 1);
125 if (n < 0)
126 eprintf("read:");
127 if (n == 0)
128 return 1;
129 if (i >= sizeof(logname) - 1)
130 eprintf("login name too long\n");
131 if (c == '\n' || c == '\r')
132 break;
133 logname[i++] = c;
134 }
135 if (logname[0] == '-')
136 eprintf("login name cannot start with '-'\n");
137 if (logname[0] == '\0')
138 return 1;
139 return execlp("/bin/login", "login", "-p", logname, NULL);
140 }
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.