Provide statical linking of GnomeVFS "libntfs" method for: --enable-standalone
[captive.git] / src / install / acquire / main.c
index d6de799..26447f4 100644 (file)
 #include <errno.h>
 #include <unistd.h>
 #include <libgnomevfs/gnome-vfs-init.h>
+#include "ui-line.h"
+#include "microsoftcom.h"
+#include <libgnomevfs/gnome-vfs-uri.h>
+#include "diskscan.h"
+#include "moduriload.h"
+#include <libgnome/gnome-program.h>
+#include <libgnomeui/gnome-ui-init.h>
+#include <setjmp.h>
+#include "ui-gnome.h"
 
-#include <captive/macros.h>
+#ifdef ENABLE_STANDALONE
+#include "standalone-libntfs.h"
+#endif
 
+#include <captive/macros.h>
+#include <captive/client.h>
+#include <captive/captivemodid.h>
 
-#include "captivemodid.h"
-#include <glib/glist.h>
-#include "moduriload.h"
-#include "diskscan.h"
 
+CaptiveCaptivemodidObject *captivemodid;
 
 int optarg_verbose;
+int optarg_dry;
+static int optarg_microsoft_com;
 static int optarg_scan_disks;
+static int optarg_scan_disks_quick;
+static int optarg_text;
 static GList *optarg_scan_path_list;   /* of (char *) */
 
 static void acquire_popt_callback
@@ -62,15 +77,27 @@ static const struct poptOption popt_table[]={
                        argDescrip: (argDescripP), \
                }
 
-               BUG_ACQUIRE_POPT('v',"verbose"   ,POPT_ARG_NONE  ,&optarg_verbose   ,0,N_("Display additional debug information"),NULL),
-               BUG_ACQUIRE_POPT(0  ,"scan-disks",POPT_ARG_NONE  ,&optarg_scan_disks,0,N_("Scan all local disks"),NULL),
-               BUG_ACQUIRE_POPT(0  ,"scan-path" ,POPT_ARG_STRING,NULL              ,0,N_("Scan specified disk path"),N_("path/URI")),
+               BUG_ACQUIRE_POPT(0  ,"text"            ,POPT_ARG_NONE  ,&optarg_text   ,0,
+                               N_("Disable Gnome UI; --text must be first argument"),NULL),
+               BUG_ACQUIRE_POPT('v',"verbose"         ,POPT_ARG_NONE  ,&optarg_verbose,0,N_("Display additional debug information"),NULL),
+               BUG_ACQUIRE_POPT('n',"dry"             ,POPT_ARG_NONE  ,&optarg_dry    ,0,N_("No modifications, no files written"),NULL),
+               BUG_ACQUIRE_POPT(0  ,"scan-disks"      ,POPT_ARG_NONE  ,&optarg_scan_disks,0,N_("Scan all files on local disks"),NULL),
+               BUG_ACQUIRE_POPT(0  ,"scan-disks-quick",POPT_ARG_NONE  ,&optarg_scan_disks_quick,0,
+                               N_("Scan MS-Windows directories on local disks"),NULL),
+               BUG_ACQUIRE_POPT(0  ,"scan-path" ,POPT_ARG_STRING,NULL              ,0,
+                               N_("Scan specified disk path or web URL"),N_("path/URI")),
+               BUG_ACQUIRE_POPT(0  ,"microsoft-com"   ,POPT_ARG_NONE  ,&optarg_microsoft_com,0,
+                               N_("Download from microsoft.com; Legal: You may need to have valid Microsoft Windows XP license."),NULL),
 
 #undef BUG_ACQUIRE_POPT
-               POPT_AUTOHELP
                POPT_TABLEEND
                };
 
+static const struct poptOption popt_table_autohelp[]={
+               { NULL,'\0',POPT_ARG_INCLUDE_TABLE,(struct poptOption *)&popt_table,0,PACKAGE },
+               POPT_AUTOHELP
+               POPT_TABLEEND
+               };
 
 /* poptCallbackType captive_popt_callback */
 static void acquire_popt_callback
@@ -84,13 +111,92 @@ static void acquire_popt_callback
 }
 
 
