finger

a simple finger client
Log | Files | Refs

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 }