Statistics
| Revision:

root / trunk / glue / glue_json.c @ 1834

History | View | Annotate | Download (67.9 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

                
312
    get_param(msg, params, "collection_name", "file_state_changed", string, collection_name);
313
    get_param(msg, params, "subject", "file_state_changed", string, subject);
314
    get_param(msg, params, "real_filename", "file_state_changed", string, real_filename);
315
    get_param(msg, params, "old_state", "file_state_changed", int, old_state);
316
    get_param(msg, params, "new_state", "file_state_changed", int, new_state);
317

                
318
    nntpgrab_core_emit_file_state_changed(FALSE, collection_name, subject, real_filename, old_state, new_state);
319
}
320

                
321
static void
322
emit_connection_connecting(const char *msg, struct json_object *params)
323
{
324
    char *servername;
325
    int conn_id;
326

                
327
    get_param(msg, params, "servername", "connection_connecting", string, servername);
328
    get_param(msg, params, "conn_id", "connection_connecting", int, conn_id);
329

                
330
    nntpgrab_core_emit_connecting(FALSE, servername, conn_id);
331
}
332

                
333
static void
334
emit_connection_connected(const char *msg, struct json_object *params)
335
{
336
    char *servername;
337
    int conn_id;
338
    char *welcome_msg;
339

                
340
    get_param(msg, params, "servername", "connection_connected", string, servername);
341
    get_param(msg, params, "conn_id", "connection_connected", int, conn_id);
342
    get_param(msg, params, "welcome_msg", "connection_connected", string, welcome_msg);
343

                
344
    nntpgrab_core_emit_connected(FALSE, servername, conn_id, welcome_msg);
345
}
346

                
347
static void
348
emit_connection_disconnect(const char *msg, struct json_object *params)
349
{
350
    char *servername;
351
    int conn_id;
352
    NNTPDisconnectType disconnect_type;
353
    char *reason;
354

                
355
    get_param(msg, params, "servername", "connection_disconnect", string, servername);
356
    get_param(msg, params, "conn_id", "connection_disconnect", int, conn_id);
357
    get_param(msg, params, "disconnect_type", "connection_disconnect", int, disconnect_type);
358
    get_param(msg, params, "reason", "connection_disconnect", string, reason);
359

                
360
    nntpgrab_core_emit_disconnect(FALSE, servername, conn_id, disconnect_type, reason);
361
}
362

                
363
static void
364
emit_schedular_state_changed(const char *msg, struct json_object *params)
365
{
366
    NGSchedularState new_state;
367
    char *reason;
368

                
369
    get_param(msg, params, "new_state", "schedular_state_changed", int, new_state);
370
    get_param(msg, params, "reason", "schedular_state_changed", string, reason);
371

                
372
    nntpgrab_core_emit_schedular_state_changed(FALSE, new_state, (strlen(reason) > 0 ? reason : NULL));
373
}
374

                
375
static void
376
emit_log_message(const char *msg, struct json_object *params)
377
{
378
    char *component;
379
    NGLogLevel log_level;
380
    char *message;
381

                
382
    get_param(msg, params, "component", "log_message", string, component);
383
    get_param(msg, params, "log_level", "log_message", int, log_level);
384
    get_param(msg, params, "msg", "log_message", string, message);
385

                
386
    nntpgrab_core_emit_log_message(FALSE, component, log_level, message, TRUE, FALSE);
387
}
388

                
389
static void
390
emit_task_moved(const char *msg, struct json_object *params)
391
{
392
    char *orig_collection_name;
393
    char *subject;
394
    char *new_collection_name;
395
    int old_position;
396
    int new_position;
397

                
398
    get_param(msg, params, "orig_collection_name", "task_moved", string, orig_collection_name);
399
    get_param(msg, params, "subject", "task_moved", string, subject);
400
    get_param(msg, params, "new_collection_name", "task_moved", string, new_collection_name);
401
    get_param(msg, params, "old_position", "task_moved", int, old_position);
402
    get_param(msg, params, "new_position", "task_moved", int, new_position);
403

                
404
    nntpgrab_core_emit_file_moved(FALSE, orig_collection_name, subject, new_collection_name, old_position, new_position);
405
}
406

                
407
static void
408
emit_collection_moved(const char *msg, struct json_object *params)
409
{
410
    char *collection_name;
411
    int old_position;
412
    int new_position;
413

                
414
    get_param(msg, params, "collection_name", "collection_moved", string, collection_name);
415
    get_param(msg, params, "old_position", "collection_moved", int, old_position);
416
    get_param(msg, params, "new_position", "collection_moved", int, new_position);
417

                
418
    nntpgrab_core_emit_collection_moved(FALSE, collection_name, old_position, new_position);
419
}
420

                
421
static void
422
emit_plugin_loaded(const char *msg, struct json_object *params)
423
{
424
    char *plugin_name;
425
    gboolean is_persistent;
426

                
427
    get_param(msg, params, "plugin_name", "plugin_loaded", string, plugin_name);
428
    get_param(msg, params, "is_persistent", "plugin_loaded", boolean, is_persistent);
429

                
430
    nntpgrab_core_emit_plugin_loaded(FALSE, plugin_name, is_persistent);
431
}
432

                
433
static void
434
emit_plugin_unloaded(const char *msg, struct json_object *params)
435
{
436
    char *plugin_name;
437

                
438
    get_param(msg, params, "plugin_name", "plugin_unloaded", string, plugin_name);
439

                
440
    nntpgrab_core_emit_plugin_unloaded(FALSE, plugin_name);
441
}
442

                
443
static void
444
emit_plugin_event(const char *msg, struct json_object *params)
445
{
446
    int i;
447
    int len;
448
    struct json_object *obj;
449
    char *plugin_name;
450
    char *event_name;
451
    char **values;
452

                
453
    get_param(msg, params, "plugin_name", "plugin_event", string, plugin_name);
454
    get_param(msg, params, "event_name", "plugin_event", string, event_name);
455

                
456
    obj = get_json_param(msg, params, "values", "plugin_event", json_type_array);
457
    if (!obj) {
458
        return;
459
    }
460

                
461
    len = json_object_array_length(obj);
462
    values = g_slice_alloc0(sizeof(char*) * (len + 1));
463

                
464
    for (i = 0; i < len; i++) {
465
        struct json_object *val_obj = json_object_array_get_idx(obj, i);
466
        char *val;
467

                
468
        g_return_if_fail(val_obj != NULL);
469

                
470
        val = json_object_get_string(val_obj);
471

                
472
        g_return_if_fail(val != NULL);
473

                
474
        values[i] = val;
475
    }
476

                
477
    nntpgrab_core_emit_plugin_event(FALSE, plugin_name, event_name, (const char **) values);
478

                
479
    g_slice_free1(sizeof(char*) * (len + 1), values);
480
}
481

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

                
492
    for (p = v; *p != '\0'; p++)
493
        h = (h << 5) - h + *p;
494

                
495
    return h;
