Statistics
| Revision:

root / trunk / server / main.c @ 1919

History | View | Annotate | Download (10.3 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
#include 
27
#include 
28
#include 
29
#include 
30
#include 
31
#ifdef ENABLE_GUI
32
#include "nntpgrab_gui_base.h"
33
#endif
34

                
35
#ifdef WIN32
36
#include 
37
#include 
38
#include  /* freeaddrinfo for Win2k */
39
#else
40
#include 
41
#include 
42
#include 
43
#include 
44
#endif /* WIN32 */
45

                
46
#include "nntpgrab.h"
47
#include "nntpgrab_utils.h"
48

                
49
#ifdef WIN32
50
#define CLOSE(x)    closesocket(x)
51
#else
52
#define CLOSE(x)    close(x)
53
#endif
54

                
55
static NntpgrabCore *core = NULL;
56

                
57
#ifdef ENABLE_GUI
58
static gboolean gui_enabled = FALSE;
59
#endif
60

                
61
#ifdef ENABLE_GUI
62
static gboolean
63
on_plugin_event(NntpgrabCore *core, const char *plugin_name, const char *event_name, const char **params, gpointer data)
64
{
65
    GtkWidget *lblNumActiveConnections;
66

                
67
    if (!strcmp(plugin_name, "JSON-RPC") && !strcmp(event_name, "num_active_connections_changed")) {
68
        lblNumActiveConnections= nntpgrab_gui_base_get_widget("lblNumActiveConnections");
69
        gtk_label_set_text(GTK_LABEL(lblNumActiveConnections), params[0]);
70
    }
71

                
72
    return FALSE;
73
}
74
#endif
75

                
76
#ifdef ENABLE_GUI
77

                
78
G_MODULE_EXPORT void
79
on_btnQuit_clicked(GtkWidget *caller, gpointer data)
80
{
81
    GtkWidget *windowMain;
82

                
83
    windowMain = nntpgrab_gui_base_get_widget("windowMain");
84

                
85
    gtk_widget_hide(windowMain);
86
    gtk_main_quit();
87
}
88

                
89
static void
90
on_schedular_state_changed(NntpgrabCore *core, NGSchedularState new_state, const char *reason)
91
{
92
    GtkWidget *btnPauseSchedular;
93
    GtkWidget *lblSchedularState;
94

                
95
    btnPauseSchedular = nntpgrab_gui_base_get_widget("btnPauseSchedular");
96
    lblSchedularState = nntpgrab_gui_base_get_widget("lblSchedularState");
97

                
98
    switch (new_state) {
99
        case SCHEDULAR_STATE_RUNNING:
100
            gtk_widget_set_sensitive(btnPauseSchedular, TRUE);
101
            gtk_button_set_label(GTK_BUTTON(btnPauseSchedular), _("Stop the schedular"));
102
            gtk_label_set_text(GTK_LABEL(lblSchedularState), _("Running"));
103
            break;
104

                
105
        case SCHEDULAR_STATE_STOPPING:
106
            gtk_widget_set_sensitive(btnPauseSchedular, FALSE);
107
            gtk_button_set_label(GTK_BUTTON(btnPauseSchedular), _("Stop the schedular"));
108
            gtk_label_set_text(GTK_LABEL(lblSchedularState), _("Stopping"));
109
            break;
110

                
111
        case SCHEDULAR_STATE_STOPPED:
112
        default:
113
            gtk_widget_set_sensitive(btnPauseSchedular, TRUE);
114
            gtk_button_set_label(GTK_BUTTON(btnPauseSchedular), _("Start the schedular"));
115
            gtk_label_set_text(GTK_LABEL(lblSchedularState), _("Stopped"));
116
            break;
117
    }
118
}
119

                
120
G_MODULE_EXPORT void
121
on_btnPauseSchedular_clicked(GtkWidget *caller, gpointer data)
122
{
123
    switch(nntpgrab_core_schedular_get_state(core)) {
124
        case SCHEDULAR_STATE_RUNNING:
125
            nntpgrab_core_schedular_stop(core, FALSE);
126
            break;
127

                
128
        case SCHEDULAR_STATE_STOPPED:
129
            nntpgrab_core_schedular_start(core);
130
            break;
131

                
132
        default:
133
            g_return_if_reached();
134
    }
135
}
136

                
137
static gboolean
138
print_handler2(gpointer data)
139
{
140
    char *message = (char*) data;
141
    static gboolean mark_initialized = FALSE;
142
    GtkTextIter iter;
143
    GtkWidget *textviewLog;
144
    GtkTextBuffer *buffer;
145
    GtkTextMark *mark;
146

                
147
    textviewLog = nntpgrab_gui_base_get_widget("textviewLog");
148
    buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textviewLog));
