uni

University stuff
git clone git://git.margiolis.net/uni.git
Log | Files | Refs | README | LICENSE

ex3_client.c (3472B)


      1 #include <sys/socket.h>
      2 #include <sys/types.h>
      3 #include <sys/un.h>
      4 
      5 #include <arpa/inet.h>
      6 #include <netdb.h>
      7 #include <netinet/in.h>
      8 
      9 #include <err.h>
     10 #include <stdio.h>
     11 #include <stdlib.h>
     12 #include <string.h>
     13 #include <unistd.h>
     14 
     15 /*
     16  * Εργαστήριο ΛΣ2 (Δ6) / Εργασία 2: Άσκηση 3 (client) / 2020-2021
     17  * Ονοματεπώνυμο: Χρήστος Μαργιώλης
     18  * ΑΜ: 19390133
     19  * Τρόπος μεταγλώττισης: `cc ex3_client.c -o ex3_client`
     20  */
     21 
     22 /* Results from server. */
     23 struct pack_res {
     24 	char str[32];
     25 	float avg;
     26 };
     27 
     28 static void *emalloc(size_t nb);
     29 static void usage(void);
     30 
     31 static char *argv0;
     32 
     33 static void *
     34 emalloc(size_t nb)
     35 {
     36 	void *p;
     37 
     38 	if ((p = malloc(nb)) == NULL)
     39 		err(1, "malloc");
     40 
     41 	return p;
     42 }
     43 
     44 static void
     45 usage(void)
     46 {
     47 	fprintf(stderr, "usage: %1$s [-s sockfile]\n"
     48 	    "       %1$s -i [-p port] [-s sockfile] hostname\n"
     49 	    "       %1$s -i [-p port] [-s sockfile] ipv4_addr\n", argv0);
     50 	exit(1);
     51 }
     52 
     53 /* Code shared with `ex3_server` is explained in `ex3_server.c`. */
     54 int
     55 main(int argc, char *argv[])
     56 {
     57 	struct pack_res *res;
     58 	struct sockaddr_un sun;
     59 	struct sockaddr_in sin;
     60 	struct hostent *hp;
     61 	char *sockfile = "/tmp/cool.sock";
     62 	int *arr;
     63 	int fd, i, n, rc;
     64 	int port = 9999;
     65 	int iflag, uflag;
     66 	char ch;
     67 
     68 	argv0 = *argv;
     69 	uflag = 1;
     70 	iflag = 0;
     71 
     72 	while ((ch = getopt(argc, argv, "ip:s:")) != -1) {
     73 		switch (ch) {
     74 		case 'i':
     75 			iflag = 1;
     76 			uflag = 0;
     77 			break;
     78 		case 'p':
     79 			if ((port = atoi(optarg)) < 1024)
     80 				errx(1, "can't use port number < 1024");
     81 			break;
     82 		case 's':
     83 			sockfile = optarg;
     84 			break;
     85 		case '?':
     86 		default:
     87 			usage();
     88 		}
     89 	}
     90 	argc -= optind;
     91 	argv += optind;
     92 
     93 	if (iflag && argc < 1)
     94 		usage();
     95 
     96 	if (iflag) {
     97 		if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
     98 			err(1, "socket(AF_INET)");
     99 		(void)memset(&sin, 0, sizeof(sin));
    100 		sin.sin_family = AF_INET;
    101 		sin.sin_port = htons(port);
    102 		if (!inet_aton(*argv, &sin.sin_addr)) {
    103 			if ((hp = gethostbyname(*argv)) == NULL)
    104 				errx(1, "gethostbyname(%s) failed", *argv);
    105 			(void)memcpy(&sin.sin_addr, hp->h_addr, hp->h_length);
    106 		}
    107 		if (connect(fd, (struct sockaddr *)&sin, sizeof(sin)) < 0)
    108 			err(1, "connect");
    109 	} else if (uflag) {
    110 		if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
    111 			err(1, "socket(AF_UNIX)");
    112 		(void)memset(&sun, 0, sizeof(sun));
    113 		sun.sun_family = AF_UNIX;
    114 		(void)strncpy(sun.sun_path, sockfile, sizeof(sun.sun_path) - 1);
    115 		
    116 		if (connect(fd, (struct sockaddr *)&sun, sizeof(sun)) < 0)
    117 			err(1, "connect");
    118 	}
    119 
    120 	res = emalloc(sizeof(struct pack_res));
    121 
    122 	for (;;) {
    123 		/* Remove any previous junk. */
    124 		(void)memset(res, 0, sizeof(struct pack_res));
    125 
    126 		/* Make sure we send valid input to the server */
    127 		do {
    128 			printf("\r%s> n: ", argv0);
    129 			rc = scanf("%d", &n);
    130 			(void)getchar();
    131 		} while (rc != 1);
    132 		arr = emalloc(n * sizeof(int));
    133 		for (i = 0; i < n; i++) {
    134 			do {
    135 				printf("\r%s> arr[%d]: ", argv0, i);
    136 				rc = scanf("%d", &arr[i]);
    137 				(void)getchar();
    138 			} while (rc != 1);
    139 		}
    140 		if (send(fd, &n, sizeof(int), 0) < 0)
    141 			err(1, "send");
    142 		if (send(fd, arr, n * sizeof(int), 0) < 0)
    143 			err(1, "send");
    144 		if (recv(fd, res, sizeof(struct pack_res), 0) < 0)
    145 			err(1, "recv");
    146 		free(arr);
    147 
    148 		printf("server response: %s\tavg: %.2f\n", res->str, res->avg);
    149 		do
    150 			printf("\r%s> continue (y/n)? ", argv0);
    151 		while ((ch = getchar()) != 'y' && ch != 'n');
    152 		if (send(fd, &ch, 1, 0) < 0)
    153 			err(1, "send");
    154 		if (ch == 'n')
    155 			break;
    156 	}
    157 	free(res);
    158 	(void)close(fd);
    159 
    160 	return 0;
    161 }