finger.c (2253B)
1 #include <sys/param.h> 2 #include <sys/socket.h> 3 4 #include <errno.h> 5 #include <netdb.h> 6 #include <stdio.h> 7 #include <stdlib.h> 8 #include <string.h> 9 #include <unistd.h> 10 11 #define BUFSZ 128 12 13 void 14 usage(void) 15 { 16 printf("usage: finger user@host\n"); 17 exit(1); 18 } 19 20 int 21 cred(char *input, char *username, char *hostname) 22 { 23 char *a; 24 25 if (!(a = strchr(input, '@'))) { 26 fprintf(stderr, "hostname not found\n"); 27 return 0; 28 } 29 if (a - input >= 32) { 30 fprintf(stderr, "username too long\n"); 31 return 0; 32 } 33 memcpy(username, input, a - input); 34 if (strlen(a+1) > MAXHOSTNAMELEN) { 35 fprintf(stderr, "hostname too long\n"); 36 return 0; 37 } 38 strcpy(hostname, a+1); 39 return 1; 40 } 41 42 int 43 main(int argc, char **argv) 44 { 45 struct addrinfo hints = { 0 }; 46 struct addrinfo *res, *p; 47 char buf[BUFSZ], hostname[MAXHOSTNAMELEN+1], user[32]; 48 char *msg; 49 ssize_t n; 50 int status, sockfd, ulen, len, err; 51 52 err = 0; 53 msg = buf; 54 55 if (argc != 2) 56 usage(); 57 if (!cred(argv[1], user, hostname)) 58 usage(); 59 hints.ai_family = AF_UNSPEC; 60 hints.ai_socktype = SOCK_STREAM; 61 if ((status = getaddrinfo(hostname, "finger", &hints, &res)) != 0) { 62 fprintf(stderr, "getaddrinfo failed: %s\n", gai_strerror(status)); 63 err = 1; 64 goto err1; 65 } 66 ulen = strlen(user); 67 for (p = res; p != NULL; p = p->ai_next) { 68 sockfd = socket(res->ai_family, res->ai_socktype, 69 res->ai_protocol); 70 if (sockfd == -1) { 71 fprintf(stderr, "socket failed: %s\n", 72 strerror(errno)); 73 err = 1; 74 goto err2; 75 } 76 if (connect(sockfd, res->ai_addr, res->ai_addrlen) == -1) { 77 fprintf(stderr, "connect failed: %s\n", 78 strerror(errno)); 79 err = 1; 80 goto err3; 81 } 82 memcpy(msg, user, ulen); 83 msg[ulen] = '\r'; 84 msg[ulen+1] = '\n'; 85 len = ulen+2; 86 do { 87 n = send(sockfd, msg, len, 0); 88 if (n == -1) { 89 fprintf(stderr, "send failed: %s\n", strerror(errno)); 90 err = 1; 91 goto err3; 92 } 93 len -= n; 94 msg += n; 95 } while (len > 0); 96 msg = buf; 97 printf("[%s]\n", hostname); 98 do { 99 n = recv(sockfd, msg, BUFSZ, 0); 100 if (n == -1) { 101 fprintf(stderr, "recv failed: %s\n", 102 strerror(errno)); 103 goto err3; 104 } 105 106 while (msg - buf < n) 107 putchar(*msg++); 108 msg = buf; 109 } while (n > 0); 110 } 111 err3: 112 close(sockfd); 113 err2: 114 freeaddrinfo(res); 115 err1: 116 return err == 1 ? 2 : 0; 117 }