Statistics
| Revision:

root / trunk / glue / glue_json.c @ 1850

History | View | Annotate | Download (68.8 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 send_group_command;
894
    ngboolean use_ssl;
895
    ngboolean enabled;
896

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

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

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

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

                
922
    memset(ret, 0, sizeof(NGConfigServer));
923

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

                
935
    json_object_put(request);
936
    json_object_put(response_result);
937

                
938
    return TRUE;
939
}
940

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

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

                
965
    if (!(response_result = send_request_and_wait_for_response(glue, request, errmsg))) {
966
        json_object_put(request);
967
        return FALSE;
968
    }
969

                
970
    json_object_put(request);
971
    json_object_put(response_result);
972

                
973
    return TRUE;
974
}
975

                
976
gboolean
977
nntpgrab_glue_internal_config_del_server(NntpgrabGlue *obj, const char *servername, char **errmsg)
978
{
979
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
980
    struct json_object *request;
981
    struct json_object *request_params;
982
    struct json_object *response_result;
983

                
984
    request_params = json_object_new_array();
985
    json_object_array_add(request_params, json_object_new_string((char*) servername));
986
    request = create_new_json_request("nntpgrab_config_del_server", request_params);
987

                
988
    if (!(response_result = send_request_and_wait_for_response(glue, request, errmsg))) {
989
        json_object_put(request);
990
        return FALSE;
991
    }
992

                
993
    json_object_put(request);
994
    json_object_put(response_result);
995

                
996
    return TRUE;
997
}
998

                
999
gboolean
1000
nntpgrab_glue_internal_config_edit_server(NntpgrabGlue *obj, const char *servername, NGConfigServer new_server, char **errmsg)
1001
{
1002
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1003
    struct json_object *request;
1004
    struct json_object *request_params;
1005
    struct json_object *server;
1006
    struct json_object *response_result;
1007

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

                
1024
    if (!(response_result = send_request_and_wait_for_response(glue, request, errmsg))) {
1025
        json_object_put(request);
1026
        return FALSE;
1027
    }
1028

                
1029
    json_object_put(request);
1030
    json_object_put(response_result);
1031

                
1032
    return TRUE;
1033
}
1034

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

                
1058
    memset(opts, 0, sizeof(NGConfigOpts));
1059

                
1060
    request = create_new_json_request("nntpgrab_config_get_opts", NULL);
1061

                
1062
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
1063
        g_print(__FILE__ ":%i nntpgrab_config_get_opts FAILED: %s\n", __LINE__, errmsg);
1064
        g_free(errmsg);
1065
        json_object_put(request);
1066
        return FALSE;
1067
    }
1068

                
1069
    get_method_param(response_result, "download_directory", "config_get_opts", string, download_directory);
1070
    get_method_param(response_result, "temp_directory", "config_get_opts", string, temp_directory);
1071
    get_method_param(response_result, "enable_intelligent_par2_downloading", "config_get_opts", boolean, enable_intelligent_par2_downloading);
1072
    get_method_param(response_result, "enable_par2_repair", "config_get_opts", boolean, enable_par2_repair);
1073
    get_method_param(response_result, "auto_import_directory", "config_get_opts", string, auto_import_directory);
1074
    get_method_param(response_result, "enable_auto_import", "config_get_opts", boolean, enable_auto_import);
1075
    get_method_param(response_result, "move_file_after_auto_import", "config_get_opts", boolean, move_file_after_auto_import);
1076
    get_method_param(response_result, "enable_auto_unpack", "config_get_opts", boolean, enable_auto_unpack);
1077
    get_method_param(response_result, "enable_bandwidth_shaping", "config_get_opts", boolean, enable_bandwidth_shaping);
1078
    get_method_param(response_result, "max_bandwidth", "config_get_opts", int, max_bandwidth);
1079
    get_method_param(response_result, "enable_webserver", "config_get_opts", boolean, enable_webserver);
1080
    get_method_param(response_result, "webserver_port", "config_get_opts", int, webserver_port);
1081
    get_method_param(response_result, "enable_logger", "config_get_opts", boolean, enable_logger);
1082
    get_method_param(response_result, "auto_remove_files_after_repair", "config_get_opts", boolean, auto_remove_files_after_repair);
