finger

a simple finger client
Log | Files | Refs

commit faa4cbb0fdae435112893c37c78156e1f65504f3
Author: Naveen Narayanan <zerous@nocebo.space>
Date:   Fri, 24 Sep 2021 21:28:30 +0200

Implement finger client

Diffstat:
Afinger.c | 124+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 124 insertions(+), 0 deletions(-)

diff --git a/finger.c b/finger.c @@ -0,0 +1,124 @@ +#include <arpa/inet.h> +#include <netinet/in.h> +#include <sys/param.h> +#include <sys/socket.h> +#include <sys/types.h> + +#include <errno.h> +#include <netdb.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#define BUFSZ 128 + +void +usage(void) +{ + printf("usage: finger user@host\n"); + exit(1); +} + +int +cred(char *u, char *h, char *s) +{ + char *a; + + if (!(a = strchr(s, '@'))) { + fprintf(stderr, "hostname not found\n"); + return 0; + } + + if (a - s >= 32) { + fprintf(stderr, "username too long\n"); + return 1; + } + memcpy(u, s, a - s); + + if (strlen(a+1) > MAXHOSTNAMELEN) { + fprintf(stderr, "hostname too long\n"); + return 0; + } + strcpy(h, a+1); + + return 1; +} + +int +main(int argc, char **argv) +{ + struct addrinfo hints, *res, *p; + char user[32], hostname[MAXHOSTNAMELEN+1]; + char *msg; + int status, sockfd, byt, len, err; + + err = 0; + + if (argc != 2) + usage(); + + if (!cred(user, hostname, argv[argc-1])) + usage(); + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + if ((status = getaddrinfo(hostname, "79", &hints, &res)) != 0) { + fprintf(stderr, "getaddrinfo failed: %s\n", gai_strerror(status)); + err = 1; + goto err1; + } + + for (p = res; p != NULL; p = p->ai_next) { + sockfd = socket(res->ai_family, res->ai_socktype, + res->ai_protocol); + if (sockfd == -1) { + fprintf(stderr, "socket failed: %s\n", + strerror(errno)); + err = 1; + goto err2; + } + + if (connect(sockfd, res->ai_addr, res->ai_addrlen) == -1) { + fprintf(stderr, "connect failed: %s\n", + strerror(errno)); + err = 1; + goto err3; + } + + len = strlen(user); + msg = malloc(BUFSZ); + if (!msg) { + err = 1; + goto err3; + } + memset(msg, 0, BUFSZ); + memcpy(msg, user, len); + msg[len] = '\r'; + msg[len+1] = '\n'; + + byt = send(sockfd, msg, len+2, 0); + if (byt == -1) { + fprintf(stderr, "send failed: %s\n", strerror(errno)); + err = 1; + goto err4; + } + + do { + byt = recv(sockfd, msg, BUFSZ, 0); + for (int i = 0; i < byt; ++i) + putchar(msg[i]); + } while (byt > 0); + } + +err4: + free(msg); +err3: + close(sockfd); +err2: + freeaddrinfo(res); +err1: + return err == 1 ? 2 : 0; +}