+void (*ui_interactive)(void);
+
+static gboolean ui_progress_dummy(GnomeVFSURI *uri)
+{
+       /* 'uri' may be NULL */
+
+       return FALSE;   /* not aborted */
+}
+
+gboolean (*ui_progress)(GnomeVFSURI *uri)=ui_progress_dummy;
+void (*ui_progress_bar)(gint done,gint length);
+
+static GList *mod_uri_list_local;
+static void mod_uri_list_local_init(void)
+{
+       if (mod_uri_list_local)
+               return;
+       mod_uri_list_local=mod_uri_list();
+}
+
+void scan_disks_quick(void)
+{
+GList *mod_uri_list_quick_local,*mod_uri_l;
+
+       mod_uri_list_local_init();
+       mod_uri_list_quick_local=NULL;
+       for (mod_uri_l=mod_uri_list_local;mod_uri_l;mod_uri_l=mod_uri_l->next) {
+               mod_uri_list_quick_local=g_list_prepend(mod_uri_list_quick_local,
+                               gnome_vfs_uri_append_path(mod_uri_l->data,"windows/system32"));
+               }
+       mod_uri_list_quick_local=g_list_reverse(mod_uri_list_quick_local);
+       g_list_foreach(mod_uri_list_quick_local,(GFunc)mod_uri_load,NULL);
+       gnome_vfs_uri_list_free(mod_uri_list_quick_local);
+}
+
+void scan_disks(void)
+{
+       mod_uri_list_local_init();
+       g_list_foreach(mod_uri_list_local,(GFunc)mod_uri_load,NULL);
+}
+
+void microsoft_com(void)
+{
+       g_list_foreach(mod_uri_microsoftcom_list(),(GFunc)mod_uri_load_base_reporting,NULL);
+}
+
+static void scan_batch(void)
+{
+       g_list_foreach(optarg_scan_path_list,(GFunc)mod_uri_load_base_reporting,NULL);
+
+       if (optarg_scan_disks_quick)
+               scan_disks_quick();
+       if (optarg_scan_disks)
+               scan_disks();
+       if (optarg_microsoft_com)
+               microsoft_com();
+}
+
+static jmp_buf gnome_init_atexit_jmpbuf;
+static gboolean gnome_init_atexit_disable;
+
+static void gnome_init_atexit_handler(void)
+{
+       if (gnome_init_atexit_disable)
+               return;
+
+       longjmp(gnome_init_atexit_jmpbuf,1);
+       g_assert_not_reached();
+       _exit(EXIT_FAILURE);
+}
+
+gboolean gnome_init_g_log_handler_hit;
+static void gnome_init_g_log_handler(const gchar *log_domain,GLogLevelFlags log_level,const gchar *message,gpointer user_data)
+{
+       gnome_init_g_log_handler_hit=TRUE;
+       g_log_default_handler(log_domain,log_level,message,user_data);
+}
+
 int main(int argc,char **argv)
 {
 poptContext context;
 int errint;
-GList *scan_uri_list;
+gboolean is_interactive;
+gboolean no_gnome;
 
-#ifdef MAINTAINER_MODE
+#if 0
        g_log_set_always_fatal(~(0
                        |G_LOG_LEVEL_MESSAGE
                        |G_LOG_LEVEL_INFO
@@ -98,46 +204,98 @@ GList *scan_uri_list;
                        ));
 #endif
 
-       /* Initialize the i18n stuff */
-       setlocale(LC_ALL,"");
-       bindtextdomain(PACKAGE,LOCALEDIR);
-       textdomain(PACKAGE);
+       captive_standalone_init();
 
        if (!gnome_vfs_init())
                g_error(_("GnomeVFS failed to initialize"));
 
-       context=poptGetContext(
-                       PACKAGE,        /* name */
-                       argc,(/*en-const*/const char **)argv,   /* argc,argv */
-                       popt_table,     /* options */
-                       POPT_CONTEXT_POSIXMEHARDER);    /* flags; && !POPT_CONTEXT_KEEP_FIRST */
-       if (context==NULL) {
-               g_assert_not_reached(); /* argument recognization args_error */
-               return EXIT_FAILURE;
-               }
-       errint=poptReadDefaultConfig(context,
-                       TRUE);  /* useEnv */
-       if (errint!=0) {
-               g_assert_not_reached(); /* argument recognization args_error */
-               return EXIT_FAILURE;
-               }
-       errint=poptGetNextOpt(context);
-       if (errint!=-1) {
-               g_assert_not_reached(); /* some non-callbacked argument reached */
-               return EXIT_FAILURE;
+#ifdef ENABLE_STANDALONE
+       standalone_libntfs_init();
+#endif
+
+       if (argv[1] && !strcmp(argv[1],"--text"))
+               optarg_text=1;
+
+       no_gnome=(optarg_text || !getenv("DISPLAY") || !*getenv("DISPLAY"));
+
+       if (no_gnome) {
+               context=poptGetContext(
+                               PACKAGE,        /* name */
+                               argc,(/*en-const*/const char **)argv,   /* argc,argv */
+                               popt_table_autohelp,    /* options */
+                               POPT_CONTEXT_POSIXMEHARDER);    /* flags; && !POPT_CONTEXT_KEEP_FIRST */
+               if (context==NULL) {
+                       g_assert_not_reached(); /* argument recognization args_error */
+                       return EXIT_FAILURE;
+                       }
+               errint=poptReadDefaultConfig(context,
+                               TRUE);  /* useEnv */
+               if (errint!=0) {
+                       g_assert_not_reached(); /* argument recognization args_error */
+                       return EXIT_FAILURE;
+                       }
+               errint=poptGetNextOpt(context);
+               if (errint!=-1) {
+                       g_assert_not_reached(); /* some non-callbacked argument reached */
+                       return EXIT_FAILURE;
+                       }
+               if (poptPeekArg(context)) {
+                       g_error(_("No arguments expected"));
+                       return EXIT_FAILURE;
+                       }
                }
-       if (poptPeekArg(context)) {
-               g_error(_("No arguments expected"));
-               return EXIT_FAILURE;
+       else {
+GnomeProgram *gnome_program;
+guint handler_id;
+
+               captive_standalone_gnome_init();
+               gnome_init_atexit_disable=FALSE;
+               g_atexit(gnome_init_atexit_handler);
+               gnome_init_g_log_handler_hit=FALSE;
+               handler_id=g_log_set_handler(
+                               "Gtk",  /* log_domain */
+                               G_LOG_LEVEL_WARNING,    /* log_levels */
+                               gnome_init_g_log_handler,       /* log_func */
+                               NULL);  /* user_data */
+               if (!setjmp(gnome_init_atexit_jmpbuf))
+                       gnome_program=gnome_program_init(PACKAGE,VERSION,LIBGNOMEUI_MODULE,argc,argv,
+                                       GNOME_PARAM_POPT_TABLE,popt_table,
+                                       GNOME_PARAM_POPT_FLAGS,(int)POPT_CONTEXT_POSIXMEHARDER,
+                                       NULL);
+               else {
+                       no_gnome=TRUE;
+                       /* No message: (captive-install-acquire:3693): Gtk-WARNING **: cannot open display:
+                        * was reported, probably only '--help' message was shown.
+                        */
+                       if (!gnome_init_g_log_handler_hit)
+                               exit(EXIT_SUCCESS);
+                       }
+               gnome_init_atexit_disable=TRUE;
+               g_log_remove_handler(
+                               "Gtk",  /* log_domain */
+                               handler_id);    /* handler_id */
                }
 
-       scan_uri_list=NULL;
-       scan_uri_list=g_list_concat(scan_uri_list,gnome_vfs_uri_list_copy(optarg_scan_path_list));
-       if (optarg_scan_disks)
-               scan_uri_list=g_list_concat(scan_uri_list,mod_uri_list());
+       is_interactive=(1
+                       && ! optarg_scan_path_list
+                       && ! optarg_scan_disks_quick
+                       && ! optarg_scan_disks 
+                       && ! optarg_microsoft_com);
+
+       /* Initialize UI here to catch all GLog errors below. */
+       if (is_interactive
+                       && (no_gnome || !ui_gnome_init())
+                       && !ui_line_init())
+               g_error(_("No UI interface could be initialized"));
+
+       captivemodid=captive_captivemodid_load_default(TRUE);
+
+       mod_uri_load_base_reporting(gnome_vfs_uri_new("file://" G_STRINGIFY(VARLIBCAPTIVEDIR)));
 
-       captivemodid_load("./w32-mod-id.captivemodid.xml");
-       g_list_foreach(scan_uri_list,(GFunc)mod_uri_load,NULL);
+       if (!is_interactive)
+               scan_batch();
+       else
+               (*ui_interactive)();
 
        gnome_vfs_shutdown();