📄 uucpd.c
字号:
/* * Copyright (c) 1985, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Rick Adams. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char copyright[] = "@(#) Copyright (c) 1985, 1993\n\ The Regents of the University of California. All rights reserved.\n";#endif /* not lint */#ifndef lintstatic char sccsid[] = "@(#)uucpd.c 8.1 (Berkeley) 6/4/93";#endif /* not lint *//* * 4.2BSD TCP/IP server for uucico * uucico's TCP channel causes this server to be run at the remote end. */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <sys/types.h>#ifdef HAVE_SYS_WAIT_H#include <sys/wait.h>#endif#include <sys/ioctl.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netdb.h>#include <signal.h>#include <fcntl.h>#ifdef TIME_WITH_SYS_TIME# include <sys/time.h># include <time.h>#else# ifdef HAVE_SYS_TIME_H# include <sys/time.h># else# include <time.h># endif#endif#include <getopt.h>#include <pwd.h>#include <unistd.h>#include <errno.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#ifdef HAVE_CRYPT_H# include <crypt.h>#endif#ifdef HAVE_TERMIOS_H# include <termios.h>#endif#ifdef HAVE_UTMP_H# include <utmp.h>#endifvoid dologin ();void usage (void);struct sockaddr_in hisctladdr;int hisaddrlen = sizeof hisctladdr;struct sockaddr_in myctladdr;int mypid;char Username[64];char *nenv[] = { Username, NULL,};extern char **environ;static const char *short_options = "hV";static struct option long_options[] = { {"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'V'}, {0}};intmain (int argc, char **argv){#ifndef BSDINETD register int s, tcp_socket; struct servent *sp;#endif /* !BSDINETD */ extern int errno; void dologout (); int c; while ((c = getopt_long (argc, argv, short_options, long_options, NULL)) != EOF) { switch (c) { case 'V': printf ("uucpd (%s %s)\n", PACKAGE_NAME, PACKAGE_VERSION); exit (0); case 'h': default: usage (); exit (0); } } environ = nenv;#ifdef BSDINETD close (1); close (2); dup (0); dup (0); hisaddrlen = sizeof (hisctladdr); if (getpeername (0, &hisctladdr, &hisaddrlen) < 0) { fprintf (stderr, "%s: ", argv[0]); perror ("getpeername"); _exit (1); } if (fork () == 0) doit (&hisctladdr); dologout (); exit (1);#else /* !BSDINETD */ sp = getservbyname ("uucp", "tcp"); if (sp == NULL) { perror ("uucpd: getservbyname"); exit (1); } if (fork ()) exit (0); if ((s = open (PATH_TTY, O_RDWR)) >= 0) { ioctl (s, TIOCNOTTY, (char *) 0); close (s); } bzero ((char *) &myctladdr, sizeof (myctladdr)); myctladdr.sin_family = AF_INET; myctladdr.sin_port = sp->s_port;#ifdef BSD4_2 tcp_socket = socket (AF_INET, SOCK_STREAM, 0); if (tcp_socket < 0) { perror ("uucpd: socket"); exit (1); } if (bind (tcp_socket, (char *) &myctladdr, sizeof (myctladdr)) < 0) { perror ("uucpd: bind"); exit (1); } listen (tcp_socket, 3); /* at most 3 simultaneuos uucp connections */ signal (SIGCHLD, dologout); for (;;) { s = accept (tcp_socket, &hisctladdr, &hisaddrlen); if (s < 0) { if (errno == EINTR) continue; perror ("uucpd: accept"); exit (1); } if (fork () == 0) { close (0); close (1); close (2); dup (s); dup (s); dup (s); close (tcp_socket); close (s); doit (&hisctladdr); exit (1); } close (s); }#endif /* BSD4_2 */#endif /* !BSDINETD */}voiddoit (struct sockaddr_in *sinp){ struct passwd *pw, *getpwnam (); char user[64], passwd[64]; char *xpasswd; alarm (60); printf ("login: "); fflush (stdout); if (readline (user, sizeof user) < 0) { fprintf (stderr, "user read\n"); return; } /* truncate username to 8 characters */ user[8] = '\0'; pw = getpwnam (user); if (pw == NULL) { fprintf (stderr, "user unknown\n"); return; } if (strcmp (pw->pw_shell, PATH_UUCICO)) { fprintf (stderr, "Login incorrect."); return; } if (pw->pw_passwd && *pw->pw_passwd != '\0') { printf ("Password: "); fflush (stdout); if (readline (passwd, sizeof passwd) < 0) { fprintf (stderr, "passwd read\n"); return; } xpasswd = crypt (passwd, pw->pw_passwd); if (strcmp (xpasswd, pw->pw_passwd)) { fprintf (stderr, "Login incorrect."); return; } } alarm (0); sprintf (Username, "USER=%s", user); dologin (pw, sinp); setgid (pw->pw_gid);#ifdef BSD4_2 initgroups (pw->pw_name, pw->pw_gid);#endif /* BSD4_2 */ chdir (pw->pw_dir); setuid (pw->pw_uid);#ifdef BSD4_2 execl (UUCICO, "uucico", (char *) 0);#endif /* BSD4_2 */ perror ("uucico server: execl");}intreadline (register char *p, register int n){ char c; while (n-- > 0) { if (read (0, &c, 1) <= 0) return (-1); c &= 0177; if (c == '\n' || c == '\r') { *p = '\0'; return (0); } *p++ = c; } return (-1);}#ifdef BSD4_2#include <fcntl.h>#endif /* BSD4_2 */voiddologout (){ int pid;#ifdef HAVE_WAITPID while ((pid = waitpid (-1, 0, WNOHANG)) > 0)#else# ifdef HAVE_WAIT3 while ((pid = wait3 (0, WNOHANG, 0)) > 0)# else while ((pid = wait (0)) > 0)#endif /* HAVE_WAIT3 */#endif /* HAVE_WAITPID */ { char line[100]; sprintf (line, "uucp%.4d", pid); logwtmp (line, "", ""); }}/* * Record login in wtmp file. */voiddologin (struct passwd *pw, struct sockaddr_in *sin){ char line[32]; char remotehost[32]; int wtmp, f; struct hostent *hp = gethostbyaddr ((char *) &sin->sin_addr, sizeof (struct in_addr), AF_INET); if (hp) { strncpy (remotehost, hp->h_name, sizeof (remotehost)); endhostent (); } else strncpy (remotehost, inet_ntoa (sin->sin_addr), sizeof (remotehost)); sprintf (line, "uucp%.4d", getpid ()); logwtmp (line, pw->pw_name, remotehost);#if defined (PATH_LASTLOG) && defined (HAVE_STRUCT_LASTLOG)#define SCPYN(a, b) strncpy(a, b, sizeof (a)) if ((f = open (PATH_LASTLOG, O_RDWR)) >= 0) { struct lastlog ll; time (&ll.ll_time); lseek (f, (long) pw->pw_uid * sizeof (struct lastlog), 0); strcpy (line, remotehost); SCPYN (ll.ll_line, line); SCPYN (ll.ll_host, remotehost); write (f, (char *) &ll, sizeof ll); close (f); }#endif}static const char usage_str[] = "Usage: uucpd [OPTIONS...]\n" "\n" "Options are:\n" " --help Display usage instructions\n" " --version Display program version\n";voidusage (void){ printf ("%s\n" "Send bug reports to <%s>\n", usage_str, PACKAGE_BUGREPORT);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -