Statistics
| Revision:

root / trunk / glue / glue_json.c @ 1853

History | View | Annotate | Download (69.2 KB)

1
/* 
2
    Copyright (C) 2005-2010  Erik van Pienbroek
3

                
4
    This program is free software; you can redistribute it and/or modify
5
    it under the terms of the GNU General Public License as published by
6
    the Free Software Foundation; either version 2 of the License, or
7
    (at your option) any later version.
8

                
9
    This program is distributed in the hope that it will be useful,
10
    but WITHOUT ANY WARRANTY; without even the implied warranty of
11
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
    GNU General Public License for more details.
13

                
14
    You should have received a copy of the GNU General Public License
15
    along with this program; if not, write to the Free Software
16
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
*/
18

                
19
#ifdef HAVE_CONFIG_H
20
#include "config.h"
21
#endif
22

                
23
#include 
24
#include 
25
#include 
26

                
27
#include 
28
#include 
29

                
30
#include "nntpgrab.h"
31
#include "nntpgrab_utils.h"
32
#include "nntpgrab_internal.h"
33
#include "nntpgrab_glue.h"
34
#include "nntpgrab_glue_internal.h"
35

                
36
#include "json_object.h"
37
#include "json.h"
38
#include "jsonrpc.h"
39

                
40
static void process_foreach_collection_event(const char *msg, struct json_object *params);
41
static void process_foreach_file_event(const char *msg, struct json_object *params);
42
static void process_foreach_group_event(const char *msg, struct json_object *params);
43

                
44
static struct json_object *
45
get_json_param(const char *msg, struct json_object *params, const char *field, const char *event_name, enum json_type type)
46
{
47
    struct json_object *obj;
48

                
49
    obj = json_object_object_get(params, (char*) field);
50
    if (!obj) {
51
        g_print(__FILE__ ":%i field '%s' is missing for event or method '%s', msg = %s\n", __LINE__, field, event_name, msg);
52
        return NULL;
53
    }
54

                
55
    if (json_object_get_type(obj) != type) {
56
        g_print(__FILE__ ":%i field '%s' is of invalid type for event or method '%s', msg = %s\n", __LINE__, field, event_name, msg);
57
        return NULL;
58
    }
59

                
60
    return obj;
61
}
62

                
63
#define get_param(msg, params, field, event_name, type, dest)                                           \
64
    {                                                                                                   \
65
        struct json_object *obj = get_json_param(msg, params, field, event_name, json_type_ ## type);   \
66
        if (!obj) {                                                                                     \
67
            return;                                                                                     \
68
        }                                                                                               \
69
        dest = json_object_get_ ## type (obj);                                                          \
70
    }
71

                
72
static void
73
emit_part_download_start(const char *msg, struct json_object *params)
74
{
75
    char *servername;
76
    int conn_id;
77
    char *collection_name;
78
    char *subject;
79
    int part_num;
80

                
81
    get_param(msg, params, "servername", "part_download_start", string, servername);
82
    get_param(msg, params, "conn_id", "part_download_start", int, conn_id);
83
    get_param(msg, params, "collection_name", "part_download_start", string, collection_name);
84
    get_param(msg, params, "subject", "part_download_start", string, subject);
85
    get_param(msg, params, "part_num", "part_download_start", int, part_num);
86

                
87
    nntpgrab_core_emit_part_download_start(FALSE, servername, conn_id, collection_name, subject, part_num);
88
}
89

                
90
static void
91
emit_part_done(const char *msg, struct json_object *params)
92
{
93
    char *servername;
94
    int conn_id;
95
    char *collection_name;
96
    char *subject;
97
    int part_num;
98
    int size;
99

                
100
    get_param(msg, params, "servername", "part_done", string, servername);
101
    get_param(msg, params, "conn_id", "part_done", int, conn_id);
102
    get_param(msg, params, "collection_name", "part_done", string, collection_name);
103
    get_param(msg, params, "subject", "part_done", string, subject);
104
    get_param(msg, params, "part_num", "part_done", int, part_num);
105
    get_param(msg, params, "size", "part_done", int, size);
106

                
107
    nntpgrab_core_emit_part_done(FALSE, servername, conn_id, collection_name, subject, part_num, size);
108
}
109

                
110
static void
111
emit_part_failed(const char *msg, struct json_object *params)
112
{
113
    char *servername;
114
    int conn_id;
115
    char *collection_name;
116
    char *subject;
117
    int part_num;
118
    int size;
119
    gboolean all_servers_tried;
120

                
121
    get_param(msg, params, "servername", "part_done", string, servername);
122
    get_param(msg, params, "conn_id", "part_done", int, conn_id);
123
    get_param(msg, params, "collection_name", "part_done", string, collection_name);
124
    get_param(msg, params, "subject", "part_done", string, subject);
125
    get_param(msg, params, "part_num", "part_done", int, part_num);
126
    get_param(msg, params, "size", "part_done", int, size);
127
    get_param(msg, params, "all_servers_tried", "part_done", boolean, all_servers_tried);
128

                
129
    nntpgrab_core_emit_part_failed(FALSE, servername, conn_id, collection_name, subject, part_num, size, all_servers_tried);
130
}
131

                
132
static void
133
emit_traffic_monitor_update(const char *msg, struct json_object *params)
134
{
135
    int bytes_received[10];
136
    int stamp;
137

                
138
    get_param(msg, params, "bytes_received1",  "traffic_monitor_update", int, bytes_received[0]);
139
    get_param(msg, params, "bytes_received2",  "traffic_monitor_update", int, bytes_received[1]);
140
    get_param(msg, params, "bytes_received3",  "traffic_monitor_update", int, bytes_received[2]);
141
    get_param(msg, params, "bytes_received4",  "traffic_monitor_update", int, bytes_received[3]);
142
    get_param(msg, params, "bytes_received5",  "traffic_monitor_update", int, bytes_received[4]);
143
    get_param(msg, params, "bytes_received6",  "traffic_monitor_update", int, bytes_received[5]);
144
    get_param(msg, params, "bytes_received7",  "traffic_monitor_update", int, bytes_received[6]);
145
    get_param(msg, params, "bytes_received8",  "traffic_monitor_update", int, bytes_received[7]);
146
    get_param(msg, params, "bytes_received9",  "traffic_monitor_update", int, bytes_received[8]);
147
    get_param(msg, params, "bytes_received10", "traffic_monitor_update", int, bytes_received[9]);
148
    get_param(msg, params, "stamp", "traffic_monitor_update", int, stamp);
149

                
150
    nntpgrab_core_emit_traffic_monitor_update(FALSE, bytes_received, stamp);
151
}
152

                
153
static void
154
emit_part_progress_update(const char *msg, struct json_object *params)
155
{
156
    char *servername;
157
    int conn_id;
158
    char *collection_name;
159
    char *subject;
160
    int part_num;
161
    int bytes_downloaded;
162
    int bytes_total;
163

                
164
    get_param(msg, params, "servername", "part_progress_update", string, servername);
165
    get_param(msg, params, "conn_id", "part_progress_update", int, conn_id);
166
    get_param(msg, params, "collection_name", "part_progress_update", string, collection_name);
167
    get_param(msg, params, "subject", "part_progress_update", string, subject);
168
    get_param(msg, params, "part_num", "part_progress_update", int, part_num);
169
    get_param(msg, params, "bytes_downloaded", "part_progress_update", int, bytes_downloaded);
170
    get_param(msg, params, "bytes_total", "part_progress_update", int, bytes_total);
171

                
172
    nntpgrab_core_emit_part_progress_update(FALSE, servername, conn_id, collection_name, subject, part_num, bytes_downloaded, bytes_total);
173
}
174

                
175
static void
176
emit_collection_added(const char *msg, struct json_object *params)
177
{
178
    char *collection_name;
179
    char *poster;
180

                
181
    get_param(msg, params, "collection_name", "collection_added", string, collection_name);
182
    get_param(msg, params, "poster", "collection_added", string, poster);
183

                
184
    nntpgrab_core_emit_collection_added(FALSE, collection_name, poster);
185
}
186

                
187
static void
188
emit_collection_removed(const char *msg, struct json_object *params)
189
{
190
    char *collection_name;
191

                
192
    get_param(msg, params, "collection_name", "collection_removed", string, collection_name);
193

                
194
    nntpgrab_core_emit_collection_removed(FALSE, collection_name);
195
}
196

                
197
static void
198
emit_collection_modified(const char *msg, struct json_object *params)
199
{
200
    char *collection_name;
201
    char *poster;
202

                
203
    get_param(msg, params, "collection_name", "collection_modified", string, collection_name);
204
    get_param(msg, params, "poster", "collection_modified", string, poster);
205

                
206
    nntpgrab_core_emit_collection_modified(FALSE, collection_name, poster);
207
}
208

                
209
static void
210
emit_file_added(const char *msg, struct json_object *params)
211
{
212
    struct json_object *obj;
213
    int len;
214
    int i;
215
    char *collection_name;
216
    char *subject;
217
    char *poster;
218
    int stamp;
219
    guint64 file_size;
220
    guint64 total_size;
221
    guint64 total_size_remaining;
222
    NGTaskState status;
223
    int num_parts;
224
    GList *groups;
225

                
226
    get_param(msg, params, "collection_name", "file_added", string, collection_name);
227
    get_param(msg, params, "subject", "file_added", string, subject);
228
    get_param(msg, params, "poster", "file_added", string, poster);
229
    get_param(msg, params, "stamp", "file_added", int, stamp);
230
    get_param(msg, params, "file_size", "file_added", int, file_size);
231
    get_param(msg, params, "total_size", "file_added", int, total_size);
232
    get_param(msg, params, "total_size_remaining", "file_added", int, total_size_remaining);
233
    get_param(msg, params, "status", "file_added", int, status);
234
    get_param(msg, params, "num_parts", "file_added", int, num_parts);
235

                
236
    obj = get_json_param(msg, params, "groups", "file_added", json_type_array);
237
    if (!obj) {
238
        return;
239
    }
240

                
241
    groups = NULL;
242
    len = json_object_array_length(obj);
243
    for (i = 0; i < len; i++) {
244
        struct json_object *group = json_object_array_get_idx(obj, i);
245
        char *groupname;
246

                
247
        g_return_if_fail(group != NULL);
248

                
249
        groupname = json_object_get_string(group);
250

                
251
        g_return_if_fail(groupname != NULL);
252

                
253
        groups = g_list_append(groups, groupname);
254
    }
255

                
256
    nntpgrab_core_emit_file_added(FALSE, collection_name, subject, poster, stamp, file_size * 1024, total_size * 1024, total_size_remaining * 1024, status, num_parts, groups);
257

                
258
    g_list_free(groups);
259
}
260

                
261
static void
262
emit_file_removed(const char *msg, struct json_object *params)
263
{
264
    char *collection_name;
265
    char *subject;
266
    guint64 total_size;
267
    guint64 total_size_remaining;
268

                
269
    get_param(msg, params, "collection_name", "file_removed", string, collection_name);
270
    get_param(msg, params, "subject", "file_removed", string, subject);
271
    get_param(msg, params, "total_size", "file_removed", int, total_size);
272
    get_param(msg, params, "total_size_remaining", "file_removed", int, total_size_remaining);
273

                
274
    nntpgrab_core_emit_file_removed(FALSE, collection_name, subject, total_size * 1024, total_size_remaining * 1024);
275
}
276

                
277
static void
278
emit_file_download_state_update(const char *msg, struct json_object *params)
279
{
280
    char *collection_name;
281
    char *subject;
282
    int num_parts_total;
283
    int num_parts_done;
284
    int num_parts_failed;
285
    guint64 file_size;
286
    guint64 file_size_remaining;
287
    guint64 total_size;
288
    guint64 total_size_remaining;
289

                
290
    get_param(msg, params, "collection_name", "file_download_state_update", string, collection_name);
291
    get_param(msg, params, "subject", "file_download_state_update", string, subject);
292
    get_param(msg, params, "num_parts_total", "file_download_state_update", int, num_parts_total);
293
    get_param(msg, params, "num_parts_done", "file_download_state_update", int, num_parts_done);
294
    get_param(msg, params, "num_parts_failed", "file_download_state_update", int, num_parts_failed);
295
    get_param(msg, params, "file_size", "file_download_state_update", int, file_size);
296
    get_param(msg, params, "file_size_remaining", "file_download_state_update", int, file_size_remaining);
297
    get_param(msg, params, "total_size", "file_download_state_update", int, total_size);
298
    get_param(msg, params, "total_size_remaining", "file_download_state_update", int, total_size_remaining);
299

                
300
    nntpgrab_core_emit_file_download_state_update(FALSE, collection_name, subject, num_parts_total, num_parts_done, num_parts_failed, file_size * 1024, file_size_remaining * 1024, total_size * 1024, total_size_remaining * 1024);
301
}
302

                
303
static void
304
emit_file_state_changed(const char *msg, struct json_object *params)
305
{
306
    char *collection_name;
307
    char *subject;
308
    char *real_filename;
309
    int old_state;
310
    int new_state;
311
    guint64 file_size_remaining;
312
    guint64 total_size;
313
    guint64 total_size_remaining;
314

                
315
    get_param(msg, params, "collection_name", "file_state_changed", string, collection_name);
316
    get_param(msg, params, "subject", "file_state_changed", string, subject);
317
    get_param(msg, params, "real_filename", "file_state_changed", string, real_filename);
318
    get_param(msg, params, "old_state", "file_state_changed", int, old_state);
319
    get_param(msg, params, "new_state", "file_state_changed", int, new_state);
320
    get_param(msg, params, "file_size_remaining", "file_state_changed", int, file_size_remaining);
321
    get_param(msg, params, "total_size", "file_state_changed", int, total_size);
322
    get_param(msg, params, "total_size_remaining", "file_state_changed", int, total_size_remaining);
323

                
324
    nntpgrab_core_emit_file_state_changed(FALSE, collection_name, subject, real_filename, old_state, new_state, file_size_remaining * 1024, total_size * 1024, total_size_remaining * 1024);
325
}
326

                
327
static void
328
emit_connection_connecting(const char *msg, struct json_object *params)
329
{
330
    char *servername;
331
    int conn_id;
332

                
333
    get_param(msg, params, "servername", "connection_connecting", string, servername);
334
    get_param(msg, params, "conn_id", "connection_connecting", int, conn_id);
335

                
336
    nntpgrab_core_emit_connecting(FALSE, servername, conn_id);
337
}
338

                
339
static void
340
emit_connection_connected(const char *msg, struct json_object *params)
341
{
342
    char *servername;
343
    int conn_id;
344
    char *welcome_msg;
345

                
346
    get_param(msg, params, "servername", "connection_connected", string, servername);
347
    get_param(msg, params, "conn_id", "connection_connected", int, conn_id);
348
    get_param(msg, params, "welcome_msg", "connection_connected", string, welcome_msg);
349

                
350
    nntpgrab_core_emit_connected(FALSE, servername, conn_id, welcome_msg);
351
}
352

                
353
static void
354
emit_connection_disconnect(const char *msg, struct json_object *params)
355
{
356
    char *servername;
357
    int conn_id;
358
    NNTPDisconnectType disconnect_type;
359
    char *reason;
360

                
361
    get_param(msg, params, "servername", "connection_disconnect", string, servername);
362
    get_param(msg, params, "conn_id", "connection_disconnect", int, conn_id);
363
    get_param(msg, params, "disconnect_type", "connection_disconnect", int, disconnect_type);
364
    get_param(msg, params, "reason", "connection_disconnect", string, reason);
365

                
366
    nntpgrab_core_emit_disconnect(FALSE, servername, conn_id, disconnect_type, reason);
367
}
368

                
369
static void
370
emit_schedular_state_changed(const char *msg, struct json_object *params)
371
{
372
    NGSchedularState new_state;
373
    char *reason;
374

                
375
    get_param(msg, params, "new_state", "schedular_state_changed", int, new_state);
376
    get_param(msg, params, "reason", "schedular_state_changed", string, reason);
377

                
378
    nntpgrab_core_emit_schedular_state_changed(FALSE, new_state, (strlen(reason) > 0 ? reason : NULL));
379
}
380

                
381
static void
382
emit_log_message(const char *msg, struct json_object *params)
383
{
384
    char *component;
385
    NGLogLevel log_level;
386
    char *message;
387

                
388
    get_param(msg, params, "component", "log_message", string, component);
389
    get_param(msg, params, "log_level", "log_message", int, log_level);
390
    get_param(msg, params, "msg", "log_message", string, message);
391

                
392
    nntpgrab_core_emit_log_message(FALSE, component, log_level, message, TRUE, FALSE);
393
}
394

                
395
static void
396
emit_task_moved(const char *msg, struct json_object *params)
397
{
398
    char *orig_collection_name;
399
    char *subject;
400
    char *new_collection_name;
401
    int old_position;
402
    int new_position;
403

                
404
    get_param(msg, params, "orig_collection_name", "task_moved", string, orig_collection_name);
405
    get_param(msg, params, "subject", "task_moved", string, subject);
406
    get_param(msg, params, "new_collection_name", "task_moved", string, new_collection_name);
407
    get_param(msg, params, "old_position", "task_moved", int, old_position);
408
    get_param(msg, params, "new_position", "task_moved", int, new_position);
409

                
410
    nntpgrab_core_emit_file_moved(FALSE, orig_collection_name, subject, new_collection_name, old_position, new_position);
411
}
412

                
413
static void
414
emit_collection_moved(const char *msg, struct json_object *params)
415
{
416
    char *collection_name;
417
    int old_position;
418
    int new_position;
419

                
420
    get_param(msg, params, "collection_name", "collection_moved", string, collection_name);
421
    get_param(msg, params, "old_position", "collection_moved", int, old_position);
422
    get_param(msg, params, "new_position", "collection_moved", int, new_position);
423

                
424
    nntpgrab_core_emit_collection_moved(FALSE, collection_name, old_position, new_position);
425
}
426

                
427
static void
428
emit_plugin_loaded(const char *msg, struct json_object *params)
429
{
430
    char *plugin_name;
431
    gboolean is_persistent;
432

                
433
    get_param(msg, params, "plugin_name", "plugin_loaded", string, plugin_name);
434
    get_param(msg, params, "is_persistent", "plugin_loaded", boolean, is_persistent);
435

                
436
    nntpgrab_core_emit_plugin_loaded(FALSE, plugin_name, is_persistent);
437
}
438

                
439
static void
440
emit_plugin_unloaded(const char *msg, struct json_object *params)
441
{
442
    char *plugin_name;
443

                
444
    get_param(msg, params, "plugin_name", "plugin_unloaded", string, plugin_name);
445

                
446
    nntpgrab_core_emit_plugin_unloaded(FALSE, plugin_name);
447
}
448

                
449
static void
450
emit_plugin_event(const char *msg, struct json_object *params)
451
{
452
    int i;
453
    int len;
454
    struct json_object *obj;
455
    char *plugin_name;
456
    char *event_name;
457
    char **values;
458

                
459
    get_param(msg, params, "plugin_name", "plugin_event", string, plugin_name);
460
    get_param(msg, params, "event_name", "plugin_event", string, event_name);
461

                
462
    obj = get_json_param(msg, params, "values", "plugin_event", json_type_array);
463
    if (!obj) {
464
        return;
465
    }
466

                
467
    len = json_object_array_length(obj);
468
    values = g_slice_alloc0(sizeof(char*) * (len + 1));
469

                
470
    for (i = 0; i < len; i++) {
471
        struct json_object *val_obj = json_object_array_get_idx(obj, i);
472
        char *val;
473

                
474
        g_return_if_fail(val_obj != NULL);
475

                
476
        val = json_object_get_string(val_obj);
477

                
478
        g_return_if_fail(val != NULL);
479

                
480
        values[i] = val;
481
    }
482

                
483
    nntpgrab_core_emit_plugin_event(FALSE, plugin_name, event_name, (const char **) values);
484

                
485
    g_slice_free1(sizeof(char*) * (len + 1), values);
486
}
487

                
488
/* This function used to be part of GLib, but because it behaviour got 
489
 * changed in GLib 2.27.4 we can't rely on it's value anymore for
490
 * hardcoded hash comparisons. This is the g_str_hash implementation
491
 * of before GLib 2.27.4 */
492
static guint
493
ng_str_hash (gconstpointer v)
494
{
495
    const signed char *p;
496
    guint32 h = 0;
497

                
498
    for (p = v; *p != '\0'; p++)
499
        h = (h << 5) - h + *p;
500

                
501
    return h;
502
}
503

                
504
static void
505
glue_process_jsonrpc_notification(const char *msg, struct json_object *obj)
506
{
507
    struct json_object *params;
508
    struct json_object *method;
509
    char *event_name;
510
    guint hash;
511

                
512
    params = json_object_object_get(obj, "params");
513
    if (!params) {
514
        g_print(__FILE__ ":%i JSON message lacks a 'params' field, ignoring: %s\n", __LINE__, msg);
515
        return;
516
    }
517

                
518
    if (json_object_get_type(params) != json_type_object) {
519
        g_print(__FILE__ ":%i JSON parameter is of invalid type, ignoring: %s\n", __LINE__, msg);
520
        return;
521
    }
522

                
523
    method = json_object_object_get(obj, "method");
524
    if (!method) {
525
        g_print(__FILE__ ":%i JSON message lacks a 'method' field, ignoring: %s\n", __LINE__, msg);
526
        return;
527
    }
528

                
529
    event_name = json_object_get_string(method);
530
    hash = ng_str_hash(event_name);
531

                
532
    switch (hash) {
533
        case 4148964023U:       /* config_changed */
534
            if (has_signal_handler_pending(CONFIG_CHANGED_SIGNAL)) {
535
                nntpgrab_core_emit_config_changed(FALSE);
536
            }
537
            break;
538
        case 718712759U:        /* part_download_start */
539
            if (has_signal_handler_pending(PART_DOWNLOAD_START_SIGNAL)) {
540
                emit_part_download_start(msg, params);
541
            }
542
            break;
543
        case 2485450830U:       /* part_done */
544
            if (has_signal_handler_pending(PART_DONE_SIGNAL)) {
545
                emit_part_done(msg, params);
546
            }
547
            break;
548
        case 560621065U:        /* part_failed */
549
            if (has_signal_handler_pending(PART_FAILED_SIGNAL)) {
550
                emit_part_failed(msg, params);
551
            }
552
            break;
553
        case 3851882960U:       /* traffic_monitor_update */
554
            if (has_signal_handler_pending(TRAFFIC_MONITOR_UPDATE_SIGNAL)) {
555
                emit_traffic_monitor_update(msg, params);
556
            }
557
            break;
558
        case 3667888847U:       /* part_progress_update */
559
            if (has_signal_handler_pending(PART_PROGRESS_UPDATE_SIGNAL)) {
560
                emit_part_progress_update(msg, params);
561
            }
562
            break;
563
        case 2792752159U:       /* collection_added */
564
            if (has_signal_handler_pending(COLLECTION_ADDED_SIGNAL)) {
565
                emit_collection_added(msg, params);
566
            }
567
            break;
568
        case 1720184767U:       /* collection_removed */
569
            if (has_signal_handler_pending(COLLECTION_REMOVED_SIGNAL)) {
570
                emit_collection_removed(msg, params);
571
            }
572
            break;
573
        case 1683429194U:       /* collection_modified */
574
            if (has_signal_handler_pending(COLLECTION_MODIFIED_SIGNAL)) {
575
                emit_collection_modified(msg, params);
576
            }
577
            break;
578
        case 2127244413U:       /* file_added */
579
            if (has_signal_handler_pending(FILE_ADDED_SIGNAL)) {
580
                emit_file_added(msg, params);
581
            }
582
            break;
583
        case 2117367965U:       /* file_removed */
584
            if (has_signal_handler_pending(FILE_REMOVED_SIGNAL)) {
585
                emit_file_removed(msg, params);
586
            }
587
            break;
588
        case 2548616203U:       /* file_download_state_update */
589
            if (has_signal_handler_pending(FILE_DOWNLOAD_STATE_UPDATE_SIGNAL)) {
590
                emit_file_download_state_update(msg, params);
591
            }
592
            break;
593
        case 3407424387U:       /* file_state_changed */
594
            if (has_signal_handler_pending(FILE_STATE_CHANGED_SIGNAL)) {
595
                emit_file_state_changed(msg, params);
596
            }
597
            break;
598
        case 1506868921U:       /* connection_connecting */
599
            if (has_signal_handler_pending(CONNECTION_CONNECTING_SIGNAL)) {
600
                emit_connection_connecting(msg, params);
601
            }
602
            break;
603
        case 2681007848U:       /* connection_connected */
604
            if (has_signal_handler_pending(CONNECTION_CONNECTED_SIGNAL)) {
605
                emit_connection_connected(msg, params);
606
            }
607
            break;
608
        case 2812926109U:       /* connection_disconnect */
609
            if (has_signal_handler_pending(CONNECTION_DISCONNECT_SIGNAL)) {
610
                emit_connection_disconnect(msg, params);
611
            }
612
            break;
613
        case 1376609542U:       /* schedular_state_changed */
614
            if (has_signal_handler_pending(SCHEDULAR_STATE_CHANGED_SIGNAL)) {
615
                emit_schedular_state_changed(msg, params);
616
            }
617
            break;
618
        case 843068174U:        /* foreach_collection_event */
619
            process_foreach_collection_event(msg, params);
620
            break;
621
        case 3826728748U:       /* foreach_file_event */
622
            process_foreach_file_event(msg, params);
623
            break;
624
        case 2102350437U:       /* foreach_group_event */
625
            process_foreach_group_event(msg, params);
626
            break;
627
        case 693552652U:        /* log_message */
628
            if (has_signal_handler_pending(LOG_MESSAGE_SIGNAL)) {
629
                emit_log_message(msg, params);
630
            }
631
            break;
632
        case 1307041657U:       /* task_moved */
633
            if (has_signal_handler_pending(TASK_MOVED_SIGNAL)) {
634
                emit_task_moved(msg, params);
635
            }
636
            break;
637
        case 2804179410U:       /* collection_moved */
638
            if (has_signal_handler_pending(COLLECTION_MOVED_SIGNAL)) {
639
                emit_collection_moved(msg, params);
640
            }
641
            break;
642
        case 2405579865U:       /* all_downloads_completed */
643
            if (has_signal_handler_pending(ALL_DOWNLOADS_COMPLETED_SIGNAL)) {
644
                nntpgrab_core_emit_all_downloads_completed(FALSE);
645
            }
646
            break;
647
        case 3241070225U:       /* plugin_loaded */
648
            if (has_signal_handler_pending(PLUGIN_LOADED_SIGNAL)) {
649
                emit_plugin_loaded(msg, params);
650
            }
651
            break;
652
        case 3055047530U:       /* plugin_unloaded */
653
            if (has_signal_handler_pending(PLUGIN_UNLOADED_SIGNAL)) {
654
                emit_plugin_unloaded(msg, params);
655
            }
656
            break;
657
        case 2037961358U:       /* plugin_event */
658
            if (has_signal_handler_pending(PLUGIN_EVENT_SIGNAL)) {
659
                emit_plugin_event(msg, params);
660
            }
661
            break;
662

                
663
        default:
664
            g_print(__FILE__ ":%i JSON notification with unknown event name received, event_name = %s, hash = %u, msg = %s\n", __LINE__, event_name, hash, msg);
665
            break;
666
    }
667
}
668

                
669
static GAsyncQueue *command_queue = NULL;
670
static GStaticMutex command_mutex = G_STATIC_MUTEX_INIT;
671
static GStaticMutex init_mutex = G_STATIC_MUTEX_INIT;
672

                
673
void
674
glue_process_jsonrpc_msg(const char *msg)
675
{
676
    struct json_object *obj;
677
    struct json_object *id;
678

                
679
    g_return_if_fail(msg != NULL);
680

                
681
    obj = json_tokener_parse((char*)msg);
682
    if (!obj) {
683
        g_print(__FILE__ ":%i Invalid message received from server, ignoring: %s\n", __LINE__, msg);
684
        return;
685
    }
686

                
687
    id = json_object_object_get(obj, "id");
688
    if (!id) {
689
        /* Notification received! */
690
        glue_process_jsonrpc_notification(msg, obj);
691
        json_object_put(obj);
692
        return;
693
    }
694

                
695
    g_print(__FILE__ ":%i JSON response received for msg: %s\n", __LINE__, msg);
696

                
697
    g_static_mutex_lock(&init_mutex);
698
    if (command_queue == NULL) {
699
        command_queue = g_async_queue_new();
700
    }
701
    g_static_mutex_unlock(&init_mutex);
702

                
703
    g_async_queue_push(command_queue, obj);
704

                
705
    /* No need to unref here as it should be done by the thread who pop's the queue */
706
}
707

                
708
/*************************************************************************************/
709
/* JSON-RPC methods */
710
/*************************************************************************************/
711
#define get_method_param(params, field, method_name, type, dest)                                        \
712
    {                                                                                                   \
713
        char *msg = json_object_get_string(params);                                                     \
714
        struct json_object *obj = get_json_param(msg, params, field, method_name, json_type_ ## type);  \
715
        if (!obj) {                                                                                     \
716
            json_object_put(params) ;                                                                   \
717
            return FALSE;                                                                               \
718
        }                                                                                               \
719
        dest = json_object_get_ ## type (obj);                                                          \
720
    }
721

                
722
static struct json_object *
723
create_new_json_request(const char *method, struct json_object *request_params)
724
{
725
    struct json_object *request;
726
    static int id = 0;
727

                
728
    if (!request_params) {
729
        request_params = json_object_new_array();
730
    }
731

                
732
    request = json_object_new_object();
733
    json_object_object_add(request, "method", json_object_new_string((char*) method));
734
    json_object_object_add(request, "id", json_object_new_int(++id));
735
    json_object_object_add(request, "params", request_params);
736

                
737
    return request;
738
}
739

                
740
static struct json_object *
741
send_request_and_wait_for_response(NntpgrabGlue *glue, struct json_object *request, char **errmsg)
742
{
743
    struct json_object *response;
744
    struct json_object *result;
745
    struct json_object *error;
746
    GTimeVal tv;
747
    int count;
748

                
749
    g_return_val_if_fail(glue != NULL, NULL);
750
    g_return_val_if_fail(request != NULL, NULL);
751
    g_return_val_if_fail(errmsg != NULL, NULL);
752

                
753
    g_static_mutex_lock(&command_mutex);
754

                
755
    if (!write_line(&glue->socket, "%s\r\n", json_object_to_json_string(request))) {
756
        g_static_mutex_unlock(&command_mutex);
757
        return NULL;
758
    }
759

                
760
    g_static_mutex_lock(&init_mutex);
761
    if (command_queue == NULL) {
762
        command_queue = g_async_queue_new();
763
    }
764
    g_static_mutex_unlock(&init_mutex);
765

                
766
    count = 0;
767
    while (count < READ_TIMEOUT_VALUE) {
768
        g_get_current_time(&tv);
769
        tv.tv_sec++;
770

                
771
        response = g_async_queue_timed_pop(command_queue, &tv);
772
        if (response) {
773
            break;
774
        } else if (glue->socket.socket_id <= 0) {
775
            *errmsg = g_strdup_printf(__FILE__ ":%i Connection got disconnected\n", __LINE__);
776

                
777
            nntpgrab_core_emit_log_message(FALSE, "Glue layer", NG_LOG_LEVEL_WARNING, *errmsg, TRUE, FALSE);
778

                
779
            g_static_mutex_unlock(&command_mutex);
780

                
781
            return NULL;
782
        }
783
        count++;
784
    }
785

                
786
    g_static_mutex_unlock(&command_mutex);
787

                
788
    if (!response) {
789
        *errmsg = g_strdup_printf(__FILE__ ":%i Timed out waiting for response from server, request = %s\n", __LINE__, json_object_to_json_string(request));
790

                
791
        nntpgrab_core_emit_log_message(FALSE, "Glue layer", NG_LOG_LEVEL_WARNING, *errmsg, TRUE, FALSE);
792

                
793
        return NULL;
794
    }
795

                
796
    error = json_object_object_get(response, "error");
797
    if (error) {
798
        *errmsg = g_strdup(json_object_get_string(error));
799

                
800
        json_object_put(response);
801

                
802
        return NULL;
803
    }
804

                
805
    result = json_object_object_get(response, "result");
806
    if (!result) {
807
        *errmsg = g_strdup_printf(__FILE__ ":%i Response from server lacks a 'result' field, request = %s, response = %s\n", __LINE__, json_object_to_json_string(request), json_object_to_json_string(response));
808

                
809
        nntpgrab_core_emit_log_message(FALSE, "Glue layer", NG_LOG_LEVEL_WARNING, *errmsg, TRUE, FALSE);
810

                
811
        json_object_put(response);
812

                
813
        return NULL;
814
    }
815

                
816
    /* We're only interested in the result, so we add a reference to that and unref the response */
817
    json_object_get(result);
818
    json_object_put(response);
819

                
820
    return result;
821
}
822

                
823
void
824
nntpgrab_glue_internal_kill_server(NntpgrabGlue *obj)
825
{
826
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
827
    struct json_object *request;
828
    struct json_object *response_result;
829
    char *errmsg = NULL;
830

                
831
    request = create_new_json_request("nntpgrab_server_request_quit", NULL);
832

                
833
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
834
        g_print(__FILE__ ":%i nntpgrab_server_request_quit FAILED: %s\n", __LINE__, errmsg);
835
        g_free(errmsg);
836
        json_object_put(request);
837
        return;
838
    }
839

                
840
    json_object_put(response_result);
841
    json_object_put(request);
842
}
843

                
844
NGList *
845
nntpgrab_glue_internal_config_get_avail_servers(NntpgrabGlue *obj)
846
{
847
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
848
    struct json_object *request;
849
    struct json_object *response_result;
850
    NGList *ret = NULL;
851
    char *errmsg = NULL;
852
    int i;
853
    int len;
854

                
855
    request = create_new_json_request("nntpgrab_config_get_avail_servers", NULL);
856

                
857
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
858
        g_print(__FILE__ ":%i nntpgrab_config_get_avail_servers FAILED: %s\n", __LINE__, errmsg);
859
        g_free(errmsg);
860
        json_object_put(request);
861
        return NULL;
862
    }
863

                
864
    len = json_object_array_length(response_result);
865
    for (i = 0; i < len; i++) {
866
        struct json_object *obj = json_object_array_get_idx(response_result, i);
867
        char *servername;
868

                
869
        g_return_val_if_fail(obj != NULL, NULL);
870

                
871
        servername = json_object_get_string(obj);
872

                
873
        g_return_val_if_fail(servername != NULL, NULL);
874

                
875
        ret = ng_list_append(ret, g_strdup(servername));
876
    }
877

                
878
    json_object_put(request);
879
    json_object_put(response_result);
880

                
881
    return ret;
882
}
883

                
884
gboolean
885
nntpgrab_glue_internal_config_get_server_info(NntpgrabGlue *obj, const char *servername, NGConfigServer *ret)
886
{
887
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
888
    struct json_object *request;
889
    struct json_object *request_params;
890
    struct json_object *response_result;
891
    char *errmsg = NULL;
892
    char *servername_received;
893
    char *hostname;
894
    int port;
895
    char *username;
896
    char *password;
897
    int max_threads;
898
    NGServerPriority priority;
899
    ngboolean send_group_command;
900
    ngboolean use_ssl;
901
    ngboolean enabled;
902

                
903
    g_return_val_if_fail(servername != NULL, FALSE);
904
    g_return_val_if_fail(ret != NULL, FALSE);
905

                
906
    request_params = json_object_new_array();
907
    json_object_array_add(request_params, json_object_new_string((char*) servername));
908
    request = create_new_json_request("nntpgrab_config_get_server_info", request_params);
909

                
910
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
911
        g_print(__FILE__ ":%i nntpgrab_config_get_server_info FAILED: %s\n", __LINE__, errmsg);
912
        g_free(errmsg);
913
        json_object_put(request);
914
        return FALSE;
915
    }
