V10/cmd/dist/sgi/connect.c

Compare this file to the similar file:
Show the results in this format:

/* usage: connect hostname (answer|send|notice) (in|out) program [ args ... ] */
/* TODO: should librarify the bit for opening an rsh-authenticated connection.  */

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <pwd.h>
#include <stdio.h>
#include <string.h>
#include "../paths.h"

int
main(int argc, char *argv[])
{
	int fd;
	struct hostent *host;
	struct servent *serv;
	struct passwd *pw;
	int lport;
	struct sockaddr_in sin;
	char byte;

	if (argc < 5)
		exit(1);

	host = gethostbyname(argv[1]);
	if (!host) {
		fprintf(stderr, "connect: can't get host '%s'\n", argv[1]);
		exit(1);
	}

	serv = getservbyname("dist", "tcp");
	if (!serv) {
		fprintf(stderr, "connect: can't get 'dist' port number\n");
		exit(1);
	}

	pw = getpwuid(getuid());	/* we assume unique uid/name map */
	if (!pw) {
		fprintf(stderr, "connect: can't get user name\n");
		exit(1);
	}

	chdir(SDIR);

	lport = 1023;
	fd = rresvport(&lport);
	if (fd < 0) {
		perror("connect: getting socket");
		exit(1);
	}

	sin.sin_family = host->h_addrtype;
	memcpy(&sin.sin_addr, host->h_addr, host->h_length);
	sin.sin_port = serv->s_port;
	if (connect(fd, &sin, sizeof sin) < 0) {
		perror("connect: opening connection");
		exit(1);
	}

	write(fd, "", 1);	/* a NUL byte */
	write(fd, pw->pw_name, strlen(pw->pw_name) + 1);
	write(fd, pw->pw_name, strlen(pw->pw_name) + 1);
	if (read(fd, &byte, 1) != 1 || byte != '\0') {
		fprintf(stderr, "connect: rsh authentication failed\n");
		exit(1);
	}

	write(fd, argv[2], strlen(argv[2]) + 1);

	if (strchr(argv[3], 'i'))
		dup2(fd, 0);
	if (strchr(argv[3], 'o'))
		dup2(fd, 1);
	close(fd);
	execv(argv[4], &argv[4]);
}