496
}
497

                
498
static void
499
glue_process_jsonrpc_notification(const char *msg, struct json_object *obj)
500
{
501
    struct json_object *params;
502
    struct json_object *method;
503
    char *event_name;
504
    guint hash;
505

                
506
    params = json_object_object_get(obj, "params");
507
    if (!params) {
508
        g_print(__FILE__ ":%i JSON message lacks a 'params' field, ignoring: %s\n", __LINE__, msg);
509
        return;
510
    }
511

                
512
    if (json_object_get_type(params) != json_type_object) {
513
        g_print(__FILE__ ":%i JSON parameter is of invalid type, ignoring: %s\n", __LINE__, msg);
514
        return;
515
    }
516

                
517
    method = json_object_object_get(obj, "method");
518
    if (!method) {
519
        g_print(__FILE__ ":%i JSON message lacks a 'method' field, ignoring: %s\n", __LINE__, msg);
520
        return;
521
    }
522

                
523
    event_name = json_object_get_string(method);
524
    hash = ng_str_hash(event_name);
525

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

                
657
        default:
658
            g_print(__FILE__ ":%i JSON notification with unknown event name received, event_name = %s, hash = %u, msg = %s\n", __LINE__, event_name, hash, msg);
659
            break;
660
    }
661
}
662

                
663
static GAsyncQueue *command_queue = NULL;
664
static GStaticMutex command_mutex = G_STATIC_MUTEX_INIT;
665
static GStaticMutex init_mutex = G_STATIC_MUTEX_INIT;
666

                
667
void
668
glue_process_jsonrpc_msg(const char *msg)
669
{
670
    struct json_object *obj;
671
    struct json_object *id;
672

                
673
    g_return_if_fail(msg != NULL);
674

                
675
    obj = json_tokener_parse((char*)msg);
676
    if (!obj) {
677
        g_print(__FILE__ ":%i Invalid message received from server, ignoring: %s\n", __LINE__, msg);
678
        return;
679
    }
680

                
681
    id = json_object_object_get(obj, "id");
682
    if (!id) {
683
        /* Notification received! */
684
        glue_process_jsonrpc_notification(msg, obj);
685
        json_object_put(obj);
686
        return;
687
    }
688

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

                
691
    g_static_mutex_lock(&init_mutex);
692
    if (command_queue == NULL) {
693
        command_queue = g_async_queue_new();
694
    }
695
    g_static_mutex_unlock(&init_mutex);
696

                
697
    g_async_queue_push(command_queue, obj);
698

                
699
    /* No need to unref here as it should be done by the thread who pop's the queue */
700
}
701

                
702
/*************************************************************************************/
703
/* JSON-RPC methods */
704
/*************************************************************************************/
705
#define get_method_param(params, field, method_name, type, dest)                                        \
706
    {                                                                                                   \
707
        char *msg = json_object_get_string(params);                                                     \
708
        struct json_object *obj = get_json_param(msg, params, field, method_name, json_type_ ## type);  \
709
        if (!obj) {                                                                                     \
710
            json_object_put(params) ;                                                                   \
711
            return FALSE;                                                                               \
712
        }                                                                                               \
713
        dest = json_object_get_ ## type (obj);                                                          \
714
    }
715

                
716
static struct json_object *
717
create_new_json_request(const char *method, struct json_object *request_params)
718
{
719
    struct json_object *request;
720
    static int id = 0;
721

                
722
    if (!request_params) {
723
        request_params = json_object_new_array();
724
    }
725

                
726
    request = json_object_new_object();
727
    json_object_object_add(request, "method", json_object_new_string((char*) method));
728
    json_object_object_add(request, "id", json_object_new_int(++id));
729
    json_object_object_add(request, "params", request_params);
730

                
731
    return request;
732
}
733

                
734
static struct json_object *
735
send_request_and_wait_for_response(NntpgrabGlue *glue, struct json_object *request, char **errmsg)
736
{
737
    struct json_object *response;
738
    struct json_object *result;
739
    struct json_object *error;
740
    GTimeVal tv;
741
    int count;
742

                
743
    g_return_val_if_fail(glue != NULL, NULL);
744
    g_return_val_if_fail(request != NULL, NULL);
745
    g_return_val_if_fail(errmsg != NULL, NULL);
746

                
747
    g_static_mutex_lock(&command_mutex);
748

                
749
    if (!write_line(&glue->socket, "%s\r\n", json_object_to_json_string(request))) {
750
        g_static_mutex_unlock(&command_mutex);
751
        return NULL;
752
    }
753

                
754
    g_static_mutex_lock(&init_mutex);
755
    if (command_queue == NULL) {
756
        command_queue = g_async_queue_new();
757
    }
758
    g_static_mutex_unlock(&init_mutex);
759

                
760
    count = 0;
761
    while (count < READ_TIMEOUT_VALUE) {
762
        g_get_current_time(&tv);
763
        tv.tv_sec++;
764

                
765
        response = g_async_queue_timed_pop(command_queue, &tv);
766
        if (response) {
767
            break;
768
        } else if (glue->socket.socket_id <= 0) {
769
            *errmsg = g_strdup_printf(__FILE__ ":%i Connection got disconnected\n", __LINE__);
770

                
771
            nntpgrab_core_emit_log_message(FALSE, "Glue layer", NG_LOG_LEVEL_WARNING, *errmsg, TRUE, FALSE);
772

                
773
            g_static_mutex_unlock(&command_mutex);
774

                
775
            return NULL;
776
        }
777
        count++;
778
    }
779

                
780
    g_static_mutex_unlock(&command_mutex);
781

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

                
785
        nntpgrab_core_emit_log_message(FALSE, "Glue layer", NG_LOG_LEVEL_WARNING, *errmsg, TRUE, FALSE);
786

                
787
        return NULL;
788
    }
789

                
790
    error = json_object_object_get(response, "error");
791
    if (error) {
792
        *errmsg = g_strdup(json_object_get_string(error));
793

                
794
        json_object_put(response);
795

                
796
        return NULL;
797
    }
798

                
799
    result = json_object_object_get(response, "result");
800
    if (!result) {
801
        *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));
802

                
803
        nntpgrab_core_emit_log_message(FALSE, "Glue layer", NG_LOG_LEVEL_WARNING, *errmsg, TRUE, FALSE);
804

                
805
        json_object_put(response);
806

                
807
        return NULL;
808
    }
809

                
810
    /* We're only interested in the result, so we add a reference to that and unref the response */
811
    json_object_get(result);
812
    json_object_put(response);
813

                
814
    return result;
815
}
816

                
817
void
818
nntpgrab_glue_internal_kill_server(NntpgrabGlue *obj)
819
{
820
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
821
    struct json_object *request;
822
    struct json_object *response_result;
823
    char *errmsg = NULL;
824

                
825
    request = create_new_json_request("nntpgrab_server_request_quit", NULL);
826

                
827
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
828
        g_print(__FILE__ ":%i nntpgrab_server_request_quit FAILED: %s\n", __LINE__, errmsg);
829
        g_free(errmsg);
830
        json_object_put(request);
831
        return;
832
    }