916

                
917
    get_method_param(response_result, "servername", "config_get_server_info", string, servername_received);
918
    get_method_param(response_result, "hostname", "config_get_server_info", string, hostname);
919
    get_method_param(response_result, "port", "config_get_server_info", int, port);
920
    get_method_param(response_result, "username", "config_get_server_info", string, username);
921
    get_method_param(response_result, "password", "config_get_server_info", string, password);
922
    get_method_param(response_result, "max_threads", "config_get_server_info", int, max_threads);
923
    get_method_param(response_result, "priority", "config_get_server_info", int, priority);
924
    get_method_param(response_result, "send_group_command", "config_get_server_info", boolean, send_group_command);
925
    get_method_param(response_result, "use_ssl", "config_get_server_info", boolean, use_ssl);
926
    get_method_param(response_result, "enabled", "config_get_server_info", boolean, enabled);
927

                
928
    memset(ret, 0, sizeof(NGConfigServer));
929

                
930
    strncpy(ret->servername, servername_received, sizeof(ret->servername));
931
    strncpy(ret->hostname, hostname, sizeof(ret->hostname));
932
    ret->port = port;
933
    strncpy(ret->username, username, sizeof(ret->username));
934
    strncpy(ret->password, password, sizeof(ret->password));
935
    ret->max_threads = max_threads;
