home *** CD-ROM | disk | FTP | other *** search
- From: chip@chinacat.unicom.com (Chip Rosenthal)
- Newsgroups: alt.sources
- Subject: uucp over TCP/IP
- Message-ID: <1991Jun11.175522.22154@chinacat.unicom.com>
- Date: 11 Jun 91 17:55:22 GMT
-
- I've now received about two dozen requests for this, so I figure it
- would be best to post.
-
- The following package implements `uucp' over TCP/IP. It is useful
- for systems which do not provide this capability. There are two
- general methods for this: TLI uucp and Berkeley uucpd. This supports
- the second method. This package has been tested with SCO XENIX (TCP
- 1.0) and SCO UNIX (TCP 1.1).
-
- I'll gladly accept bug reports/fixes/hacks.
-
- #! /bin/sh
- # this is a "shar" archive - run through "/bin/sh" to extract 4 files:
- # README uucpm.c uucpd.c Makefile
- # Wrapped by chip@chinacat on Tue Jun 11 12:45:53 CDT 1991
- # Unpacking this archive requires: sed test wc (possibly mkdir)
- # Existing files will not be clobbered unless "-c" is specified on the cmd line.
- if test -f README -a "$1" != "-c" ; then
- echo "README: file exists - will not be overwritten"
- else
- echo "x - README (file 1 of 4, 5277 chars)"
- sed -e 's/^X//' << 'END_OF_FILE_README' > README
- X
- X *** uucp over SCO UNIX/XENIX TCP/IP ***
- X
- XSUMMARY
- X
- X This package provides two daemon to allow Berkeley-style uucp
- X transfers over TCP/IP for SCO UNIX and SCO XENIX systems. The
- X `uucpd' daemon is a BSD UNIX program (version 5.9 6/1/90), ported
- X to SCO. It implements the slave (i.e. responding) end of the
- X transfer. The `uucpm' daemon was written specifically for this
- X package. It implements the master (i.e. initiating) end of the
- X transfer.
- X
- XINSTALLATION
- X
- X - Edit the site-specific customizations at the top of the `Makefile'.
- X
- X - Run `make'.
- X
- X - Install the `uucpd' and `uucpm' binaries. I place them in a
- X directory called `/etc/local'. They may reside anywhere, but
- X the rest of these directions assume that's where they are.
- X
- X - Add a line to `/etc/inetd.conf' which says:
- X
- X uucp stream tcp nowait root /etc/local/uucpd uucpd
- X
- X Yes, `uucpd' does need to run as root.
- X
- X - Decide how many outgoing TCP/IP connections you want to support,
- X and which pty(s) you wish to allocate to them. Myself, I only
- X support a single connection, and allocate the /dev/[pt]typ7
- X pair. The rest of these notes assume that configuration.
- X
- X - Add the commands to start the `uucpm' daemon. You could put them
- X into `/etc/tcp' but I prefer not to since the `mkdev tcp' will
- X trounce that script if you rerun it. I add the command:
- X
- X /etc/local/uucpm /dev/ptyp7
- X
- X to an appropriate /etc/rc.d (XENIX) or /etc/rc2.d (UNIX) file.
- X If you want to support multiple sessions, you will need to start
- X a `uucpm' daemon upon each of the pty's selected.
- X
- X - Declare the pty device(s) available for uucp. This may be done with
- X an entry in your /usr/lib/uucp/Devices file such as:
- X
- X TCPIP ttyp7 - 19200 direct
- X
- X Note that `uucpm' was started on the master end of the pty
- X (ptyp7), but here we give the slave end (ttyp7). If you are
- X supporting multiple sessions, provide similar entries for all
- X of the pty's.
- X
- X - Finally, enter the /usr/lib/uucp/Systems information for machines
- X on the network:
- X
- X coldsnap Any TCPIP Any - "" coldsnap gin: NAME word: PASSWORD
- X ^^^^^^^^^^^
- X
- X The highlighted portion of the chat script is where the connection
- X to the remote machine is established. All you need to do is
- X send out the machine name, and the `uucpm' daemon will establish
- X a socket to the specified machine. If there is no password on
- X the account, `uucpd' will not prompt for one, and thus it may
- X be left off. Also note that for security reasons, `uucpd'
- X insists that the login shell is `/usr/lib/uucp/uucico'.
- X
- X - You are now ready to roll. Remember - to test this stuff out
- X you will need to either: (1) `kill -1' the init process and
- X manually start the `uucpm' daemon, or (2) reboot the system.
- X `uucpm' has an undocumented `-D' switch to run in a debugging
- X (non-daemon) mode.
- X
- X
- XTHEORY OF OPERATION - SLAVE SIDE
- X
- X When a connection is established upon port 540, the `well known
- X port' for uucp, the `inetd' superserver starts up the `uucpd'
- X program. This program prompts for and receives (through the
- X network) the username and password for a uucp login. It does the
- X loginish things, like setup an environment and make /etc/wtmp
- X entries. Then, it forks off a child to run `uucico' for the remote
- X system. When `uucico' terminates `uucpd' cleans up (i.e. makes
- X the logout entry into /etc/wtmp, shuts down the socket, etc.) and
- X terminates.
- X
- X
- XTHEORY OF OPERATION - MASTER SIDE
- X
- X The `uucpm' daemon sits upon the master end of a pty, waiting for
- X an incoming request. When `uucico' attempts a connection to a
- X networked system, it selects one of the TCPIP devices - the slave
- X end of the pty. `uucpm' reads one CR delimited line - the name
- X of the remote system. The chat script shown above starts with an
- X `expect nothing/send system name' sequence, which provides `uucpm'
- X the information it requires. `uucpm' then attempts to establish
- X a socket to port 540 on the named system, and if successful just
- X passes data between the pty and the socket. When either the socket
- X shuts down (i.e. the remote slave uucico finishes) or the pty
- X shuts down (i.e. the local master uucico finishes), `uucpm' closes
- X up everything and reopens the pty awaiting another request.
- X
- X
- XWISHLIST
- X
- X I am particularly unhappy with the way `uucpd' handles the /etc/wtmp
- X file. I think it could record more useful information. It's also
- X crummy that you always get a logout entry made - even if the login
- X wasn't successful. Unfortunately - this is extremely difficult
- X to fix and still maintain compatibility with the non-inetd form
- X of `uucpd'. I'm tempted to rip that out and fix the wtmp stuff.
- X
- X If somebody wanted to get fancy, it is theoretically possible to
- X do a version of `uucpm' run as an SCO binary dialer. That would
- X avoid having to have a daemon laying around. I'm not sure it's
- X is worth it - it's certainly of no use on non-SCO systems.
- X
- X
- XChip Rosenthal
- X<chip@chinacat.unicom.com>
- XUnicom Systems Development, Inc.
- X
- X@(#) README 1.1 91/06/07 01:27:43
- X
- END_OF_FILE_README
- size="`wc -c < README`"
- if test 5277 -ne "$size" ; then
- echo "README: extraction error - got $size chars"
- fi
- fi
- if test -f uucpm.c -a "$1" != "-c" ; then
- echo "uucpm.c: file exists - will not be overwritten"
- else
- echo "x - uucpm.c (file 2 of 4, 7915 chars)"
- sed -e 's/^X//' << 'END_OF_FILE_uucpm.c' > uucpm.c
- X/*
- X * uucpm - daemon to run master uucico process over TCP/IP network
- X *
- X * Chip Rosenthal <chip@chinacat.unicom.com>
- X * Unicom Systems Development, Inc.
- X *
- X * This program detatches itself to become a daemon, and then runs through
- X * an infinite loop - one iteration per uucico invocation. At the top of
- X * the loop, it opens the master end of a pty. When a uucico process opens
- X * the slave end, this program reads in the name of the target machine,
- X * establishes a socket to "uucpd" on that machine, and then passes data
- X * between the socket and pty. When EOF is reached upon either the socket
- X * or the pty, both are shutdown, and the pty is reopened to await another
- X * uucico invocation.
- X */
- X
- X#ifndef lint
- Xstatic char SCCSID[] = "@(#) uucpm.c 1.2 91/06/11 12:45:16";
- X#endif
- X
- X#include <sys/types.h>
- X#include <sys/socket.h>
- X#include <netinet/in.h>
- X#include <netdb.h>
- X#include <syslog.h>
- X#include <signal.h>
- X#include <stdio.h>
- X#include <fcntl.h>
- X
- X#define USAGE "usage: %s master_pty\n"
- X
- Xextern int errno;
- Xextern char *sys_errlist[];
- X#define errmssg sys_errlist[errno]
- X
- X#define Dprintf if ( !Debug ) ; else fprintf
- Xint Debug = 0;
- X
- Xsigcatcher(sig)
- Xint sig;
- X{
- X syslog(LOG_INFO, "caught signal %d - terminating", sig);
- X exit(0);
- X}
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X int sfd, pfd, numfd, n;
- X char host[64], buf[512], *ptypath;
- X struct sockaddr_in sin;
- X struct servent *sp;
- X struct hostent *hp;
- X fd_set fdset;
- X
- X /*
- X * Crack command line.
- X */
- X if ( argc == 2 ) {
- X ptypath = argv[1];
- X } else if ( argc == 3 && strcmp(argv[1], "-D") == 0 ) {
- X ++Debug;
- X ptypath = argv[2];
- X } else {
- X fprintf(stderr, USAGE, argv[0]);
- X exit(1);
- X }
- X
- X /*
- X * Verify the pty exists.
- X */
- X if ( access(ptypath, 06) != 0 ) {
- X fprintf(stderr, "%s: can't access '%s' [%s]\n",
- X argv[0], ptypath, errmssg);
- X exit(1);
- X }
- X
- X openlog("uucpm", LOG_PID|LOG_CONS, LOG_DAEMON);
- X
- X /*
- X * Setup as daemon.
- X */
- X if ( !Debug ) {
- X
- X /*
- X * Fork off child process.
- X */
- X switch ( fork() ) {
- X case -1: syslog(LOG_ERR, "fork failed [%s]", errmssg); exit(1);
- X case 0: break;
- X default: exit(0);
- X }
- X
- X /*
- X * Detatch from controlling terminal.
- X */
- X if ( setpgrp() < 0 ) {
- X syslog(LOG_ERR, "process group detatch failed [%s]", errmssg);
- X exit(1);
- X }
- X for ( n = 1 ; n <= NSIG ; ++n ) {
- X switch ( n ) {
- X case SIGHUP: (void) signal(n, SIG_IGN); break;
- X case SIGCLD: (void) signal(n, SIG_DFL); break;
- X default: (void) signal(n, sigcatcher); break;
- X }
- X }
- X (void) close(0);
- X (void) close(1);
- X (void) close(2);
- X (void) chdir("/");
- X (void) umask(0);
- X
- X /*
- X * Fork again so we become owned by init.
- X */
- X switch ( fork() ) {
- X case -1: syslog(LOG_ERR, "fork failed [%s]", errmssg); exit(1);
- X case 0: break;
- X default: exit(0);
- X }
- X
- X }
- X
- X /*
- X * Once through loop per uucp connection request.
- X */
- X syslog(LOG_INFO, "daemon running on '%s'", ptypath);
- X sfd = pfd = -1;
- X for (;;) {
- X
- X /*
- X * Shutdown any fd's open from last time. Pause when shutting down
- X * pty to allow uucico to close down and release the slave end. The
- X * sleep is ugly, but the alternatives (I can think of) are even
- X * uglier (e.g. find the PID which has it locked and busy wait until
- X * that PID terminates).
- X */
- X if ( sfd >= 0 ) {
- X (void) close(sfd);
- X sfd = -1;
- X }
- X if ( pfd >= 0 ) {
- X (void) close(pfd);
- X pfd = -1;
- X sleep(5);
- X }
- X
- X /*
- X * Open up the master side of the pty.
- X */
- X if ( (pfd=open(ptypath, O_RDWR)) < 0 ) {
- X syslog(LOG_ERR, "open '%s' failed [%s]", ptypath, errmssg);
- X exit(1);
- X }
- X
- X /*
- X * Block until the slave side is opened, i.e. the pty is writeable.
- X */
- X Dprintf(stderr, "opened pty '%s' - blocking for slave\n", ptypath);
- X FD_ZERO(&fdset);
- X FD_SET(pfd, &fdset);
- X if ( select(pfd+1, (fd_set *)0, &fdset, (fd_set *)0,
- X (struct timeval *)0) < 0 || !FD_ISSET(pfd, &fdset) ) {
- X syslog(LOG_ERR, "select failed [%s]", errmssg);
- X continue;
- X }
- X
- X /*
- X * Read in the host name.
- X */
- X Dprintf(stderr, "slave active - waiting for uucp request\n");
- X if ( rdline(pfd, host, sizeof(host)) < 0 ) {
- X syslog(LOG_ERR, "host name read on '%s' failed [%s]",
- X ptypath, errmssg);
- X continue;
- X }
- X
- X /*
- X * Get the host and service information.
- X */
- X if ( (hp=gethostbyname(host)) == NULL ) {
- X syslog(LOG_ERR, "host '%s' lookup failed", host);
- X sprintf(buf, "error - unknown host '%s'\n", host);
- X (void) wrbuf(pfd, "pty", buf, strlen(buf));
- X continue;
- X }
- X if ( (sp=getservbyname("uucp", "tcp")) == NULL ) {
- X syslog(LOG_ERR, "service 'uucp/tcp' lookup failed");
- X exit(1);
- X }
- X Dprintf(stderr, "attempting connection - host %s, addr %s, port %d\n",
- X host,
- X inet_ntoa(*((struct in_addr *)hp->h_addr)),
- X ntohs(sp->s_port)
- X );
- X
- X /*
- X * Setup the socket to "uucpd" on the slave system.
- X */
- X bzero((char *)&sin, sizeof(sin));
- X bcopy(hp->h_addr, (char*)&sin.sin_addr , hp->h_length);
- X sin.sin_family = hp->h_addrtype;
- X sin.sin_port = sp->s_port;
- X if ( (sfd=socket(AF_INET, SOCK_STREAM, 0)) < 0 ) {
- X syslog(LOG_ERR, "socket create failed [%s]", errmssg);
- X continue;
- X }
- X if ( connect(sfd, (char *)&sin, sizeof(sin)) < 0 ) {
- X syslog(LOG_ERR, "socket connect failed [%s]", errmssg);
- X continue;
- X }
- X
- X /*
- X * Multiplex the data between the local and remote uucico's.
- X */
- X numfd = ( pfd > sfd ? pfd : sfd ) + 1;
- X Dprintf(stderr, "connect successful\n");
- X for (;;) {
- X
- X /*
- X * Wait for some data to read.
- X */
- X FD_ZERO(&fdset);
- X FD_SET(pfd, &fdset);
- X FD_SET(sfd, &fdset);
- X if ( select(numfd, &fdset, (fd_set *)0, (fd_set *)0,
- X (struct timeval *)0) < 0 ) {
- X syslog(LOG_ERR, "select failed [%s]", errmssg);
- X break;
- X }
- X
- X /*
- X * Pass data from the pty to the socket.
- X */
- X if ( FD_ISSET(pfd, &fdset) ) {
- X if ( (n=rdbuf(pfd, "pty", buf, sizeof(buf))) <= 0 )
- X break;
- X if ( wrbuf(sfd, "socket", buf, n) < 0 )
- X break;
- X continue;
- X }
- X
- X /*
- X * Pass data from the socket to the pty.
- X */
- X if ( FD_ISSET(sfd, &fdset) ) {
- X if ( (n=rdbuf(sfd, "socket", buf, sizeof(buf))) <= 0 )
- X break;
- X if ( wrbuf(pfd, "pty", buf, n) < 0 )
- X break;
- X continue;
- X }
- X
- X /* why did we wakeup?? */
- X
- X }
- X
- X /*
- X * The uucico session is complete. Loop back to wait for another
- X * session. The pty and socket fd's will be shutdown at the top
- X * of the loop.
- X */
- X
- X }
- X
- X /*NOTREACHED*/
- X
- X}
- X
- X
- X/*
- X * Read in a CR-terminated line of text.
- X * Return 0 upon success, -1 upon failure.
- X */
- Xint rdline(fd, buf, n)
- Xint fd; /* file descriptor to read from */
- Xchar *buf; /* place to stick the text */
- Xint n; /* maximum number of chars to read */
- X{
- X while ( --n > 0 ) {
- X if ( read(fd, buf, 1) != 1 )
- X return -1;
- X if ( *buf == '\r' )
- X break;
- X ++buf;
- X }
- X *buf = '\0';
- X return 0;
- X}
- X
- X
- X/*
- X * Read in a bufferful of data.
- X * Returns number of bytes read, 0 upon EOF, -1 upon error.
- X */
- Xint rdbuf(fd, name, buf, buflen)
- Xint fd; /* file descriptor to read from */
- Xchar *name; /* name to use in diagnostics */
- Xchar *buf; /* place to stick the data */
- Xint buflen; /* maximum number of bytes to read */
- X{
- X register int n;
- X
- X if ( (n=read(fd, buf, (unsigned)buflen)) < 0 ) {
- X syslog(LOG_ERR, "%s read error [%s]", name, errmssg);
- X return -1;
- X }
- X if ( n == 0 ) {
- X Dprintf(stderr, "hangup on %s\n", name);
- X return 0;
- X }
- X Dprintf(stderr, "read from %s %d bytes\n", name, n);
- X return n;
- X}
- X
- X
- X/*
- X * Write out a bufferful of data.
- X * Returns 0 upon success, -1 upon error.
- X */
- Xint wrbuf(fd, name, buf, buflen)
- Xint fd; /* file descriptor to write to */
- Xchar *name; /* name to use in diagnostics */
- Xregister char *buf; /* the data to write out */
- Xregister int buflen; /* number of bytes to write */
- X{
- X register int n;
- X
- X while ( buflen > 0 ) {
- X if ( (n=write(fd, buf, (unsigned)buflen)) < 0 ) {
- X syslog(LOG_ERR, "%s write error [%s]", name, errmssg);
- X return -1;
- X }
- X Dprintf(stderr, "write to %s %d bytes\n", name, n);
- X buflen -= n;
- X buf += n;
- X }
- X return 0;
- X}
- X
- END_OF_FILE_uucpm.c
- size="`wc -c < uucpm.c`"
- if test 7915 -ne "$size" ; then
- echo "uucpm.c: extraction error - got $size chars"
- fi
- fi
- if test -f uucpd.c -a "$1" != "-c" ; then
- echo "uucpd.c: file exists - will not be overwritten"
- else
- echo "x - uucpd.c (file 3 of 4, 8481 chars)"
- sed -e 's/^X//' << 'END_OF_FILE_uucpd.c' > uucpd.c
- X/*
- X * @(#) uucpd.c 1.1 91/06/07 01:33:44
- X *
- X * Chip Rosenthal <chip@chinacat.unicom.com>
- X * Unicom Systems Development, Inc.
- X *
- X * Ported to System Vr3.2 and XENIX V. Compile with -DSYSV defined.
- X * Tested on SCO XENIX (TCP 1.0.1h) and SCO UNIX (TCP 1.1.3x).
- X * Compile with -DLAI_TCP defined.
- X * Only tested under "inetd". Compile with -DBSDINET defined.
- X * Made "lastlog" logging optional. Omit by -DNO_LASTLOG.
- X * Made "(struct utmp *)->ut_host" optional. Omit with -DNO_UTHOST.
- X * Added support to obtain password from "/etc/shadow". Define -DSHADOWPWD.
- X * Support for the SCO/Secureware wretched monstrosity. Use -DSECURECRAP.
- X */
- X
- X/*
- X * Copyright (c) 1985 The Regents of the University of California.
- X * All rights reserved.
- X *
- X * This code is derived from software contributed to Berkeley by
- X * Rick Adams.
- X *
- X * Redistribution and use in source and binary forms are permitted
- X * provided that: (1) source distributions retain this entire copyright
- X * notice and comment, and (2) distributions including binaries display
- X * the following acknowledgement: ``This product includes software
- X * developed by the University of California, Berkeley and its contributors''
- X * in the documentation or other materials provided with the distribution
- X * and in all advertising materials mentioning features or use of this
- X * software. Neither the name of the University nor the names of its
- X * contributors may be used to endorse or promote products derived
- X * from this software without specific prior written permission.
- X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- X */
- X
- X#ifndef lint
- Xchar copyright[] =
- X"@(#) Copyright (c) 1985 The Regents of the University of California.\n\
- X All rights reserved.\n";
- X#endif /* not lint */
- X
- X#ifndef lint
- Xstatic char sccsid[] = "@(#)uucpd.c 5.9 (Berkeley) 6/1/90";
- X#endif /* not lint */
- X
- X/*
- X * 4.2BSD TCP/IP server for uucico
- X * uucico's TCP channel causes this server to be run at the remote end.
- X */
- X
- X#include <sys/types.h>
- X#include <sys/socket.h>
- X#ifdef SYSV
- X#include <fcntl.h>
- X#else
- X#include <sys/wait.h>
- X#include <sys/ioctl.h>
- X#include <sys/file.h>
- X#endif
- X#include <netinet/in.h>
- X#include <netdb.h>
- X#include <signal.h>
- X#include <errno.h>
- X#include <pwd.h>
- X#include <stdio.h>
- X#ifdef SHADOWPWD
- X#include <shadow.h>
- X#endif
- X#ifdef SECURECRAP
- X#define SecureWare
- X#include <sys/security.h>
- X#include <prot.h>
- X#endif
- X#ifdef SYSV
- X#define _PATH_UUCICO "/usr/lib/uucp/uucico"
- X#define _PATH_WTMP "/etc/wtmp"
- X#else
- X#include "pathnames.h"
- X#endif
- X
- Xstruct sockaddr_in hisctladdr;
- Xint hisaddrlen = sizeof hisctladdr;
- Xstruct sockaddr_in myctladdr;
- Xint mypid;
- X
- Xchar Username[64];
- Xchar *nenv[] = {
- X Username,
- X NULL,
- X};
- Xextern char **environ;
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar **argv;
- X{
- X#ifndef BSDINETD
- X register int s, tcp_socket;
- X struct servent *sp;
- X#endif /*!BSDINETD*/
- X extern int errno;
- X int dologout();
- X
- X#ifdef SECURECRAP
- X setluid(getuid());
- X#endif
- X
- X environ = nenv;
- X#ifdef BSDINETD
- X close(1); close(2);
- X dup(0); dup(0);
- X hisaddrlen = sizeof (hisctladdr);
- X if (getpeername(0, &hisctladdr, &hisaddrlen) < 0) {
- X fprintf(stderr, "%s: ", argv[0]);
- X perror("getpeername");
- X _exit(1);
- X }
- X if (fork() == 0) {
- X doit(&hisctladdr);
- X exit(1);
- X }
- X dologout();
- X exit(1);
- X#else /*!BSDINETD*/
- X sp = getservbyname("uucp", "tcp");
- X if (sp == NULL){
- X perror("uucpd: getservbyname");
- X exit(1);
- X }
- X if (fork())
- X exit(0);
- X if ((s=open(_PATH_TTY, 2)) >= 0){
- X ioctl(s, TIOCNOTTY, (char *)0);
- X close(s);
- X }
- X
- X bzero((char *)&myctladdr, sizeof (myctladdr));
- X myctladdr.sin_family = AF_INET;
- X myctladdr.sin_port = sp->s_port;
- X#ifdef BSD4_2
- X tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
- X if (tcp_socket < 0) {
- X perror("uucpd: socket");
- X exit(1);
- X }
- X if (bind(tcp_socket, (char *)&myctladdr, sizeof (myctladdr)) < 0) {
- X perror("uucpd: bind");
- X exit(1);
- X }
- X listen(tcp_socket, 3); /* at most 3 simultaneuos uucp connections */
- X signal(SIGCHLD, dologout);
- X
- X for(;;) {
- X s = accept(tcp_socket, &hisctladdr, &hisaddrlen);
- X if (s < 0){
- X if (errno == EINTR)
- X continue;
- X perror("uucpd: accept");
- X exit(1);
- X }
- X if (fork() == 0) {
- X close(0); close(1); close(2);
- X dup(s); dup(s); dup(s);
- X close(tcp_socket); close(s);
- X doit(&hisctladdr);
- X exit(1);
- X }
- X close(s);
- X }
- X#endif /*BSD4_2*/
- X
- X#endif /*!BSDINETD*/
- X}
- X
- Xdoit(sinp)
- Xstruct sockaddr_in *sinp;
- X{
- X char user[64], passwd[64];
- X char *xpasswd, *crypt();
- X struct passwd *pw, *getpwnam();
- X
- X alarm(60);
- X printf("login: "); fflush(stdout);
- X if (readline(user, sizeof user) < 0) {
- X fprintf(stderr, "user read\n");
- X return;
- X }
- X /* truncate username to 8 characters */
- X user[8] = '\0';
- X pw = getpwnam(user);
- X if (pw == NULL) {
- X fprintf(stderr, "user unknown\n");
- X return;
- X }
- X#ifdef SHADOWPWD /*{*/
- X {
- X struct spwd *spw;
- X if ( (spw=getspnam(user)) == NULL ) {
- X fprintf(stderr, "user unknown\n");
- X return;
- X }
- X pw->pw_passwd = spw->sp_pwdp;
- X }
- X#endif /*}SHADOWPWD*/
- X#ifdef SECURECRAP /*{*/
- X {
- X struct pr_passwd *prpw;
- X static char *av[] = { "uucpd", NULL };
- X set_auth_parameters(1,av);
- X if ( (prpw=getprpwnam(user)) == NULL ) {
- X fprintf(stderr, "user unknown\n");
- X return;
- X }
- X pw->pw_passwd = prpw->ufld.fd_encrypt;
- X }
- X#endif /*}SECURECRAP*/
- X if (strcmp(pw->pw_shell, _PATH_UUCICO)) {
- X fprintf(stderr, "Login incorrect.\n");
- X return;
- X }
- X if (pw->pw_passwd && *pw->pw_passwd != '\0') {
- X printf("Password: "); fflush(stdout);
- X if (readline(passwd, sizeof passwd) < 0) {
- X fprintf(stderr, "passwd read\n");
- X return;
- X }
- X xpasswd = crypt(passwd, pw->pw_passwd);
- X if (strcmp(xpasswd, pw->pw_passwd)) {
- X fprintf(stderr, "Login incorrect.\n");
- X return;
- X }
- X }
- X alarm(0);
- X sprintf(Username, "USER=%s", user);
- X dologin(pw, sinp);
- X setgid(pw->pw_gid);
- X#ifdef BSD4_2
- X initgroups(pw->pw_name, pw->pw_gid);
- X#endif /*BSD4_2*/
- X chdir(pw->pw_dir);
- X setuid(pw->pw_uid);
- X#ifdef BSD4_2
- X execl(UUCICO, "uucico", (char *)0);
- X#endif /*BSD4_2*/
- X#ifdef SYSV
- X execl(_PATH_UUCICO, "uucico", (char *)0);
- X#endif
- X perror("uucico server: execl");
- X}
- X
- Xreadline(p, n)
- Xregister char *p;
- Xregister int n;
- X{
- X char c;
- X
- X while (n-- > 0) {
- X if (read(0, &c, 1) <= 0)
- X return(-1);
- X c &= 0177;
- X if (c == '\n' || c == '\r') {
- X *p = '\0';
- X return(0);
- X }
- X *p++ = c;
- X }
- X return(-1);
- X}
- X
- X#include <utmp.h>
- X#ifdef BSD4_2
- X#include <fcntl.h>
- X#endif /*BSD4_2*/
- X
- X#define SCPYN(a, b) strncpy(a, b, sizeof (a))
- X
- Xstruct utmp utmp;
- X
- Xdologout()
- X{
- X#ifdef SYSV
- X int status;
- X#else
- X union wait status;
- X#endif
- X char line[32];
- X int pid, wtmp;
- X
- X#ifdef BSDINETD
- X while ((pid=wait(&status)) > 0) {
- X#else /*!BSDINETD*/
- X while ((pid=wait3(&status,WNOHANG,0)) > 0) {
- X#endif /*!BSDINETD*/
- X wtmp = open(_PATH_WTMP, O_WRONLY|O_APPEND);
- X if (wtmp >= 0) {
- X sprintf(line, "uucp%.04d", pid%10000);
- X SCPYN(utmp.ut_line, line);
- X SCPYN(utmp.ut_name, "");
- X#ifndef NO_UTHOST
- X SCPYN(utmp.ut_host, "");
- X#endif
- X (void) time(&utmp.ut_time);
- X#ifdef SYSV
- X utmp.ut_type = DEAD_PROCESS;
- X utmp.ut_pid = getpid();
- X utmp.ut_exit.e_termination = status & 0xFF;
- X utmp.ut_exit.e_exit = (status>>8) & 0xFF;
- X#endif
- X (void) write(wtmp, (char *)&utmp, sizeof (utmp));
- X (void) close(wtmp);
- X }
- X }
- X}
- X
- X/*
- X * Record login in wtmp file.
- X */
- Xdologin(pw, sin)
- Xstruct passwd *pw;
- Xstruct sockaddr_in *sin;
- X{
- X char line[32];
- X char remotehost[32];
- X int wtmp;
- X#ifndef NO_LASTLOG
- X int f;
- X#endif
- X struct hostent *hp = gethostbyaddr(&sin->sin_addr,
- X sizeof (struct in_addr), AF_INET);
- X
- X if (hp) {
- X strncpy(remotehost, hp->h_name, sizeof (remotehost));
- X endhostent();
- X } else
- X strncpy(remotehost, inet_ntoa(sin->sin_addr),
- X sizeof (remotehost));
- X wtmp = open(_PATH_WTMP, O_WRONLY|O_APPEND);
- X if (wtmp >= 0) {
- X /* hack, but must be unique and no tty line */
- X sprintf(line, "uucp%.04d", getpid()%10000);
- X SCPYN(utmp.ut_line, line);
- X SCPYN(utmp.ut_name, pw->pw_name);
- X#ifndef NO_UTHOST
- X SCPYN(utmp.ut_host, remotehost);
- X#endif
- X time(&utmp.ut_time);
- X#ifdef SYSV
- X utmp.ut_type = USER_PROCESS;
- X utmp.ut_pid = getpid();
- X utmp.ut_exit.e_termination = 0;
- X utmp.ut_exit.e_exit = 0;
- X#endif
- X (void) write(wtmp, (char *)&utmp, sizeof (utmp));
- X (void) close(wtmp);
- X }
- X#ifndef NO_LASTLOG
- X if ((f = open(_PATH_LASTLOG, O_RDWR)) >= 0) {
- X struct lastlog ll;
- X
- X time(&ll.ll_time);
- X lseek(f, (long)pw->pw_uid * sizeof(struct lastlog), 0);
- X strcpy(line, remotehost);
- X SCPYN(ll.ll_line, line);
- X SCPYN(ll.ll_host, remotehost);
- X (void) write(f, (char *) &ll, sizeof ll);
- X (void) close(f);
- X }
- X#endif
- X}
- END_OF_FILE_uucpd.c
- size="`wc -c < uucpd.c`"
- if test 8481 -ne "$size" ; then
- echo "uucpd.c: extraction error - got $size chars"
- fi
- fi
- if test -f Makefile -a "$1" != "-c" ; then
- echo "Makefile: file exists - will not be overwritten"
- else
- echo "x - Makefile (file 4 of 4, 1784 chars)"
- sed -e 's/^X//' << 'END_OF_FILE_Makefile' > Makefile
- X# @(#) Makefile 1.2 91/06/11 12:45:15
- X
- XSHELL = /bin/sh
- XCC = cc
- XALL = uucpm uucpd
- XLINT = uucpm.lint uucpd.lint
- XSRCS = README uucpm.c uucpd.c Makefile
- X
- Xall: $(ALL)
- Xlint: $(LINT)
- X
- X##############################################################################
- X#
- X# Site-specific customizations.
- X#
- X
- X#
- X# Site-specific definitions for networking. SCO needs "-DLAI_TCP".
- X#
- XSITEDEFS = -DLAI_TCP
- X
- X#
- X# Enable the following for SCO UNIX.
- X#
- X#SECURECRAP = -DSECURECRAP
- X#LDPROT = -lprot
- X
- X#
- X# Enable the following for /etc/shadow support.
- X#
- XSHADOWPWD = -DSHADOWPWD
- XLDSHADOW = -lshadow
- X
- X#
- X# Define to point to your socket library - maybe "-lsocket", maybe "-linet".
- X#
- XLDSOCKET = -lsocket
- X
- X#
- X# Define to point to your crypt library - usually "-lcrypt".
- X#
- XLDCRYPT = -lcrypt
- X
- X#
- X# You probably want to define the following as "cp".
- X#
- XINST = inst -D
- X
- X#
- X# Enable the following if files are checked into SCCS.
- X#
- X$(SRCS) : SCCS/s.$$@ ; sccs get $@
- Xclobber : clean ; sccs clean ; sccs get Makefile
- X
- X#
- X##############################################################################
- X
- X
- XDEFS_M = $(SITEDEFS)
- XDEFS_D = -DSYSV -DBSDINETD -DNO_LASTLOG -DNO_UTHOST \
- X $(SITEDEFS) $(SHADOWPWD) $(SECURECRAP)
- XLIBS_M = $(LDSOCKET)
- XLIBS_D = $(LDSOCKET) $(LDCRYPT) $(LDSHADOW) $(LDPROT)
- X
- Xclean:
- X rm -f $(ALL) $(LINT) *.o a.out core
- X
- Xinstall: all
- X $(INST) uucpm /etc/local/uucpm
- X $(INST) uucpd /etc/local/uucpd
- X
- Xuucpm: uucpm.o
- X $(CC) -o uucpm uucpm.o $(LIBS_M)
- X
- Xuucpd: uucpd.o
- X $(CC) -o uucpd uucpd.o $(LIBS_D)
- X
- Xuucpm.o: uucpm.c
- X $(CC) -O -c $(DEFS_M) uucpm.c
- X
- Xuucpd.o: uucpd.c
- X $(CC) -O -c $(DEFS_D) uucpd.c
- X
- Xuucpm.lint: uucpm
- X lint -DNO_PROTOTYPE $(DEFS_M) uucpm.c $(LIBS_M) >$@
- X
- Xuucpd.lint: uucpd
- X lint -DNO_PROTOTYPE $(DEFS_D) uucpd.c $(LIBS_D) >$@
- X
- XSHAR = uucpm.shar
- Xshar : $(SHAR)
- X$(SHAR) : $(SRCS) ; shar $(SRCS) >$@
- X
- END_OF_FILE_Makefile
- size="`wc -c < Makefile`"
- if test 1784 -ne "$size" ; then
- echo "Makefile: extraction error - got $size chars"
- fi
- fi
- echo "done - 4 files extracted"
- exit 0
- --
- Chip Rosenthal <chip@chinacat.Unicom.COM> | Don't play that
- Unicom Systems Development 512-482-8260 | loud, Mr. Collins.
-