149

                
150
    gtk_text_buffer_get_end_iter(buffer, &iter);
151
    gtk_text_buffer_insert(buffer, &iter, message, -1);
152

                
153
    // Scroll to the end
154
    if (!mark_initialized) {
155
        mark_initialized = TRUE;
156
        gtk_text_buffer_create_mark (buffer, "scroll", &iter, TRUE);
157
    }
158

                
159
    mark = gtk_text_buffer_get_mark (buffer, "scroll");
160
    gtk_text_buffer_get_end_iter (buffer, &iter);
161

                
162
    // Move the iterator to the beginning of line, so we don't scroll in horizontal direction
163
    gtk_text_iter_set_line_offset (&iter, 0);
164

                
165
    gtk_text_buffer_move_mark (buffer, mark, &iter);
166
    gtk_text_view_scroll_mark_onscreen(GTK_TEXT_VIEW(textviewLog), mark);
167

                
168
    g_free(message);
169

                
170
    return FALSE;
171
}
172

                
173
static void
174
nntpgrab_server_print_handler(const char *message)
175
{
176
    g_idle_add(print_handler2, g_strdup(message));
177
}
178
#endif
179

                
180
static void
181
on_log_message(NntpgrabCore *core, const char *component, NGLogLevel log_level, const char *msg)
182
{
183
    char stamp_str[64];
184
    char *log_level_str;
185
    struct tm *tm;
186
    time_t stamp;
187

                
188
    memset(&stamp_str, 0, sizeof(stamp_str));
189
    stamp = time(NULL);
190
    tm = localtime(&stamp);
191
    strftime(stamp_str, sizeof(stamp_str) - 1, "%Y-%m-%d %H:%M:%S", tm);
192

                
193
    switch (log_level) {
194
        case NG_LOG_LEVEL_INFO:
195
            log_level_str = "INFO";
196
            break;
197

                
198
        case NG_LOG_LEVEL_WARNING:
199
            log_level_str = "WARNING";
200
            break;
201

                
202
        case NG_LOG_LEVEL_ERROR:
203
            log_level_str = "ERROR";
204
            break;
205

                
206
        case NG_LOG_LEVEL_FATAL:
207
            log_level_str = "FATAL";
208
            break;
209

                
210
        case NG_LOG_LEVEL_DEBUG:
211
            log_level_str = "DEBUG";
212
            break;
213

                
214
        case NG_LOG_LEVEL_ALL:
215
        default:
216
            /* Shouldn't happen */
217
            log_level_str = "UNKNOWN";
218
            break;
219
    }
220

                
221
    if (log_level == NG_LOG_LEVEL_WARNING || log_level == NG_LOG_LEVEL_ERROR) {
222
        g_warning("%s - %s - %s - %s\n", stamp_str, component, log_level_str, msg);
223
    } else if (log_level == NG_LOG_LEVEL_FATAL) {
224
        g_error("%s - %s - %s - %s\n", stamp_str, component, log_level_str, msg);
225
    } else {
226
        g_print("%s - %s - %s - %s\n", stamp_str, component, log_level_str, msg);
227
    }
228
}
229

                
230
static void
231
quit_request_received(NntpgrabCore *core, gpointer data)
232
{
233
    g_print("Received request to abort the NNTPGrab Server\n");
234
#ifdef ENABLE_GUI
235
    gtk_main_quit();
236
#else
237
    ng_event_handler_loop_quit();
238
#endif
239
}
240

                
241
#if !defined(DARWIN) && !defined(WIN32) && !defined(ENABLE_GUI)
242
static void
243
print_help(void)
244
{
245
    g_print("===============\n");
246
    g_print("NNTPGrab Server\n");
247
    g_print("===============\n");
248
    g_print("\n");
249
    g_print("Possible arguments:\n");
250
    g_print("-b / --background\tStart the NNTPGrab Server in the background\n");
251
    g_print("-h / --help\t\tYou're watching it now\n");
252
    g_print("\n");
253
}
254
#endif
255

                
256
int
257
main(int argc, char **argv)
258
{
259
    char *errors = NULL;
260
    char *warnings = NULL;
261
    NGConfigOpts opts;
262

                
263
#if !defined(DARWIN) && !defined(WIN32) && !defined(ENABLE_GUI)
264
    gboolean do_fork = FALSE;
265
    int i = 1;
266

                
267
    while (argv[i]) {
268
        if (!strcmp(argv[i], "-b") || !strcmp(argv[i], "--background")) {
269
            do_fork = TRUE;
270
        } else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
271
            print_help();
272
            return 0;
273
        }
274
        i++;
275
    }
