1074da446be7839a9f40f2d21419504286f69140
[fio.git] / client.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <limits.h>
5 #include <errno.h>
6 #include <fcntl.h>
7 #include <sys/poll.h>
8 #include <sys/types.h>
9 #include <sys/stat.h>
10 #include <sys/wait.h>
11 #include <sys/mman.h>
12 #include <netinet/in.h>
13 #include <arpa/inet.h>
14 #include <netdb.h>
15
16 #include "fio.h"
17 #include "server.h"
18 #include "crc/crc32.h"
19
20 int fio_client_fd = -1;
21
22 int fio_client_connect(const char *host)
23 {
24         struct sockaddr_in addr;
25         int fd;
26
27         memset(&addr, 0, sizeof(addr));
28         addr.sin_family = AF_INET;
29         addr.sin_port = htons(fio_net_port);
30
31         if (inet_aton(host, &addr.sin_addr) != 1) {
32                 struct hostent *hent;
33
34                 hent = gethostbyname(host);
35                 if (!hent) {
36                         log_err("fio: gethostbyname: %s\n", strerror(errno));
37                         return 1;
38                 }
39
40                 memcpy(&addr.sin_addr, hent->h_addr, 4);
41         }
42
43         fd = socket(AF_INET, SOCK_STREAM, 0);
44         if (fd < 0) {
45                 log_err("fio: socket: %s\n", strerror(errno));
46                 return 1;
47         }
48
49         if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
50                 log_err("fio: connect: %s\n", strerror(errno));
51                 return 1;
52         }
53
54         fio_client_fd = fd;
55         return 0;
56 }
57
58 static int send_file_buf(char *buf, off_t size)
59 {
60         return fio_net_send_cmd(fio_client_fd, FIO_NET_CMD_JOB, buf, size);
61 }
62
63 /*
64  * Send file contents to server backend. We could use sendfile(), but to remain
65  * more portable lets just read/write the darn thing.
66  */
67 int fio_client_send_ini(const char *filename)
68 {
69         struct stat sb;
70         char *p, *buf;
71         off_t len;
72         int fd, ret;
73
74         fd = open(filename, O_RDONLY);
75         if (fd < 0) {
76                 log_err("fio: job file open: %s\n", strerror(errno));
77                 return 1;
78         }
79
80         if (fstat(fd, &sb) < 0) {
81                 log_err("fio: job file stat: %s\n", strerror(errno));
82                 return 1;
83         }
84
85         buf = malloc(sb.st_size);
86
87         len = sb.st_size;
88         p = buf;
89         do {
90                 ret = read(fd, p, len);
91                 if (ret > 0) {
92                         len -= ret;
93                         if (!len)
94                                 break;
95                         p += ret;
96                         continue;
97                 } else if (!ret)
98                         break;
99                 else if (errno == EAGAIN || errno == EINTR)
100                         continue;
101         } while (1);
102
103         ret = send_file_buf(buf, sb.st_size);
104         free(buf);
105         return ret;
106 }
107
108 int fio_handle_clients(void)
109 {
110         struct fio_net_cmd *cmd;
111
112         while (!exit_backend) {
113                 cmd = fio_net_cmd_read(fio_client_fd);
114                 if (!cmd)
115                         continue;
116
117                 if (cmd->opcode == FIO_NET_CMD_ACK) {
118                         free(cmd);
119                         continue;
120                 }
121                 if (cmd->opcode == FIO_NET_CMD_QUIT) {
122                         free(cmd);
123                         break;
124                 }
125                 if (cmd->opcode != FIO_NET_CMD_TEXT) {
126                         printf("non text: %d\n", cmd->opcode);
127                         free(cmd);
128                         continue;
129                 }
130                 fwrite(cmd->payload, cmd->pdu_len, 1, stdout);
131                 fflush(stdout);
132                 free(cmd);
133         }
134
135         return 0;
136 }