833

                
834
    json_object_put(response_result);
835
    json_object_put(request);
836
}
837

                
838
NGList *
839
nntpgrab_glue_internal_config_get_avail_servers(NntpgrabGlue *obj)
840
{
841
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
842
    struct json_object *request;
843
    struct json_object *response_result;
844
    NGList *ret = NULL;
845
    char *errmsg = NULL;
846
    int i;
847
    int len;
848

                
849
    request = create_new_json_request("nntpgrab_config_get_avail_servers", NULL);
850

                
851
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
852
        g_print(__FILE__ ":%i nntpgrab_config_get_avail_servers FAILED: %s\n", __LINE__, errmsg);
853
        g_free(errmsg);
854
        json_object_put(request);
855
        return NULL;
856
    }
857

                
858
    len = json_object_array_length(response_result);
859
    for (i = 0; i < len; i++) {
860
        struct json_object *obj = json_object_array_get_idx(response_result, i);
861
        char *servername;
862

                
863
        g_return_val_if_fail(obj != NULL, NULL);
864

                
865
        servername = json_object_get_string(obj);
866

                
867
        g_return_val_if_fail(servername != NULL, NULL);
868

                
869
        ret = ng_list_append(ret, g_strdup(servername));
870
    }
871

                
872
    json_object_put(request);
873
    json_object_put(response_result);
874

                
875
    return ret;
876
}
877

                
878
gboolean
879
nntpgrab_glue_internal_config_get_server_info(NntpgrabGlue *obj, const char *servername, NGConfigServer *ret)
880
{
881
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
882
    struct json_object *request;
883
    struct json_object *request_params;
884
    struct json_object *response_result;
885
    char *errmsg = NULL;
886
    char *servername_received;
887
    char *hostname;
888
    int port;
889
    char *username;
890
    char *password;
891
    int max_threads;
892
    NGServerPriority priority;
893
    ngboolean use_ssl;
894
    ngboolean enabled;
895

                
896
    g_return_val_if_fail(servername != NULL, FALSE);
897
    g_return_val_if_fail(ret != NULL, FALSE);
898

                
899
    request_params = json_object_new_array();
900
    json_object_array_add(request_params, json_object_new_string((char*) servername));
901
    request = create_new_json_request("nntpgrab_config_get_server_info", request_params);
902

                
903
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
904
        g_print(__FILE__ ":%i nntpgrab_config_get_server_info FAILED: %s\n", __LINE__, errmsg);
905
        g_free(errmsg);
906
        json_object_put(request);
907
        return FALSE;
908
    }
909

                
910
    get_method_param(response_result, "servername", "config_get_server_info", string, servername_received);
911
    get_method_param(response_result, "hostname", "config_get_server_info", string, hostname);
912
    get_method_param(response_result, "port", "config_get_server_info", int, port);
913
    get_method_param(response_result, "username", "config_get_server_info", string, username);
914
    get_method_param(response_result, "password", "config_get_server_info", string, password);
915
    get_method_param(response_result, "max_threads", "config_get_server_info", int, max_threads);
916
    get_method_param(response_result, "priority", "config_get_server_info", int, priority);
917
    get_method_param(response_result, "use_ssl", "config_get_server_info", boolean, use_ssl);
918
    get_method_param(response_result, "enabled", "config_get_server_info", boolean, enabled);
919

                
920
    memset(ret, 0, sizeof(NGConfigServer));
921

                
922
    strncpy(ret->servername, servername_received, sizeof(ret->servername));
923
    strncpy(ret->hostname, hostname, sizeof(ret->hostname));
924
    ret->port = port;
925
    strncpy(ret->username, username, sizeof(ret->username));
926
    strncpy(ret->password, password, sizeof(ret->password));
927
    ret->max_threads = max_threads;
928
    ret->priority = priority;
929
    ret->use_ssl = use_ssl;
930
    ret->enabled = enabled;
931

                
932
    json_object_put(request);
933
    json_object_put(response_result);
934

                
935
    return TRUE;
936
}
937

                
938
gboolean
939
nntpgrab_glue_internal_config_add_server(NntpgrabGlue *obj, NGConfigServer new_server, char **errmsg)
940
{
941
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
942
    struct json_object *request;
943
    struct json_object *request_params;
944
    struct json_object *server;
945
    struct json_object *response_result;
946

                
947
    request_params = json_object_new_array();
948
    server = json_object_new_object();
949
    json_object_object_add(server, "servername", json_object_new_string((char*) new_server.servername));
950
    json_object_object_add(server, "hostname", json_object_new_string((char*) new_server.hostname));
951
    json_object_object_add(server, "port", json_object_new_int(new_server.port));
952
    json_object_object_add(server, "username", json_object_new_string((char*) new_server.username));
953
    json_object_object_add(server, "password", json_object_new_string((char*) new_server.password));
954
    json_object_object_add(server, "max_threads", json_object_new_int(new_server.max_threads));
955
    json_object_object_add(server, "priority", json_object_new_int(new_server.priority));
956
    json_object_object_add(server, "use_ssl", json_object_new_boolean(new_server.use_ssl));
957
    json_object_object_add(server, "enabled", json_object_new_boolean(new_server.enabled));
958
    json_object_array_add(request_params, server);
959
    request = create_new_json_request("nntpgrab_config_add_server", request_params);
960

                
961
    if (!(response_result = send_request_and_wait_for_response(glue, request, errmsg))) {
962
        json_object_put(request);
963
        return FALSE;
964
    }
965

                
966
    json_object_put(request);
967
    json_object_put(response_result);
968

                
969
    return TRUE;
970
}
971

                
972
gboolean
973
nntpgrab_glue_internal_config_del_server(NntpgrabGlue *obj, const char *servername, char **errmsg)
974
{
975
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
976
    struct json_object *request;
977
    struct json_object *request_params;
978
    struct json_object *response_result;
979

                
980
    request_params = json_object_new_array();
981
    json_object_array_add(request_params, json_object_new_string((char*) servername));
982
    request = create_new_json_request("nntpgrab_config_del_server", request_params);
983

                
984
    if (!(response_result = send_request_and_wait_for_response(glue, request, errmsg))) {
985
        json_object_put(request);
986
        return FALSE;
987
    }
988

                
989
    json_object_put(request);
990
    json_object_put(response_result);
991

                
992
    return TRUE;
993
}
994

                
995
gboolean
996
nntpgrab_glue_internal_config_edit_server(NntpgrabGlue *obj, const char *servername, NGConfigServer new_server, char **errmsg)
997
{
998
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
999
    struct json_object *request;
1000
    struct json_object *request_params;
1001
    struct json_object *server;
1002
    struct json_object *response_result;
1003

                
1004
    request_params = json_object_new_array();
1005
    server = json_object_new_object();
1006
    json_object_object_add(server, "servername", json_object_new_string((char*) new_server.servername));
1007
    json_object_object_add(server, "hostname", json_object_new_string((char*) new_server.hostname));
1008
    json_object_object_add(server, "port", json_object_new_int(new_server.port));
1009
    json_object_object_add(server, "username", json_object_new_string((char*) new_server.username));
1010
    json_object_object_add(server, "password", json_object_new_string((char*) new_server.password));
1011
    json_object_object_add(server, "max_threads", json_object_new_int(new_server.max_threads));
1012
    json_object_object_add(server, "priority", json_object_new_int(new_server.priority));
1013
    json_object_object_add(server, "use_ssl", json_object_new_boolean(new_server.use_ssl));
1014
    json_object_object_add(server, "enabled", json_object_new_boolean(new_server.enabled));
1015
    json_object_array_add(request_params, json_object_new_string((char*) servername));
1016
    json_object_array_add(request_params, server);
1017
    request = create_new_json_request("nntpgrab_config_edit_server", request_params);
1018

                
1019
    if (!(response_result = send_request_and_wait_for_response(glue, request, errmsg))) {
1020
        json_object_put(request);
1021
        return FALSE;
1022
    }
1023

                
1024
    json_object_put(request);
1025
    json_object_put(response_result);
1026

                
1027
    return TRUE;
1028
}
1029

                
1030
gboolean
1031
nntpgrab_glue_internal_config_get_opts(NntpgrabGlue *obj, NGConfigOpts *opts)
1032
{
1033
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1034
    struct json_object *request;
1035
    struct json_object *response_result;
1036
    char *errmsg = NULL;
1037
    char *download_directory;
1038
    char *temp_directory;
1039
    gboolean enable_intelligent_par2_downloading;
1040
    gboolean enable_par2_repair;
1041
    char *auto_import_directory;
1042
    gboolean enable_auto_import;
1043
    gboolean move_file_after_auto_import;
1044
    gboolean enable_auto_unpack;
1045
    gboolean enable_bandwidth_shaping;
1046
    int max_bandwidth;
1047
    gboolean enable_webserver;
1048
    int webserver_port;
1049
    gboolean enable_logger;
1050
    gboolean auto_remove_files;
1051

                
1052
    memset(opts, 0, sizeof(NGConfigOpts));
1053

                
1054
    request = create_new_json_request("nntpgrab_config_get_opts", NULL);
1055

                
1056
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
1057
        g_print(__FILE__ ":%i nntpgrab_config_get_opts FAILED: %s\n", __LINE__, errmsg);
1058
        g_free(errmsg);
1059
        json_object_put(request);
1060
        return FALSE;
1061
    }