936
    ret->priority = priority;
937
    ret->send_group_command = send_group_command;
938
    ret->use_ssl = use_ssl;
939
    ret->enabled = enabled;
940

                
941
    json_object_put(request);
942
    json_object_put(response_result);
943

                
944
    return TRUE;
945
}
946

                
947
gboolean
948
nntpgrab_glue_internal_config_add_server(NntpgrabGlue *obj, NGConfigServer new_server, char **errmsg)
949
{
950
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
951
    struct json_object *request;
952
    struct json_object *request_params;
953
    struct json_object *server;
954
    struct json_object *response_result;
955

                
956
    request_params = json_object_new_array();
957
    server = json_object_new_object();
958
    json_object_object_add(server, "servername", json_object_new_string((char*) new_server.servername));
959
    json_object_object_add(server, "hostname", json_object_new_string((char*) new_server.hostname));
960
    json_object_object_add(server, "port", json_object_new_int(new_server.port));
961
    json_object_object_add(server, "username", json_object_new_string((char*) new_server.username));
962
    json_object_object_add(server, "password", json_object_new_string((char*) new_server.password));
963
    json_object_object_add(server, "max_threads", json_object_new_int(new_server.max_threads));
964
    json_object_object_add(server, "priority", json_object_new_int(new_server.priority));
965
    json_object_object_add(server, "send_group_command", json_object_new_boolean(new_server.send_group_command));
966
    json_object_object_add(server, "use_ssl", json_object_new_boolean(new_server.use_ssl));
967
    json_object_object_add(server, "enabled", json_object_new_boolean(new_server.enabled));
968
    json_object_array_add(request_params, server);
969
    request = create_new_json_request("nntpgrab_config_add_server", request_params);
970

                
971
    if (!(response_result = send_request_and_wait_for_response(glue, request, errmsg))) {
972
        json_object_put(request);
973
        return FALSE;
974
    }
975

                
976
    json_object_put(request);
977
    json_object_put(response_result);
978

                
979
    return TRUE;
980
}
981

                
982
gboolean
983
nntpgrab_glue_internal_config_del_server(NntpgrabGlue *obj, const char *servername, char **errmsg)
984
{
985
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
986
    struct json_object *request;
987
    struct json_object *request_params;
988
    struct json_object *response_result;
989

                
990
    request_params = json_object_new_array();
991
    json_object_array_add(request_params, json_object_new_string((char*) servername));
992
    request = create_new_json_request("nntpgrab_config_del_server", request_params);
993

                
994
    if (!(response_result = send_request_and_wait_for_response(glue, request, errmsg))) {
995
        json_object_put(request);
996
        return FALSE;
997
    }
998

                
999
    json_object_put(request);
1000
    json_object_put(response_result);
1001

                
1002
    return TRUE;
1003
}
1004

                
1005
gboolean
1006
nntpgrab_glue_internal_config_edit_server(NntpgrabGlue *obj, const char *servername, NGConfigServer new_server, char **errmsg)
1007
{
1008
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1009
    struct json_object *request;
1010
    struct json_object *request_params;
1011
    struct json_object *server;
1012
    struct json_object *response_result;
1013

                
1014
    request_params = json_object_new_array();
1015
    server = json_object_new_object();
1016
    json_object_object_add(server, "servername", json_object_new_string((char*) new_server.servername));
1017
    json_object_object_add(server, "hostname", json_object_new_string((char*) new_server.hostname));
1018
    json_object_object_add(server, "port", json_object_new_int(new_server.port));
1019
    json_object_object_add(server, "username", json_object_new_string((char*) new_server.username));
1020
    json_object_object_add(server, "password", json_object_new_string((char*) new_server.password));
1021
    json_object_object_add(server, "max_threads", json_object_new_int(new_server.max_threads));
1022
    json_object_object_add(server, "priority", json_object_new_int(new_server.priority));
1023
    json_object_object_add(server, "send_group_command", json_object_new_boolean(new_server.send_group_command));
1024
    json_object_object_add(server, "use_ssl", json_object_new_boolean(new_server.use_ssl));
1025
    json_object_object_add(server, "enabled", json_object_new_boolean(new_server.enabled));
1026
    json_object_array_add(request_params, json_object_new_string((char*) servername));
1027
    json_object_array_add(request_params, server);
1028
    request = create_new_json_request("nntpgrab_config_edit_server", request_params);
1029

                
1030
    if (!(response_result = send_request_and_wait_for_response(glue, request, errmsg))) {
1031
        json_object_put(request);
1032
        return FALSE;
1033
    }
1034

                
1035
    json_object_put(request);
1036
    json_object_put(response_result);
1037

                
1038
    return TRUE;
1039
}
1040

                
1041
gboolean
1042
nntpgrab_glue_internal_config_get_opts(NntpgrabGlue *obj, NGConfigOpts *opts)
1043
{
1044
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1045
    struct json_object *request;
1046
    struct json_object *response_result;
1047
    char *errmsg = NULL;
1048
    char *download_directory;
1049
    char *temp_directory;
1050
    gboolean enable_intelligent_par2_downloading;
1051
    gboolean enable_par2_repair;
1052
    char *auto_import_directory;
1053
    gboolean enable_auto_import;
1054
    gboolean move_file_after_auto_import;
1055
    gboolean enable_auto_unpack;
1056
    gboolean enable_bandwidth_shaping;
1057
    int max_bandwidth;
1058
    gboolean enable_webserver;
1059
    int webserver_port;
1060
    gboolean enable_logger;
1061
    gboolean auto_remove_files_after_repair;
1062
    gboolean auto_remove_files_after_unpack;
1063

                
1064
    memset(opts, 0, sizeof(NGConfigOpts));
1065

                
1066
    request = create_new_json_request("nntpgrab_config_get_opts", NULL);
1067

                
1068
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
1069
        g_print(__FILE__ ":%i nntpgrab_config_get_opts FAILED: %s\n", __LINE__, errmsg);
1070
        g_free(errmsg);
1071
        json_object_put(request);
1072
        return FALSE;
1073
    }
