main_dbus.c

Go to the documentation of this file.
00001 /*
00002  Copyright (C) 2005-2007 Erik van Pienbroek
00003 
00004  This program is free software; you can redistribute it and/or modify
00005  it under the terms of the GNU General Public License as published by
00006  the Free Software Foundation; either version 2 of the License, or
00007  (at your option) any later version.
00008 
00009  This program is distributed in the hope that it will be useful,
00010  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00012  GNU General Public License for more details.
00013 
00014  You should have received a copy of the GNU General Public License
00015  along with this program; if not, write to the Free Software
00016  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00017 */
00018 
00019 #include 
00020 #include 
00021 
00022 #include "nntpgrab.h"
00023 #include "nntpgrab_utils.h"
00024 #include "marshalers.h"
00025 
00026 typedef struct NNTPGrabDBus NNTPGrabDBus;
00027 typedef struct NNTPGrabDBusClass NNTPGrabDBusClass;
00028 
00029 gboolean nntpgrab_dbus_config_get_avail_servers (NNTPGrabDBus *server, GPtrArray **servers, GError **error);
00030 gboolean nntpgrab_dbus_config_get_server_info (NNTPGrabDBus *server, const char *servername, GValueArray **ret, GError **error);
00031 gboolean nntpgrab_dbus_config_add_server (NNTPGrabDBus *server, const char *servername, GValueArray *info, GError **error);
00032 gboolean nntpgrab_dbus_config_del_server (NNTPGrabDBus *server, const char *servername, gboolean *retval, GError **error);
00033 gboolean nntpgrab_dbus_config_edit_server (NNTPGrabDBus *server, const char *servername, const GValueArray *info, gboolean *retval, GError **error);
00034 gboolean nntpgrab_dbus_config_get_opts (NNTPGrabDBus *server, GValueArray **opts, GError **error);
00035 gboolean nntpgrab_dbus_config_set_opts (NNTPGrabDBus *server, const GValueArray *opts, GError **error);
00036 gboolean nntpgrab_dbus_schedular_start (NNTPGrabDBus *server, gboolean *retval, GError **error);
00037 gboolean nntpgrab_dbus_schedular_stop (NNTPGrabDBus *server, gboolean *retval, GError **error);
00038 gboolean nntpgrab_dbus_schedular_get_state (NNTPGrabDBus *server, gint *state, GError **error);
00039 gboolean nntpgrab_dbus_schedular_add_task_to_queue (NNTPGrabDBus *server, const char *collection_name, const char *subject, const char *poster, const gint64 stamp, const gint64 file_size, char **groups, const GPtrArray *parts, char **errmsg, gboolean *retval, GError **error);
00040 gboolean nntpgrab_dbus_schedular_del_task_from_queue (NNTPGrabDBus *server, const char *collection_name, const char *subject, char **errmsg, gboolean *retval, GError **error);
00041 gboolean nntpgrab_dbus_schedular_restart_task (NNTPGrabDBus *server, const char *collection_name, const char *subject, char **errmsg, gboolean *retval, GError **error);
00042 gboolean nntpgrab_dbus_schedular_save_queue (NNTPGrabDBus *server, char **errmsg, gboolean *retval, GError **error);
00043 gboolean nntpgrab_dbus_schedular_foreach_task (NNTPGrabDBus *server, GError **error);
00044 
00045 #include "nntpgrab-dbus-server.h"
00046 
00047 #include 
00048 
00049 #define NNTPGRAB_TYPE_DBUS (dbus_get_type ())
00050 #define NNTPGRAB_DBUS(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), NNTPGRAB_TYPE_DBUS, NNTPGrabDBus))
00051 #define NNTPGRAB_DBUS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NNTPGRAB_TYPE_DBUS, NNTPGrabDBusClass))
00052 #define IS_NNTPGRAB_DBUS(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), NNTPGRAB_TYPE_DBUS))
00053 #define IS_NNTPGRAB_DBUS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NNTPGRAB_TYPE_DBUS))
00054 #define NNTPGRAB_DBUS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NNTPGRAB_TYPE_DBUS, NNTPGrabDBusClass))
00055 
00056 struct NNTPGrabDBus
00057 {
00058     GObject parent;
00059 
00060     NNTPGrabCore *core;
00061 };
00062 
00063 struct NNTPGrabDBusClass
00064 {
00065     GObjectClass parent;
00066     DBusGConnection *connection;
00067 };
00068 
00069 enum
00070 {
00071     CONFIG_CHANGED_SIGNAL,
00072     PART_DOWNLOAD_START_SIGNAL,
00073     PART_DONE_SIGNAL,
00074     PART_FAILED_SIGNAL,
00075     PART_PROGRESS_UPDATE_SIGNAL,
00076     COLLECTION_ADDED_SIGNAL,
00077     COLLECTION_REMOVED_SIGNAL,
00078     FILE_ADDED_SIGNAL,
00079     FILE_REMOVED_SIGNAL,
00080     FILE_STATE_CHANGED_SIGNAL,
00081     CONNECTION_CONNECTING_SIGNAL,
00082     CONNECTION_CONNECTED_SIGNAL,
00083     CONNECTION_DISCONNECT_SIGNAL,
00084     FATAL_ERROR_SIGNAL,
00085     DEBUG_MESSAGE_SIGNAL,
00086     LAST_SIGNAL
00087 };
00088 
00089 static guint signals[LAST_SIGNAL] = { 0 };
00090 
00091 G_DEFINE_TYPE(NNTPGrabDBus, dbus, G_TYPE_OBJECT)
00092 
00093 static void
00094 dbus_init (NNTPGrabDBus *obj)
00095 {
00096     GError *error = NULL;
00097     DBusGProxy *driver_proxy;
00098     NNTPGrabDBusClass *klass = NNTPGRAB_DBUS_GET_CLASS (obj);
00099     unsigned int request_ret;
00100     char *err = NULL;
00101     char *warnings = NULL;
00102 
00103     /* Register DBUS path */
00104     dbus_g_connection_register_g_object (klass->connection,
00105             "/org/nntpgrab/NNTPGrab",
00106             G_OBJECT (obj));
00107 
00108     /* Register the service name, the constant here are defined in dbus-glib-bindings.h */
00109     driver_proxy = dbus_g_proxy_new_for_name (klass->connection,
00110             DBUS_SERVICE_DBUS,
00111             DBUS_PATH_DBUS,
00112             DBUS_INTERFACE_DBUS);
00113 
00114     if(!org_freedesktop_DBus_request_name (driver_proxy,
00115             "org.nntpgrab.NNTPGrab",
00116             0, &request_ret,    /* See tutorial for more infos about these */
00117             &error))
00118     {
00119         g_warning("Unable to register service: %s", error->message);
00120         g_error_free (error);
00121     }
00122     g_object_unref (driver_proxy);
00123 g_print("registration done\n");
00124 
00125     obj->core = nntpgrab_core_init(NNTPGRAB_API_VERSION, &err, &warnings);
00126     if (!obj->core) {
00127         g_error(err);
00128     }
00129 
00130     if (warnings) {
00131         g_print(warnings);
00132         g_free(warnings);
00133     }
00134 }
00135 
00136 static void
00137 dbus_finalize (GObject *obj)
00138 {
00139     NNTPGrabDBus *dbus = NNTPGRAB_DBUS(obj);
00140 
00141     nntpgrab_core_cleanup(dbus->core);
00142 }
00143 
00144 static void
00145 dbus_class_init (NNTPGrabDBusClass *klass)
00146 {
00147     GError *error = NULL;
00148     GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
00149 
00150     gobject_class->finalize = dbus_finalize;
00151 
00152     signals[CONFIG_CHANGED_SIGNAL] =       g_signal_new("config_changed",
00153                                                         G_OBJECT_CLASS_TYPE (klass),
00154                                                         G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
00155                                                         0,
00156                                                         NULL, NULL,
00157                                                         nntpgrab_marshal_VOID__VOID,
00158                                                         G_TYPE_NONE, 0);
00159 
00160     signals[PART_DOWNLOAD_START_SIGNAL] = g_signal_new ("part_download_start",
00161                                                         G_OBJECT_CLASS_TYPE (klass),
00162                                                         G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
00163                                                         0,
00164                                                         NULL, NULL,
00165                                                         nntpgrab_marshal_VOID__STRING_INT_STRING_STRING_INT,
00166                                                         G_TYPE_NONE, 5, G_TYPE_STRING, G_TYPE_INT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT);
00167 
00168     signals[PART_DONE_SIGNAL] =           g_signal_new ("part_done",
00169                                                         G_OBJECT_CLASS_TYPE (klass),
00170                                                         G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
00171                                                         0,
00172                                                         NULL, NULL,
00173                                                         nntpgrab_marshal_VOID__STRING_INT_STRING_STRING_INT,
00174                                                         G_TYPE_NONE, 5, G_TYPE_STRING, G_TYPE_INT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT);
00175 
00176     signals[PART_FAILED_SIGNAL] =         g_signal_new ("part_failed",
00177                                                         G_OBJECT_CLASS_TYPE (klass),
00178                                                         G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
00179                                                         0,
00180                                                         NULL, NULL,
00181                                                         nntpgrab_marshal_VOID__STRING_INT_STRING_STRING_INT,
00182                                                         G_TYPE_NONE, 5, G_TYPE_STRING, G_TYPE_INT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT);
00183 
00184     signals[PART_PROGRESS_UPDATE_SIGNAL] = g_signal_new ("part_progress_update",
00185                                                          G_OBJECT_CLASS_TYPE (klass),
00186                                                          G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
00187                                                          0,
00188                                                          NULL, NULL,
00189                                                          nntpgrab_marshal_VOID__STRING_INT_STRING_INT_INT_INT,
00190                                                          G_TYPE_NONE, 6, G_TYPE_STRING, G_TYPE_INT, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT);
00191 
00192     signals[COLLECTION_ADDED_SIGNAL] =    g_signal_new ("collection_added",
00193                                                         G_OBJECT_CLASS_TYPE (klass),
00194                                                         G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
00195                                                         0,
00196                                                         NULL, NULL,
00197                                                         nntpgrab_marshal_VOID__STRING,
00198                                                         G_TYPE_NONE, 1, G_TYPE_STRING);
00199 
00200     signals[COLLECTION_REMOVED_SIGNAL] =  g_signal_new ("collection_removed",
00201                                                         G_OBJECT_CLASS_TYPE (klass),
00202                                                         G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
00203                                                         0,
00204                                                         NULL, NULL,
00205                                                         nntpgrab_marshal_VOID__STRING,
00206                                                         G_TYPE_NONE, 1, G_TYPE_STRING);
00207 
00208     signals[FILE_ADDED_SIGNAL] =          g_signal_new ("file_added",
00209                                                         G_OBJECT_CLASS_TYPE (klass),
00210                                                         G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
00211                                                         0,
00212                                                         NULL, NULL,
00213                                                         nntpgrab_marshal_VOID__STRING_STRING_STRING_UINT64_UINT64_INT_INT_POINTER,
00214                                                         G_TYPE_NONE, 8, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT64, G_TYPE_UINT64, G_TYPE_INT, G_TYPE_INT, G_TYPE_POINTER);
00215 
00216     signals[FILE_REMOVED_SIGNAL] =        g_signal_new ("file_removed",
00217                                                         G_OBJECT_CLASS_TYPE (klass),
00218                                                         G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
00219                                                         0,
00220                                                         NULL, NULL,
00221                                                         nntpgrab_marshal_VOID__STRING_STRING,
00222                                                         G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING);
00223 
00224     signals[FILE_STATE_CHANGED_SIGNAL] =  g_signal_new ("file_state_changed",
00225                                                         G_OBJECT_CLASS_TYPE (klass),
00226                                                         G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
00227                                                         0,
00228                                                         NULL, NULL,
00229                                                         nntpgrab_marshal_VOID__STRING_STRING_INT_INT,
00230                                                         G_TYPE_NONE, 4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT);
00231 
00232     signals[CONNECTION_CONNECTING_SIGNAL] =  g_signal_new   ("connection_connecting",
00233                                                              G_OBJECT_CLASS_TYPE (klass),
00234                                                              G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
00235                                                              0,
00236                                                              NULL, NULL,
00237                                                              nntpgrab_marshal_VOID__STRING_INT,
00238                                                              G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_INT);
00239 
00240     signals[CONNECTION_CONNECTED_SIGNAL] =  g_signal_new    ("connection_connected",
00241                                                              G_OBJECT_CLASS_TYPE (klass),
00242                                                              G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
00243                                                              0,
00244                                                              NULL, NULL,
00245                                                              nntpgrab_marshal_VOID__STRING_INT_STRING,
00246                                                              G_TYPE_NONE, 3, G_TYPE_STRING, G_TYPE_INT, G_TYPE_STRING);
00247 
00248     signals[CONNECTION_DISCONNECT_SIGNAL] = g_signal_new ("connection_disconnect",
00249                                                           G_OBJECT_CLASS_TYPE (klass),
00250                                                           G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
00251                                                           0,
00252                                                           NULL, NULL,
00253                                                           nntpgrab_marshal_VOID__STRING_INT_ENUM_STRING,
00254                                                           G_TYPE_NONE, 4, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT, G_TYPE_STRING);
00255 
00256     signals[FATAL_ERROR_SIGNAL] =           g_signal_new ("fatal_error",
00257                                                           G_OBJECT_CLASS_TYPE (klass),
00258                                                           G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
00259                                                           0,
00260                                                           NULL, NULL,
00261                                                           nntpgrab_marshal_VOID__STRING,
00262                                                           G_TYPE_NONE, 1, G_TYPE_STRING);
00263 
00264     signals[DEBUG_MESSAGE_SIGNAL] =         g_signal_new ("debug_message",
00265                                                           G_OBJECT_CLASS_TYPE (klass),
00266                                                           G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
00267                                                           0,
00268                                                           NULL, NULL,
00269                                                           nntpgrab_marshal_VOID__POINTER_STRING,
00270                                                           G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_STRING);
00271 
00272     /* Init the DBus connection, per-klass */
00273     klass->connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
00274     if (klass->connection == NULL)
00275     {
00276         g_warning("Unable to connect to dbus: %s", error->message);
00277         g_error_free (error);
00278         return;
00279     }
00280 
00281     /* &dbus_glib__object_info is provided in the server-bindings.h file */
00282     /* OBJECT_TYPE_SERVER is the GType of your server object */
00283     dbus_g_object_type_install_info (NNTPGRAB_TYPE_DBUS, &dbus_glib_nntpgrab_dbus_object_info);
00284 
00285 g_print("dbus type registered\n");
00286 
00287 }
00288 
00289 gboolean
00290 nntpgrab_dbus_config_get_avail_servers (NNTPGrabDBus *server, GPtrArray **servers, GError **error)
00291 {
00292     return TRUE;
00293 }
00294 
00295 gboolean
00296 nntpgrab_dbus_config_get_server_info (NNTPGrabDBus *obj, const char *servername, GValueArray **ret, GError **error)
00297 {
00298     NNTPGrabDBus *dbus = NNTPGRAB_DBUS(obj);
00299     ConfigServer server;
00300 
00301     if (!nntpgrab_config_get_server_info(dbus->core, servername, &server)) {
00302         return FALSE;
00303     }
00304 
00305     *ret = g_value_array_new (8);
00306 
00307     // Arguments need to be passed in reverse order as a prepend is faster than a append
00308 
00309     g_value_array_prepend (*ret, NULL);
00310     g_value_init (g_value_array_get_nth (*ret, 0), G_TYPE_INT);
00311     g_value_set_int (g_value_array_get_nth (*ret, 0), server.priority);
00312 
00313     g_value_array_prepend (*ret, NULL);
00314     g_value_init (g_value_array_get_nth (*ret, 0), G_TYPE_INT);
00315     g_value_set_int (g_value_array_get_nth (*ret, 0), server.max_threads);
00316 
00317     g_value_array_prepend (*ret, NULL);
00318     g_value_init (g_value_array_get_nth (*ret, 0), G_TYPE_STRING);
00319     g_value_set_string (g_value_array_get_nth (*ret, 0), server.password);
00320 
00321     g_value_array_prepend (*ret, NULL);
00322     g_value_init (g_value_array_get_nth (*ret, 0), G_TYPE_STRING);
00323     g_value_set_string (g_value_array_get_nth (*ret, 0), server.username);
00324 
00325     g_value_array_prepend (*ret, NULL);
00326     g_value_init (g_value_array_get_nth (*ret, 0), G_TYPE_INT);
00327     g_value_set_int (g_value_array_get_nth (*ret, 0), server.port);
00328 
00329     g_value_array_prepend (*ret, NULL);
00330     g_value_init (g_value_array_get_nth (*ret, 0), G_TYPE_STRING);
00331     g_value_set_string (g_value_array_get_nth (*ret, 0), server.hostname);
00332 
00333     g_value_array_prepend (*ret, NULL);
00334     g_value_init (g_value_array_get_nth (*ret, 0), G_TYPE_STRING);
00335     g_value_set_string (g_value_array_get_nth (*ret, 0), server.servername);
00336 
00337 #if 0
00338     if (problem)
00339     {
00340         /* We have an error, set the gerror */
00341         g_set_error (error, g_quark_from_static_string ("echo"),
00342                     0xdeadbeef,
00343                     "Some random problem occured, you're screwed");
00344         return FALSE;
00345     }
00346 #endif
00347 
00348     return TRUE;
00349 }
00350 
00351 gboolean
00352 nntpgrab_dbus_config_add_server (NNTPGrabDBus *server, const char *servername, GValueArray *info, GError **error)
00353 {
00354     return TRUE;
00355 }
00356 
00357 gboolean
00358 nntpgrab_dbus_config_del_server (NNTPGrabDBus *server, const char *servername, gboolean *retval, GError **error)
00359 {
00360     NNTPGrabDBus *dbus = NNTPGRAB_DBUS(server);
00361 
00362     g_assert(retval);
00363 
00364     *retval = nntpgrab_config_del_server(dbus->core, servername);
00365 
00366     return TRUE;
00367 }
00368 
00369 gboolean
00370 nntpgrab_dbus_config_edit_server (NNTPGrabDBus *server, const char *servername, const GValueArray *info, gboolean *retval, GError **error)
00371 {
00372     return TRUE;
00373 }
00374 
00375 gboolean
00376 nntpgrab_dbus_config_get_opts (NNTPGrabDBus *server, GValueArray **opts, GError **error)
00377 {
00378     return TRUE;
00379 }
00380 
00381 gboolean
00382 nntpgrab_dbus_config_set_opts (NNTPGrabDBus *server, const GValueArray *opts, GError **error)
00383 {
00384     return TRUE;
00385 }
00386 
00387 gboolean
00388 nntpgrab_dbus_schedular_start (NNTPGrabDBus *server, gboolean *retval, GError **error)
00389 {
00390     NNTPGrabDBus *dbus = NNTPGRAB_DBUS(server);
00391 
00392     g_assert(retval);
00393 
00394     *retval = nntpgrab_schedular_start(dbus->core);
00395 
00396     return TRUE;
00397 }
00398 
00399 gboolean
00400 nntpgrab_dbus_schedular_stop (NNTPGrabDBus *server, gboolean *retval, GError **error)
00401 {
00402     NNTPGrabDBus *dbus = NNTPGRAB_DBUS(server);
00403 
00404     g_assert(retval);
00405 
00406     // DBus provides async methods itself, so we can always wait here for the command to complete
00407     *retval = nntpgrab_schedular_stop(dbus->core, TRUE);
00408 
00409     return TRUE;
00410 }
00411 
00412 gboolean
00413 nntpgrab_dbus_schedular_get_state (NNTPGrabDBus *server, gint *state, GError **error)
00414 {
00415     NNTPGrabDBus *dbus = NNTPGRAB_DBUS(server);
00416 
00417     g_assert(state);
00418 
00419     *state = nntpgrab_schedular_get_state(dbus->core);
00420 
00421     return TRUE;
00422 }
00423 
00424 gboolean
00425 nntpgrab_dbus_schedular_add_task_to_queue (NNTPGrabDBus *server, const char *collection_name, const char *subject, const char *poster, const gint64 stamp, const gint64 file_size, char **groups, const GPtrArray *parts, char **errmsg, gboolean *retval, GError **error)
00426 {
00427     return TRUE;
00428 }
00429 
00430 gboolean
00431 nntpgrab_dbus_schedular_del_task_from_queue (NNTPGrabDBus *server, const char *collection_name, const char *subject, char **errmsg, gboolean *retval, GError **error)
00432 {
00433     NNTPGrabDBus *dbus = NNTPGRAB_DBUS(server);
00434 
00435     g_assert(retval);
00436 
00437     *retval = nntpgrab_schedular_del_task_from_queue(dbus->core, collection_name, subject, errmsg);
00438 
00439     return TRUE;
00440 }
00441 
00442 gboolean nntpgrab_dbus_schedular_restart_task (NNTPGrabDBus *server, const char *collection_name, const char *subject, char **errmsg, gboolean *retval, GError **error)
00443 {
00444     NNTPGrabDBus *dbus = NNTPGRAB_DBUS(server);
00445 
00446     g_assert(retval);
00447 
00448     *retval = nntpgrab_schedular_restart_task(dbus->core, collection_name, subject, errmsg);
00449 
00450     return TRUE;
00451 }
00452 
00453 gboolean
00454 nntpgrab_dbus_schedular_save_queue (NNTPGrabDBus *server, char **errmsg, gboolean *retval, GError **error)
00455 {
00456     NNTPGrabDBus *dbus = NNTPGRAB_DBUS(server);
00457 
00458     g_assert(retval);
00459 
00460     *retval = nntpgrab_schedular_save_queue(dbus->core, errmsg);
00461 
00462     return TRUE;
00463 }
00464 
00465 gboolean
00466 nntpgrab_dbus_schedular_foreach_task (NNTPGrabDBus *server, GError **error)
00467 {
00468     return TRUE;
00469 }
00470 
00471 int main(int argc, char **argv)
00472 {
00473     NNTPGrabDBus *dbus;
00474     GMainLoop *loop;
00475 
00476     g_type_init();
00477 
00478     dbus = g_object_new(NNTPGRAB_TYPE_DBUS, NULL);
00479 
00480     loop = g_main_loop_new(NULL, FALSE);
00481 
00482     g_main_loop_run(loop);
00483 
00484     return 0;
00485 }

Generated on Sun Oct 12 01:45:29 2008 for NNTPGrab by  1.5.4