1062

                
1063
    get_method_param(response_result, "download_directory", "config_get_opts", string, download_directory);
1064
    get_method_param(response_result, "temp_directory", "config_get_opts", string, temp_directory);
1065
    get_method_param(response_result, "enable_intelligent_par2_downloading", "config_get_opts", boolean, enable_intelligent_par2_downloading);
1066
    get_method_param(response_result, "enable_par2_repair", "config_get_opts", boolean, enable_par2_repair);
1067
    get_method_param(response_result, "auto_import_directory", "config_get_opts", string, auto_import_directory);
1068
    get_method_param(response_result, "enable_auto_import", "config_get_opts", boolean, enable_auto_import);
1069
    get_method_param(response_result, "move_file_after_auto_import", "config_get_opts", boolean, move_file_after_auto_import);
1070
    get_method_param(response_result, "enable_auto_unpack", "config_get_opts", boolean, enable_auto_unpack);
1071
    get_method_param(response_result, "enable_bandwidth_shaping", "config_get_opts", boolean, enable_bandwidth_shaping);
1072
    get_method_param(response_result, "max_bandwidth", "config_get_opts", int, max_bandwidth);
1073
    get_method_param(response_result, "enable_webserver", "config_get_opts", boolean, enable_webserver);
1074
    get_method_param(response_result, "webserver_port", "config_get_opts", int, webserver_port);
1075
    get_method_param(response_result, "enable_logger", "config_get_opts", boolean, enable_logger);
1076
    get_method_param(response_result, "auto_remove_files", "config_get_opts", boolean, auto_remove_files);
1077

                
1078
    strncpy(opts->download_directory, download_directory, sizeof(opts->download_directory) - 1);
1079
    strncpy(opts->temp_directory, temp_directory, sizeof(opts->temp_directory) - 1);
1080
    opts->enable_intelligent_par2_downloading = enable_intelligent_par2_downloading;
1081
    opts->enable_par2_repair = enable_par2_repair;
1082
    strncpy(opts->auto_import_directory, auto_import_directory, sizeof(opts->auto_import_directory) - 1);
1083
    opts->enable_auto_import = enable_auto_import;
1084
    opts->move_file_after_auto_import = move_file_after_auto_import;
1085
    opts->enable_auto_unpack = enable_auto_unpack;
1086
    opts->enable_bandwidth_shaping = enable_bandwidth_shaping;
1087
    opts->max_bandwidth = max_bandwidth;
1088
    opts->enable_webserver = enable_webserver;
1089
    opts->webserver_port = webserver_port;
1090
    opts->enable_logger = enable_logger;
1091
    opts->auto_remove_files = auto_remove_files;
1092

                
1093
    json_object_put(request);
1094
    json_object_put(response_result);
1095

                
1096
    return TRUE;
1097
}
1098

                
1099
gboolean
1100
nntpgrab_glue_internal_config_set_opts(NntpgrabGlue *obj, NGConfigOpts opts)
1101
{
1102
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1103
    struct json_object *request;
1104
    struct json_object *request_params;
1105
    struct json_object *param;
1106
    struct json_object *response_result;
1107
    char *errmsg = NULL;
1108

                
1109
    request_params = json_object_new_array();
1110
    param = json_object_new_object();
1111
    json_object_object_add(param, "download_directory", json_object_new_string((char*) opts.download_directory));
1112
    json_object_object_add(param, "temp_directory", json_object_new_string((char*) opts.temp_directory));
1113
    json_object_object_add(param, "enable_intelligent_par2_downloading", json_object_new_boolean(opts.enable_intelligent_par2_downloading));
1114
    json_object_object_add(param, "enable_par2_repair", json_object_new_boolean(opts.enable_par2_repair));
1115
    json_object_object_add(param, "auto_import_directory", json_object_new_string((char*) opts.auto_import_directory));
1116
    json_object_object_add(param, "enable_auto_import", json_object_new_boolean(opts.enable_auto_import));
1117
    json_object_object_add(param, "move_file_after_auto_import", json_object_new_boolean(opts.move_file_after_auto_import));
1118
    json_object_object_add(param, "enable_auto_unpack", json_object_new_boolean(opts.enable_auto_unpack));
1119
    json_object_object_add(param, "enable_bandwidth_shaping", json_object_new_boolean(opts.enable_bandwidth_shaping));
1120
    json_object_object_add(param, "max_bandwidth", json_object_new_int(opts.max_bandwidth));
1121
    json_object_object_add(param, "enable_webserver", json_object_new_boolean(opts.enable_webserver));
1122
    json_object_object_add(param, "webserver_port", json_object_new_int(opts.webserver_port));
1123
    json_object_object_add(param, "enable_logger", json_object_new_boolean(opts.enable_logger));
1124
    json_object_object_add(param, "auto_remove_files", json_object_new_boolean(opts.auto_remove_files));
1125
    json_object_array_add(request_params, param);
1126
    request = create_new_json_request("nntpgrab_config_set_opts", request_params);
1127

                
1128
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
1129
        g_print(__FILE__ ":%i nntpgrab_config_set_opts FAILED: %s\n", __LINE__, errmsg);
1130
        g_free(errmsg);
1131
        json_object_put(request);
1132
        return FALSE;
1133
    }