1074

                
1075
    get_method_param(response_result, "download_directory", "config_get_opts", string, download_directory);
1076
    get_method_param(response_result, "temp_directory", "config_get_opts", string, temp_directory);
1077
    get_method_param(response_result, "enable_intelligent_par2_downloading", "config_get_opts", boolean, enable_intelligent_par2_downloading);
1078
    get_method_param(response_result, "enable_par2_repair", "config_get_opts", boolean, enable_par2_repair);
1079
    get_method_param(response_result, "auto_import_directory", "config_get_opts", string, auto_import_directory);
1080
    get_method_param(response_result, "enable_auto_import", "config_get_opts", boolean, enable_auto_import);
1081
    get_method_param(response_result, "move_file_after_auto_import", "config_get_opts", boolean, move_file_after_auto_import);
1082
    get_method_param(response_result, "enable_auto_unpack", "config_get_opts", boolean, enable_auto_unpack);
1083
    get_method_param(response_result, "enable_bandwidth_shaping", "config_get_opts", boolean, enable_bandwidth_shaping);
1084
    get_method_param(response_result, "max_bandwidth", "config_get_opts", int, max_bandwidth);
1085
    get_method_param(response_result, "enable_webserver", "config_get_opts", boolean, enable_webserver);
1086
    get_method_param(response_result, "webserver_port", "config_get_opts", int, webserver_port);
