commit faa4cbb0fdae435112893c37c78156e1f65504f3
Author: Naveen Narayanan <zerous@nocebo.space>
Date: Fri, 24 Sep 2021 21:28:30 +0200
Implement finger client
Diffstat:
A | finger.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;
+}