1083
    get_method_param(response_result, "auto_remove_files_after_unpack", "config_get_opts", boolean, auto_remove_files_after_unpack);
1084

                
1085
    strncpy(opts->download_directory, download_directory, sizeof(opts->download_directory) - 1);
1086
    strncpy(opts->temp_directory, temp_directory, sizeof(opts->temp_directory) - 1);
1087
    opts->enable_intelligent_par2_downloading = enable_intelligent_par2_downloading;
1088
    opts->enable_par2_repair = enable_par2_repair;
1089
    strncpy(opts->auto_import_directory, auto_import_directory, sizeof(opts->auto_import_directory) - 1);
1090
    opts->enable_auto_import = enable_auto_import;
1091
    opts->move_file_after_auto_import = move_file_after_auto_import;
1092
    opts->enable_auto_unpack = enable_auto_unpack;
1093
    opts->enable_bandwidth_shaping = enable_bandwidth_shaping;
1094
    opts->max_bandwidth = max_bandwidth;
1095
    opts->enable_webserver = enable_webserver;
1096
    opts->webserver_port = webserver_port;
1097
    opts->enable_logger = enable_logger;
1098
    opts->auto_remove_files_after_repair = auto_remove_files_after_repair;
1099
    opts->auto_remove_files_after_unpack = auto_remove_files_after_unpack;
1100

                
1101
    json_object_put(request);
1102
    json_object_put(response_result);
1103

                
1104
    return TRUE;
1105
}
1106

                
1107
gboolean
1108
nntpgrab_glue_internal_config_set_opts(NntpgrabGlue *obj, NGConfigOpts opts)
1109
{
1110
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1111
    struct json_object *request;
1112
    struct json_object *request_params;
1113
    struct json_object *param;
1114
    struct json_object *response_result;
1115
    char *errmsg = NULL;
1116

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

                
1137
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
1138
        g_print(__FILE__ ":%i nntpgrab_config_set_opts FAILED: %s\n", __LINE__, errmsg);
1139
        g_free(errmsg);
1140
        json_object_put(request);
1141
        return FALSE;
1142
    }
1143

                
1144
    json_object_put(request);
1145
    json_object_put(response_result);
1146

                
1147
    return TRUE;
1148
}
1149

                
1150
gboolean
1151
nntpgrab_glue_internal_config_get_folder_listing(NntpgrabGlue *obj, const char *parent, NGList **folders)
1152
{
1153
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1154
    struct json_object *request;
1155
    struct json_object *request_params;
1156
    struct json_object *response_result;
1157
    char *errmsg = NULL;
1158
    int i;
1159
    int len;
1160

                
1161
    request_params = json_object_new_array();
1162
    if (parent) {
1163
        json_object_array_add(request_params, json_object_new_string((char*) parent));
1164
    } else {
1165
        json_object_array_add(request_params, NULL);
1166
    }
1167
    request = create_new_json_request("nntpgrab_utils_get_folder_listing", request_params);
1168

                
1169
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
1170
        g_print(__FILE__ ":%i nntpgrab_utils_get_folder_listing FAILED: %s\n", __LINE__, errmsg);
1171
        g_free(errmsg);
1172
        json_object_put(request);
1173
        return FALSE;
1174
    }
1175

                
1176
    if (json_object_get_type(response_result) != json_type_array) {
1177
        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));
1178
        json_object_put(request);
1179
        json_object_put(response_result);
1180

                
1181
        return FALSE;
1182
    }
1183

                
1184
    len = json_object_array_length(response_result);
1185
    *folders = NULL;
1186
    for (i = 0; i < len; i++) {
1187
        struct json_object *param = json_object_array_get_idx(response_result, i);
1188
        NNTPGrabFolder *folder;
1189
        char *folder_str;
1190

                
1191
        g_return_val_if_fail(obj != NULL, FALSE);
1192

                
1193
        folder = g_slice_new0(NNTPGrabFolder);
1194

                
1195
        get_method_param(param, "folder", "nntpgrab_utils_get_folder_listing", string, folder_str);
1196
        get_method_param(param, "has_subfolders", "nntpgrab_utils_get_folder_listing", boolean, folder->has_subfolders);
1197
        strncpy(folder->folder, folder_str, sizeof(folder->folder) - 1);
1198

                
1199
        *folders = ng_list_append(*folders, folder);
1200
    }