1087
    get_method_param(response_result, "enable_logger", "config_get_opts", boolean, enable_logger);
1088
    get_method_param(response_result, "auto_remove_files_after_repair", "config_get_opts", boolean, auto_remove_files_after_repair);
1089
    get_method_param(response_result, "auto_remove_files_after_unpack", "config_get_opts", boolean, auto_remove_files_after_unpack);
1090

                
1091
    strncpy(opts->download_directory, download_directory, sizeof(opts->download_directory) - 1);
1092
    strncpy(opts->temp_directory, temp_directory, sizeof(opts->temp_directory) - 1);
1093
    opts->enable_intelligent_par2_downloading = enable_intelligent_par2_downloading;
1094
    opts->enable_par2_repair = enable_par2_repair;
1095
    strncpy(opts->auto_import_directory, auto_import_directory, sizeof(opts->auto_import_directory) - 1);
1096
    opts->enable_auto_import = enable_auto_import;
1097
    opts->move_file_after_auto_import = move_file_after_auto_import;
1098
    opts->enable_auto_unpack = enable_auto_unpack;
1099
    opts->enable_bandwidth_shaping = enable_bandwidth_shaping;
1100
    opts->max_bandwidth = max_bandwidth;
1101
    opts->enable_webserver = enable_webserver;
1102
    opts->webserver_port = webserver_port;
1103
    opts->enable_logger = enable_logger;
1104
    opts->auto_remove_files_after_repair = auto_remove_files_after_repair;
1105
    opts->auto_remove_files_after_unpack = auto_remove_files_after_unpack;
1106

                
1107
    json_object_put(request);
1108
    json_object_put(response_result);
1109

                
1110
    return TRUE;
1111
}
1112

                
1113
gboolean
1114
nntpgrab_glue_internal_config_set_opts(NntpgrabGlue *obj, NGConfigOpts opts)
1115
{
1116
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1117
    struct json_object *request;
1118
    struct json_object *request_params;
1119
    struct json_object *param;
1120
    struct json_object *response_result;
1121
    char *errmsg = NULL;
1122

                
1123
    request_params = json_object_new_array();
1124
    param = json_object_new_object();
1125
    json_object_object_add(param, "download_directory", json_object_new_string((char*) opts.download_directory));
1126
    json_object_object_add(param, "temp_directory", json_object_new_string((char*) opts.temp_directory));
1127
    json_object_object_add(param, "enable_intelligent_par2_downloading", json_object_new_boolean(opts.enable_intelligent_par2_downloading));
1128
    json_object_object_add(param, "enable_par2_repair", json_object_new_boolean(opts.enable_par2_repair));
1129
    json_object_object_add(param, "auto_import_directory", json_object_new_string((char*) opts.auto_import_directory));
1130
    json_object_object_add(param, "enable_auto_import", json_object_new_boolean(opts.enable_auto_import));
1131
    json_object_object_add(param, "move_file_after_auto_import", json_object_new_boolean(opts.move_file_after_auto_import));
1132
    json_object_object_add(param, "enable_auto_unpack", json_object_new_boolean(opts.enable_auto_unpack));
1133
    json_object_object_add(param, "enable_bandwidth_shaping", json_object_new_boolean(opts.enable_bandwidth_shaping));
1134
    json_object_object_add(param, "max_bandwidth", json_object_new_int(opts.max_bandwidth));
1135
    json_object_object_add(param, "enable_webserver", json_object_new_boolean(opts.enable_webserver));
1136
    json_object_object_add(param, "webserver_port", json_object_new_int(opts.webserver_port));
1137
    json_object_object_add(param, "enable_logger", json_object_new_boolean(opts.enable_logger));
1138
    json_object_object_add(param, "auto_remove_files_after_repair", json_object_new_boolean(opts.auto_remove_files_after_repair));
1139
    json_object_object_add(param, "auto_remove_files_after_unpack", json_object_new_boolean(opts.auto_remove_files_after_unpack));
1140
    json_object_array_add(request_params, param);
1141
    request = create_new_json_request("nntpgrab_config_set_opts", request_params);
1142

                
1143
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
1144
        g_print(__FILE__ ":%i nntpgrab_config_set_opts FAILED: %s\n", __LINE__, errmsg);
1145
        g_free(errmsg);
1146
        json_object_put(request);
1147
        return FALSE;
1148
    }