1134

                
1135
    json_object_put(request);
1136
    json_object_put(response_result);
1137

                
1138
    return TRUE;
1139
}
1140

                
1141
gboolean
1142
nntpgrab_glue_internal_config_get_folder_listing(NntpgrabGlue *obj, const char *parent, NGList **folders)
1143
{
1144
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1145
    struct json_object *request;
1146
    struct json_object *request_params;
1147
    struct json_object *response_result;
1148
    char *errmsg = NULL;
1149
    int i;
1150
    int len;
1151

                
1152
    request_params = json_object_new_array();
1153
    if (parent) {
1154
        json_object_array_add(request_params, json_object_new_string((char*) parent));
1155
    } else {
1156
        json_object_array_add(request_params, NULL);
1157
    }
1158
    request = create_new_json_request("nntpgrab_utils_get_folder_listing", request_params);
1159

                
1160
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
1161
        g_print(__FILE__ ":%i nntpgrab_utils_get_folder_listing FAILED: %s\n", __LINE__, errmsg);
1162
        g_free(errmsg);
1163
        json_object_put(request);
1164
        return FALSE;
1165
    }
1166

                
1167
    if (json_object_get_type(response_result) != json_type_array) {
1168
        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));
1169
        json_object_put(request);
1170
        json_object_put(response_result);
1171

                
1172
        return FALSE;
1173
    }
1174

                
1175
    len = json_object_array_length(response_result);
1176
    *folders = NULL;
1177
    for (i = 0; i < len; i++) {
1178
        struct json_object *param = json_object_array_get_idx(response_result, i);
1179
        NNTPGrabFolder *folder;
1180
        char *folder_str;
1181

                
1182
        g_return_val_if_fail(obj != NULL, FALSE);
1183

                
1184
        folder = g_slice_new0(NNTPGrabFolder);
1185

                
1186
        get_method_param(param, "folder", "nntpgrab_utils_get_folder_listing", string, folder_str);
1187
        get_method_param(param, "has_subfolders", "nntpgrab_utils_get_folder_listing", boolean, folder->has_subfolders);
1188
        strncpy(folder->folder, folder_str, sizeof(folder->folder) - 1);
1189

                
1190
        *folders = ng_list_append(*folders, folder);
1191
    }
1192

                
1193
    json_object_put(request);
1194
    json_object_put(response_result);
1195

                
1196
    return TRUE;
1197
}
1198

                
1199
gboolean
1200
nntpgrab_glue_internal_schedular_start(NntpgrabGlue *obj)
1201
{
1202
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1203
    struct json_object *request;
1204
    struct json_object *response_result;
1205
    char *errmsg = NULL;
1206

                
1207
    request = create_new_json_request("nntpgrab_schedular_start", NULL);
1208

                
1209
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
1210
        g_print(__FILE__ ":%i nntpgrab_schedular_start FAILED: %s\n", __LINE__, errmsg);
1211
        g_free(errmsg);
1212
        json_object_put(request);
1213
        return FALSE;
1214
    }
1215

                
1216
    json_object_put(request);
1217
    json_object_put(response_result);
1218

                
1219
    return TRUE;
1220
}
1221

                
1222
gboolean
1223
nntpgrab_glue_internal_schedular_stop(NntpgrabGlue *obj, gboolean wait)
1224
{
1225
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1226
    struct json_object *request;
1227
    struct json_object *request_params;
1228
    struct json_object *response_result;
1229
    char *errmsg = NULL;
1230

                
1231
    request_params = json_object_new_array();
1232
    json_object_array_add(request_params, json_object_new_boolean(wait));
1233
    request = create_new_json_request("nntpgrab_schedular_stop", request_params);
1234

                
1235
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
1236
        g_print(__FILE__ ":%i nntpgrab_schedular_stop FAILED: %s\n", __LINE__, errmsg);
1237
        g_free(errmsg);
1238
        json_object_put(request);
1239
        return FALSE;
1240
    }
1241

                
1242
    json_object_put(request);
1243
    json_object_put(response_result);
1244

                
1245
    return TRUE;
1246
}
1247

                
1248
NGSchedularState
1249
nntpgrab_glue_internal_schedular_get_state(NntpgrabGlue *obj)
1250
{
1251
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1252
    struct json_object *request;
1253
    struct json_object *response_result;
1254
    char *errmsg = NULL;
1255
    NGSchedularState ret;
1256

                
1257
    request = create_new_json_request("nntpgrab_schedular_get_state", NULL);
1258

                
1259
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
1260
        g_print(__FILE__ ":%i nntpgrab_schedular_get_state FAILED: %s\n", __LINE__, errmsg);
1261
        g_free(errmsg);
1262
        json_object_put(request);
1263
        return SCHEDULAR_STATE_STOPPED;
1264
    }
1265

                
1266
    if (json_object_get_type(response_result) != json_type_int) {
1267
        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));
1268
        json_object_put(request);
1269
        json_object_put(response_result);
1270

                
1271
        return SCHEDULAR_STATE_STOPPED;
1272
    }
1273

                
1274
    ret = json_object_get_int(response_result);
1275

                
1276
    json_object_put(request);
1277
    json_object_put(response_result);
1278

                
1279
    return ret;
