blob: e6e9a2e0124b0f5a10a89faed6341249260b3ef6 [file] [log] [blame]
Etan Cohen7ef855e2014-08-20 10:11:11 -07001/* This is a simple TCP client that connects to port 1234 and prints a list
2 * of files in a given directory.
3 *
4 * It directly deserializes and serializes messages from network, minimizing
5 * memory use.
6 *
7 * For flexibility, this example is implemented using posix api.
8 * In a real embedded system you would typically use some other kind of
9 * a communication and filesystem layer.
10 */
11
12#include <sys/socket.h>
13#include <sys/types.h>
14#include <netinet/in.h>
15#include <unistd.h>
16#include <dirent.h>
17#include <stdio.h>
18#include <string.h>
19
20#include <pb_encode.h>
21#include <pb_decode.h>
22
23#include "fileproto.pb.h"
24#include "common.h"
25
26bool printfile_callback(pb_istream_t *stream, const pb_field_t *field, void **arg)
27{
28 FileInfo fileinfo;
29
30 if (!pb_decode(stream, FileInfo_fields, &fileinfo))
31 return false;
32
33 printf("%-10lld %s\n", (long long)fileinfo.inode, fileinfo.name);
34
35 return true;
36}
37
38bool listdir(int fd, char *path)
39{
40 ListFilesRequest request;
41 ListFilesResponse response;
42 pb_istream_t input = pb_istream_from_socket(fd);
43 pb_ostream_t output = pb_ostream_from_socket(fd);
44 uint8_t zero = 0;
45
46 if (path == NULL)
47 {
48 request.has_path = false;
49 }
50 else
51 {
52 request.has_path = true;
53 if (strlen(path) + 1 > sizeof(request.path))
54 {
55 fprintf(stderr, "Too long path.\n");
56 return false;
57 }
58
59 strcpy(request.path, path);
60 }
61
62 if (!pb_encode(&output, ListFilesRequest_fields, &request))
63 {
64 fprintf(stderr, "Encoding failed.\n");
65 return false;
66 }
67
68 /* We signal the end of request with a 0 tag. */
69 pb_write(&output, &zero, 1);
70
71 response.file.funcs.decode = &printfile_callback;
72
73 if (!pb_decode(&input, ListFilesResponse_fields, &response))
74 {
75 fprintf(stderr, "Decode failed: %s\n", PB_GET_ERROR(&input));
76 return false;
77 }
78
79 if (response.path_error)
80 {
81 fprintf(stderr, "Server reported error.\n");
82 return false;
83 }
84
85 return true;
86}
87
88int main(int argc, char **argv)
89{
90 int sockfd;
91 struct sockaddr_in servaddr;
92 char *path = NULL;
93
94 if (argc > 1)
95 path = argv[1];
96
97 sockfd = socket(AF_INET, SOCK_STREAM, 0);
98
99 memset(&servaddr, 0, sizeof(servaddr));
100 servaddr.sin_family = AF_INET;
101 servaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
102 servaddr.sin_port = htons(1234);
103
104 if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0)
105 {
106 perror("connect");
107 return 1;
108 }
109
110 if (!listdir(sockfd, path))
111 return 2;
112
113 close(sockfd);
114
115 return 0;
116}