cleanup, add Berkeley header
[unix-history] / usr / src / libexec / uucpd / uucpd.c
CommitLineData
cd56d176 1#ifndef lint
308f8b07 2static char sccsid[] = "@(#)uucpd.c 5.5 (Berkeley) %G%";
cd56d176
RC
3#endif
4
5/*
308f8b07 6 * 4.2BSD TCP/IP server for uucico
46b15d8a 7 * uucico's TCP channel causes this server to be run at the remote end.
cd56d176
RC
8 */
9
46b15d8a 10#include "uucp.h"
79b62878 11#include <netdb.h>
46b15d8a 12#include <signal.h>
cd56d176 13#include <errno.h>
cd56d176
RC
14#include <sys/socket.h>
15#include <netinet/in.h>
46b15d8a 16#include <sys/wait.h>
79b62878 17#include <sys/ioctl.h>
46b15d8a
RC
18#include <pwd.h>
19#include <lastlog.h>
cd56d176 20
46b15d8a
RC
21char lastlog[] = "/usr/adm/lastlog";
22struct sockaddr_in hisctladdr;
23int hisaddrlen = sizeof hisctladdr;
24struct sockaddr_in myctladdr;
25int mypid;
cd56d176 26
79b62878
JB
27char Username[64];
28char *nenv[] = {
29 Username,
30 NULL,
31};
32extern char **environ;
33
cd56d176 34main(argc, argv)
46b15d8a
RC
35int argc;
36char **argv;
cd56d176 37{
1a85e9d2 38#ifndef BSDINETD
46b15d8a
RC
39 register int s, tcp_socket;
40 struct servent *sp;
1a85e9d2 41#endif !BSDINETD
46b15d8a
RC
42 extern int errno;
43 int dologout();
cd56d176 44
79b62878 45 environ = nenv;
46b15d8a
RC
46#ifdef BSDINETD
47 close(1); close(2);
48 dup(0); dup(0);
49 hisaddrlen = sizeof (hisctladdr);
50 if (getpeername(0, &hisctladdr, &hisaddrlen) < 0) {
cd56d176
RC
51 fprintf(stderr, "%s: ", argv[0]);
52 perror("getpeername");
53 _exit(1);
54 }
46b15d8a
RC
55 if (fork() == 0)
56 doit(&hisctladdr);
57 dologout();
cd56d176 58 exit(1);
46b15d8a
RC
59#else !BSDINETD
60 sp = getservbyname("uucp", "tcp");
61 if (sp == NULL){
62 perror("uucpd: getservbyname");
63 exit(1);
64 }
79b62878
JB
65 if (fork())
66 exit(0);
46b15d8a
RC
67 if ((s=open("/dev/tty", 2)) >= 0){
68 ioctl(s, TIOCNOTTY, (char *)0);
69 close(s);
70 }
71
72 bzero((char *)&myctladdr, sizeof (myctladdr));
79b62878
JB
73 myctladdr.sin_family = AF_INET;
74 myctladdr.sin_port = sp->s_port;
75#ifdef BSD4_2
76 tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
77 if (tcp_socket < 0) {
46b15d8a
RC
78 perror("uucpd: socket");
79 exit(1);
80 }
79b62878 81 if (bind(tcp_socket, (char *)&myctladdr, sizeof (myctladdr)) < 0) {
46b15d8a
RC
82 perror("uucpd: bind");
83 exit(1);
84 }
79b62878 85 listen(tcp_socket, 3); /* at most 3 simultaneuos uucp connections */
46b15d8a 86 signal(SIGCHLD, dologout);
46b15d8a
RC
87
88 for(;;) {
89 s = accept(tcp_socket, &hisctladdr, &hisaddrlen);
90 if (s < 0){
79b62878 91 if (errno == EINTR)
46b15d8a
RC
92 continue;
93 perror("uucpd: accept");
94 exit(1);
95 }
79b62878 96 if (fork() == 0) {
46b15d8a
RC
97 close(0); close(1); close(2);
98 dup(s); dup(s); dup(s);
79b62878 99 close(tcp_socket); close(s);
46b15d8a
RC
100 doit(&hisctladdr);
101 exit(1);
102 }
103 close(s);
104 }
79b62878
JB
105#endif BSD4_2
106
79b62878 107#endif !BSDINETD
46b15d8a
RC
108}
109
110doit(sinp)
111struct sockaddr_in *sinp;
112{
79b62878 113 char user[64], passwd[64];
46b15d8a
RC
114 char *xpasswd, *crypt();
115 struct passwd *pw, *getpwnam();
116
117 alarm(60);
1a85e9d2 118 printf("login: "); fflush(stdout);
46b15d8a
RC
119 if (readline(user, sizeof user) < 0) {
120 fprintf(stderr, "user read\n");
121 return;
122 }
123 /* truncate username to 8 characters */
124 user[8] = '\0';
125 pw = getpwnam(user);
126 if (pw == NULL) {
127 fprintf(stderr, "user unknown\n");
128 return;
129 }
130 if (strcmp(pw->pw_shell, UUCICO)) {
131 fprintf(stderr, "Login incorrect.");
132 return;
133 }
134 if (pw->pw_passwd && *pw->pw_passwd != '\0') {
1a85e9d2 135 printf("Password: "); fflush(stdout);
46b15d8a
RC
136 if (readline(passwd, sizeof passwd) < 0) {
137 fprintf(stderr, "passwd read\n");
138 return;
139 }
140 xpasswd = crypt(passwd, pw->pw_passwd);
141 if (strcmp(xpasswd, pw->pw_passwd)) {
142 fprintf(stderr, "Login incorrect.");
143 return;
144 }
145 }
146 alarm(0);
79b62878 147 sprintf(Username, "USER=%s", user);
46b15d8a 148 dologin(pw, sinp);
79b62878
JB
149 setgid(pw->pw_gid);
150#ifdef BSD4_2
46b15d8a 151 initgroups(pw->pw_name, pw->pw_gid);
79b62878 152#endif BSD4_2
46b15d8a 153 chdir(pw->pw_dir);
79b62878
JB
154 setuid(pw->pw_uid);
155#ifdef BSD4_2
46b15d8a 156 execl(UUCICO, "uucico", (char *)0);
79b62878 157#endif BSD4_2
46b15d8a
RC
158 perror("uucico server: execl");
159}
160
161readline(p, n)
1a85e9d2
RC
162register char *p;
163register int n;
46b15d8a
RC
164{
165 char c;
166
167 while (n-- > 0) {
168 if (read(0, &c, 1) <= 0)
169 return(-1);
170 c &= 0177;
171 if (c == '\n' || c == '\r') {
172 *p = '\0';
173 return(0);
174 }
175 *p++ = c;
176 }
177 return(-1);
178}
179
180#include <utmp.h>
79b62878 181#ifdef BSD4_2
46b15d8a 182#include <fcntl.h>
79b62878
JB
183#endif BSD4_2
184
46b15d8a
RC
185#define SCPYN(a, b) strncpy(a, b, sizeof (a))
186
187struct utmp utmp;
188
189dologout()
190{
191 union wait status;
192 int pid, wtmp;
193
194#ifdef BSDINETD
79b62878 195 while ((pid=wait(&status)) > 0) {
46b15d8a 196#else !BSDINETD
79b62878 197 while ((pid=wait3(&status,WNOHANG,0)) > 0) {
46b15d8a
RC
198#endif !BSDINETD
199 wtmp = open("/usr/adm/wtmp", O_WRONLY|O_APPEND);
200 if (wtmp >= 0) {
201 sprintf(utmp.ut_line, "uucp%.4d", pid);
202 SCPYN(utmp.ut_name, "");
203 SCPYN(utmp.ut_host, "");
79b62878 204 (void) time(&utmp.ut_time);
46b15d8a
RC
205 (void) write(wtmp, (char *)&utmp, sizeof (utmp));
206 (void) close(wtmp);
207 }
208 }
209}
210
211/*
212 * Record login in wtmp file.
213 */
214dologin(pw, sin)
215struct passwd *pw;
216struct sockaddr_in *sin;
217{
218 char line[32];
219 char remotehost[32];
220 int wtmp, f;
221 struct hostent *hp = gethostbyaddr(&sin->sin_addr,
222 sizeof (struct in_addr), AF_INET);
223
224 if (hp) {
225 strncpy(remotehost, hp->h_name, sizeof (remotehost));
226 endhostent();
227 } else
228 strncpy(remotehost, inet_ntoa(sin->sin_addr),
229 sizeof (remotehost));
230 wtmp = open("/usr/adm/wtmp", O_WRONLY|O_APPEND);
231 if (wtmp >= 0) {
232 /* hack, but must be unique and no tty line */
233 sprintf(line, "uucp%.4d", getpid());
234 SCPYN(utmp.ut_line, line);
235 SCPYN(utmp.ut_name, pw->pw_name);
236 SCPYN(utmp.ut_host, remotehost);
79b62878 237 time(&utmp.ut_time);
46b15d8a
RC
238 (void) write(wtmp, (char *)&utmp, sizeof (utmp));
239 (void) close(wtmp);
240 }
241 if ((f = open(lastlog, 2)) >= 0) {
242 struct lastlog ll;
243
244 time(&ll.ll_time);
245 lseek(f, (long)pw->pw_uid * sizeof(struct lastlog), 0);
246 strcpy(line, remotehost);
247 SCPYN(ll.ll_line, line);
248 SCPYN(ll.ll_host, remotehost);
249 (void) write(f, (char *) &ll, sizeof ll);
250 (void) close(f);
251 }
cd56d176 252}