1201

                
1202
    json_object_put(request);
1203
    json_object_put(response_result);
1204

                
1205
    return TRUE;
1206
}
1207

                
1208
gboolean
1209
nntpgrab_glue_internal_schedular_start(NntpgrabGlue *obj)
1210
{
1211
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1212
    struct json_object *request;
1213
    struct json_object *response_result;
1214
    char *errmsg = NULL;
1215

                
1216
    request = create_new_json_request("nntpgrab_schedular_start", NULL);
1217

                
1218
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
1219
        g_print(__FILE__ ":%i nntpgrab_schedular_start FAILED: %s\n", __LINE__, errmsg);
1220
        g_free(errmsg);
1221
        json_object_put(request);
1222
        return FALSE;
1223
    }
1224

                
1225
    json_object_put(request);
1226
    json_object_put(response_result);
1227

                
1228
    return TRUE;
1229
}
1230

                
1231
gboolean
1232
nntpgrab_glue_internal_schedular_stop(NntpgrabGlue *obj, gboolean wait)
1233
{
1234
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1235
    struct json_object *request;
1236
    struct json_object *request_params;
1237
    struct json_object *response_result;
1238
    char *errmsg = NULL;
1239

                
1240
    request_params = json_object_new_array();
1241
    json_object_array_add(request_params, json_object_new_boolean(wait));
1242
    request = create_new_json_request("nntpgrab_schedular_stop", request_params);
1243

                
1244
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
1245
        g_print(__FILE__ ":%i nntpgrab_schedular_stop FAILED: %s\n", __LINE__, errmsg);
1246
        g_free(errmsg);
1247
        json_object_put(request);
1248
        return FALSE;
1249
    }
1250

                
1251
    json_object_put(request);
1252
    json_object_put(response_result);
1253

                
1254
    return TRUE;
1255
}
1256

                
1257
NGSchedularState
1258
nntpgrab_glue_internal_schedular_get_state(NntpgrabGlue *obj)
1259
{
1260
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1261
    struct json_object *request;
1262
    struct json_object *response_result;
1263
    char *errmsg = NULL;
1264
    NGSchedularState ret;
1265

                
1266
    request = create_new_json_request("nntpgrab_schedular_get_state", NULL);
1267

                
1268
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
1269
        g_print(__FILE__ ":%i nntpgrab_schedular_get_state FAILED: %s\n", __LINE__, errmsg);
1270
        g_free(errmsg);
1271
        json_object_put(request);
1272
        return SCHEDULAR_STATE_STOPPED;
1273
    }
1274

                
1275
    if (json_object_get_type(response_result) != json_type_int) {
1276
        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));
1277
        json_object_put(request);
1278
        json_object_put(response_result);
1279

                
1280
        return SCHEDULAR_STATE_STOPPED;
1281
    }
1282

                
1283
    ret = json_object_get_int(response_result);
1284

                
1285
    json_object_put(request);
1286
    json_object_put(response_result);
1287

                
1288
    return ret;
