|
|
researchv10 Norman
/* 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]);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.