1149

                
1150
    json_object_put(request);
1151
    json_object_put(response_result);
1152

                
1153
    return TRUE;
1154
}
1155

                
1156
gboolean
1157
nntpgrab_glue_internal_config_get_folder_listing(NntpgrabGlue *obj, const char *parent, NGList **folders)
1158
{
1159
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1160
    struct json_object *request;
1161
    struct json_object *request_params;
1162
    struct json_object *response_result;
1163
    char *errmsg = NULL;
1164
    int i;
1165
    int len;
1166

                
1167
    request_params = json_object_new_array();
1168
    if (parent) {
1169
        json_object_array_add(request_params, json_object_new_string((char*) parent));
1170
    } else {
1171
        json_object_array_add(request_params, NULL);
1172
    }
1173
    request = create_new_json_request("nntpgrab_utils_get_folder_listing", request_params);
1174

                
1175
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
1176
        g_print(__FILE__ ":%i nntpgrab_utils_get_folder_listing FAILED: %s\n", __LINE__, errmsg);
1177
        g_free(errmsg);
1178
        json_object_put(request);
1179
        return FALSE;
1180
    }
1181

                
1182
    if (json_object_get_type(response_result) != json_type_array) {
1183
        g_print(__FILE__ ":%i nntpgrab_utils_get_folder_listing FAILED: response_result is of invalid type, type = %i\n", __LINE__, json_object_get_type(response_result));
1184
        json_object_put(request);
1185
        json_object_put(response_result);
1186

                
1187
        return FALSE;
1188
    }
1189

                
1190
    len = json_object_array_length(response_result);
1191
    *folders = NULL;
1192
    for (i = 0; i < len; i++) {
1193
        struct json_object *param = json_object_array_get_idx(response_result, i);
1194
        NNTPGrabFolder *folder;
1195
        char *folder_str;
1196

                
1197
        g_return_val_if_fail(obj != NULL, FALSE);
1198

                
1199
        folder = g_slice_new0(NNTPGrabFolder);
1200

                
1201
        get_method_param(param, "folder", "nntpgrab_utils_get_folder_listing", string, folder_str);
1202
        get_method_param(param, "has_subfolders", "nntpgrab_utils_get_folder_listing", boolean, folder->has_subfolders);
1203
        strncpy(folder->folder, folder_str, sizeof(folder->folder) - 1);
1204

                
1205
        *folders = ng_list_append(*folders, folder);
1206
    }
1207

                
1208
    json_object_put(request);
1209
    json_object_put(response_result);
1210

                
1211
    return TRUE;
1212
}
1213

                
1214
gboolean
1215
nntpgrab_glue_internal_schedular_start(NntpgrabGlue *obj)
1216
{
1217
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1218
    struct json_object *request;
1219
    struct json_object *response_result;
1220
    char *errmsg = NULL;
1221

                
1222
    request = create_new_json_request("nntpgrab_schedular_start", NULL);
1223

                
1224
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
1225
        g_print(__FILE__ ":%i nntpgrab_schedular_start FAILED: %s\n", __LINE__, errmsg);
1226
        g_free(errmsg);
1227
        json_object_put(request);
1228
        return FALSE;
1229
    }
1230

                
1231
    json_object_put(request);
1232
    json_object_put(response_result);
1233

                
1234
    return TRUE;
1235
}
1236

                
1237
gboolean
1238
nntpgrab_glue_internal_schedular_stop(NntpgrabGlue *obj, gboolean wait)
1239
{
1240
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1241
    struct json_object *request;
1242
    struct json_object *request_params;
1243
    struct json_object *response_result;
1244
    char *errmsg = NULL;
1245

                
1246
    request_params = json_object_new_array();
1247
    json_object_array_add(request_params, json_object_new_boolean(wait));
1248
    request = create_new_json_request("nntpgrab_schedular_stop", request_params);
1249

                
1250
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
1251
        g_print(__FILE__ ":%i nntpgrab_schedular_stop FAILED: %s\n", __LINE__, errmsg);
1252
        g_free(errmsg);
1253
        json_object_put(request);
1254
        return FALSE;
1255
    }
1256

                
1257
    json_object_put(request);
1258
    json_object_put(response_result);
1259

                
1260
    return TRUE;
1261
}
1262

                
1263
NGSchedularState
1264
nntpgrab_glue_internal_schedular_get_state(NntpgrabGlue *obj)
1265
{
1266
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1267
    struct json_object *request;
1268
    struct json_object *response_result;
1269
    char *errmsg = NULL;
1270
    NGSchedularState ret;
1271

                
1272
    request = create_new_json_request("nntpgrab_schedular_get_state", NULL);
1273

                
1274
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
1275
        g_print(__FILE__ ":%i nntpgrab_schedular_get_state FAILED: %s\n", __LINE__, errmsg);
1276
        g_free(errmsg);
1277
        json_object_put(request);
1278
        return SCHEDULAR_STATE_STOPPED;
1279
    }
1280

                
1281
    if (json_object_get_type(response_result) != json_type_int) {
1282
        g_print(__FILE__ ":%i nntpgrab_schedular_get_state FAILED: response_result is of invalid type, type = %i\n", __LINE__, json_object_get_type(response_result));
1283
        json_object_put(request);
1284
        json_object_put(response_result);
1285

                
1286
        return SCHEDULAR_STATE_STOPPED;
1287
    }
1288

                
1289
    ret = json_object_get_int(response_result);
1290

                
1291
    json_object_put(request);
1292
    json_object_put(response_result);
1293

                
1294
    return ret;
