#include #include #include /* for getservbyname */ #include #include #include int main(int argc, char **argv) { int s; /* file descriptor */ struct sockaddr_in address; char buffer[INET_ADDRSTRLEN]; /* for inet_pton */ struct hostent *entry; /* for gethostbyname, gethostbyaddr */ pid_t pid; int c; /* return value of getchar is int, not char */ int status; 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", argv[0]); return 1; } address.sin_port = p->s_port; /* doesn't need htons */ } else if (argc == 3) { /* two command line arguments */ /* %hd for "short decimal": a port number is 16 bits */ if (sscanf(argv[2], "%hd", &address.sin_port) != 1) { fprintf(stderr, "%s: %s is not a legal port number\n", argv[0], argv[2]); return 2; } address.sin_port = htons(address.sin_port); } else { fprintf(stderr, "%s: usage hostname [port]\n", argv[0]); return 3; } entry = gethostbyname(argv[1]); if (entry == NULL) { fprintf(stderr, "%s: gethostbyname, h_errno == %d\n", argv[0], 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(argv[0]); return 5; } if (inet_ntop(AF_INET, &address.sin_addr, buffer, sizeof buffer) == NULL) { perror(argv[0]); return 6; } printf("Trying %s...\n", buffer); if (connect(s, (struct sockaddr *)&address, sizeof address) != 0) { perror(argv[0]); 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", argv[0], h_errno); return 8; } printf("Connected to %s.\n", entry->h_name); pid = fork(); if (pid < 0) { perror(argv[0]); return 9; } if (pid == 0) { /* Arrive here if I am the child. Copy from the server to the stdout. */ char c; int n; while ((n = read(s, &c, 1)) == 1) { putchar(c); } if (n < 0) { perror(argv[0]); return 1; } 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(argv[0]); return 10; } } if (shutdown(s, SHUT_RDWR) != 0) { perror(argv[0]); return 11; } pid = wait(&status); if (!WIFEXITED(status) || WEXITSTATUS(status) != EXIT_SUCCESS) { fprintf(stderr, "%s: child did not return exit status 0.\n", argv[0]); return 12; } return EXIT_SUCCESS; }