276

                
277
    if (do_fork) {
278
        pid_t pid = fork();
279
        if (pid == -1) {
280
            perror("fork");
281
            return 1;
282
        } else if (pid == 0) {
283
            /* This is the child process */
284
            fclose(stdin);
285
            fclose(stdout);
286
            fclose(stderr);
287
        } else {
288
            /* This is the parent process */
289
            g_print(_("The NNTPGrab Server was successfully started in the background\n"));
290
            return 0;
291
        }
292
    }
293
#endif
294

                
295
#if defined(WIN32) && !defined(ENABLE_GUI)
296
    /* Service code here */
297
#endif
298

                
299
    nntpgrab_utils_perform_base_initialization();
300

                
301
#ifdef ENABLE_GUI
302
    // Is there an graphical environment running?
303
#if !defined(WIN32) && !defined(DARWIN)
304
    if (g_getenv("DISPLAY")) {
305
#else
306
    if (TRUE) {
307
#endif
308
        gtk_init(&argc, &argv);
309

                
310
        nntpgrab_gui_base_create_ui("nntpgrab_server");
311
        nntpgrab_gui_base_tray_create();
312
        g_set_print_handler(nntpgrab_server_print_handler);
313
        gui_enabled = TRUE;
314
    }
315
#endif
316

                
317
    g_print(_("Now initialising the NNTPGrab Core...\n"));
318
    core = nntpgrab_core_new();
319

                
320
    if (!nntpgrab_core_init(core, NNTPGRAB_API_VERSION, &errors, &warnings)) {
321
        g_critical(_("NNTPGrab initialisation FAILED: %s\n"), errors);
322
#ifdef ENABLE_GUI
323
        g_idle_add((GSourceFunc) gtk_main_quit, NULL);
324
        gtk_main();
325
#endif
326
        exit(1);
327
    }
328

                
329
    /* Load the JSON-RPC plugin */
330
    opts = nntpgrab_core_config_get_opts(core);
331
    if (!nntpgrab_core_embedded_server_start(core, opts.webserver_port, &errors)) {
332
        g_critical(_("Unable to load JSON-RPC plugin: %s\n"), errors);
333
#ifdef ENABLE_GUI
334
        g_idle_add((GSourceFunc) gtk_main_quit, NULL);
335
        gtk_main();
336
#endif
337

                
338
        nntpgrab_core_destroy(core);
339

                
340
        exit(1);
341
    }
342

                
343
#ifdef ENABLE_GUI
344
    if (gui_enabled) {
345
        GtkWidget *windowMain = nntpgrab_gui_base_get_widget("windowMain");
346
        gtk_widget_show(windowMain);
347

                
348
        ng_signal_connect(core, "schedular_state_changed", NG_CALLBACK(on_schedular_state_changed), NULL);
349
        ng_signal_connect(core, "plugin_event", NG_CALLBACK(on_plugin_event), NULL);
350
    }
351
#endif
352

                
353
    ng_signal_connect(core, "log_message", NG_CALLBACK(on_log_message), NULL);
354
    ng_signal_connect(core, "quit_requested", NG_CALLBACK(quit_request_received), NULL);
355

                
356
    nntpgrab_core_set_emit_log_messages(core, TRUE);
357

                
358
    nntpgrab_core_schedular_start(core);
359

                
360
    if (warnings) {
361
        g_print("Warning:\n%s\n", warnings);
362
        g_free(warnings);
363
    }
364

                
365
    /* Main loop */
366
#ifdef ENABLE_GUI
367
    if (gui_enabled) {
368
        gtk_main();
369
    } else {
370
#endif
371
        ng_event_handler_loop_run();
372
#ifdef ENABLE_GUI
373
    }
374
#endif
375

                
376
    /* Cleanup */
377
#ifdef ENABLE_GUI
378
    if (gui_enabled && nntpgrab_gui_base_tray_icon_get_is_shown()) {
379
        nntpgrab_gui_base_tray_destroy();
380
    }
381

                
382
    nntpgrab_gui_base_destroy_ui();
383
#endif
384

                
385
    nntpgrab_core_destroy(core);
386

                
387
    return 0;
388
}