1289
}
1290

                
1291
gboolean
1292
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)
1293
{
1294
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1295
    struct json_object *request;
1296
    struct json_object *request_params;
1297
    struct json_object *response_result;
1298
    struct json_object *json_obj;
1299
    NGList *list;
1300

                
1301
    request_params = json_object_new_array();
1302
    json_object_array_add(request_params, json_object_new_string((char*) collection_name));
1303
    json_object_array_add(request_params, json_object_new_string((char*) subject));
1304
    json_object_array_add(request_params, json_object_new_string((char*) poster));
1305
    json_object_array_add(request_params, json_object_new_int(stamp));
1306
    json_object_array_add(request_params, json_object_new_int(file_size / 1024));
1307

                
1308
    json_obj = json_object_new_array();
1309
    json_object_array_add(request_params, json_obj);
1310
    list = groups;
1311
    while (list) {
1312
        char *groupname = list->data;
1313

                
1314
        json_object_array_add(json_obj, json_object_new_string(groupname));
1315

                
1316
        list = ng_list_next(list);
1317
    }
1318

                
1319
    json_obj = json_object_new_array();
1320
    json_object_array_add(request_params, json_obj);
1321
    list = parts;
1322
    while (list) {
1323
        NNTPGrabPart *part = list->data;
1324
        struct json_object *part_obj = json_object_new_object();
1325

                
1326
        json_object_object_add(part_obj, "message_id", json_object_new_string((char*) part->message_id));
1327
        json_object_object_add(part_obj, "part_num", json_object_new_int(part->part_num));
1328
        json_object_object_add(part_obj, "size", json_object_new_int(part->size));
1329
        json_object_array_add(json_obj, part_obj);
1330

                
1331
        list = ng_list_next(list);
1332
    }
1333

                
1334
    request = create_new_json_request("nntpgrab_schedular_add_file_to_queue", request_params);
1335

                
1336
    if (!(response_result = send_request_and_wait_for_response(glue, request, errmsg))) {
1337
        json_object_put(request);
1338
        return FALSE;
1339
    }
1340

                
1341
    json_object_put(request);
1342
    json_object_put(response_result);
1343

                
1344
    return TRUE;
1345
}
1346

                
1347
gboolean
1348
nntpgrab_glue_internal_schedular_del_task_from_queue(NntpgrabGlue *obj, const char *collection_name, const char *subject, char **errmsg)
1349
{
1350
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1351
    struct json_object *request;
1352
    struct json_object *request_params;
1353
    struct json_object *response_result;
1354

                
1355
    request_params = json_object_new_array();
1356
    json_object_array_add(request_params, json_object_new_string((char*) collection_name));
1357
    if (subject) {
1358
        json_object_array_add(request_params, json_object_new_string((char*) subject));
1359
    } else {
1360
        json_object_array_add(request_params, NULL);
1361
    }
1362
    request = create_new_json_request("nntpgrab_schedular_del_file_from_queue", request_params);
1363

                
1364
    if (!(response_result = send_request_and_wait_for_response(glue, request, errmsg))) {
1365
        json_object_put(request);
1366
        return FALSE;
1367
    }
1368

                
1369
    json_object_put(request);
1370
    json_object_put(response_result);
1371

                
1372
    return TRUE;
1373
}
1374

                
1375
gboolean
1376
nntpgrab_glue_internal_schedular_restart_task(NntpgrabGlue *obj, const char *collection_name, const char *subject, char **errmsg)
1377
{
1378
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1379
    struct json_object *request;
1380
    struct json_object *request_params;
1381
    struct json_object *response_result;
1382

                
1383
    g_return_val_if_fail(collection_name != NULL, FALSE);
1384
    /* NOTE: subject CAN be NULL */
1385

                
1386
    request_params = json_object_new_array();
1387
    json_object_array_add(request_params, json_object_new_string((char*) collection_name));
1388
    if (subject) {
1389
        json_object_array_add(request_params, json_object_new_string((char*) subject));
1390
    } else {
1391
        json_object_array_add(request_params, NULL);
1392
    }
1393
    request = create_new_json_request("nntpgrab_schedular_restart_file", request_params);
1394

                
1395
    if (!(response_result = send_request_and_wait_for_response(glue, request, errmsg))) {
1396
        json_object_put(request);
1397
        return FALSE;
1398
    }
1399

                
1400
    json_object_put(request);
1401
    json_object_put(response_result);
1402

                
1403
    return TRUE;
1404
}
1405

                
1406
gboolean
1407
nntpgrab_glue_internal_schedular_save_queue(NntpgrabGlue *obj, char **errmsg)
1408
{
1409
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1410
    struct json_object *request;
1411
    struct json_object *response_result;
1412

                
1413
    request = create_new_json_request("nntpgrab_schedular_save_queue", NULL);
1414

                
1415
    if (!(response_result = send_request_and_wait_for_response(glue, request, errmsg))) {
1416
        json_object_put(request);
1417
        return FALSE;
1418
    }
1419

                
1420
    json_object_put(request);
1421
    json_object_put(response_result);
1422

                
1423
    return TRUE;
1424
}
1425

                
1426
static ForeachCollectionFunc collection_func_global = NULL;
1427
static ForeachFileFunc file_func_global = NULL;
1428
static ForeachGroupFunc group_func_global = NULL;
1429
static void *foreach_task_user_data_global = NULL;
1430

                
1431
static void
1432
process_foreach_collection_event(const char *msg, struct json_object *params)
1433
{
1434
    char *collection_name = NULL;
1435
    char *poster = NULL;
1436
    guint64 total_size = 0;
1437
    guint64 total_size_remaining = 0;
1438
    int position = 0;
1439

                
1440
    if (!collection_func_global) {
1441
        return;
1442
    }
1443

                
1444
    get_param(msg, params, "collection_name", "foreach_collection_event", string, collection_name);
1445
    get_param(msg, params, "poster", "foreach_collection_event", string, poster);
1446
    get_param(msg, params, "total_size", "foreach_collection_event", int, total_size);
1447
    get_param(msg, params, "total_size_remaining", "foreach_collection_event", int, total_size_remaining);
1448
    get_param(msg, params, "position", "foreach_collection_event", int, position);
1449

                
1450
    /* JSON doesn't support 64bit integers so all file sizes are in KB instead of bytes */
1451
    total_size *= 1024;
1452
    total_size_remaining *= 1024;
1453

                
1454
    collection_func_global(collection_name, poster, total_size, total_size_remaining, position, foreach_task_user_data_global);
1455
}
1456

                
1457
static void
1458
process_foreach_file_event(const char *msg, struct json_object *params)
1459
{
1460
    char *collection_name = NULL;
1461
    char *subject = NULL;
1462
    char *poster;
1463
    int stamp;
1464
    guint64 file_size;
1465
    guint64 file_size_remaining;
1466
    int num_parts_total;
1467
    int num_parts_downloaded;
1468
    int num_parts_failed;
1469
    NGTaskState status;
1470
    char *filename;
1471
    int position;
1472

                
1473
    if (!file_func_global) {
1474
        return;
1475
    }
1476

                
1477
    get_param(msg, params, "collection_name", "foreach_file_event", string, collection_name);
1478
    get_param(msg, params, "subject", "foreach_file_event", string, subject);
1479
    get_param(msg, params, "poster", "foreach_file_event", string, poster);
1480
    get_param(msg, params, "stamp", "foreach_file_event", int, stamp);
1481
    get_param(msg, params, "file_size", "foreach_file_event", int, file_size);
1482
    get_param(msg, params, "file_size_remaining", "foreach_file_event", int, file_size_remaining);
1483
    get_param(msg, params, "num_parts_total", "foreach_file_event", int, num_parts_total);
1484
    get_param(msg, params, "num_parts_downloaded", "foreach_file_event", int, num_parts_downloaded);
1485
    get_param(msg, params, "num_parts_failed", "foreach_file_event", int, num_parts_failed);
1486
    get_param(msg, params, "status", "foreach_file_event", int, status);
1487
    get_param(msg, params, "filename", "foreach_file_event", string, filename);
1488
    get_param(msg, params, "position", "foreach_file_event", int, position);
1489

                
1490
    /* JSON doesn't support 64bit integers so all file sizes are in KB instead of bytes */
1491
    file_size *= 1024;
1492
    file_size_remaining *= 1024;
1493

                
1494
    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);