1295
}
1296

                
1297
gboolean
1298
nntpgrab_glue_internal_schedular_add_task_to_queue(NntpgrabGlue *obj, const char *collection_name, const char *subject, const char *poster, time_t stamp, nguint64 file_size, NGList *groups, NGList *parts, char **errmsg)
1299
{
1300
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1301
    struct json_object *request;
1302
    struct json_object *request_params;
1303
    struct json_object *response_result;
1304
    struct json_object *json_obj;
1305
    NGList *list;
1306

                
1307
    request_params = json_object_new_array();
1308
    json_object_array_add(request_params, json_object_new_string((char*) collection_name));
1309
    json_object_array_add(request_params, json_object_new_string((char*) subject));
1310
    json_object_array_add(request_params, json_object_new_string((char*) poster));
1311
    json_object_array_add(request_params, json_object_new_int(stamp));
1312
    json_object_array_add(request_params, json_object_new_int(file_size / 1024));
1313

                
1314
    json_obj = json_object_new_array();
1315
    json_object_array_add(request_params, json_obj);
1316
    list = groups;
1317
    while (list) {
1318
        char *groupname = list->data;
1319

                
1320
        json_object_array_add(json_obj, json_object_new_string(groupname));
1321

                
1322
        list = ng_list_next(list);
1323
    }
1324

                
1325
    json_obj = json_object_new_array();
1326
    json_object_array_add(request_params, json_obj);
1327
    list = parts;
1328
    while (list) {
1329
        NNTPGrabPart *part = list->data;
1330
        struct json_object *part_obj = json_object_new_object();
1331

                
1332
        json_object_object_add(part_obj, "message_id", json_object_new_string((char*) part->message_id));
1333
        json_object_object_add(part_obj, "part_num", json_object_new_int(part->part_num));
1334
        json_object_object_add(part_obj, "size", json_object_new_int(part->size));
1335
        json_object_array_add(json_obj, part_obj);
1336

                
1337
        list = ng_list_next(list);
1338
    }
1339

                
1340
    request = create_new_json_request("nntpgrab_schedular_add_file_to_queue", request_params);
1341

                
1342
    if (!(response_result = send_request_and_wait_for_response(glue, request, errmsg))) {
1343
        json_object_put(request);
1344
        return FALSE;
1345
    }
1346

                
1347
    json_object_put(request);
1348
    json_object_put(response_result);
1349

                
1350
    return TRUE;
1351
}
1352

                
1353
gboolean
1354
nntpgrab_glue_internal_schedular_del_task_from_queue(NntpgrabGlue *obj, const char *collection_name, const char *subject, char **errmsg)
1355
{
1356
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1357
    struct json_object *request;
1358
    struct json_object *request_params;
1359
    struct json_object *response_result;
1360

                
1361
    request_params = json_object_new_array();
1362
    json_object_array_add(request_params, json_object_new_string((char*) collection_name));
1363
    if (subject) {
1364
        json_object_array_add(request_params, json_object_new_string((char*) subject));
1365
    } else {
1366
        json_object_array_add(request_params, NULL);
1367
    }
1368
    request = create_new_json_request("nntpgrab_schedular_del_file_from_queue", request_params);
1369

                
1370
    if (!(response_result = send_request_and_wait_for_response(glue, request, errmsg))) {
1371
        json_object_put(request);
1372
        return FALSE;
1373
    }
1374

                
1375
    json_object_put(request);
1376
    json_object_put(response_result);
1377

                
1378
    return TRUE;
1379
}
1380

                
1381
gboolean
1382
nntpgrab_glue_internal_schedular_restart_task(NntpgrabGlue *obj, const char *collection_name, const char *subject, char **errmsg)
1383
{
1384
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1385
    struct json_object *request;
1386
    struct json_object *request_params;
1387
    struct json_object *response_result;
1388

                
1389
    g_return_val_if_fail(collection_name != NULL, FALSE);
1390
    /* NOTE: subject CAN be NULL */
1391

                
1392
    request_params = json_object_new_array();
1393
    json_object_array_add(request_params, json_object_new_string((char*) collection_name));
1394
    if (subject) {
1395
        json_object_array_add(request_params, json_object_new_string((char*) subject));
1396
    } else {
1397
        json_object_array_add(request_params, NULL);
1398
    }
1399
    request = create_new_json_request("nntpgrab_schedular_restart_file", request_params);
1400

                
1401
    if (!(response_result = send_request_and_wait_for_response(glue, request, errmsg))) {
1402
        json_object_put(request);
1403
        return FALSE;
1404
    }
1405

                
1406
    json_object_put(request);
1407
    json_object_put(response_result);
1408

                
1409
    return TRUE;
1410
}
1411

                
1412
gboolean
1413
nntpgrab_glue_internal_schedular_save_queue(NntpgrabGlue *obj, char **errmsg)
1414
{
1415
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1416
    struct json_object *request;
1417
    struct json_object *response_result;
1418

                
1419
    request = create_new_json_request("nntpgrab_schedular_save_queue", NULL);
1420

                
1421
    if (!(response_result = send_request_and_wait_for_response(glue, request, errmsg))) {
1422
        json_object_put(request);
1423
        return FALSE;
1424
    }
1425

                
1426
    json_object_put(request);
1427
    json_object_put(response_result);
1428

                
1429
    return TRUE;
1430
}
1431

                
1432
static ForeachCollectionFunc collection_func_global = NULL;
1433
static ForeachFileFunc file_func_global = NULL;
1434
static ForeachGroupFunc group_func_global = NULL;
1435
static void *foreach_task_user_data_global = NULL;
1436

                
1437
static void
1438
process_foreach_collection_event(const char *msg, struct json_object *params)
1439
{
1440
    char *collection_name = NULL;
1441
    char *poster = NULL;
1442
    guint64 total_size = 0;
1443
    guint64 total_size_remaining = 0;
1444
    int position = 0;
1445

                
1446
    if (!collection_func_global) {
1447
        return;
1448
    }
1449

                
1450
    get_param(msg, params, "collection_name", "foreach_collection_event", string, collection_name);
1451
    get_param(msg, params, "poster", "foreach_collection_event", string, poster);
1452
    get_param(msg, params, "total_size", "foreach_collection_event", int, total_size);
1453
    get_param(msg, params, "total_size_remaining", "foreach_collection_event", int, total_size_remaining);
1454
    get_param(msg, params, "position", "foreach_collection_event", int, position);
1455

                
1456
    /* JSON doesn't support 64bit integers so all file sizes are in KB instead of bytes */
1457
    total_size *= 1024;
1458
    total_size_remaining *= 1024;
1459

                
1460
    collection_func_global(collection_name, poster, total_size, total_size_remaining, position, foreach_task_user_data_global);
1461
}
1462

                
1463
static void
1464
process_foreach_file_event(const char *msg, struct json_object *params)
1465
{
1466
    char *collection_name = NULL;
1467
    char *subject = NULL;
1468
    char *poster;
1469
    int stamp;
1470
    guint64 file_size;
1471
    guint64 file_size_remaining;
1472
    int num_parts_total;
1473
    int num_parts_downloaded;
1474
    int num_parts_failed;
1475
    NGTaskState status;
1476
    char *filename;
1477
    int position;
1478

                
1479
    if (!file_func_global) {
1480
        return;
1481
    }
1482

                
1483
    get_param(msg, params, "collection_name", "foreach_file_event", string, collection_name);
1484
    get_param(msg, params, "subject", "foreach_file_event", string, subject);
1485
    get_param(msg, params, "poster", "foreach_file_event", string, poster);
1486
    get_param(msg, params, "stamp", "foreach_file_event", int, stamp);
1487
    get_param(msg, params, "file_size", "foreach_file_event", int, file_size);
1488
    get_param(msg, params, "file_size_remaining", "foreach_file_event", int, file_size_remaining);
1489
    get_param(msg, params, "num_parts_total", "foreach_file_event", int, num_parts_total);
1490
    get_param(msg, params, "num_parts_downloaded", "foreach_file_event", int, num_parts_downloaded);
1491
    get_param(msg, params, "num_parts_failed", "foreach_file_event", int, num_parts_failed);
1492
    get_param(msg, params, "status", "foreach_file_event", int, status);
1493
    get_param(msg, params, "filename", "foreach_file_event", string, filename);
1494
    get_param(msg, params, "position", "foreach_file_event", int, position);
1495

                
1496
    /* JSON doesn't support 64bit integers so all file sizes are in KB instead of bytes */
1497
    file_size *= 1024;
1498
    file_size_remaining *= 1024;
1499

                
1500
    file_func_global(collection_name, subject, poster, stamp, file_size, file_size_remaining, position, num_parts_total, num_parts_downloaded, num_parts_failed, status, filename, foreach_task_user_data_global);
1501
}
1502

                
1503
static void
1504
process_foreach_group_event(const char *msg, struct json_object *params)
1505
{
1506
    char *collection_name = NULL;
1507
    char *subject = NULL;
1508
    char *group = NULL;
1509

                
1510
    if (!group_func_global) {
1511
        return;
1512
    }
1513

                
1514
    get_param(msg, params, "collection_name", "foreach_group_event", string, collection_name);
1515
    get_param(msg, params, "subject", "foreach_group_event", string, subject);
1516
    get_param(msg, params, "group", "foreach_group_event", string, group);
1517

                
1518
    group_func_global(collection_name, subject, group, foreach_task_user_data_global);
1519
}
1520

                
1521
gboolean
1522
nntpgrab_glue_internal_schedular_foreach_task(NntpgrabGlue *obj, ForeachCollectionFunc collection_func, ForeachFileFunc file_func, ForeachGroupFunc group_func, void *data)
1523
{
1524
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1525
    struct json_object *request;
1526
    struct json_object *response_result;
1527
    char *errmsg = NULL;
1528
    gboolean ret;
1529

                
1530
    g_return_val_if_fail(obj != NULL, FALSE);
1531
    g_return_val_if_fail(collection_func != NULL || file_func != NULL || group_func != NULL, FALSE);
1532

                
1533
    request = create_new_json_request("nntpgrab_schedular_foreach_task", NULL);
1534

                
1535
    collection_func_global = collection_func;
1536
    file_func_global = file_func;
1537
    group_func_global = group_func;
1538
    foreach_task_user_data_global = data;
1539

                
1540
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
1541
        g_free(errmsg);
1542
        json_object_put(request);
1543
        collection_func_global = NULL;
1544
        file_func_global = NULL;
1545
        group_func_global = NULL;
1546
        foreach_task_user_data_global = NULL;
1547
        return FALSE;
1548
    }
1549

                
1550
    collection_func_global = NULL;
1551
    file_func_global = NULL;
1552
    group_func_global = NULL;
1553
    foreach_task_user_data_global = NULL;
1554

                
1555
    if (json_object_get_type(response_result) != json_type_boolean) {
1556
        // invalid type
1557
        g_print(__FILE__ ":%i response is of invalid type for method 'schedular_foreach_task', response = %s\n", __LINE__, json_object_get_string(response_result));
1558
        json_object_put(request);
1559
        json_object_put(response_result);
1560
        return FALSE;
1561
    }
1562

                
1563
    ret = json_object_get_boolean(response_result);
1564

                
1565
    json_object_put(request);
1566
    json_object_put(response_result);
1567

                
1568
    return ret;
1569
}
1570

                
1571
gboolean
1572
nntpgrab_glue_internal_schedular_move_task(NntpgrabGlue *obj, const char *collection_name_src, const char *subject_src, const char *collection_name_dest, int position_dest)
1573
{
1574
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1575
    struct json_object *request;
1576
    struct json_object *request_params;
1577
    struct json_object *response_result;
1578
    char *errmsg = NULL;
1579

                
1580
    request_params = json_object_new_array();
1581
    json_object_array_add(request_params, json_object_new_string((char*) collection_name_src));
1582
    json_object_array_add(request_params, json_object_new_string((char*) subject_src));
1583
    json_object_array_add(request_params, json_object_new_string((char*) collection_name_dest));
1584
    json_object_array_add(request_params, json_object_new_int(position_dest));
1585
    request = create_new_json_request("nntpgrab_schedular_move_file", request_params);
1586

                
1587
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
1588
        g_print(__FILE__ ":%i nntpgrab_schedular_move_file FAILED: %s\n", __LINE__, errmsg);
1589
        g_free(errmsg);
1590
        json_object_put(request);
1591
        return FALSE;
1592
    }
1593

                
1594
    json_object_put(request);
1595
    json_object_put(response_result);
1596

                
1597
    return TRUE;
