blob: f79ae0799a10eea7223af123d486276b23579b06 [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>
5 * \date 2012
6 */
7/*
8 * Copyright (C) 2012 CESNET
9 *
10 * LICENSE TERMS
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in
19 * the documentation and/or other materials provided with the
20 * distribution.
21 * 3. Neither the name of the Company nor the names of its contributors
22 * may be used to endorse or promote products derived from this
23 * software without specific prior written permission.
24 *
25 * ALTERNATIVELY, provided that this notice is retained in full, this
26 * product may be distributed under the terms of the GNU General Public
27 * License (GPL) version 2 or later, in which case the provisions
28 * of the GPL apply INSTEAD OF those given above.
29 *
30 * This software is provided ``as is'', and any express or implied
31 * warranties, including, but not limited to, the implied warranties of
32 * merchantability and fitness for a particular purpose are disclaimed.
33 * In no event shall the company or contributors be liable for any
34 * direct, indirect, incidental, special, exemplary, or consequential
35 * damages (including, but not limited to, procurement of substitute
36 * goods or services; loss of use, data, or profits; or business
37 * interruption) however caused and on any theory of liability, whether
38 * in contract, strict liability, or tort (including negligence or
39 * otherwise) arising in any way out of the use of this software, even
40 * if advised of the possibility of such damage.
41 *
42 */
43
David Kupka1e3e4c82012-09-04 09:32:15 +020044#define _GNU_SOURCE
Radek Krejci8fd1f5e2012-07-24 17:33:36 +020045#include <unistd.h>
46#include <stdio.h>
47#include <stdlib.h>
48#include <string.h>
Tomas Cejkab272bf12012-09-05 16:49:12 +020049#include <err.h>
Radek Krejci8fd1f5e2012-07-24 17:33:36 +020050#include <errno.h>
51#include <sys/types.h>
52#include <sys/socket.h>
53#include <sys/un.h>
54#include <json/json.h>
David Kupka1e3e4c82012-09-04 09:32:15 +020055#include <ctype.h>
Radek Krejci8fd1f5e2012-07-24 17:33:36 +020056
Radek Krejci6cb08982012-07-25 18:01:06 +020057#define SOCKET_FILENAME "/tmp/mod_netconf.sock"
David Kupka1e3e4c82012-09-04 09:32:15 +020058#define BUFFER_SIZE 40960
Radek Krejci8fd1f5e2012-07-24 17:33:36 +020059
60typedef enum MSG_TYPE {
61 REPLY_OK,
62 REPLY_DATA,
63 REPLY_ERROR,
Radek Krejci9e04c7b2012-07-26 15:54:25 +020064 REPLY_INFO,
Radek Krejci8fd1f5e2012-07-24 17:33:36 +020065 MSG_CONNECT,
66 MSG_DISCONNECT,
67 MSG_GET,
68 MSG_GETCONFIG,
69 MSG_EDITCONFIG,
70 MSG_COPYCONFIG,
71 MSG_DELETECONFIG,
72 MSG_LOCK,
73 MSG_UNLOCK,
Radek Krejci9e04c7b2012-07-26 15:54:25 +020074 MSG_KILL,
Radek Krejci80c10d92012-07-30 08:38:50 +020075 MSG_INFO,
Tomas Cejka0aeca8b2012-12-22 19:56:03 +010076 MSG_GENERIC,
77 MSG_GETSCHEMA
Radek Krejci8fd1f5e2012-07-24 17:33:36 +020078} MSG_TYPE;
79
80void print_help(char* progname)
81{
82 printf("Usage: %s <command>\n", progname);
83 printf("Available commands:\n");
84 printf("\tconnect\n");
85 printf("\tdisconnect\n");
86 printf("\tcopy-config\n");
87 printf("\tdelete-config\n");
88 printf("\tedit-config\n");
89 printf("\tget\n");
90 printf("\tget-config\n");
91 printf("\tkill-session\n");
92 printf("\tlock\n");
93 printf("\tunlock\n");
Radek Krejci9e04c7b2012-07-26 15:54:25 +020094 printf("\tinfo\n");
Radek Krejci80c10d92012-07-30 08:38:50 +020095 printf("\tgeneric\n");
Radek Krejci8fd1f5e2012-07-24 17:33:36 +020096}
97
Tomas Cejkab272bf12012-09-05 16:49:12 +020098/**
99 * \brief Get multiline input text.
100 *
101 * Print given prompt and read text ending with CTRL+D.
102 * Output string is terminated by 0. Ending '\n' is removed.
103 *
104 * On error, err is called!
105 *
106 * \param[out] output - pointer to memory where string is stored
107 * \param[out] size - size of string return by getdelim()
108 * \param[in] prompt - text printed as a prompt
109 */
110void readmultiline(char **output, size_t *size, const char *prompt)
111{
112 printf(prompt);
113 if (getdelim (output, size, 'D' - 0x40, stdin) == -1) {
114 if (errno) {
115 err(errno, "Cannot read input.");
116 }
117 *output = (char *) malloc(sizeof(char));
118 **output = 0;
119 return;
120 }
121 (*output)[(*size)-1] = 0; /* input text end "sanitation" */
122 (*output)[(strlen(*output))-1] = 0; /* input text end "sanitation" */
123}
124
125/**
126 * \brief Get input text.
127 *
128 * Print given prompt and read one line of text.
129 * Output string is terminated by 0. Ending '\n' is removed.
130 *
131 * On error, err is called!
132 *
133 * \param[out] output - pointer to memory where string is stored
134 * \param[out] size - size of string return by getline()
135 * \param[in] prompt - text printed as a prompt
136 */
137void readline(char **output, size_t *size, const char *prompt)
138{
139 printf(prompt);
140 if (getline (output, size, stdin) == -1) {
141 if (errno) {
142 err(errno, "Cannot read input.");
143 }
144 }
145 (*output)[(*size)-1] = 0; /* input text end "sanitation" */
146 (*output)[(strlen(*output))-1] = 0; /* input text end "sanitation" */
147}
148
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200149int main (int argc, char* argv[])
150{
Kupka David00b9c5c2012-09-05 09:45:50 +0200151 json_object* msg = NULL, *reply = NULL, *capabilities = NULL;
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200152 const char* msg_text;
153 int sock;
154 struct sockaddr_un addr;
155 size_t len;
David Kupka1e3e4c82012-09-04 09:32:15 +0200156 char *buffer;
157 char* line = NULL, *chunked_msg_text;
Radek Krejci9e04c7b2012-07-26 15:54:25 +0200158 int i, alen;
David Kupka1e3e4c82012-09-04 09:32:15 +0200159 int buffer_size, buffer_len, ret, chunk_len;
160 char c, chunk_len_str[12];
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200161
162 if (argc != 2) {
163 print_help(argv[0]);
164 return (2);
165 }
166
167 /* connect to the daemon */
168 sock = socket(PF_UNIX, SOCK_STREAM, 0);
169 if (sock == -1) {
170 fprintf(stderr, "Creating socket failed (%s)", strerror(errno));
171 return (EXIT_FAILURE);
172 }
173 addr.sun_family = AF_UNIX;
174 strncpy(addr.sun_path, SOCKET_FILENAME, sizeof(addr.sun_path));
175 len = strlen(addr.sun_path) + sizeof(addr.sun_family);
176 if (connect(sock, (struct sockaddr *) &addr, len) == -1) {
177 fprintf(stderr, "Connecting to mod_netconf (%s) failed (%s)", SOCKET_FILENAME, strerror(errno));
178 close(sock);
179 return (EXIT_FAILURE);
180 }
181
182 line = malloc(sizeof(char) * BUFFER_SIZE);
183
184 if (strcmp(argv[1], "connect") == 0) {
Radek Krejciaa422df2012-07-25 18:04:59 +0200185 /*
186 * create NETCONF session
187 */
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200188 msg = json_object_new_object();
189 json_object_object_add(msg, "type", json_object_new_int(MSG_CONNECT));
Tomas Cejka42434462012-09-05 18:11:43 +0200190 readline(&line, &len, "Hostname: ");
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200191 json_object_object_add(msg, "host", json_object_new_string(line));
Tomas Cejka42434462012-09-05 18:11:43 +0200192 readline(&line, &len, "Port: ");
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200193 json_object_object_add(msg, "port", json_object_new_string(line));
Tomas Cejka42434462012-09-05 18:11:43 +0200194 readline(&line, &len, "Username: ");
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200195 json_object_object_add(msg, "user", json_object_new_string(line));
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200196 system("stty -echo");
Tomas Cejka42434462012-09-05 18:11:43 +0200197 readline(&line, &len, "Password: ");
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200198 system("stty echo");
199 printf("\n");
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200200 json_object_object_add(msg, "pass", json_object_new_string(line));
Tomas Cejka42434462012-09-05 18:11:43 +0200201
Tomas Cejkab272bf12012-09-05 16:49:12 +0200202 /* clean read password - it is needless because we have a copy in json... :-( */
203 memset(line, 'X', len);
204 free(line);
205 line = NULL;
206
207 printf("Supported capabilities\n");
208 capabilities = json_object_new_array();
209 json_object_object_add(msg, "capabilities", capabilities);
210 while (1) {
211 readline(&line, &len, "Next capability (empty for end): ");
212 if (strlen(line) == 0) {
213 break;
214 }
215 json_object_array_add (capabilities, json_object_new_string(line));
216 }
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200217 } else if (strcmp(argv[1], "disconnect") == 0) {
Radek Krejciaa422df2012-07-25 18:04:59 +0200218 /*
219 * Close NETCONF session
220 */
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200221 msg = json_object_new_object();
222 json_object_object_add(msg, "type", json_object_new_int(MSG_DISCONNECT));
Tomas Cejkab272bf12012-09-05 16:49:12 +0200223 readline(&line, &len, "Session: ");
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200224 json_object_object_add(msg, "session", json_object_new_string(line));
225 } else if (strcmp(argv[1], "copy-config") == 0) {
Radek Krejciaa422df2012-07-25 18:04:59 +0200226 /*
227 * NETCONF <copy-config>
228 */
Radek Krejci035bf4e2012-07-25 10:59:09 +0200229 msg = json_object_new_object();
230 json_object_object_add(msg, "type", json_object_new_int(MSG_COPYCONFIG));
Tomas Cejkab272bf12012-09-05 16:49:12 +0200231 readline(&line, &len, "Session: ");
Radek Krejci035bf4e2012-07-25 10:59:09 +0200232 json_object_object_add(msg, "session", json_object_new_string(line));
Tomas Cejkab272bf12012-09-05 16:49:12 +0200233 readline(&line, &len, "Source (running|startup|candidate): ");
Radek Krejciae021c12012-07-25 18:03:52 +0200234 if (strlen(line) > 0) {
235 json_object_object_add(msg, "source", json_object_new_string(line));
236 } else {
Tomas Cejkab272bf12012-09-05 16:49:12 +0200237 readmultiline(&line, &len, "Configuration data (ending with CTRL+D): ");
Radek Krejciae021c12012-07-25 18:03:52 +0200238 json_object_object_add(msg, "config", json_object_new_string(line));
239 }
Tomas Cejkab272bf12012-09-05 16:49:12 +0200240 readline(&line, &len, "Target (running|startup|candidate): ");
Radek Krejci035bf4e2012-07-25 10:59:09 +0200241 json_object_object_add(msg, "target", json_object_new_string(line));
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200242 } else if (strcmp(argv[1], "delete-config") == 0) {
Radek Krejciaa422df2012-07-25 18:04:59 +0200243 /*
244 * NETCONF <delete-config>
245 */
246 msg = json_object_new_object();
247 json_object_object_add(msg, "type", json_object_new_int(MSG_DELETECONFIG));
Tomas Cejkab272bf12012-09-05 16:49:12 +0200248 readline(&line, &len, "Session: ");
Radek Krejciaa422df2012-07-25 18:04:59 +0200249 json_object_object_add(msg, "session", json_object_new_string(line));
Tomas Cejkab272bf12012-09-05 16:49:12 +0200250 readline(&line, &len, "Target (running|startup|candidate): ");
Radek Krejciaa422df2012-07-25 18:04:59 +0200251 json_object_object_add(msg, "target", json_object_new_string(line));
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200252 } else if (strcmp(argv[1], "edit-config") == 0) {
Radek Krejciaa422df2012-07-25 18:04:59 +0200253 /*
254 * NETCONF <edit-config>
255 */
256 msg = json_object_new_object();
257 json_object_object_add(msg, "type", json_object_new_int(MSG_EDITCONFIG));
Tomas Cejkab272bf12012-09-05 16:49:12 +0200258 readline(&line, &len, "Session: ");
Radek Krejciaa422df2012-07-25 18:04:59 +0200259 json_object_object_add(msg, "session", json_object_new_string(line));
Tomas Cejkab272bf12012-09-05 16:49:12 +0200260 readline(&line, &len, "Target (running|startup|candidate): ");
Radek Krejciaa422df2012-07-25 18:04:59 +0200261 json_object_object_add(msg, "target", json_object_new_string(line));
Tomas Cejkab272bf12012-09-05 16:49:12 +0200262 readline(&line, &len, "Default operation (merge|replace|none): ");
Radek Krejciaa422df2012-07-25 18:04:59 +0200263 if (strlen(line) > 0) {
264 json_object_object_add(msg, "default-operation", json_object_new_string(line));
265 }
Tomas Cejkab272bf12012-09-05 16:49:12 +0200266 readline(&line, &len, "Error option (stop-on-error|continue-on-error|rollback-on-error): ");
Radek Krejciaa422df2012-07-25 18:04:59 +0200267 if (strlen(line) > 0) {
268 json_object_object_add(msg, "error-option", json_object_new_string(line));
269 }
Tomas Cejkab272bf12012-09-05 16:49:12 +0200270 readmultiline(&line, &len, "Configuration data (ending with CTRL+D): ");
Radek Krejcib1e08f42012-07-26 10:54:28 +0200271 json_object_object_add(msg, "config", json_object_new_string(line));
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200272 } else if (strcmp(argv[1], "get") == 0) {
Radek Krejciaa422df2012-07-25 18:04:59 +0200273 /*
274 * NETCONF <get>
275 */
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200276 msg = json_object_new_object();
277 json_object_object_add(msg, "type", json_object_new_int(MSG_GET));
Tomas Cejkab272bf12012-09-05 16:49:12 +0200278 readline(&line, &len, "Session: ");
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200279 json_object_object_add(msg, "session", json_object_new_string(line));
Tomas Cejkab272bf12012-09-05 16:49:12 +0200280 readmultiline(&line, &len, "Filter (ending with CTRL+D): ");
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200281 if (strlen(line) > 0) {
282 json_object_object_add(msg, "filter", json_object_new_string(line));
283 }
284 } else if (strcmp(argv[1], "get-config") == 0) {
Radek Krejciaa422df2012-07-25 18:04:59 +0200285 /*
286 * NETCONF <get-config>
287 */
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200288 msg = json_object_new_object();
289 json_object_object_add(msg, "type", json_object_new_int(MSG_GETCONFIG));
Tomas Cejkab272bf12012-09-05 16:49:12 +0200290 readline(&line, &len, "Session: ");
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200291 json_object_object_add(msg, "session", json_object_new_string(line));
Tomas Cejkab272bf12012-09-05 16:49:12 +0200292 readline(&line, &len, "Source (running|startup|candidate): ");
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200293 json_object_object_add(msg, "source", json_object_new_string(line));
Tomas Cejkab272bf12012-09-05 16:49:12 +0200294 readmultiline(&line, &len, "Filter (ending with CTRL+D): ");
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200295 if (strlen(line) > 0) {
296 json_object_object_add(msg, "filter", json_object_new_string(line));
297 }
298 } else if (strcmp(argv[1], "kill-session") == 0) {
Radek Krejciaa422df2012-07-25 18:04:59 +0200299 /*
300 * NETCONF <kill-session>
301 */
302 msg = json_object_new_object();
303 json_object_object_add(msg, "type", json_object_new_int(MSG_KILL));
Tomas Cejkab272bf12012-09-05 16:49:12 +0200304 readline(&line, &len, "Session: ");
Radek Krejciaa422df2012-07-25 18:04:59 +0200305 json_object_object_add(msg, "session", json_object_new_string(line));
Tomas Cejkab272bf12012-09-05 16:49:12 +0200306 readline(&line, &len, "Kill session with ID: ");
Radek Krejciaa422df2012-07-25 18:04:59 +0200307 json_object_object_add(msg, "session-id", json_object_new_string(line));
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200308 } else if (strcmp(argv[1], "lock") == 0) {
Radek Krejciaa422df2012-07-25 18:04:59 +0200309 /*
310 * NETCONF <lock>
311 */
312 msg = json_object_new_object();
313 json_object_object_add(msg, "type", json_object_new_int(MSG_LOCK));
Tomas Cejkab272bf12012-09-05 16:49:12 +0200314 readline(&line, &len, "Session: ");
Radek Krejciaa422df2012-07-25 18:04:59 +0200315 json_object_object_add(msg, "session", json_object_new_string(line));
Tomas Cejkab272bf12012-09-05 16:49:12 +0200316 readline(&line, &len, "Target (running|startup|candidate): ");
Radek Krejciaa422df2012-07-25 18:04:59 +0200317 json_object_object_add(msg, "target", json_object_new_string(line));
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200318 } else if (strcmp(argv[1], "unlock") == 0) {
Radek Krejciaa422df2012-07-25 18:04:59 +0200319 /*
320 * NETCONF <unlock>
321 */
322 msg = json_object_new_object();
323 json_object_object_add(msg, "type", json_object_new_int(MSG_UNLOCK));
Tomas Cejkab272bf12012-09-05 16:49:12 +0200324 readline(&line, &len,"Session: ");
Radek Krejciaa422df2012-07-25 18:04:59 +0200325 json_object_object_add(msg, "session", json_object_new_string(line));
Tomas Cejkab272bf12012-09-05 16:49:12 +0200326 readline(&line, &len, "Target (running|startup|candidate): ");
Radek Krejciaa422df2012-07-25 18:04:59 +0200327 json_object_object_add(msg, "target", json_object_new_string(line));
Radek Krejci9e04c7b2012-07-26 15:54:25 +0200328 } else if (strcmp(argv[1], "info") == 0) {
329 /*
330 * Get information about NETCONF session
331 */
332 msg = json_object_new_object();
333 json_object_object_add(msg, "type", json_object_new_int(MSG_INFO));
Tomas Cejkab272bf12012-09-05 16:49:12 +0200334 readline(&line, &len, "Session: ");
Radek Krejci9e04c7b2012-07-26 15:54:25 +0200335 json_object_object_add(msg, "session", json_object_new_string(line));
Radek Krejci80c10d92012-07-30 08:38:50 +0200336 } else if (strcmp(argv[1], "generic") == 0) {
337 /*
338 * Generic NETCONF request
339 */
340 msg = json_object_new_object();
341 json_object_object_add(msg, "type", json_object_new_int(MSG_GENERIC));
Tomas Cejkab272bf12012-09-05 16:49:12 +0200342 readline(&line, &len, "Session: ");
Radek Krejci80c10d92012-07-30 08:38:50 +0200343 json_object_object_add(msg, "session", json_object_new_string(line));
Tomas Cejkab272bf12012-09-05 16:49:12 +0200344 readmultiline(&line, &len, "NETCONF <rpc> content (ending with CTRL+D): ");
Radek Krejci80c10d92012-07-30 08:38:50 +0200345 json_object_object_add(msg, "content", json_object_new_string(line));
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200346 } else {
Radek Krejciaa422df2012-07-25 18:04:59 +0200347 /*
348 * Unknown request
349 */
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200350 fprintf(stderr, "Unknown command %s\n", argv[1]);
351 close(sock);
352 return (EXIT_FAILURE);
353 }
354
355 /* send the message */
356 if (msg != NULL) {
357 msg_text = json_object_to_json_string(msg);
David Kupka1e3e4c82012-09-04 09:32:15 +0200358 asprintf (&chunked_msg_text, "\n#%d\n%s\n##\n", (int)strlen(msg_text), msg_text);
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200359
Radek Krejci035bf4e2012-07-25 10:59:09 +0200360 if (json_object_object_get(msg, "pass") == NULL) {
361 /* print message only if it does not contain password */
362 printf("Sending: %s\n", msg_text);
363 }
David Kupka1e3e4c82012-09-04 09:32:15 +0200364 send(sock, chunked_msg_text, strlen(chunked_msg_text) + 1, 0);
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200365
366 json_object_put(msg);
David Kupka1e3e4c82012-09-04 09:32:15 +0200367 free (chunked_msg_text);
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200368 } else {
369 close(sock);
370 return (EXIT_FAILURE);
371 }
372
David Kupka1e3e4c82012-09-04 09:32:15 +0200373 /* read json in chunked framing */
374 buffer_size = 0;
375 buffer_len = 0;
376 buffer = NULL;
377 while (1) {
378 /* read chunk length */
379 if ((ret = recv (sock, &c, 1, 0)) != 1 || c != '\n') {
380 free (buffer);
381 buffer = NULL;
382 break;
383 }
384 if ((ret = recv (sock, &c, 1, 0)) != 1 || c != '#') {
385 free (buffer);
386 buffer = NULL;
387 break;
388 }
389 i=0;
390 memset (chunk_len_str, 0, 12);
391 while ((ret = recv (sock, &c, 1, 0) == 1 && (isdigit(c) || c == '#'))) {
392 if (i==0 && c == '#') {
393 if (recv (sock, &c, 1, 0) != 1 || c != '\n') {
394 /* end but invalid */
395 free (buffer);
396 buffer = NULL;
397 }
398 /* end of message, double-loop break */
399 goto msg_complete;
400 }
401 chunk_len_str[i++] = c;
402 }
403 if (c != '\n') {
404 free (buffer);
405 buffer = NULL;
406 break;
407 }
408 if ((chunk_len = atoi (chunk_len_str)) == 0) {
409 free (buffer);
410 buffer = NULL;
411 break;
412 }
413 buffer_size += chunk_len+1;
414 buffer = realloc (buffer, sizeof(char)*buffer_size);
415 if ((ret = recv (sock, buffer+buffer_len, chunk_len, 0)) == -1 || ret != chunk_len) {
416 free (buffer);
417 buffer = NULL;
418 break;
419 }
420 buffer_len += ret;
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200421 }
David Kupka1e3e4c82012-09-04 09:32:15 +0200422msg_complete:
423
424 if (buffer != NULL) {
425 reply = json_tokener_parse(buffer);
426 free (buffer);
427 } else {
428 reply = NULL;
429 }
430
Radek Krejci035bf4e2012-07-25 10:59:09 +0200431 printf("Received:\n");
432 if (reply == NULL) {
433 printf("(null)\n");
434 } else {
435 json_object_object_foreach(reply, key, value) {
436 printf("Key: %s, Value: ", key);
437 switch (json_object_get_type(value)) {
438 case json_type_string:
439 printf("%s\n", json_object_get_string(value));
440 break;
441 case json_type_int:
442 printf("%d\n", json_object_get_int(value));
443 break;
Radek Krejci9e04c7b2012-07-26 15:54:25 +0200444 case json_type_array:
445 printf("\n");
446 alen = json_object_array_length(value);
447 for (i = 0; i < alen; i++) {
448 printf("\t(%d) %s\n", i, json_object_get_string(json_object_array_get_idx(value, i)));
449 }
450 break;
Radek Krejci035bf4e2012-07-25 10:59:09 +0200451 default:
452 printf("\n");
453 break;
454 }
455 }
456 json_object_put(reply);
457 }
Radek Krejci8fd1f5e2012-07-24 17:33:36 +0200458 close(sock);
459 free(line);
460
461 return (EXIT_SUCCESS);
462}