1495
}
1496

                
1497
static void
1498
process_foreach_group_event(const char *msg, struct json_object *params)
1499
{
1500
    char *collection_name = NULL;
1501
    char *subject = NULL;
1502
    char *group = NULL;
1503

                
1504
    if (!group_func_global) {
1505
        return;
1506
    }
1507

                
1508
    get_param(msg, params, "collection_name", "foreach_group_event", string, collection_name);
1509
    get_param(msg, params, "subject", "foreach_group_event", string, subject);
1510
    get_param(msg, params, "group", "foreach_group_event", string, group);
1511

                
1512
    group_func_global(collection_name, subject, group, foreach_task_user_data_global);
1513
}
1514

                
1515
gboolean
1516
nntpgrab_glue_internal_schedular_foreach_task(NntpgrabGlue *obj, ForeachCollectionFunc collection_func, ForeachFileFunc file_func, ForeachGroupFunc group_func, void *data)
1517
{
1518
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1519
    struct json_object *request;
1520
    struct json_object *response_result;
1521
    char *errmsg = NULL;
1522
    gboolean ret;
1523

                
1524
    g_return_val_if_fail(obj != NULL, FALSE);
1525
    g_return_val_if_fail(collection_func != NULL || file_func != NULL || group_func != NULL, FALSE);
1526

                
1527
    request = create_new_json_request("nntpgrab_schedular_foreach_task", NULL);
1528

                
1529
    collection_func_global = collection_func;
1530
    file_func_global = file_func;
1531
    group_func_global = group_func;
1532
    foreach_task_user_data_global = data;
1533

                
1534
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
1535
        g_free(errmsg);
1536
        json_object_put(request);
1537
        collection_func_global = NULL;
1538
        file_func_global = NULL;
1539
        group_func_global = NULL;
1540
        foreach_task_user_data_global = NULL;
1541
        return FALSE;
1542
    }
