let's make server work out of the box if u set:
[profile/ivi/evas.git] / src / bin / evas_cserve2_client.c
1 #include "config.h"
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <errno.h>
6 #include <string.h>
7 #include <sys/types.h>
8 #include <sys/socket.h>
9 #include <sys/un.h>
10 #include <unistd.h>
11
12 #include "evas_cserve2.h"
13
14 static const char *SOCK_PATH = "/tmp/cserve2.socket";
15 static unsigned int _rid_count = 0;
16
17 static struct sockaddr_un socket_local;
18 #ifndef UNIX_PATH_MAX
19 #define UNIX_PATH_MAX sizeof(socket_local.sun_path)
20 #endif
21
22 static void
23 debug_msg(const void *buf, int size)
24 {
25     const char *str = buf;
26     int i;
27
28     printf("message: ");
29     for (i = 0; i < size; i++)
30       printf("%x ", str[i]);
31
32     printf("\n");
33 }
34
35 static int
36 _read_line(char *buf, int size)
37 {
38    int len;
39    char *c;
40
41    fgets(buf, size, stdin);
42    c = strchr(buf, '#');
43    if (c)
44      *c = '\0';
45    else
46      {
47         c = strchr(buf, '\n');
48         if (c)
49           *c = '\0';
50      }
51    len = strlen(buf);
52
53    return len + 1;
54 }
55
56 static void *
57 parse_input_open(int *size)
58 {
59    char path[4096];
60    char key[4096];
61    char line[4096];
62    int path_len, key_len;
63    Msg_Open msg;
64    char *buf;
65    int file_id;
66
67    _read_line(line, sizeof(line));
68    path_len = _read_line(path, sizeof(path));
69    key_len = _read_line(key, sizeof(key));
70
71    sscanf(line, "%d", &file_id);
72
73    buf = malloc(sizeof(msg) + path_len + key_len);
74
75    msg.base.rid = _rid_count++;
76    msg.base.type = CSERVE2_OPEN;
77    msg.file_id = file_id;
78    msg.path_offset = 0;
79    msg.key_offset = path_len;
80
81    memcpy(buf, &msg, sizeof(msg));
82    memcpy(buf + sizeof(msg), path, path_len);
83    memcpy(buf + sizeof(msg) + path_len, key, key_len);
84
85    *size = sizeof(msg) + path_len + key_len;
86
87    return buf;
88 }
89
90 static void *
91 parse_input_setopts(int *size)
92 {
93    Msg_Setopts *msg;
94    char line[4096];
95    int file_id, image_id;
96    double dpi;
97    int w, h;
98    int scale;
99    int rx, ry, rw, rh;
100    int orientation;
101
102    // reading file_id, image_id
103    _read_line(line, sizeof(line));
104    sscanf(line, "%d %d", &file_id, &image_id);
105
106    // reading load dpi
107    _read_line(line, sizeof(line));
108    dpi = atof(line);
109
110    // reading load size
111    _read_line(line, sizeof(line));
112    sscanf(line, "%d %d", &w, &h);
113
114    // reading load scale down
115    _read_line(line, sizeof(line));
116    sscanf(line, "%d", &scale);
117
118    // reading load region
119    _read_line(line, sizeof(line));
120    sscanf(line, "%d %d %d %d", &rx, &ry, &rw, &rh);
121
122    // reading orientation
123    _read_line(line, sizeof(line));
124    sscanf(line, "%d", &orientation);
125
126
127    msg = calloc(1, sizeof(*msg));
128
129    msg->base.rid = _rid_count++;
130    msg->base.type = CSERVE2_SETOPTS;
131    msg->file_id = file_id;
132    msg->image_id = image_id;
133    msg->opts.dpi = dpi;
134    msg->opts.w = w;
135    msg->opts.h = h;
136    msg->opts.scale_down = scale;
137    msg->opts.rx = rx;
138    msg->opts.ry = ry;
139    msg->opts.rw = rw;
140    msg->opts.rh = rh;
141    msg->opts.orientation = !!orientation;
142
143    *size = sizeof(*msg);
144
145    return msg;
146 }
147
148 static void *
149 parse_input_load(int *size)
150 {
151    Msg_Load *msg;
152    char line[4096];
153    int image_id;
154
155    // read image_id
156    _read_line(line, sizeof(line));
157    sscanf(line, "%d", &image_id);
158
159    msg = calloc(1, sizeof(*msg));
160
161    msg->base.rid = _rid_count++;
162    msg->base.type = CSERVE2_LOAD;
163    msg->image_id = image_id;
164
165    *size = sizeof(*msg);
166
167    return msg;
168 }
169
170 static void *
171 parse_input_preload(int *size)
172 {
173    Msg_Preload *msg;
174    char line[4096];
175    int image_id;
176
177    // read image_id
178    _read_line(line, sizeof(line));
179    sscanf(line, "%d", &image_id);
180
181    msg = calloc(1, sizeof(*msg));
182
183    msg->base.rid = _rid_count++;
184    msg->base.type = CSERVE2_PRELOAD;
185    msg->image_id = image_id;
186
187    *size = sizeof(*msg);
188
189    return msg;
190 }
191
192 static void *
193 parse_input_unload(int *size)
194 {
195    Msg_Unload *msg;
196    char line[4096];
197    int image_id;
198
199    // read image_id
200    _read_line(line, sizeof(line));
201    sscanf(line, "%d", &image_id);
202
203    msg = calloc(1, sizeof(*msg));
204
205    msg->base.rid = _rid_count++;
206    msg->base.type = CSERVE2_UNLOAD;
207    msg->image_id = image_id;
208
209    *size = sizeof(*msg);
210
211    return msg;
212 }
213
214 static void *
215 parse_input_close(int *size)
216 {
217    Msg_Close *msg;
218    char line[4096];
219    int file_id;
220
221    // read file_id
222    _read_line(line, sizeof(line));
223    sscanf(line, "%d", &file_id);
224
225    msg = calloc(1, sizeof(*msg));
226
227    msg->base.rid = _rid_count++;
228    msg->base.type = CSERVE2_CLOSE;
229    msg->file_id = file_id;
230
231    *size = sizeof(*msg);
232
233    return msg;
234 }
235
236 static void
237 parse_answer_opened(const void *buf)
238 {
239    const Msg_Opened *msg = buf;
240    printf("OPENED rid = %d\n", msg->base.rid);
241    printf("size: %dx%d, alpha: %d\n\n",
242           msg->image.w, msg->image.h, msg->image.alpha);
243 }
244
245 static void
246 parse_answer_setoptsed(const void *buf)
247 {
248    const Msg_Setoptsed *msg = buf;
249    printf("SETOPTSED rid = %d\n", msg->base.rid);
250 }
251
252 static void
253 parse_answer_loaded(const void *buf)
254 {
255    const Msg_Loaded *msg = buf;
256    const char *path;
257
258    path = ((const char *)msg) + sizeof(*msg);
259
260    printf("LOADED rid = %d\n", msg->base.rid);
261    printf("shm mmap_offset = 0x%x, use_offset = 0x%x, mmap size = %d bytes\n",
262           msg->shm.mmap_offset, msg->shm.use_offset, msg->shm.mmap_size);
263    printf("shm path: \"%s\"\n\n", path);
264 }
265
266 static void
267 parse_answer_preloaded(const void *buf)
268 {
269    const Msg_Preloaded *msg = buf;
270
271    printf("PRELOADED rid = %d\n", msg->base.rid);
272 }
273
274 static void
275 parse_answer_error(const void *buf)
276 {
277    const Msg_Error *msg = buf;
278
279    printf("ERROR rid = %d, error = %d\n", msg->base.rid, msg->error);
280 }
281
282 static void
283 parse_answer(const void *buf)
284 {
285    const Msg_Base *msg = buf;
286
287    switch (msg->type)
288      {
289       case CSERVE2_OPENED:
290          parse_answer_opened(buf);
291          break;
292       case CSERVE2_SETOPTSED:
293          parse_answer_setoptsed(buf);
294          break;
295       case CSERVE2_LOADED:
296          parse_answer_loaded(buf);
297          break;
298       case CSERVE2_PRELOADED:
299          parse_answer_preloaded(buf);
300          break;
301       case CSERVE2_ERROR:
302          parse_answer_error(buf);
303          break;
304       default:
305          printf("unhandled answer: %d\n", msg->type);
306      }
307 }
308
309 static struct {
310    const char *name;
311    Message_Type type;
312    void *(*parse_func)(int *size);
313 } _msg_types[] = {
314    { "OPEN", CSERVE2_OPEN, parse_input_open },
315    { "OPENED", CSERVE2_OPENED, NULL },
316    { "SETOPTS", CSERVE2_SETOPTS, parse_input_setopts },
317    { "SETOPTSED", CSERVE2_SETOPTSED, NULL },
318    { "LOAD", CSERVE2_LOAD, parse_input_load },
319    { "LOADED", CSERVE2_LOADED, NULL },
320    { "PRELOAD", CSERVE2_PRELOAD, parse_input_preload },
321    { "PRELOADED", CSERVE2_PRELOADED, NULL },
322    { "UNLOAD", CSERVE2_UNLOAD, parse_input_unload },
323    { "CLOSE", CSERVE2_CLOSE, parse_input_close },
324    { NULL, 0, NULL }
325 };
326
327 int main(void)
328 {
329    int s, t, len, skip_cmd = 0;
330    struct sockaddr_un remote;
331    char msgbuf[4096], buf[UNIX_PATH_MAX], *env;
332
333    if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
334      {
335         perror("socket");
336         exit(1);
337      }
338
339    printf("Trying to connect...\n");
340
341    remote.sun_family = AF_UNIX;
342    env = getenv("EVAS_CSERVE2_SOCKET");
343    if (!env)
344      {
345         snprintf(buf, sizeof(buf), "/tmp/.evas-cserve2-%x.socket",
346                  (int)getuid());
347         env = buf;
348      }
349    strncpy(remote.sun_path, env, UNIX_PATH_MAX - 1);
350    len = strlen(remote.sun_path) + sizeof(remote.sun_family);
351    if (connect(s, (struct sockaddr *)&remote, len) == -1)
352      {
353         perror("connect");
354         exit(1);
355      }
356
357    printf("Connected.\n");
358
359    while(!feof(stdin))
360      {
361         char cmd[1024];
362         int i;
363         int size;
364         void *msg;
365
366         if (skip_cmd)
367           skip_cmd = 0;
368         else
369           printf("\n> ");
370         fgets(cmd, sizeof(cmd), stdin);
371         len = strlen(cmd) - 1;
372         cmd[len] = '\0';
373
374         if (!len)
375           {
376              skip_cmd = 1;
377              continue;
378           }
379
380         for (i = 0; _msg_types[i].name; i++)
381           {
382              if (!strcmp(cmd, _msg_types[i].name))
383                break;
384           }
385
386         // discards the end of the message if we can't parse it
387         if (!_msg_types[i].name)
388           {
389              printf("Invalid command.\n");
390              continue;
391           }
392
393         if (!_msg_types[i].parse_func)
394           {
395              printf("Command %s still unhandled.\n", _msg_types[i].name);
396              continue;
397           }
398
399         msg = _msg_types[i].parse_func(&size);
400
401         if (send(s, &size, sizeof(size), MSG_NOSIGNAL) == -1)
402           {
403              perror("send size");
404              exit(1);
405           }
406         if (send(s, msg, size, MSG_NOSIGNAL) == -1)
407           {
408              perror("send");
409              exit(1);
410           }
411
412         free(msg);
413
414         usleep(100000);
415
416         if ((t=recv(s, &size, sizeof(size), MSG_DONTWAIT)) > 0)
417           {
418              len = recv(s, msgbuf, size, 0);
419              printf("size of received message: %d\n", len);
420              if (len != size)
421                {
422                   printf("couldn't read entire message.\n");
423                   continue;
424                }
425              debug_msg(&size, sizeof(size));
426              debug_msg(msgbuf, size);
427              parse_answer(msgbuf);
428           }
429         else
430           {
431              if (t < 0 && ((errno == EAGAIN) || (errno == EWOULDBLOCK)))
432                continue;
433              else fprintf(stderr, "Server closed connection\n");
434              exit(1);
435           }
436      }
437
438    close(s);
439
440    return 0;
441 }