1280
}
1281

                
1282
gboolean
1283
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)
1284
{
1285
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1286
    struct json_object *request;
1287
    struct json_object *request_params;
1288
    struct json_object *response_result;
1289
    struct json_object *json_obj;
1290
    NGList *list;
1291

                
1292
    request_params = json_object_new_array();
1293
    json_object_array_add(request_params, json_object_new_string((char*) collection_name));
1294
    json_object_array_add(request_params, json_object_new_string((char*) subject));
1295
    json_object_array_add(request_params, json_object_new_string((char*) poster));
1296
    json_object_array_add(request_params, json_object_new_int(stamp));
1297
    json_object_array_add(request_params, json_object_new_int(file_size / 1024));
1298

                
1299
    json_obj = json_object_new_array();
1300
    json_object_array_add(request_params, json_obj);
1301
    list = groups;
1302
    while (list) {
1303
        char *groupname = list->data;
1304

                
1305
        json_object_array_add(json_obj, json_object_new_string(groupname));
1306

                
1307
        list = ng_list_next(list);
1308
    }
1309

                
1310
    json_obj = json_object_new_array();
1311
    json_object_array_add(request_params, json_obj);
1312
    list = parts;
1313
    while (list) {
1314
        NNTPPart *part = list->data;
1315
        struct json_object *part_obj = json_object_new_object();
1316

                
1317
        json_object_object_add(part_obj, "message_id", json_object_new_string((char*) part->message_id));
1318
        json_object_object_add(part_obj, "part_num", json_object_new_int(part->part_num));
1319
        json_object_object_add(part_obj, "size", json_object_new_int(part->size));
1320
        json_object_array_add(json_obj, part_obj);
1321

                
1322
        list = ng_list_next(list);
1323
    }
1324

                
1325
    request = create_new_json_request("nntpgrab_schedular_add_file_to_queue", request_params);
1326

                
1327
    if (!(response_result = send_request_and_wait_for_response(glue, request, errmsg))) {
1328
        json_object_put(request);
1329
        return FALSE;
1330
    }
1331

                
1332
    json_object_put(request);
1333
    json_object_put(response_result);
1334

                
1335
    return TRUE;
1336
}
1337

                
1338
gboolean
1339
nntpgrab_glue_internal_schedular_del_task_from_queue(NntpgrabGlue *obj, const char *collection_name, const char *subject, char **errmsg)
1340
{
1341
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1342
    struct json_object *request;
1343
    struct json_object *request_params;
1344
    struct json_object *response_result;
1345

                
1346
    request_params = json_object_new_array();
1347
    json_object_array_add(request_params, json_object_new_string((char*) collection_name));
1348
    if (subject) {
1349
        json_object_array_add(request_params, json_object_new_string((char*) subject));
1350
    } else {
1351
        json_object_array_add(request_params, NULL);
1352
    }
1353
    request = create_new_json_request("nntpgrab_schedular_del_file_from_queue", request_params);
1354

                
1355
    if (!(response_result = send_request_and_wait_for_response(glue, request, errmsg))) {
1356
        json_object_put(request);
1357
        return FALSE;
1358
    }
1359

                
1360
    json_object_put(request);
1361
    json_object_put(response_result);
1362

                
1363
    return TRUE;
1364
}
1365

                
1366
gboolean
1367
nntpgrab_glue_internal_schedular_restart_task(NntpgrabGlue *obj, const char *collection_name, const char *subject, char **errmsg)
1368
{
1369
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1370
    struct json_object *request;
1371
    struct json_object *request_params;
1372
    struct json_object *response_result;
1373

                
1374
    g_return_val_if_fail(collection_name != NULL, FALSE);
1375
    /* NOTE: subject CAN be NULL */
1376

                
1377
    request_params = json_object_new_array();
1378
    json_object_array_add(request_params, json_object_new_string((char*) collection_name));
1379
    if (subject) {
1380
        json_object_array_add(request_params, json_object_new_string((char*) subject));
1381
    } else {
1382
        json_object_array_add(request_params, NULL);
1383
    }
1384
    request = create_new_json_request("nntpgrab_schedular_restart_file", request_params);
1385

                
1386
    if (!(response_result = send_request_and_wait_for_response(glue, request, errmsg))) {
1387
        json_object_put(request);
1388
        return FALSE;
1389
    }
1390

                
1391
    json_object_put(request);
1392
    json_object_put(response_result);
1393

                
1394
    return TRUE;
1395
}
1396

                
1397
gboolean
1398
nntpgrab_glue_internal_schedular_save_queue(NntpgrabGlue *obj, char **errmsg)
1399
{
1400
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1401
    struct json_object *request;
1402
    struct json_object *response_result;
1403

                
1404
    request = create_new_json_request("nntpgrab_schedular_save_queue", NULL);
1405

                
1406
    if (!(response_result = send_request_and_wait_for_response(glue, request, errmsg))) {
1407
        json_object_put(request);
1408
        return FALSE;
1409
    }
1410

                
1411
    json_object_put(request);
1412
    json_object_put(response_result);
1413

                
1414
    return TRUE;
1415
}
1416

                
1417
static ForeachCollectionFunc collection_func_global = NULL;
1418
static ForeachFileFunc file_func_global = NULL;
1419
static ForeachGroupFunc group_func_global = NULL;
1420
static void *foreach_task_user_data_global = NULL;
1421

                
1422
static void
1423
process_foreach_collection_event(const char *msg, struct json_object *params)
1424
{
1425
    char *collection_name = NULL;
1426
    char *poster = NULL;
1427
    guint64 total_size = 0;
1428
    guint64 total_size_remaining = 0;
1429
    int position = 0;
1430

                
1431
    if (!collection_func_global) {
1432
        return;
1433
    }
1434

                
1435
    get_param(msg, params, "collection_name", "foreach_collection_event", string, collection_name);
1436
    get_param(msg, params, "poster", "foreach_collection_event", string, poster);
1437
    get_param(msg, params, "total_size", "foreach_collection_event", int, total_size);
1438
    get_param(msg, params, "total_size_remaining", "foreach_collection_event", int, total_size_remaining);
1439
    get_param(msg, params, "position", "foreach_collection_event", int, position);
1440

                
1441
    /* JSON doesn't support 64bit integers so all file sizes are in KB instead of bytes */
1442
    total_size *= 1024;
1443
    total_size_remaining *= 1024;
1444

                
1445
    collection_func_global(collection_name, poster, total_size, total_size_remaining, position, foreach_task_user_data_global);
1446
}
1447

                
1448
static void
1449
process_foreach_file_event(const char *msg, struct json_object *params)
1450
{
1451
    char *collection_name = NULL;
1452
    char *subject = NULL;
1453
    char *poster;
1454
    int stamp;
1455
    guint64 file_size;
1456
    guint64 file_size_remaining;
1457
    int num_parts_total;
1458
    int num_parts_downloaded;
1459
    int num_parts_failed;
1460
    NGTaskState status;
1461
    char *filename;
1462
    int position;
1463

                
1464
    if (!file_func_global) {
1465
        return;
1466
    }
1467

                
1468
    get_param(msg, params, "collection_name", "foreach_file_event", string, collection_name);
1469
    get_param(msg, params, "subject", "foreach_file_event", string, subject);
1470
    get_param(msg, params, "poster", "foreach_file_event", string, poster);
1471
    get_param(msg, params, "stamp", "foreach_file_event", int, stamp);
1472
    get_param(msg, params, "file_size", "foreach_file_event", int, file_size);
1473
    get_param(msg, params, "file_size_remaining", "foreach_file_event", int, file_size_remaining);
1474
    get_param(msg, params, "num_parts_total", "foreach_file_event", int, num_parts_total);
1475
    get_param(msg, params, "num_parts_downloaded", "foreach_file_event", int, num_parts_downloaded);
1476
    get_param(msg, params, "num_parts_failed", "foreach_file_event", int, num_parts_failed);
1477
    get_param(msg, params, "status", "foreach_file_event", int, status);
1478
    get_param(msg, params, "filename", "foreach_file_event", string, filename);
1479
    get_param(msg, params, "position", "foreach_file_event", int, position);
1480

                
1481
    /* JSON doesn't support 64bit integers so all file sizes are in KB instead of bytes */
1482
    file_size *= 1024;
1483
    file_size_remaining *= 1024;
1484

                
1485
    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);
