#include #include #include /* for getservbyname */ #include #include #include #include char *progname; int s; /* file descriptor */ void death_of_child(int sig); int main(int argc, char **argv) { struct sockaddr_in address; char buffer[INET_ADDRSTRLEN]; /* for inet_pton */ struct hostent *entry; /* for gethostbyname, gethostbyaddr */ pid_t pid; int c; progname = argv[0]; bzero((char *)&address, sizeof address); address.sin_family = AF_INET; if (argc == 2) { /* one command line argument */ const struct servent *const p = getservbyname("telnet", "tcp"); if (p == NULL) { fprintf(stderr, "%s: couldn't find telnet port number\n", progname); return 1; } address.sin_port = p->s_port; } else if (argc == 3) { /* two command line arguments */ if (sscanf(argv[2], "%hd", &address.sin_port) != 1) { fprintf(stderr, "%s: %s is not a legal port number\n", progname, argv[2]); return 2; } address.sin_port = htons(address.sin_port); } else { fprintf(stderr, "%s: usage hostname [port]\n", progname); return 3; } entry = gethostbyname(argv[1]); if (entry == NULL) { fprintf(stderr, "%s: gethostbyname, h_errno == %d\n", progname, h_errno); return 4; } address.sin_addr.s_addr = *(in_addr_t *)entry->h_addr_list[0]; s = socket(AF_INET, SOCK_STREAM, 0); if (s < 0) { perror(progname); return 5; } if (inet_ntop(AF_INET, &address.sin_addr, buffer, sizeof buffer) == NULL) { perror(progname); return 6; } printf("Trying %s...\n", buffer); if (connect(s, (struct sockaddr *)&address, sizeof address) != 0) { perror(progname); return 7; } entry = gethostbyaddr((char *)&address.sin_addr, sizeof address.sin_addr, AF_INET); if (entry == NULL) { fprintf(stderr, "%s: gethostbyaddr, h_errno == %d\n", progname, h_errno); return 8; } printf("Connected to %s.\n", entry->h_name); if (signal(SIGCHLD, death_of_child) == SIG_ERR) { perror(progname); return 9; } pid = fork(); if (pid < 0) { perror(progname); return 10; } if (pid == 0) { /* Arrive here if I am the child. Copy from the server to the stdout. */ char c; while (read(s, &c, 1) == 1) { putchar(c); } return EXIT_SUCCESS; } /* Arrive here if I am the parent. Copy from the stdin to the server. */ while((c = getchar()) != EOF) { char ch = c; if (write(s, &ch, 1) != 1) { perror(progname); return 11; } } if (shutdown(s, SHUT_RDWR) != 0) { perror(progname); return 12; } printf("Connection closed.\n"); return EXIT_SUCCESS; } void death_of_child(int sig) { int status; if (wait(&status) < 0) { perror(progname); exit(13); } if (!WIFEXITED(status) || WEXITSTATUS(status) != EXIT_SUCCESS) { fprintf(stderr, "%s: child did not return exit status %d.\n", progname, EXIT_SUCCESS); } if (shutdown(s, SHUT_RDWR) != 0) { perror(progname); exit(14); } printf("Connection closed by foreign host.\n"); exit(EXIT_SUCCESS); }