1543

                
1544
    collection_func_global = NULL;
1545
    file_func_global = NULL;
1546
    group_func_global = NULL;
1547
    foreach_task_user_data_global = NULL;
1548

                
1549
    if (json_object_get_type(response_result) != json_type_boolean) {
1550
        // invalid type
1551
        g_print(__FILE__ ":%i response is of invalid type for method 'schedular_foreach_task', response = %s\n", __LINE__, json_object_get_string(response_result));
1552
        json_object_put(request);
1553
        json_object_put(response_result);
1554
        return FALSE;
1555
    }
1556

                
1557
    ret = json_object_get_boolean(response_result);
1558

                
1559
    json_object_put(request);
1560
    json_object_put(response_result);
1561

                
1562
    return ret;
1563
}
1564

                
1565
gboolean
1566
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)
1567
{
1568
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1569
    struct json_object *request;
1570
    struct json_object *request_params;
1571
    struct json_object *response_result;
1572
    char *errmsg = NULL;
1573

                
1574
    request_params = json_object_new_array();
1575
    json_object_array_add(request_params, json_object_new_string((char*) collection_name_src));
1576
    json_object_array_add(request_params, json_object_new_string((char*) subject_src));
1577
    json_object_array_add(request_params, json_object_new_string((char*) collection_name_dest));
1578
    json_object_array_add(request_params, json_object_new_int(position_dest));
1579
    request = create_new_json_request("nntpgrab_schedular_move_file", request_params);
1580

                
1581
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
1582
        g_print(__FILE__ ":%i nntpgrab_schedular_move_file FAILED: %s\n", __LINE__, errmsg);
1583
        g_free(errmsg);
1584
        json_object_put(request);
1585
        return FALSE;
1586
    }
1587

                
1588
    json_object_put(request);
1589
    json_object_put(response_result);
1590

                
1591
    return TRUE;
1592
}
1593

                
1594
gboolean
1595
nntpgrab_glue_internal_schedular_move_collection(NntpgrabGlue *obj, const char *collection_name, int new_position)
1596
{
1597
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1598
    struct json_object *request;
1599
    struct json_object *request_params;
1600
    struct json_object *response_result;
1601
    char *errmsg = NULL;
1602

                
1603
    request_params = json_object_new_array();
1604
    json_object_array_add(request_params, json_object_new_string((char*) collection_name));
1605
    json_object_array_add(request_params, json_object_new_int(new_position));
1606
    request = create_new_json_request("nntpgrab_schedular_move_collection", request_params);
1607

                
1608
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
1609
        g_print(__FILE__ ":%i nntpgrab_schedular_move_collection FAILED: %s\n", __LINE__, errmsg);
1610
        g_free(errmsg);
1611
        json_object_put(request);
1612
        return FALSE;
1613
    }
1614

                
1615
    json_object_put(request);
1616
    json_object_put(response_result);
1617

                
1618
    return TRUE;
1619
}
1620

                
1621
gboolean
1622
nntpgrab_glue_internal_schedular_mark_task_optional(NntpgrabGlue *obj, const char *collection_name, const char *subject, ngboolean is_optional)
1623
{
1624
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1625
    struct json_object *request;
1626
    struct json_object *request_params;
1627
    struct json_object *response_result;
1628
    char *errmsg = NULL;
1629

                
1630
    request_params = json_object_new_array();
1631
    json_object_array_add(request_params, json_object_new_string((char*) collection_name));
1632
    json_object_array_add(request_params, json_object_new_string((char*) subject));
1633
    json_object_array_add(request_params, json_object_new_boolean(is_optional));
1634
    request = create_new_json_request("nntpgrab_schedular_mark_task_optional", request_params);
1635

                
1636
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
1637
        g_print(__FILE__ ":%i nntpgrab_schedular_mark_task_optional FAILED: %s\n", __LINE__, errmsg);
1638
        g_free(errmsg);
1639
        json_object_put(request);
1640
        return FALSE;
1641
    }
