blob: 8e91a523e0ef8445e86a9f3369656803f24d30ca [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");
Radek Krejci8fd1f5e2012-07-24 17:33:36 +020080}
81
Tomas Cejkab272bf12012-09-05 16:49:12 +020082/**
83 * \brief Get multiline input text.
84 *
85 * Print given prompt and read text ending with CTRL+D.
86 * Output string is terminated by 0. Ending '\n' is removed.
87 *
88 * On error, err is called!
89 *
90 * \param[out] output - pointer to memory where string is stored
91 * \param[out] size - size of string return by getdelim()
92 * \param[in] prompt - text printed as a prompt
93 */
94void readmultiline(char **output, size_t *size, const char *prompt)
95{
Michal Vaskoda0ab5c2015-11-13 13:24:51 +010096 printf(prompt);
97 if (getdelim (output, size, 'D' - 0x40, stdin) == -1) {
98 if (errno) {
99 err(errno, "Cannot read input.");
100 }
101 *output = (char *) malloc(sizeof(char));
102 **output = 0;
103 return;
104 }
105 (*output)[(*size)-1] = 0; /* input text end "sanitation" */
106 (*output)[(strlen(*output))-1] = 0; /* input text end "sanitation" */
Tomas Cejkab272bf12012-09-05 16:49:12 +0200107}
108
109/**
110 * \brief Get input text.
111 *
112 * Print given prompt and read one line of text.
113 * Output string is terminated by 0. Ending '\n' is removed.
114 *
115 * On error, err is called!
116 *
117 * \param[out] output - pointer to memory where string is stored
118 * \param[out] size - size of string return by getline()
119 * \param[in] prompt - text printed as a prompt
120 */
121void readline(char **output, size_t *size, const char *prompt)
122{
Michal Vaskoda0ab5c2015-11-13 13:24:51 +0100123 printf(prompt);
124 if (getline (output, size, stdin) == -1) {
125 if (errno) {
126 err(errno, "Cannot read input.");
127 }
128 }
129 (*output)[(*size)-1] = 0; /* input text end "sanitation" */
130 (*output)[(strlen(*output))-1] = 0; /* input text end "sanitation" */
Tomas Cejkab272bf12012-09-05 16:49:12 +0200131}
132
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200133int main (int argc, char* argv[])
134{
Michal Vaskoda0ab5c2015-11-13 13:24:51 +0100135 json_object* msg = NULL, *reply = NULL, *obj, *obj2;
136 const char* msg_text;
137 int sock;
138 struct sockaddr_un addr;
139 size_t len;
140 char *buffer;
141 char* line = NULL, *chunked_msg_text;
142 int i;
143 int buffer_size, buffer_len, ret, chunk_len;
144 char c, chunk_len_str[12];
145 unsigned int session_key;
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200146
Michal Vaskoda0ab5c2015-11-13 13:24:51 +0100147 if (argc != 2) {
148 print_help(argv[0]);
149 return (2);
150 }
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200151
Michal Vaskoda0ab5c2015-11-13 13:24:51 +0100152 /* connect to the daemon */
153 sock = socket(PF_UNIX, SOCK_STREAM, 0);
154 if (sock == -1) {
155 fprintf(stderr, "Creating socket failed (%s)\n", strerror(errno));
156 return (EXIT_FAILURE);
157 }
158 addr.sun_family = AF_UNIX;
159 strncpy(addr.sun_path, SOCKET_FILENAME, sizeof(addr.sun_path));
160 len = strlen(addr.sun_path) + sizeof(addr.sun_family);
161 if (connect(sock, (struct sockaddr *) &addr, len) == -1) {
Michal Vasko7f46ede2016-02-24 10:45:55 +0100162 fprintf(stderr, "Connecting to netopeerguid (%s) failed (%s)\n", SOCKET_FILENAME, strerror(errno));
Michal Vaskoda0ab5c2015-11-13 13:24:51 +0100163 close(sock);
164 return (EXIT_FAILURE);
165 }
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200166
Michal Vaskoda0ab5c2015-11-13 13:24:51 +0100167 line = malloc(sizeof(char) * BUFFER_SIZE);
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200168
Michal Vaskoda0ab5c2015-11-13 13:24:51 +0100169 if (strcmp(argv[1], "connect") == 0) {
170 /*
171 * create NETCONF session
172 */
173 msg = json_object_new_object();
174 json_object_object_add(msg, "type", json_object_new_int(MSG_CONNECT));
175 readline(&line, &len, "Hostname: ");
176 json_object_object_add(msg, "host", json_object_new_string(line));
177 readline(&line, &len, "Port: ");
178 json_object_object_add(msg, "port", json_object_new_string(line));
179 readline(&line, &len, "Username: ");
180 json_object_object_add(msg, "user", json_object_new_string(line));
181 system("stty -echo");
182 readline(&line, &len, "Password: ");
183 system("stty echo");
184 printf("\n");
185 json_object_object_add(msg, "pass", json_object_new_string(line));
Tomas Cejka42434462012-09-05 18:11:43 +0200186
Michal Vaskoda0ab5c2015-11-13 13:24:51 +0100187 /* clean read password - it is needless because we have a copy in json... :-( */
188 memset(line, 'X', len);
189 free(line);
190 line = NULL;
191 } else if (strcmp(argv[1], "disconnect") == 0) {
192 /*
193 * Close NETCONF session
194 */
195 msg = json_object_new_object();
196 json_object_object_add(msg, "type", json_object_new_int(MSG_DISCONNECT));
197 readline(&line, &len, "Session: ");
198 obj = json_object_new_array();
199 session_key = atoi(line);
200 json_object_array_add(obj, json_object_new_int(session_key));
201 json_object_object_add(msg, "sessions", obj);
202 } else if (strcmp(argv[1], "copy-config") == 0) {
203 /*
204 * NETCONF <copy-config>
205 */
206 msg = json_object_new_object();
207 json_object_object_add(msg, "type", json_object_new_int(MSG_COPYCONFIG));
208 readline(&line, &len, "Session: ");
209 obj = json_object_new_array();
210 session_key = atoi(line);
211 json_object_array_add(obj, json_object_new_int(session_key));
212 json_object_object_add(msg, "sessions", obj);
213 readline(&line, &len, "Source (running|startup|candidate): ");
214 if (strlen(line) > 0) {
215 json_object_object_add(msg, "source", json_object_new_string(line));
216 } else {
217 readmultiline(&line, &len, "Configuration data (ending with CTRL+D): ");
Michal Vasko7f46ede2016-02-24 10:45:55 +0100218 obj = json_object_new_array();
219 json_object_array_add(obj, json_object_new_string(line));
220 json_object_object_add(msg, "configs", obj);
Michal Vaskoda0ab5c2015-11-13 13:24:51 +0100221 }
222 readline(&line, &len, "Target (running|startup|candidate): ");
223 json_object_object_add(msg, "target", json_object_new_string(line));
224 } else if (strcmp(argv[1], "delete-config") == 0) {
225 /*
226 * NETCONF <delete-config>
227 */
228 msg = json_object_new_object();
229 json_object_object_add(msg, "type", json_object_new_int(MSG_DELETECONFIG));
230 readline(&line, &len, "Session: ");
231 obj = json_object_new_array();
232 session_key = atoi(line);
233 json_object_array_add(obj, json_object_new_int(session_key));
234 json_object_object_add(msg, "sessions", obj);
235 readline(&line, &len, "Target (running|startup|candidate): ");
236 json_object_object_add(msg, "target", json_object_new_string(line));
237 } else if (strcmp(argv[1], "edit-config") == 0) {
238 /*
239 * NETCONF <edit-config>
240 */
241 msg = json_object_new_object();
242 json_object_object_add(msg, "type", json_object_new_int(MSG_EDITCONFIG));
243 readline(&line, &len, "Session: ");
244 obj = json_object_new_array();
245 session_key = atoi(line);
246 json_object_array_add(obj, json_object_new_int(session_key));
247 json_object_object_add(msg, "sessions", obj);
248 readline(&line, &len, "Target (running|startup|candidate): ");
249 json_object_object_add(msg, "target", json_object_new_string(line));
250 readline(&line, &len, "Default operation (merge|replace|none): ");
251 if (strlen(line) > 0) {
252 json_object_object_add(msg, "default-operation", json_object_new_string(line));
253 }
254 readline(&line, &len, "Error option (stop-on-error|continue-on-error|rollback-on-error): ");
255 if (strlen(line) > 0) {
256 json_object_object_add(msg, "error-option", json_object_new_string(line));
257 }
258 readmultiline(&line, &len, "Configuration data (ending with CTRL+D): ");
Michal Vasko7f46ede2016-02-24 10:45:55 +0100259 obj = json_object_new_array();
260 json_object_array_add(obj, json_object_new_string(line));
261 json_object_object_add(msg, "configs", obj);
Michal Vaskoda0ab5c2015-11-13 13:24:51 +0100262 } else if (strcmp(argv[1], "get") == 0) {
263 /*
264 * NETCONF <get>
265 */
266 msg = json_object_new_object();
267 json_object_object_add(msg, "type", json_object_new_int(MSG_GET));
268 readline(&line, &len, "Session: ");
269 obj = json_object_new_array();
270 session_key = atoi(line);
271 json_object_array_add(obj, json_object_new_int(session_key));
272 json_object_object_add(msg, "sessions", obj);
273 readmultiline(&line, &len, "Filter (ending with CTRL+D): ");
274 if (strlen(line) > 0) {
275 json_object_object_add(msg, "filter", json_object_new_string(line));
276 }
277 do {
278 readline(&line, &len, "Strict (y/n): ");
279 } while (strcmp(line, "y") && strcmp(line, "n"));
280 json_object_object_add(msg, "strict", json_object_new_boolean(strcmp(line, "y") ? 0 : 1));
281 } else if (strcmp(argv[1], "get-config") == 0) {
282 /*
283 * NETCONF <get-config>
284 */
285 msg = json_object_new_object();
286 json_object_object_add(msg, "type", json_object_new_int(MSG_GETCONFIG));
287 readline(&line, &len, "Session: ");
288 obj = json_object_new_array();
289 session_key = atoi(line);
290 json_object_array_add(obj, json_object_new_int(session_key));
291 json_object_object_add(msg, "sessions", obj);
292 readline(&line, &len, "Source (running|startup|candidate): ");
293 json_object_object_add(msg, "source", json_object_new_string(line));
294 readmultiline(&line, &len, "Filter (ending with CTRL+D): ");
295 if (strlen(line) > 0) {
296 json_object_object_add(msg, "filter", json_object_new_string(line));
297 }
298 do {
299 readline(&line, &len, "Strict (y/n): ");
300 } while (strcmp(line, "y") && strcmp(line, "n"));
301 json_object_object_add(msg, "strict", json_object_new_boolean(strcmp(line, "y") ? 0 : 1));
302 } else if (strcmp(argv[1], "kill-session") == 0) {
303 /*
304 * NETCONF <kill-session>
305 */
306 msg = json_object_new_object();
307 json_object_object_add(msg, "type", json_object_new_int(MSG_KILL));
308 readline(&line, &len, "Session: ");
309 obj = json_object_new_array();
310 session_key = atoi(line);
311 json_object_array_add(obj, json_object_new_int(session_key));
312 json_object_object_add(msg, "sessions", obj);
313 readline(&line, &len, "Kill session with ID: ");
314 json_object_object_add(msg, "session-id", json_object_new_string(line));
315 } else if (strcmp(argv[1], "lock") == 0) {
316 /*
317 * NETCONF <lock>
318 */
319 msg = json_object_new_object();
320 json_object_object_add(msg, "type", json_object_new_int(MSG_LOCK));
321 readline(&line, &len, "Session: ");
322 obj = json_object_new_array();
323 session_key = atoi(line);
324 json_object_array_add(obj, json_object_new_int(session_key));
325 json_object_object_add(msg, "sessions", obj);
326 readline(&line, &len, "Target (running|startup|candidate): ");
327 json_object_object_add(msg, "target", json_object_new_string(line));
328 } else if (strcmp(argv[1], "unlock") == 0) {
329 /*
330 * NETCONF <unlock>
331 */
332 msg = json_object_new_object();
333 json_object_object_add(msg, "type", json_object_new_int(MSG_UNLOCK));
334 readline(&line, &len,"Session: ");
335 obj = json_object_new_array();
336 session_key = atoi(line);
337 json_object_array_add(obj, json_object_new_int(session_key));
338 json_object_object_add(msg, "sessions", obj);
339 readline(&line, &len, "Target (running|startup|candidate): ");
340 json_object_object_add(msg, "target", json_object_new_string(line));
341 } else if (strcmp(argv[1], "info") == 0) {
342 /*
343 * Get information about NETCONF session
344 */
345 msg = json_object_new_object();
346 json_object_object_add(msg, "type", json_object_new_int(MSG_INFO));
347 readline(&line, &len, "Session: ");
348 obj = json_object_new_array();
349 session_key = atoi(line);
350 json_object_array_add(obj, json_object_new_int(session_key));
351 json_object_object_add(msg, "sessions", obj);
352 } else if (strcmp(argv[1], "generic") == 0) {
353 /*
354 * Generic NETCONF request
355 */
356 msg = json_object_new_object();
357 json_object_object_add(msg, "type", json_object_new_int(MSG_GENERIC));
358 readline(&line, &len, "Session: ");
359 obj = json_object_new_array();
360 session_key = atoi(line);
361 json_object_array_add(obj, json_object_new_int(session_key));
362 json_object_object_add(msg, "sessions", obj);
363 readmultiline(&line, &len, "NETCONF <rpc> content (ending with CTRL+D): ");
Michal Vasko7f46ede2016-02-24 10:45:55 +0100364 obj = json_object_new_array();
365 json_object_array_add(obj, json_object_new_string(line));
366 json_object_object_add(msg, "contents", obj);
Michal Vaskoda0ab5c2015-11-13 13:24:51 +0100367 } else if (strcmp(argv[1], "getschema") == 0) {
368 /*
369 * Get information about NETCONF session
370 */
371 msg = json_object_new_object();
372 json_object_object_add(msg, "type", json_object_new_int(MSG_GETSCHEMA));
373 readline(&line, &len, "Session: ");
374 obj = json_object_new_array();
375 session_key = atoi(line);
376 json_object_array_add(obj, json_object_new_int(session_key));
377 json_object_object_add(msg, "sessions", obj);
378 readline(&line, &len, "Identificator: ");
379 json_object_object_add(msg, "identifier", json_object_new_string(line));
380 readline(&line, &len, "Format [YIN]: ");
381 json_object_object_add(msg, "format", json_object_new_string(line));
382 readline(&line, &len, "Version: ");
383 json_object_object_add(msg, "version", json_object_new_string(line));
384 } else if (strcmp(argv[1], "query") == 0) {
385 /*
386 * Query metadata about a node
387 */
388 msg = json_object_new_object();
389 json_object_object_add(msg, "type", json_object_new_int(SCH_QUERY));
390 readline(&line, &len, "Session: ");
391 obj = json_object_new_array();
392 session_key = atoi(line);
393 json_object_array_add(obj, json_object_new_int(session_key));
394 json_object_object_add(msg, "sessions", obj);
395 readline(&line, &len, "Filter: ");
396 obj = json_object_new_array();
397 json_object_array_add(obj, json_object_new_string(line));
398 json_object_object_add(msg, "filters", obj);
399 do {
400 readline(&line, &len, "Load children (y/n): ");
401 } while (strcmp(line, "y") && strcmp(line, "n"));
402 json_object_object_add(msg, "load_children", json_object_new_boolean(strcmp(line, "y") ? 0 : 1));
403 } else if (strcmp(argv[1], "merge") == 0) {
404 /*
405 * Merge configuration data with metadata
406 */
407 msg = json_object_new_object();
408 json_object_object_add(msg, "type", json_object_new_int(SCH_QUERY));
409 readline(&line, &len, "Session: ");
410 obj = json_object_new_array();
411 session_key = atoi(line);
412 json_object_array_add(obj, json_object_new_int(session_key));
413 json_object_object_add(msg, "sessions", obj);
414 readmultiline(&line, &len, "Configuration data (ending with CTRL+D): ");
415 obj = json_object_new_array();
416 json_object_array_add(obj, json_object_new_string(line));
417 json_object_object_add(msg, "configurations", obj);
418 } else {
419 /*
420 * Unknown request
421 */
422 fprintf(stderr, "Unknown command %s\n", argv[1]);
423 close(sock);
424 return (EXIT_FAILURE);
425 }
Tomas Cejkab272bf12012-09-05 16:49:12 +0200426
Michal Vaskoda0ab5c2015-11-13 13:24:51 +0100427 /* send the message */
428 if (msg != NULL) {
429 msg_text = json_object_to_json_string(msg);
430 asprintf (&chunked_msg_text, "\n#%d\n%s\n##\n", (int)strlen(msg_text), msg_text);
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200431
Michal Vaskoda0ab5c2015-11-13 13:24:51 +0100432 if (json_object_object_get(msg, "pass") == NULL) {
433 /* print message only if it does not contain password */
434 printf("Sending: %s\n", msg_text);
435 }
436 send(sock, chunked_msg_text, strlen(chunked_msg_text) + 1, 0);
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200437
Michal Vaskoda0ab5c2015-11-13 13:24:51 +0100438 json_object_put(msg);
439 free (chunked_msg_text);
440 } else {
441 close(sock);
442 return (EXIT_FAILURE);
443 }
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200444
Michal Vaskoda0ab5c2015-11-13 13:24:51 +0100445 /* read json in chunked framing */
446 buffer_size = 0;
447 buffer_len = 0;
448 buffer = NULL;
449 while (1) {
450 /* read chunk length */
451 if ((ret = recv (sock, &c, 1, 0)) != 1 || c != '\n') {
452 free (buffer);
453 buffer = NULL;
454 break;
455 }
456 if ((ret = recv (sock, &c, 1, 0)) != 1 || c != '#') {
457 free (buffer);
458 buffer = NULL;
459 break;
460 }
461 i=0;
462 memset (chunk_len_str, 0, 12);
463 while ((ret = recv (sock, &c, 1, 0) == 1 && (isdigit(c) || c == '#'))) {
464 if (i==0 && c == '#') {
465 if (recv (sock, &c, 1, 0) != 1 || c != '\n') {
466 /* end but invalid */
467 free (buffer);
468 buffer = NULL;
469 }
470 /* end of message, double-loop break */
471 goto msg_complete;
472 }
473 chunk_len_str[i++] = c;
474 }
475 if (c != '\n') {
476 free (buffer);
477 buffer = NULL;
478 break;
479 }
480 if ((chunk_len = atoi (chunk_len_str)) == 0) {
481 free (buffer);
482 buffer = NULL;
483 break;
484 }
485 buffer_size += chunk_len+1;
486 buffer = realloc (buffer, sizeof(char)*buffer_size);
487 if ((ret = recv (sock, buffer+buffer_len, chunk_len, 0)) == -1 || ret != chunk_len) {
488 free (buffer);
489 buffer = NULL;
490 break;
491 }
492 buffer_len += ret;
493 }
David Kupka1e3e4c82012-09-04 09:32:15 +0200494msg_complete:
495
Michal Vaskoda0ab5c2015-11-13 13:24:51 +0100496 if (buffer != NULL) {
497 reply = json_tokener_parse(buffer);
498 free (buffer);
499 } else {
500 reply = NULL;
501 }
502 free(line);
David Kupka1e3e4c82012-09-04 09:32:15 +0200503
Michal Vaskoda0ab5c2015-11-13 13:24:51 +0100504 printf("Received:\n");
505 if (reply == NULL) {
506 printf("(null)\n");
507 } else {
508 asprintf(&line, "%d", session_key);
509 json_object_object_get_ex(reply, line, &obj);
510 free(line);
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200511
Michal Vaskoda0ab5c2015-11-13 13:24:51 +0100512 json_object_object_get_ex(obj, "type", &obj2);
513 switch (json_object_get_int(obj2)) {
514 case 0:
515 printf("OK\n");
516 printf("%s\n", json_object_to_json_string_ext(reply, JSON_C_TO_STRING_PRETTY | JSON_C_TO_STRING_SPACED));
517 break;
518 case 1:
519 printf("DATA\n");
520 json_object_object_get_ex(obj, "data", &obj2);
521 msg_text = json_object_get_string(obj2);
522 obj = json_tokener_parse(msg_text);
523 printf("%s\n", json_object_to_json_string_ext(obj, JSON_C_TO_STRING_PRETTY | JSON_C_TO_STRING_SPACED));
524 json_object_put(obj);
525 break;
526 case 2:
527 printf("ERROR\n");
528 printf("%s\n", json_object_to_json_string_ext(reply, JSON_C_TO_STRING_PRETTY | JSON_C_TO_STRING_SPACED));
529 break;
530 case 3:
531 printf("INFO\n");
532 printf("%s\n", json_object_to_json_string_ext(reply, JSON_C_TO_STRING_PRETTY | JSON_C_TO_STRING_SPACED));
533 break;
534 default:
535 printf("(unknown)\n");
536 printf("%s\n", json_object_to_json_string_ext(reply, JSON_C_TO_STRING_PRETTY | JSON_C_TO_STRING_SPACED));
537 break;
538 }
539 json_object_put(reply);
540 }
541 close(sock);
542
543 return (EXIT_SUCCESS);
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200544}