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