1642

                
1643
    json_object_put(request);
1644
    json_object_put(response_result);
1645

                
1646
    return TRUE;
1647
}
1648

                
1649
NGList *
1650
nntpgrab_glue_internal_plugins_get_avail_plugins(NntpgrabGlue *obj)
1651
{
1652
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1653
    struct json_object *request;
1654
    struct json_object *response_result;
1655
    NGList *ret = NULL;
1656
    char *errmsg = NULL;
1657
    int i;
1658
    int len;
1659

                
1660
    request = create_new_json_request("nntpgrab_plugins_get_avail_plugins", NULL);
1661

                
1662
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
1663
        g_print(__FILE__ ":%i nntpgrab_plugins_get_avail_plugins FAILED: %s\n", __LINE__, errmsg);
1664
        g_free(errmsg);
1665
        json_object_put(request);
1666
        return NULL;
1667
    }
1668

                
1669
    len = json_object_array_length(response_result);
1670
    for (i = 0; i < len; i++) {
1671
        struct json_object *obj = json_object_array_get_idx(response_result, i);
1672
        char *servername;
1673

                
1674
        g_return_val_if_fail(obj != NULL, NULL);
1675

                
1676
        servername = json_object_get_string(obj);
1677

                
1678
        g_return_val_if_fail(servername != NULL, NULL);
1679

                
1680
        ret = ng_list_append(ret, g_strdup(servername));
1681
    }
1682

                
1683
    json_object_put(request);
1684
    json_object_put(response_result);
1685

                
1686
    return ret;
1687
}
1688

                
1689
gboolean
1690
nntpgrab_glue_internal_plugins_get_plugin_info(NntpgrabGlue *obj, const char *plugin_name, NNTPGrabPluginInfo *plugin_info)
1691
{
1692
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1693
    struct json_object *request;
1694
    struct json_object *request_params;
1695
    struct json_object *response_result;
1696
    char *errmsg = NULL;
1697
    char *name;
1698
    char *version;
1699
    char *author;
1700
    char *url;
1701
    char *description;
1702
    gboolean is_loaded;
1703
    gboolean is_persistent;
1704

                
1705
    g_return_val_if_fail(plugin_name != NULL, FALSE);
1706
    g_return_val_if_fail(plugin_info != NULL, FALSE);
1707

                
1708
    request_params = json_object_new_array();
1709
    json_object_array_add(request_params, json_object_new_string((char*) plugin_name));
1710
    request = create_new_json_request("nntpgrab_plugins_get_plugin_info", request_params);
1711

                
1712
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
1713
        g_print(__FILE__ ":%i nntpgrab_plugins_get_plugin_info FAILED: %s\n", __LINE__, errmsg);
1714
        g_free(errmsg);
1715
        json_object_put(request);
1716
        return FALSE;
1717
    }
1718

                
1719
    get_method_param(response_result, "name", "plugins_get_plugin_info", string, name);
1720
    get_method_param(response_result, "version", "plugins_get_plugin_info", string, version);
1721
    get_method_param(response_result, "author", "plugins_get_plugin_info", string, author);
1722
    get_method_param(response_result, "url", "plugins_get_plugin_info", string, url);
1723
    get_method_param(response_result, "description", "plugins_get_plugin_info", string, description);
1724
    get_method_param(response_result, "is_loaded", "plugins_get_plugin_info", boolean, is_loaded);
1725
    get_method_param(response_result, "is_persistent", "plugins_get_plugin_info", boolean, is_persistent);
1726

                
1727
    memset(plugin_info, 0, sizeof(NNTPGrabPluginInfo));
1728

                
1729
    strncpy(plugin_info->name, name, sizeof(plugin_info->name));
1730
    strncpy(plugin_info->version, version, sizeof(plugin_info->version));
1731
    strncpy(plugin_info->author, author, sizeof(plugin_info->author));
