blob: 3fe120bbee4e7da646a9dcb3cbf0562dcb992501 [file] [log] [blame]
Radek Krejci8fd1f5e2012-07-24 17:33:36 +02001/*!
2 * \file test-client.c
3 * \brief Testing client sending JSON requsts to the mod_netconf socket
4 * \author Radek Krejci <rkrejci@cesnet.cz>
Tomas Cejka94da2c52013-01-08 18:20:30 +01005 * \author Tomas Cejka <cejkat@cesnet.cz>
Radek Krejci8fd1f5e2012-07-24 17:33:36 +02006 * \date 2012
Tomas Cejka94da2c52013-01-08 18:20:30 +01007 * \date 2013
Radek Krejci8fd1f5e2012-07-24 17:33:36 +02008 */
9/*
10 * Copyright (C) 2012 CESNET
11 *
12 * LICENSE TERMS
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 * 1. Redistributions of source code must retain the above copyright
18 * notice, this list of conditions and the following disclaimer.
19 * 2. Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in
21 * the documentation and/or other materials provided with the
22 * distribution.
23 * 3. Neither the name of the Company nor the names of its contributors
24 * may be used to endorse or promote products derived from this
25 * software without specific prior written permission.
26 *
27 * ALTERNATIVELY, provided that this notice is retained in full, this
28 * product may be distributed under the terms of the GNU General Public
29 * License (GPL) version 2 or later, in which case the provisions
30 * of the GPL apply INSTEAD OF those given above.
31 *
32 * This software is provided ``as is'', and any express or implied
33 * warranties, including, but not limited to, the implied warranties of
34 * merchantability and fitness for a particular purpose are disclaimed.
35 * In no event shall the company or contributors be liable for any
36 * direct, indirect, incidental, special, exemplary, or consequential
37 * damages (including, but not limited to, procurement of substitute
38 * goods or services; loss of use, data, or profits; or business
39 * interruption) however caused and on any theory of liability, whether
40 * in contract, strict liability, or tort (including negligence or
41 * otherwise) arising in any way out of the use of this software, even
42 * if advised of the possibility of such damage.
43 *
44 */
45
David Kupka1e3e4c82012-09-04 09:32:15 +020046#define _GNU_SOURCE
Radek Krejci8fd1f5e2012-07-24 17:33:36 +020047#include <unistd.h>
48#include <stdio.h>
49#include <stdlib.h>
50#include <string.h>
Tomas Cejkab272bf12012-09-05 16:49:12 +020051#include <err.h>
Radek Krejci8fd1f5e2012-07-24 17:33:36 +020052#include <errno.h>
53#include <sys/types.h>
54#include <sys/socket.h>
55#include <sys/un.h>
Michal Vasko0208a862016-03-16 09:12:44 +010056#include <json.h>
David Kupka1e3e4c82012-09-04 09:32:15 +020057#include <ctype.h>
Tomas Cejka94da2c52013-01-08 18:20:30 +010058#include "message_type.h"
Radek Krejci8fd1f5e2012-07-24 17:33:36 +020059
Michal Vaskoa53ef882015-11-24 11:02:01 +010060#define SOCKET_FILENAME "/var/run/netopeerguid.sock"
David Kupka1e3e4c82012-09-04 09:32:15 +020061#define BUFFER_SIZE 40960
Radek Krejci8fd1f5e2012-07-24 17:33:36 +020062
Radek Krejci8fd1f5e2012-07-24 17:33:36 +020063void print_help(char* progname)
64{
Michal Vaskoda0ab5c2015-11-13 13:24:51 +010065 printf("Usage: %s <command>\n", progname);
66 printf("Available commands:\n");
67 printf("\tconnect\n");
68 printf("\tdisconnect\n");
69 printf("\tcopy-config\n");
70 printf("\tdelete-config\n");
71 printf("\tedit-config\n");
72 printf("\tget\n");
73 printf("\tget-config\n");
74 printf("\tkill-session\n");
75 printf("\tlock\n");
76 printf("\tunlock\n");
77 printf("\tinfo\n");
78 printf("\tgeneric\n");
79 printf("\tgetschema\n");
Michal Vaskoa7f0ae32016-03-17 15:45:12 +010080 printf("\tquery\n");
81 printf("\tmerge\n");
Radek Krejci8fd1f5e2012-07-24 17:33:36 +020082}
83
Tomas Cejkab272bf12012-09-05 16:49:12 +020084/**
85 * \brief Get multiline input text.
86 *
87 * Print given prompt and read text ending with CTRL+D.
88 * Output string is terminated by 0. Ending '\n' is removed.
89 *
90 * On error, err is called!
91 *
92 * \param[out] output - pointer to memory where string is stored
93 * \param[out] size - size of string return by getdelim()
94 * \param[in] prompt - text printed as a prompt
95 */
96void readmultiline(char **output, size_t *size, const char *prompt)
97{
Michal Vaskoda0ab5c2015-11-13 13:24:51 +010098 printf(prompt);
Peter Nagy4507c962016-03-17 13:47:54 +010099 fflush(stdout);
Michal Vaskoda0ab5c2015-11-13 13:24:51 +0100100 if (getdelim (output, size, 'D' - 0x40, stdin) == -1) {
101 if (errno) {
102 err(errno, "Cannot read input.");
103 }
104 *output = (char *) malloc(sizeof(char));
105 **output = 0;
106 return;
107 }
108 (*output)[(*size)-1] = 0; /* input text end "sanitation" */
109 (*output)[(strlen(*output))-1] = 0; /* input text end "sanitation" */
Tomas Cejkab272bf12012-09-05 16:49:12 +0200110}
111
112/**
113 * \brief Get input text.
114 *
115 * Print given prompt and read one line of text.
116 * Output string is terminated by 0. Ending '\n' is removed.
117 *
118 * On error, err is called!
119 *
120 * \param[out] output - pointer to memory where string is stored
121 * \param[out] size - size of string return by getline()
122 * \param[in] prompt - text printed as a prompt
123 */
124void readline(char **output, size_t *size, const char *prompt)
125{
Michal Vaskoda0ab5c2015-11-13 13:24:51 +0100126 printf(prompt);
Peter Nagy4507c962016-03-17 13:47:54 +0100127 fflush(stdout);
Michal Vaskoda0ab5c2015-11-13 13:24:51 +0100128 if (getline (output, size, stdin) == -1) {
129 if (errno) {
130 err(errno, "Cannot read input.");
131 }
132 }
133 (*output)[(*size)-1] = 0; /* input text end "sanitation" */
134 (*output)[(strlen(*output))-1] = 0; /* input text end "sanitation" */
Tomas Cejkab272bf12012-09-05 16:49:12 +0200135}
136
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200137int main (int argc, char* argv[])
138{
Michal Vaskoda0ab5c2015-11-13 13:24:51 +0100139 json_object* msg = NULL, *reply = NULL, *obj, *obj2;
140 const char* msg_text;
141 int sock;
142 struct sockaddr_un addr;
143 size_t len;
144 char *buffer;
145 char* line = NULL, *chunked_msg_text;
146 int i;
147 int buffer_size, buffer_len, ret, chunk_len;
148 char c, chunk_len_str[12];
149 unsigned int session_key;
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200150
Michal Vaskoda0ab5c2015-11-13 13:24:51 +0100151 if (argc != 2) {
152 print_help(argv[0]);
153 return (2);
154 }
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200155
Michal Vaskoda0ab5c2015-11-13 13:24:51 +0100156 /* connect to the daemon */
157 sock = socket(PF_UNIX, SOCK_STREAM, 0);
158 if (sock == -1) {
159 fprintf(stderr, "Creating socket failed (%s)\n", strerror(errno));
160 return (EXIT_FAILURE);
161 }
162 addr.sun_family = AF_UNIX;
163 strncpy(addr.sun_path, SOCKET_FILENAME, sizeof(addr.sun_path));
164 len = strlen(addr.sun_path) + sizeof(addr.sun_family);
165 if (connect(sock, (struct sockaddr *) &addr, len) == -1) {
Michal Vasko7f46ede2016-02-24 10:45:55 +0100166 fprintf(stderr, "Connecting to netopeerguid (%s) failed (%s)\n", SOCKET_FILENAME, strerror(errno));
Michal Vaskoda0ab5c2015-11-13 13:24:51 +0100167 close(sock);
168 return (EXIT_FAILURE);
169 }
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200170
Michal Vaskoda0ab5c2015-11-13 13:24:51 +0100171 line = malloc(sizeof(char) * BUFFER_SIZE);
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200172
Michal Vaskoda0ab5c2015-11-13 13:24:51 +0100173 if (strcmp(argv[1], "connect") == 0) {
174 /*
175 * create NETCONF session
176 */
177 msg = json_object_new_object();
178 json_object_object_add(msg, "type", json_object_new_int(MSG_CONNECT));
179 readline(&line, &len, "Hostname: ");
180 json_object_object_add(msg, "host", json_object_new_string(line));
181 readline(&line, &len, "Port: ");
182 json_object_object_add(msg, "port", json_object_new_string(line));
183 readline(&line, &len, "Username: ");
184 json_object_object_add(msg, "user", json_object_new_string(line));
185 system("stty -echo");
186 readline(&line, &len, "Password: ");
187 system("stty echo");
188 printf("\n");
189 json_object_object_add(msg, "pass", json_object_new_string(line));
Tomas Cejka42434462012-09-05 18:11:43 +0200190
Michal Vaskoda0ab5c2015-11-13 13:24:51 +0100191 /* clean read password - it is needless because we have a copy in json... :-( */
192 memset(line, 'X', len);
193 free(line);
194 line = NULL;
195 } else if (strcmp(argv[1], "disconnect") == 0) {
196 /*
197 * Close NETCONF session
198 */
199 msg = json_object_new_object();
200 json_object_object_add(msg, "type", json_object_new_int(MSG_DISCONNECT));
201 readline(&line, &len, "Session: ");
202 obj = json_object_new_array();
203 session_key = atoi(line);
204 json_object_array_add(obj, json_object_new_int(session_key));
205 json_object_object_add(msg, "sessions", obj);
206 } else if (strcmp(argv[1], "copy-config") == 0) {
207 /*
208 * NETCONF <copy-config>
209 */
210 msg = json_object_new_object();
211 json_object_object_add(msg, "type", json_object_new_int(MSG_COPYCONFIG));
212 readline(&line, &len, "Session: ");
213 obj = json_object_new_array();
214 session_key = atoi(line);
215 json_object_array_add(obj, json_object_new_int(session_key));
216 json_object_object_add(msg, "sessions", obj);
217 readline(&line, &len, "Source (running|startup|candidate): ");
218 if (strlen(line) > 0) {
219 json_object_object_add(msg, "source", json_object_new_string(line));
220 } else {
221 readmultiline(&line, &len, "Configuration data (ending with CTRL+D): ");
Michal Vasko7f46ede2016-02-24 10:45:55 +0100222 obj = json_object_new_array();
223 json_object_array_add(obj, json_object_new_string(line));
224 json_object_object_add(msg, "configs", obj);
Michal Vaskoda0ab5c2015-11-13 13:24:51 +0100225 }
226 readline(&line, &len, "Target (running|startup|candidate): ");
227 json_object_object_add(msg, "target", json_object_new_string(line));
228 } else if (strcmp(argv[1], "delete-config") == 0) {
229 /*
230 * NETCONF <delete-config>
231 */
232 msg = json_object_new_object();
233 json_object_object_add(msg, "type", json_object_new_int(MSG_DELETECONFIG));
234 readline(&line, &len, "Session: ");
235 obj = json_object_new_array();
236 session_key = atoi(line);
237 json_object_array_add(obj, json_object_new_int(session_key));
238 json_object_object_add(msg, "sessions", obj);
239 readline(&line, &len, "Target (running|startup|candidate): ");
240 json_object_object_add(msg, "target", json_object_new_string(line));
241 } else if (strcmp(argv[1], "edit-config") == 0) {
242 /*
243 * NETCONF <edit-config>
244 */
245 msg = json_object_new_object();
246 json_object_object_add(msg, "type", json_object_new_int(MSG_EDITCONFIG));
247 readline(&line, &len, "Session: ");
248 obj = json_object_new_array();
249 session_key = atoi(line);
250 json_object_array_add(obj, json_object_new_int(session_key));
251 json_object_object_add(msg, "sessions", obj);
252 readline(&line, &len, "Target (running|startup|candidate): ");
253 json_object_object_add(msg, "target", json_object_new_string(line));
254 readline(&line, &len, "Default operation (merge|replace|none): ");
255 if (strlen(line) > 0) {
256 json_object_object_add(msg, "default-operation", json_object_new_string(line));
257 }
258 readline(&line, &len, "Error option (stop-on-error|continue-on-error|rollback-on-error): ");
259 if (strlen(line) > 0) {
260 json_object_object_add(msg, "error-option", json_object_new_string(line));
261 }
262 readmultiline(&line, &len, "Configuration data (ending with CTRL+D): ");
Michal Vasko7f46ede2016-02-24 10:45:55 +0100263 obj = json_object_new_array();
264 json_object_array_add(obj, json_object_new_string(line));
265 json_object_object_add(msg, "configs", obj);
Michal Vaskoda0ab5c2015-11-13 13:24:51 +0100266 } else if (strcmp(argv[1], "get") == 0) {
267 /*
268 * NETCONF <get>
269 */
270 msg = json_object_new_object();
271 json_object_object_add(msg, "type", json_object_new_int(MSG_GET));
272 readline(&line, &len, "Session: ");
273 obj = json_object_new_array();
274 session_key = atoi(line);
275 json_object_array_add(obj, json_object_new_int(session_key));
276 json_object_object_add(msg, "sessions", obj);
277 readmultiline(&line, &len, "Filter (ending with CTRL+D): ");
278 if (strlen(line) > 0) {
279 json_object_object_add(msg, "filter", json_object_new_string(line));
280 }
281 do {
282 readline(&line, &len, "Strict (y/n): ");
283 } while (strcmp(line, "y") && strcmp(line, "n"));
284 json_object_object_add(msg, "strict", json_object_new_boolean(strcmp(line, "y") ? 0 : 1));
285 } else if (strcmp(argv[1], "get-config") == 0) {
286 /*
287 * NETCONF <get-config>
288 */
289 msg = json_object_new_object();
290 json_object_object_add(msg, "type", json_object_new_int(MSG_GETCONFIG));
291 readline(&line, &len, "Session: ");
292 obj = json_object_new_array();
293 session_key = atoi(line);
294 json_object_array_add(obj, json_object_new_int(session_key));
295 json_object_object_add(msg, "sessions", obj);
296 readline(&line, &len, "Source (running|startup|candidate): ");
297 json_object_object_add(msg, "source", json_object_new_string(line));
298 readmultiline(&line, &len, "Filter (ending with CTRL+D): ");
299 if (strlen(line) > 0) {
300 json_object_object_add(msg, "filter", json_object_new_string(line));
301 }
302 do {
303 readline(&line, &len, "Strict (y/n): ");
304 } while (strcmp(line, "y") && strcmp(line, "n"));
305 json_object_object_add(msg, "strict", json_object_new_boolean(strcmp(line, "y") ? 0 : 1));
306 } else if (strcmp(argv[1], "kill-session") == 0) {
307 /*
308 * NETCONF <kill-session>
309 */
310 msg = json_object_new_object();
311 json_object_object_add(msg, "type", json_object_new_int(MSG_KILL));
312 readline(&line, &len, "Session: ");
313 obj = json_object_new_array();
314 session_key = atoi(line);
315 json_object_array_add(obj, json_object_new_int(session_key));
316 json_object_object_add(msg, "sessions", obj);
317 readline(&line, &len, "Kill session with ID: ");
318 json_object_object_add(msg, "session-id", json_object_new_string(line));
319 } else if (strcmp(argv[1], "lock") == 0) {
320 /*
321 * NETCONF <lock>
322 */
323 msg = json_object_new_object();
324 json_object_object_add(msg, "type", json_object_new_int(MSG_LOCK));
325 readline(&line, &len, "Session: ");
326 obj = json_object_new_array();
327 session_key = atoi(line);
328 json_object_array_add(obj, json_object_new_int(session_key));
329 json_object_object_add(msg, "sessions", obj);
330 readline(&line, &len, "Target (running|startup|candidate): ");
331 json_object_object_add(msg, "target", json_object_new_string(line));
332 } else if (strcmp(argv[1], "unlock") == 0) {
333 /*
334 * NETCONF <unlock>
335 */
336 msg = json_object_new_object();
337 json_object_object_add(msg, "type", json_object_new_int(MSG_UNLOCK));
338 readline(&line, &len,"Session: ");
339 obj = json_object_new_array();
340 session_key = atoi(line);
341 json_object_array_add(obj, json_object_new_int(session_key));
342 json_object_object_add(msg, "sessions", obj);
343 readline(&line, &len, "Target (running|startup|candidate): ");
344 json_object_object_add(msg, "target", json_object_new_string(line));
345 } else if (strcmp(argv[1], "info") == 0) {
346 /*
347 * Get information about NETCONF session
348 */
349 msg = json_object_new_object();
350 json_object_object_add(msg, "type", json_object_new_int(MSG_INFO));
351 readline(&line, &len, "Session: ");
352 obj = json_object_new_array();
353 session_key = atoi(line);
354 json_object_array_add(obj, json_object_new_int(session_key));
355 json_object_object_add(msg, "sessions", obj);
356 } else if (strcmp(argv[1], "generic") == 0) {
357 /*
358 * Generic NETCONF request
359 */
360 msg = json_object_new_object();
361 json_object_object_add(msg, "type", json_object_new_int(MSG_GENERIC));
362 readline(&line, &len, "Session: ");
363 obj = json_object_new_array();
364 session_key = atoi(line);
365 json_object_array_add(obj, json_object_new_int(session_key));
366 json_object_object_add(msg, "sessions", obj);
367 readmultiline(&line, &len, "NETCONF <rpc> content (ending with CTRL+D): ");
Michal Vasko7f46ede2016-02-24 10:45:55 +0100368 obj = json_object_new_array();
369 json_object_array_add(obj, json_object_new_string(line));
370 json_object_object_add(msg, "contents", obj);
Michal Vaskoda0ab5c2015-11-13 13:24:51 +0100371 } else if (strcmp(argv[1], "getschema") == 0) {
372 /*
373 * Get information about NETCONF session
374 */
375 msg = json_object_new_object();
376 json_object_object_add(msg, "type", json_object_new_int(MSG_GETSCHEMA));
377 readline(&line, &len, "Session: ");
378 obj = json_object_new_array();
379 session_key = atoi(line);
380 json_object_array_add(obj, json_object_new_int(session_key));
381 json_object_object_add(msg, "sessions", obj);
382 readline(&line, &len, "Identificator: ");
383 json_object_object_add(msg, "identifier", json_object_new_string(line));
384 readline(&line, &len, "Format [YIN]: ");
385 json_object_object_add(msg, "format", json_object_new_string(line));
386 readline(&line, &len, "Version: ");
387 json_object_object_add(msg, "version", json_object_new_string(line));
388 } else if (strcmp(argv[1], "query") == 0) {
389 /*
390 * Query metadata about a node
391 */
392 msg = json_object_new_object();
393 json_object_object_add(msg, "type", json_object_new_int(SCH_QUERY));
394 readline(&line, &len, "Session: ");
395 obj = json_object_new_array();
396 session_key = atoi(line);
397 json_object_array_add(obj, json_object_new_int(session_key));
398 json_object_object_add(msg, "sessions", obj);
399 readline(&line, &len, "Filter: ");
400 obj = json_object_new_array();
401 json_object_array_add(obj, json_object_new_string(line));
402 json_object_object_add(msg, "filters", obj);
403 do {
404 readline(&line, &len, "Load children (y/n): ");
405 } while (strcmp(line, "y") && strcmp(line, "n"));
406 json_object_object_add(msg, "load_children", json_object_new_boolean(strcmp(line, "y") ? 0 : 1));
407 } else if (strcmp(argv[1], "merge") == 0) {
408 /*
409 * Merge configuration data with metadata
410 */
411 msg = json_object_new_object();
412 json_object_object_add(msg, "type", json_object_new_int(SCH_QUERY));
413 readline(&line, &len, "Session: ");
414 obj = json_object_new_array();
415 session_key = atoi(line);
416 json_object_array_add(obj, json_object_new_int(session_key));
417 json_object_object_add(msg, "sessions", obj);
418 readmultiline(&line, &len, "Configuration data (ending with CTRL+D): ");
419 obj = json_object_new_array();
420 json_object_array_add(obj, json_object_new_string(line));
421 json_object_object_add(msg, "configurations", obj);
422 } else {
423 /*
424 * Unknown request
425 */
426 fprintf(stderr, "Unknown command %s\n", argv[1]);
427 close(sock);
428 return (EXIT_FAILURE);
429 }
Tomas Cejkab272bf12012-09-05 16:49:12 +0200430
Michal Vaskoda0ab5c2015-11-13 13:24:51 +0100431 /* send the message */
432 if (msg != NULL) {
433 msg_text = json_object_to_json_string(msg);
434 asprintf (&chunked_msg_text, "\n#%d\n%s\n##\n", (int)strlen(msg_text), msg_text);
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200435
Michal Vaskoda0ab5c2015-11-13 13:24:51 +0100436 if (json_object_object_get(msg, "pass") == NULL) {
437 /* print message only if it does not contain password */
438 printf("Sending: %s\n", msg_text);
439 }
440 send(sock, chunked_msg_text, strlen(chunked_msg_text) + 1, 0);
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200441
Michal Vaskoda0ab5c2015-11-13 13:24:51 +0100442 json_object_put(msg);
443 free (chunked_msg_text);
444 } else {
445 close(sock);
446 return (EXIT_FAILURE);
447 }
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200448
Michal Vaskoda0ab5c2015-11-13 13:24:51 +0100449 /* read json in chunked framing */
450 buffer_size = 0;
451 buffer_len = 0;
452 buffer = NULL;
453 while (1) {
454 /* read chunk length */
455 if ((ret = recv (sock, &c, 1, 0)) != 1 || c != '\n') {
456 free (buffer);
457 buffer = NULL;
458 break;
459 }
460 if ((ret = recv (sock, &c, 1, 0)) != 1 || c != '#') {
461 free (buffer);
462 buffer = NULL;
463 break;
464 }
465 i=0;
466 memset (chunk_len_str, 0, 12);
467 while ((ret = recv (sock, &c, 1, 0) == 1 && (isdigit(c) || c == '#'))) {
468 if (i==0 && c == '#') {
469 if (recv (sock, &c, 1, 0) != 1 || c != '\n') {
470 /* end but invalid */
471 free (buffer);
472 buffer = NULL;
473 }
474 /* end of message, double-loop break */
475 goto msg_complete;
476 }
477 chunk_len_str[i++] = c;
478 }
479 if (c != '\n') {
480 free (buffer);
481 buffer = NULL;
482 break;
483 }
484 if ((chunk_len = atoi (chunk_len_str)) == 0) {
485 free (buffer);
486 buffer = NULL;
487 break;
488 }
489 buffer_size += chunk_len+1;
490 buffer = realloc (buffer, sizeof(char)*buffer_size);
Peter Nagy4507c962016-03-17 13:47:54 +0100491 while (buffer_len < chunk_len && ret != -1) {
492 ret = recv (sock, buffer+buffer_len, chunk_len-buffer_len, 0);
493 buffer_len += ret;
494 }
495 if (ret == -1 || buffer_len != chunk_len) {
Michal Vaskoda0ab5c2015-11-13 13:24:51 +0100496 free (buffer);
497 buffer = NULL;
498 break;
499 }
Michal Vaskoda0ab5c2015-11-13 13:24:51 +0100500 }
David Kupka1e3e4c82012-09-04 09:32:15 +0200501msg_complete:
502
Michal Vaskoda0ab5c2015-11-13 13:24:51 +0100503 if (buffer != NULL) {
504 reply = json_tokener_parse(buffer);
505 free (buffer);
506 } else {
507 reply = NULL;
508 }
509 free(line);
David Kupka1e3e4c82012-09-04 09:32:15 +0200510
Michal Vaskoda0ab5c2015-11-13 13:24:51 +0100511 printf("Received:\n");
512 if (reply == NULL) {
513 printf("(null)\n");
514 } else {
515 asprintf(&line, "%d", session_key);
516 json_object_object_get_ex(reply, line, &obj);
517 free(line);
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200518
Michal Vaskoda0ab5c2015-11-13 13:24:51 +0100519 json_object_object_get_ex(obj, "type", &obj2);
520 switch (json_object_get_int(obj2)) {
521 case 0:
522 printf("OK\n");
523 printf("%s\n", json_object_to_json_string_ext(reply, JSON_C_TO_STRING_PRETTY | JSON_C_TO_STRING_SPACED));
524 break;
525 case 1:
526 printf("DATA\n");
527 json_object_object_get_ex(obj, "data", &obj2);
528 msg_text = json_object_get_string(obj2);
529 obj = json_tokener_parse(msg_text);
530 printf("%s\n", json_object_to_json_string_ext(obj, JSON_C_TO_STRING_PRETTY | JSON_C_TO_STRING_SPACED));
531 json_object_put(obj);
532 break;
533 case 2:
534 printf("ERROR\n");
535 printf("%s\n", json_object_to_json_string_ext(reply, JSON_C_TO_STRING_PRETTY | JSON_C_TO_STRING_SPACED));
536 break;
537 case 3:
538 printf("INFO\n");
539 printf("%s\n", json_object_to_json_string_ext(reply, JSON_C_TO_STRING_PRETTY | JSON_C_TO_STRING_SPACED));
540 break;
541 default:
542 printf("(unknown)\n");
543 printf("%s\n", json_object_to_json_string_ext(reply, JSON_C_TO_STRING_PRETTY | JSON_C_TO_STRING_SPACED));
544 break;
545 }
546 json_object_put(reply);
547 }
548 close(sock);
549
550 return (EXIT_SUCCESS);
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200551}