1486
}
1487

                
1488
static void
1489
process_foreach_group_event(const char *msg, struct json_object *params)
1490
{
1491
    char *collection_name = NULL;
1492
    char *subject = NULL;
1493
    char *group = NULL;
1494

                
1495
    if (!group_func_global) {
1496
        return;
1497
    }
1498

                
1499
    get_param(msg, params, "collection_name", "foreach_group_event", string, collection_name);
1500
    get_param(msg, params, "subject", "foreach_group_event", string, subject);
1501
    get_param(msg, params, "group", "foreach_group_event", string, group);
1502

                
1503
    group_func_global(collection_name, subject, group, foreach_task_user_data_global);
1504
}
1505

                
1506
gboolean
1507
nntpgrab_glue_internal_schedular_foreach_task(NntpgrabGlue *obj, ForeachCollectionFunc collection_func, ForeachFileFunc file_func, ForeachGroupFunc group_func, void *data)
1508
{
1509
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1510
    struct json_object *request;
1511
    struct json_object *response_result;
1512
    char *errmsg = NULL;
1513
    gboolean ret;
1514

                
1515
    g_return_val_if_fail(obj != NULL, FALSE);
1516
    g_return_val_if_fail(collection_func != NULL || file_func != NULL || group_func != NULL, FALSE);
1517

                
1518
    request = create_new_json_request("nntpgrab_schedular_foreach_task", NULL);
1519

                
1520
    collection_func_global = collection_func;
1521
    file_func_global = file_func;
1522
    group_func_global = group_func;
1523
    foreach_task_user_data_global = data;
1524

                
1525
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
1526
        g_free(errmsg);
1527
        json_object_put(request);
1528
        collection_func_global = NULL;
1529
        file_func_global = NULL;
1530
        group_func_global = NULL;
1531
        foreach_task_user_data_global = NULL;
1532
        return FALSE;
1533
    }
1534

                
1535
    collection_func_global = NULL;
1536
    file_func_global = NULL;
1537
    group_func_global = NULL;
1538
    foreach_task_user_data_global = NULL;
1539

                
1540
    if (json_object_get_type(response_result) != json_type_boolean) {
1541
        // invalid type
1542
        g_print(__FILE__ ":%i response is of invalid type for method 'schedular_foreach_task', response = %s\n", __LINE__, json_object_get_string(response_result));
1543
        json_object_put(request);
1544
        json_object_put(response_result);
1545
        return FALSE;
1546
    }
1547

                
1548
    ret = json_object_get_boolean(response_result);
1549

                
1550
    json_object_put(request);
1551
    json_object_put(response_result);
1552

                
1553
    return ret;
1554
}
1555

                
1556
gboolean
1557
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)
1558
{
1559
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1560
    struct json_object *request;
1561
    struct json_object *request_params;
1562
    struct json_object *response_result;
1563
    char *errmsg = NULL;
1564

                
1565
    request_params = json_object_new_array();
1566
    json_object_array_add(request_params, json_object_new_string((char*) collection_name_src));
1567
    json_object_array_add(request_params, json_object_new_string((char*) subject_src));
1568
    json_object_array_add(request_params, json_object_new_string((char*) collection_name_dest));
1569
    json_object_array_add(request_params, json_object_new_int(position_dest));
1570
    request = create_new_json_request("nntpgrab_schedular_move_file", request_params);
1571

                
1572
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
1573
        g_print(__FILE__ ":%i nntpgrab_schedular_move_file FAILED: %s\n", __LINE__, errmsg);
1574
        g_free(errmsg);
1575
        json_object_put(request);
1576
        return FALSE;
1577
    }
1578

                
1579
    json_object_put(request);
1580
    json_object_put(response_result);
1581

                
1582
    return TRUE;
1583
}
1584

                
1585
gboolean
1586
nntpgrab_glue_internal_schedular_move_collection(NntpgrabGlue *obj, const char *collection_name, int new_position)
1587
{
1588
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1589
    struct json_object *request;
1590
    struct json_object *request_params;
1591
    struct json_object *response_result;
1592
    char *errmsg = NULL;
1593

                
1594
    request_params = json_object_new_array();
1595
    json_object_array_add(request_params, json_object_new_string((char*) collection_name));
1596
    json_object_array_add(request_params, json_object_new_int(new_position));
1597
    request = create_new_json_request("nntpgrab_schedular_move_collection", request_params);
1598

                
1599
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
1600
        g_print(__FILE__ ":%i nntpgrab_schedular_move_collection FAILED: %s\n", __LINE__, errmsg);
1601
        g_free(errmsg);
1602
        json_object_put(request);
1603
        return FALSE;
1604
    }
1605

                
1606
    json_object_put(request);
1607
    json_object_put(response_result);
1608

                
1609
    return TRUE;
1610
}
1611

                
1612
gboolean
1613
nntpgrab_glue_internal_schedular_mark_task_optional(NntpgrabGlue *obj, const char *collection_name, const char *subject, ngboolean is_optional)
1614
{
1615
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1616
    struct json_object *request;
1617
    struct json_object *request_params;
1618
    struct json_object *response_result;
1619
    char *errmsg = NULL;
1620

                
1621
    request_params = json_object_new_array();
1622
    json_object_array_add(request_params, json_object_new_string((char*) collection_name));
1623
    json_object_array_add(request_params, json_object_new_string((char*) subject));
1624
    json_object_array_add(request_params, json_object_new_boolean(is_optional));
1625
    request = create_new_json_request("nntpgrab_schedular_mark_task_optional", request_params);
1626

                
1627
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
1628
        g_print(__FILE__ ":%i nntpgrab_schedular_mark_task_optional FAILED: %s\n", __LINE__, errmsg);
1629
        g_free(errmsg);
1630
        json_object_put(request);
1631
        return FALSE;
1632
    }
1633

                
1634
    json_object_put(request);
1635
    json_object_put(response_result);
1636

                
1637
    return TRUE;
1638
}
1639

                
1640
NGList *
1641
nntpgrab_glue_internal_plugins_get_avail_plugins(NntpgrabGlue *obj)
1642
{
1643
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1644
    struct json_object *request;
1645
    struct json_object *response_result;
1646
    NGList *ret = NULL;
1647
    char *errmsg = NULL;
1648
    int i;
1649
    int len;
1650

                
1651
    request = create_new_json_request("nntpgrab_plugins_get_avail_plugins", NULL);
1652

                
1653
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
1654
        g_print(__FILE__ ":%i nntpgrab_plugins_get_avail_plugins FAILED: %s\n", __LINE__, errmsg);
1655
        g_free(errmsg);
1656
        json_object_put(request);
1657
        return NULL;
1658
    }
