rs@mirror.UUCP (10/28/85)
This sharfile contains a client and server for "whois." The server does little more than just pass off the request to the "finger" program, but that's enough. The client is a from-scratch writing of whois. It replaced the standard "whois" because (a) we're not on ARPA (sri-nic is useless to us) and (b) I wanted to be able to say "whois rs@mirror" and have it work. Please MAIL me any bugs or problems you find... /r$ # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # # Wrapped by mirror!rs on Mon Oct 28 14:51:51 EST 1985 # Contents: whois.c whoisd.c echo x - whois.c sed 's/^XX//' > "whois.c" <<'@//E*O*F whois.c//' XX#include <stdio.h> XX#include <netdb.h> XX#include <sys/types.h> XX#include <sys/socket.h> XX#include <netinet/in.h> XX/* Handy shorthands. */ XX#define SOCK(Socket) (struct sockaddr *)&(Socket) XX#define DIE(s) perror(s), exit(1) XX/* Get the default host to connect to; you may want to change this. */ XX#define DEFAULT (gethostname(Name, sizeof Name) < 0 ? "sri-nic" : Name) XX/* Global variables. */ XXchar *Who = ""; XXchar *Where; XXchar Name[32]; XXstruct sockaddr_in Socket; XXstruct hostent *Host; XXstruct servent *Service; XX/* Linked in later. */ XXextern char *index(); XXmain(ac, av) XX int ac; XX char *av[]; XX{ XX register FILE *Stream; XX register char *p; XX register int c; XX register int s; XX /* Parse JCL. */ XX Where = DEFAULT; XX switch (ac) XX { XX default: XXBad: XX fprintf(stderr, "usage:\t%s [-h host] user\nor\t%s [user][@host]\n", XX av[0], av[0]); XX exit(1); XX case 1: XX /* default to "@DEFAULT-HOST" */ XX break; XX case 2: XX /* "user@host" "@host" "user" */ XX Who = av[1]; XX if (p = index(av[1], '@')) XX { XX *p++ = '\0'; XX Where = p; XX } XX break; XX case 4: XX if (strcmp(av[1], "-h")) XX goto Bad; XX /* "-h host user" */ XX Where = av[2]; XX Who = av[3]; XX } XX /* Try to get host and the service. */ XX Host = gethostbyname(Where); XX if (Host == NULL) XX { XX fprintf(stderr, "whois: %s: host unknown\n", Where); XX exit(1); XX } XX if ((Service = getservbyname("whois", "tcp")) == NULL) XX DIE("whois (whois/tcp unknown service)"); XX /* Creation and bondage (kinky sex?). */ XX if ((s = socket(Host->h_addrtype, SOCK_STREAM, 0)) < 0) XX DIE("whois (socket)"); XX Socket.sin_family = Host->h_addrtype; XX if (bind(s, SOCK(Socket), sizeof Socket) < 0) XX DIE("whois (bind)"); XX /* Connect to the server at the right port. */ XX bcopy(Host->h_addr, (char *)&Socket.sin_addr, Host->h_length); XX Socket.sin_port = Service->s_port; XX if (connect(s, SOCK(Socket), sizeof Socket) < 0) XX DIE("whois (connect)"); XX /* Send out the request. */ XX if ((Stream = fdopen(s, "w")) == NULL) XX DIE("whois (fdopen to service)"); XX fprintf(Stream, "%s\r\n", Who); XX (void)fflush(Stream); XX /* Get the response. */ XX if ((Stream = fdopen(s, "r")) == NULL) XX DIE("whois (fdopen from service)"); XX while ((c = getc(Stream)) != EOF) XX (void)putchar(c); XX (void)fclose(Stream); XX exit(0); XX} @//E*O*F whois.c// chmod u=rw,g=rw,o=rw whois.c echo x - whoisd.c sed 's/^XX//' > "whoisd.c" <<'@//E*O*F whoisd.c//' XX/* XX** A "Whois" server, TCP Port 43 (RFC 812) XX** XX** Copyright, 1985, Richard E. $alz. Permission is granted to the public XX** to copy and use this software without charge, provided that this notice XX** and any statement of authorship are reproduced on all copies. The author XX** makes no warranty expressed or implied, nor assumes any liability or XX** responsibility for the use of this software. XX*/ XX#include <stdio.h> XX#include <netdb.h> XX#include <sys/types.h> XX#include <sys/ioctl.h> XX#include <sys/socket.h> XX#include <net/if.h> XX#include <netinet/in.h> XX#include <signal.h> XX#include <errno.h> XX#include <sys/wait.h> XX#include <sys/time.h> XX#include <sys/resource.h> XX/* Handy shorthands. */ XX#define SIZE 256 /* This is reasonable */ XX#define SOCK(Socket) (struct sockaddr *)&(Socket) /* For lint */ XX#define DIE(s) perror(s), exit(1); /* Say bye-bye */ XX/* Global variables. */ XXstruct hostent *Host; XXstruct servent *Service; XXstruct sockaddr_in Socket = { AF_INET }; XXint Size; XXchar Buff[SIZE]; XXchar Command[SIZE]; XXchar LOSE_MSG[] = "Sorry; can't\n"; XX/* Linked in later. */ XXextern int errno; XXextern FILE *popen(); XXextern char *strcpy(); XXextern char *strcat(); XXWait() XX{ XX union wait Status; XX while (wait3(&Status, WNOHANG, (struct rusage *)NULL) > 0) XX ; XX} XXmain() XX{ XX register FILE *Stream; XX register int In; XX register int Client; XX register int i; XX /* Who are we? */ XX if (getuid()) XX DIE("whoisd (not super user)"); XX /* Where are we? */ XX if (gethostname(Buff, sizeof Buff) < 0) XX DIE("whoisd (gethostname)"); XX if ((Host = gethostbyname(Buff)) == NULL) XX DIE("whoisd (gethostbyname)"); XX /* What are we trying to do? */ XX if ((Service = getservbyname("whois", "tcp")) == NULL) XX DIE("whoisd (tcp/whois unknown service)"); XX#ifndef DEBUG XX if (fork()) XX exit(0); XX /* Open up the console for error logging, but ignore signals XX that come from it. */ XX (void)freopen("/dev/console", "w", stderr); XX if ((i = open("/dev/tty", 2)) >= 0) XX { XX (void)ioctl(i, TIOCNOTTY, 0); XX (void)close(i); XX } XX (void)close(0); XX (void)close(1); XX#endif DEBUG XX /* Creation and bondage (my, how kinky). */ XX Socket.sin_family = Host->h_addrtype; XX Socket.sin_port = Service->s_port; XX bcopy(Host->h_addr, (char *)&Socket.sin_addr, Host->h_length); XX if ((In = socket(AF_INET, SOCK_STREAM, 0)) < 0) XX DIE("whoisd (socket)"); XX if (bind(In, SOCK(Socket), sizeof Socket) < 0) XX DIE("whoisd (bind)"); XX if (listen(In, 5) < 0) XX DIE("whoisd (listen)"); XX (void)signal(SIGCHLD, Wait); XX /* Service loop. */ XX for ( ; ; ) XX { XX /* Wait for something to come in. */ XX Size = sizeof Socket; XX if ((Client = accept(In, SOCK(Socket), &Size)) < 0) XX { XX if (errno != EINTR) XX perror("whoisd (accept)"); XX (void)sleep(1); XX continue; XX } XX /* Spawn off a kid to handle it. Should check for fork failure... */ XX if (fork()) XX { XX (void)close(Client); XX continue; XX } XX /* Shut down stuff the kid doesn't need, read the request. */ XX (void)signal(SIGCHLD, SIG_IGN); XX if ((i = read(Client, Buff, sizeof Buff)) < 0) XX DIE("whoisd (read)"); XX /* Cons up the command line. */ XX (void)strcpy(Command, "/usr/ucb/finger"); XX if (i) XX { XX /* Strip off the \r\n, append the argument. */ XX Buff[i - 2] = '\0'; XX (void)strcat(Command, " "); XX (void)strcat(Command, Buff); XX } XX if ((Stream = popen(Command, "r")) == NULL) XX { XX perror("whoisd (popen)"); XX (void)write(Client, LOSE_MSG, sizeof LOSE_MSG - 1); XX } XX else XX { XX register FILE *Reply; XX Reply = fdopen(Client, "w"); XX while (fgets(Buff, sizeof Buff, Stream)) XX fprintf(Reply, "%s", Buff); XX (void)fflush(Reply); XX if (pclose(Stream) == EOF) XX perror("whoisd (fclose)"); XX } XX if (close(Client) < 0) XX DIE("whoisd (close)"); XX exit(0); XX } XX} @//E*O*F whoisd.c// chmod u=rw,g=rw,o=rw whoisd.c exit 0 -- Rich $alz {mit-eddie, ihnp4!inmet, wjh12, cca, datacube} !mirror!rs Mirror Systems 2067 Massachusetts Ave. 617-661-0777 Cambridge, MA, 02140