1732
    strncpy(plugin_info->url, url, sizeof(plugin_info->url));
1733
    strncpy(plugin_info->description, description, sizeof(plugin_info->description));
1734
    plugin_info->is_loaded = is_loaded;
1735
    plugin_info->is_persistent = is_persistent;
1736

                
1737
    json_object_put(request);
1738
    json_object_put(response_result);
1739

                
1740
    return TRUE;
1741
}
1742

                
1743
gboolean
1744
nntpgrab_glue_internal_plugins_load_plugin(NntpgrabGlue *obj, const char *plugin_name, char **errmsg)
1745
{
1746
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1747
    struct json_object *request;
1748
    struct json_object *request_params;
1749
    struct json_object *response_result;
1750

                
1751
    request_params = json_object_new_array();
1752
    json_object_array_add(request_params, json_object_new_string((char*) plugin_name));
1753
    request = create_new_json_request("nntpgrab_plugins_load_plugin", request_params);
1754

                
1755
    if (!(response_result = send_request_and_wait_for_response(glue, request, errmsg))) {
1756
        json_object_put(request);
1757
        return FALSE;
1758
    }
1759

                
1760
    json_object_put(request);
1761
    json_object_put(response_result);
1762

                
1763
    return TRUE;
1764
}
1765

                
1766
gboolean
1767
nntpgrab_glue_internal_plugins_unload_plugin(NntpgrabGlue *obj, const char *plugin_name, char **errmsg)
1768
{
1769
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1770
    struct json_object *request;
1771
    struct json_object *request_params;
1772
    struct json_object *response_result;
1773

                
1774
    request_params = json_object_new_array();
1775
    json_object_array_add(request_params, json_object_new_string((char*) plugin_name));
1776
    request = create_new_json_request("nntpgrab_plugins_unload_plugin", request_params);
1777

                
1778
    if (!(response_result = send_request_and_wait_for_response(glue, request, errmsg))) {
1779
        json_object_put(request);
1780
        return FALSE;
1781
    }
1782

                
1783
    json_object_put(request);
1784
    json_object_put(response_result);
1785

                
1786
    return TRUE;
1787
}
1788

                
1789
gboolean
1790
nntpgrab_glue_internal_plugins_set_persistent(NntpgrabGlue *obj, const char *plugin_name, ngboolean persistent)
1791
{
1792
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1793
    struct json_object *request;
1794
    struct json_object *request_params;
1795
    struct json_object *response_result;
1796
    char *errmsg = NULL;
1797

                
1798
    request_params = json_object_new_array();
1799
    json_object_array_add(request_params, json_object_new_string((char*) plugin_name));
1800
    json_object_array_add(request_params, json_object_new_boolean(persistent));
1801
    request = create_new_json_request("nntpgrab_plugins_set_persistent", request_params);
1802

                
1803
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
1804
        g_print(__FILE__ ":%i nntpgrab_plugins_set_persistent FAILED: %s\n", __LINE__, errmsg);
1805
        g_free(errmsg);
1806
        json_object_put(request);
1807
        return FALSE;
1808
    }
1809

                
1810
    json_object_put(request);
1811
    json_object_put(response_result);
1812

                
1813
    return TRUE;
1814
}
1815

                
1816
void
1817
nntpgrab_glue_internal_set_emit_log_messages(NntpgrabGlue *obj, ngboolean val)
1818
{
1819
    NntpgrabGlue *glue = NNTPGRAB_GLUE(obj);
1820
    struct json_object *request;
1821
    struct json_object *request_params;
1822
    struct json_object *response_result;
1823
    char *errmsg = NULL;
1824

                
1825
    request_params = json_object_new_array();
1826
    json_object_array_add(request_params, json_object_new_boolean(val));
1827
    request = create_new_json_request("nntpgrab_set_emit_log_messages", request_params);
1828

                
1829
    if (!(response_result = send_request_and_wait_for_response(glue, request, &errmsg))) {
1830
        g_print(__FILE__ ":%i nntpgrab_set_emit_log_messages FAILED: %s\n", __LINE__, errmsg);
1831
        g_free(errmsg);
1832
        json_object_put(request);
1833
        return;
1834
    }
1835

                
1836
    json_object_put(response_result);
1837
    json_object_put(request);
1838
}