1659

                
1660
    len = json_object_array_length(response_result);
1661
    for (i = 0; i < len; i++) {
1662
        struct json_object *obj = json_object_array_get_idx(response_result, i);
1663
        char *servername;
1664

                
1665
        g_return_val_if_fail(obj != NULL, NULL);
1666

                
1667
        servername = json_object_get_string(obj);
1668

                
1669
        g_return_val_if_fail(servername != NULL, NULL);
1670

                
1671
        ret = ng_list_append(ret, g_strdup(servername));
1672
    }
1673

                
1674
    json_object_put(request);
1675
    json_object_put(response_result);
1676

                
1677
    return ret;
1678
}
1679

                
1680
gboolean
1681
nntpgrab_glue_internal_plugins_get_plugin_info(NntpgrabGlue *obj, const char *plugin_name, NNTPGrabPluginInfo *plugin_info)
1682
{
1683
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1684
    struct json_object *request;
1685
    struct json_object *request_params;
1686
    struct json_object *response_result;
1687
    char *errmsg = NULL;
1688
    char *name;
1689
    char *version;
1690
    char *author;
1691
    char *url;
1692
    char *description;
1693
    gboolean is_loaded;
1694
    gboolean is_persistent;
1695

                
1696
    g_return_val_if_fail(plugin_name != NULL, FALSE);
1697
    g_return_val_if_fail(plugin_info != NULL, FALSE);
1698

                
1699
    request_params = json_object_new_array();
1700
    json_object_array_add(request_params, json_object_new_string((char*) plugin_name));
1701
    request = create_new_json_request("nntpgrab_plugins_get_plugin_info", request_params);
1702

                
1703
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
1704
        g_print(__FILE__ ":%i nntpgrab_plugins_get_plugin_info FAILED: %s\n", __LINE__, errmsg);
1705
        g_free(errmsg);
1706
        json_object_put(request);
1707
        return FALSE;
1708
    }
1709

                
1710
    get_method_param(response_result, "name", "plugins_get_plugin_info", string, name);
1711
    get_method_param(response_result, "version", "plugins_get_plugin_info", string, version);
1712
    get_method_param(response_result, "author", "plugins_get_plugin_info", string, author);
1713
    get_method_param(response_result, "url", "plugins_get_plugin_info", string, url);
1714
    get_method_param(response_result, "description", "plugins_get_plugin_info", string, description);
1715
    get_method_param(response_result, "is_loaded", "plugins_get_plugin_info", boolean, is_loaded);
1716
    get_method_param(response_result, "is_persistent", "plugins_get_plugin_info", boolean, is_persistent);
1717

                
1718
    memset(plugin_info, 0, sizeof(NNTPGrabPluginInfo));
1719

                
1720
    strncpy(plugin_info->name, name, sizeof(plugin_info->name));
1721
    strncpy(plugin_info->version, version, sizeof(plugin_info->version));
1722
    strncpy(plugin_info->author, author, sizeof(plugin_info->author));
1723
    strncpy(plugin_info->url, url, sizeof(plugin_info->url));
1724
    strncpy(plugin_info->description, description, sizeof(plugin_info->description));
1725
    plugin_info->is_loaded = is_loaded;
1726
    plugin_info->is_persistent = is_persistent;
1727

                
1728
    json_object_put(request);
1729
    json_object_put(response_result);
1730

                
1731
    return TRUE;
1732
}
1733

                
1734
gboolean
1735
nntpgrab_glue_internal_plugins_load_plugin(NntpgrabGlue *obj, const char *plugin_name, char **errmsg)
1736
{
1737
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1738
    struct json_object *request;
1739
    struct json_object *request_params;
1740
    struct json_object *response_result;
1741

                
1742
    request_params = json_object_new_array();
1743
    json_object_array_add(request_params, json_object_new_string((char*) plugin_name));
1744
    request = create_new_json_request("nntpgrab_plugins_load_plugin", request_params);
1745

                
1746
    if (!(response_result = send_request_and_wait_for_response(glue, request, errmsg))) {
1747
        json_object_put(request);
1748
        return FALSE;
1749
    }
1750

                
1751
    json_object_put(request);
1752
    json_object_put(response_result);
1753

                
1754
    return TRUE;
1755
}
1756

                
1757
gboolean
1758
nntpgrab_glue_internal_plugins_unload_plugin(NntpgrabGlue *obj, const char *plugin_name, char **errmsg)
1759
{
1760
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1761
    struct json_object *request;
1762
    struct json_object *request_params;
1763
    struct json_object *response_result;
1764

                
1765
    request_params = json_object_new_array();
1766
    json_object_array_add(request_params, json_object_new_string((char*) plugin_name));
1767
    request = create_new_json_request("nntpgrab_plugins_unload_plugin", request_params);
1768

                
1769
    if (!(response_result = send_request_and_wait_for_response(glue, request, errmsg))) {
1770
        json_object_put(request);
1771
        return FALSE;
1772
    }
1773

                
1774
    json_object_put(request);
1775
    json_object_put(response_result);
1776

                
1777
    return TRUE;
1778
}
1779

                
1780
gboolean
1781
nntpgrab_glue_internal_plugins_set_persistent(NntpgrabGlue *obj, const char *plugin_name, ngboolean persistent)
1782
{
1783
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1784
    struct json_object *request;
1785
    struct json_object *request_params;
1786
    struct json_object *response_result;
1787
    char *errmsg = NULL;
1788

                
1789
    request_params = json_object_new_array();
1790
    json_object_array_add(request_params, json_object_new_string((char*) plugin_name));
1791
    json_object_array_add(request_params, json_object_new_boolean(persistent));
1792
    request = create_new_json_request("nntpgrab_plugins_set_persistent", request_params);
1793

                
1794
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
1795
        g_print(__FILE__ ":%i nntpgrab_plugins_set_persistent FAILED: %s\n", __LINE__, errmsg);
1796
        g_free(errmsg);
1797
        json_object_put(request);
1798
        return FALSE;
1799
    }
1800

                
1801
    json_object_put(request);
1802
    json_object_put(response_result);
1803

                
1804
    return TRUE;
1805
}
1806

                
1807
void
1808
nntpgrab_glue_internal_set_emit_log_messages(NntpgrabGlue *obj, ngboolean val)
1809
{
1810
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1811
    struct json_object *request;
1812
    struct json_object *request_params;
1813
    struct json_object *response_result;
1814
    char *errmsg = NULL;
1815

                
1816
    request_params = json_object_new_array();
1817
    json_object_array_add(request_params, json_object_new_boolean(val));
1818
    request = create_new_json_request("nntpgrab_set_emit_log_messages", request_params);
1819

                
1820
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
1821
        g_print(__FILE__ ":%i nntpgrab_set_emit_log_messages FAILED: %s\n", __LINE__, errmsg);
1822
        g_free(errmsg);
1823
        json_object_put(request);
1824
        return;
1825
    }
1826

                
1827
    json_object_put(response_result);
1828
    json_object_put(request);
1829
}