1598
}
1599

                
1600
gboolean
1601
nntpgrab_glue_internal_schedular_move_collection(NntpgrabGlue *obj, const char *collection_name, int new_position)
1602
{
1603
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1604
    struct json_object *request;
1605
    struct json_object *request_params;
1606
    struct json_object *response_result;
1607
    char *errmsg = NULL;
1608

                
1609
    request_params = json_object_new_array();
1610
    json_object_array_add(request_params, json_object_new_string((char*) collection_name));
1611
    json_object_array_add(request_params, json_object_new_int(new_position));
1612
    request = create_new_json_request("nntpgrab_schedular_move_collection", request_params);
1613

                
1614
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
1615
        g_print(__FILE__ ":%i nntpgrab_schedular_move_collection FAILED: %s\n", __LINE__, errmsg);
1616
        g_free(errmsg);
1617
        json_object_put(request);
1618
        return FALSE;
1619
    }
1620

                
1621
    json_object_put(request);
1622
    json_object_put(response_result);
1623

                
1624
    return TRUE;
1625
}
1626

                
1627
gboolean
1628
nntpgrab_glue_internal_schedular_mark_task_optional(NntpgrabGlue *obj, const char *collection_name, const char *subject, ngboolean is_optional)
1629
{
1630
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1631
    struct json_object *request;
1632
    struct json_object *request_params;
1633
    struct json_object *response_result;
1634
    char *errmsg = NULL;
1635

                
1636
    request_params = json_object_new_array();
1637
    json_object_array_add(request_params, json_object_new_string((char*) collection_name));
1638
    json_object_array_add(request_params, json_object_new_string((char*) subject));
1639
    json_object_array_add(request_params, json_object_new_boolean(is_optional));
1640
    request = create_new_json_request("nntpgrab_schedular_mark_task_optional", request_params);
1641

                
1642
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
1643
        g_print(__FILE__ ":%i nntpgrab_schedular_mark_task_optional FAILED: %s\n", __LINE__, errmsg);
1644
        g_free(errmsg);
1645
        json_object_put(request);
1646
        return FALSE;
1647
    }
1648

                
1649
    json_object_put(request);
1650
    json_object_put(response_result);
1651

                
1652
    return TRUE;
1653
}
1654

                
1655
NGList *
1656
nntpgrab_glue_internal_plugins_get_avail_plugins(NntpgrabGlue *obj)
1657
{
1658
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1659
    struct json_object *request;
1660
    struct json_object *response_result;
1661
    NGList *ret = NULL;
1662
    char *errmsg = NULL;
1663
    int i;
1664
    int len;
1665

                
1666
    request = create_new_json_request("nntpgrab_plugins_get_avail_plugins", NULL);
1667

                
1668
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
1669
        g_print(__FILE__ ":%i nntpgrab_plugins_get_avail_plugins FAILED: %s\n", __LINE__, errmsg);
1670
        g_free(errmsg);
1671
        json_object_put(request);
1672
        return NULL;
1673
    }
1674

                
1675
    len = json_object_array_length(response_result);
1676
    for (i = 0; i < len; i++) {
1677
        struct json_object *obj = json_object_array_get_idx(response_result, i);
1678
        char *servername;
1679

                
1680
        g_return_val_if_fail(obj != NULL, NULL);
1681

                
1682
        servername = json_object_get_string(obj);
1683

                
1684
        g_return_val_if_fail(servername != NULL, NULL);
1685

                
1686
        ret = ng_list_append(ret, g_strdup(servername));
1687
    }
1688

                
1689
    json_object_put(request);
1690
    json_object_put(response_result);
1691

                
1692
    return ret;
1693
}
1694

                
1695
gboolean
1696
nntpgrab_glue_internal_plugins_get_plugin_info(NntpgrabGlue *obj, const char *plugin_name, NNTPGrabPluginInfo *plugin_info)
1697
{
1698
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1699
    struct json_object *request;
1700
    struct json_object *request_params;
1701
    struct json_object *response_result;
1702
    char *errmsg = NULL;
1703
    char *name;
1704
    char *version;
1705
    char *author;
1706
    char *url;
1707
    char *description;
1708
    gboolean is_loaded;
1709
    gboolean is_persistent;
1710

                
1711
    g_return_val_if_fail(plugin_name != NULL, FALSE);
1712
    g_return_val_if_fail(plugin_info != NULL, FALSE);
1713

                
1714
    request_params = json_object_new_array();
1715
    json_object_array_add(request_params, json_object_new_string((char*) plugin_name));
1716
    request = create_new_json_request("nntpgrab_plugins_get_plugin_info", request_params);
1717

                
1718
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
1719
        g_print(__FILE__ ":%i nntpgrab_plugins_get_plugin_info FAILED: %s\n", __LINE__, errmsg);
1720
        g_free(errmsg);
1721
        json_object_put(request);
1722
        return FALSE;
1723
    }
1724

                
1725
    get_method_param(response_result, "name", "plugins_get_plugin_info", string, name);
1726
    get_method_param(response_result, "version", "plugins_get_plugin_info", string, version);
1727
    get_method_param(response_result, "author", "plugins_get_plugin_info", string, author);
1728
    get_method_param(response_result, "url", "plugins_get_plugin_info", string, url);
1729
    get_method_param(response_result, "description", "plugins_get_plugin_info", string, description);
1730
    get_method_param(response_result, "is_loaded", "plugins_get_plugin_info", boolean, is_loaded);
1731
    get_method_param(response_result, "is_persistent", "plugins_get_plugin_info", boolean, is_persistent);
1732

                
1733
    memset(plugin_info, 0, sizeof(NNTPGrabPluginInfo));
1734

                
1735
    strncpy(plugin_info->name, name, sizeof(plugin_info->name));
1736
    strncpy(plugin_info->version, version, sizeof(plugin_info->version));
1737
    strncpy(plugin_info->author, author, sizeof(plugin_info->author));
1738
    strncpy(plugin_info->url, url, sizeof(plugin_info->url));
1739
    strncpy(plugin_info->description, description, sizeof(plugin_info->description));
1740
    plugin_info->is_loaded = is_loaded;
1741
    plugin_info->is_persistent = is_persistent;
1742

                
1743
    json_object_put(request);
1744
    json_object_put(response_result);
1745

                
1746
    return TRUE;
1747
}
1748

                
1749
gboolean
1750
nntpgrab_glue_internal_plugins_load_plugin(NntpgrabGlue *obj, const char *plugin_name, char **errmsg)
1751
{
1752
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1753
    struct json_object *request;
1754
    struct json_object *request_params;
1755
    struct json_object *response_result;
1756

                
1757
    request_params = json_object_new_array();
1758
    json_object_array_add(request_params, json_object_new_string((char*) plugin_name));
1759
    request = create_new_json_request("nntpgrab_plugins_load_plugin", request_params);
1760

                
1761
    if (!(response_result = send_request_and_wait_for_response(glue, request, errmsg))) {
1762
        json_object_put(request);
1763
        return FALSE;
1764
    }
1765

                
1766
    json_object_put(request);
1767
    json_object_put(response_result);
1768

                
1769
    return TRUE;
1770
}
1771

                
1772
gboolean
1773
nntpgrab_glue_internal_plugins_unload_plugin(NntpgrabGlue *obj, const char *plugin_name, char **errmsg)
1774
{
1775
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1776
    struct json_object *request;
1777
    struct json_object *request_params;
1778
    struct json_object *response_result;
1779

                
1780
    request_params = json_object_new_array();
1781
    json_object_array_add(request_params, json_object_new_string((char*) plugin_name));
1782
    request = create_new_json_request("nntpgrab_plugins_unload_plugin", request_params);
1783

                
1784
    if (!(response_result = send_request_and_wait_for_response(glue, request, errmsg))) {
1785
        json_object_put(request);
1786
        return FALSE;
1787
    }
1788

                
1789
    json_object_put(request);
1790
    json_object_put(response_result);
1791

                
1792
    return TRUE;
1793
}
1794

                
1795
gboolean
1796
nntpgrab_glue_internal_plugins_set_persistent(NntpgrabGlue *obj, const char *plugin_name, ngboolean persistent)
1797
{
1798
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1799
    struct json_object *request;
1800
    struct json_object *request_params;
1801
    struct json_object *response_result;
1802
    char *errmsg = NULL;
1803

                
1804
    request_params = json_object_new_array();
1805
    json_object_array_add(request_params, json_object_new_string((char*) plugin_name));
1806
    json_object_array_add(request_params, json_object_new_boolean(persistent));
1807
    request = create_new_json_request("nntpgrab_plugins_set_persistent", request_params);
1808

                
1809
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
1810
        g_print(__FILE__ ":%i nntpgrab_plugins_set_persistent FAILED: %s\n", __LINE__, errmsg);
1811
        g_free(errmsg);
1812
        json_object_put(request);
1813
        return FALSE;
1814
    }
1815

                
1816
    json_object_put(request);
1817
    json_object_put(response_result);
1818

                
1819
    return TRUE;
1820
}
1821

                
1822
void
1823
nntpgrab_glue_internal_set_emit_log_messages(NntpgrabGlue *obj, ngboolean val)
1824
{
1825
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1826
    struct json_object *request;
1827
    struct json_object *request_params;
1828
    struct json_object *response_result;
1829
    char *errmsg = NULL;
1830

                
1831
    request_params = json_object_new_array();
1832
    json_object_array_add(request_params, json_object_new_boolean(val));
1833
    request = create_new_json_request("nntpgrab_set_emit_log_messages", request_params);
1834

                
1835
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
1836
        g_print(__FILE__ ":%i nntpgrab_set_emit_log_messages FAILED: %s\n", __LINE__, errmsg);
1837
        g_free(errmsg);
1838
        json_object_put(request);
1839
        return;
1840
    }
1841

                
1842
    json_object_put(response_result);
1843
    json_object_put(request);
1844
}