GIOModule: Use G_SEARCHPATH_SEPARATOR_S instead of ":"
[platform/upstream/glib.git] / gio / giomodule.c
1 /* GIO - GLib Input, Output and Streaming Library
2  * 
3  * Copyright (C) 2006-2007 Red Hat, Inc.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General
16  * Public License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  * Boston, MA 02111-1307, USA.
19  *
20  * Author: Alexander Larsson <alexl@redhat.com>
21  */
22
23 #include "config.h"
24
25 #include <string.h>
26
27 #include "giomodule.h"
28 #include "giomodule-priv.h"
29 #include "glocalfilemonitor.h"
30 #include "glocaldirectorymonitor.h"
31 #include "gnativevolumemonitor.h"
32 #include "gproxyresolver.h"
33 #include "gproxy.h"
34 #include "gsettingsbackendinternal.h"
35 #include "gsocks4proxy.h"
36 #include "gsocks4aproxy.h"
37 #include "gsocks5proxy.h"
38 #include "gtlsbackend.h"
39 #include "gvfs.h"
40 #ifdef G_OS_WIN32
41 #include "gregistrysettingsbackend.h"
42 #endif
43 #include <glib/gstdio.h>
44
45 #undef G_DISABLE_DEPRECATED
46
47 #ifdef G_OS_UNIX
48 #include "gdesktopappinfo.h"
49 #endif
50
51 /**
52  * SECTION:giomodule
53  * @short_description: Loadable GIO Modules
54  * @include: gio/gio.h
55  *
56  * Provides an interface and default functions for loading and unloading 
57  * modules. This is used internally to make GIO extensible, but can also
58  * be used by others to implement module loading.
59  * 
60  **/
61
62 /**
63  * SECTION:extensionpoints
64  * @short_description: Extension Points
65  * @include: gio.h
66  * @see_also: <link linkend="extending-gio">Extending GIO</link>
67  *
68  * #GIOExtensionPoint provides a mechanism for modules to extend the
69  * functionality of the library or application that loaded it in an 
70  * organized fashion.  
71  *
72  * An extension point is identified by a name, and it may optionally
73  * require that any implementation must by of a certain type (or derived
74  * thereof). Use g_io_extension_point_register() to register an
75  * extension point, and g_io_extension_point_set_required_type() to
76  * set a required type.
77  *
78  * A module can implement an extension point by specifying the #GType 
79  * that implements the functionality. Additionally, each implementation
80  * of an extension point has a name, and a priority. Use
81  * g_io_extension_point_implement() to implement an extension point.
82  * 
83  *  |[
84  *  GIOExtensionPoint *ep;
85  *
86  *  /&ast; Register an extension point &ast;/
87  *  ep = g_io_extension_point_register ("my-extension-point");
88  *  g_io_extension_point_set_required_type (ep, MY_TYPE_EXAMPLE);
89  *  ]|
90  *
91  *  |[
92  *  /&ast; Implement an extension point &ast;/
93  *  G_DEFINE_TYPE (MyExampleImpl, my_example_impl, MY_TYPE_EXAMPLE);
94  *  g_io_extension_point_implement ("my-extension-point",
95  *                                  my_example_impl_get_type (),
96  *                                  "my-example",
97  *                                  10);
98  *  ]|
99  *
100  *  It is up to the code that registered the extension point how
101  *  it uses the implementations that have been associated with it.
102  *  Depending on the use case, it may use all implementations, or
103  *  only the one with the highest priority, or pick a specific
104  *  one by name.
105  *
106  *  To avoid opening all modules just to find out what extension
107  *  points they implement, GIO makes use of a caching mechanism,
108  *  see <link linkend="gio-querymodules">gio-querymodules</link>.
109  *  You are expected to run this command after installing a
110  *  GIO module.
111  *
112  *  The <envar>GIO_EXTRA_MODULES</envar> environment variable can be
113  *  used to specify additional directories to automatically load modules
114  *  from. This environment variable has the same syntax as the
115  *  <envar>PATH</envar>. If two modules have the same base name in different
116  *  directories, then the latter one will be ignored. If additional
117  *  directories are specified GIO will load modules from the built-in
118  *  directory last.
119  */
120
121 /**
122  * GIOModuleScope:
123  *
124  * Represents a scope for loading IO modules. A scope can be used for blocking
125  * duplicate modules, or blocking a module you don't want to load.
126  *
127  * The scope can be used with g_io_modules_load_all_in_directory_with_scope()
128  * or g_io_modules_scan_all_in_directory_with_scope().
129  *
130  * Since: 2.30
131  */
132 struct _GIOModuleScope {
133   GIOModuleScopeFlags flags;
134   GHashTable *basenames;
135 };
136
137 /**
138  * g_io_module_scope_new:
139  * @flags: flags for the new scope
140  *
141  * Create a new scope for loading of IO modules. A scope can be used for
142  * blocking duplicate modules, or blocking a module you don't want to load.
143  *
144  * Specify the %G_IO_MODULES_SCOPE_BLOCK_DUPLICATES flag to block modules
145  * which have the same base name as a module that has already been seen
146  * in this scope.
147  *
148  * Returns: (transfer full): the new module scope
149  *
150  * Since: 2.30
151  */
152 GIOModuleScope *
153 g_io_module_scope_new (GIOModuleScopeFlags flags)
154 {
155   GIOModuleScope *scope = g_new0 (GIOModuleScope, 1);
156   scope->flags = flags;
157   scope->basenames = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
158   return scope;
159 }
160
161 /**
162  * g_io_module_scope_free:
163  * @scope: a module loading scope
164  *
165  * Free a module scope.
166  *
167  * Since: 2.30
168  */
169 void
170 g_io_module_scope_free (GIOModuleScope *scope)
171 {
172   if (!scope)
173     return;
174   g_hash_table_destroy (scope->basenames);
175   g_free (scope);
176 }
177
178 /**
179  * g_io_module_scope_block:
180  * @scope: a module loading scope
181  * @basename: the basename to block
182  *
183  * Block modules with the given @basename from being loaded when
184  * this scope is used with g_io_modules_scan_all_in_directory_with_scope()
185  * or g_io_modules_load_all_in_directory_with_scope().
186  *
187  * Since: 2.30
188  */
189 void
190 g_io_module_scope_block (GIOModuleScope *scope,
191                          const gchar    *basename)
192 {
193   gchar *key;
194
195   g_return_if_fail (scope != NULL);
196   g_return_if_fail (basename != NULL);
197
198   key = g_strdup (basename);
199   g_hash_table_insert (scope->basenames, key, key);
200 }
201
202 static gboolean
203 _g_io_module_scope_contains (GIOModuleScope *scope,
204                              const gchar    *basename)
205 {
206   return g_hash_table_lookup (scope->basenames, basename) ? TRUE : FALSE;
207 }
208
209 struct _GIOModule {
210   GTypeModule parent_instance;
211
212   gchar       *filename;
213   GModule     *library;
214   gboolean     initialized; /* The module was loaded at least once */
215
216   void (* load)   (GIOModule *module);
217   void (* unload) (GIOModule *module);
218 };
219
220 struct _GIOModuleClass
221 {
222   GTypeModuleClass parent_class;
223
224 };
225
226 static void      g_io_module_finalize      (GObject      *object);
227 static gboolean  g_io_module_load_module   (GTypeModule  *gmodule);
228 static void      g_io_module_unload_module (GTypeModule  *gmodule);
229
230 struct _GIOExtension {
231   char *name;
232   GType type;
233   gint priority;
234 };
235
236 struct _GIOExtensionPoint {
237   GType required_type;
238   char *name;
239   GList *extensions;
240   GList *lazy_load_modules;
241 };
242
243 static GHashTable *extension_points = NULL;
244 G_LOCK_DEFINE_STATIC(extension_points);
245
246 G_DEFINE_TYPE (GIOModule, g_io_module, G_TYPE_TYPE_MODULE);
247
248 static void
249 g_io_module_class_init (GIOModuleClass *class)
250 {
251   GObjectClass     *object_class      = G_OBJECT_CLASS (class);
252   GTypeModuleClass *type_module_class = G_TYPE_MODULE_CLASS (class);
253
254   object_class->finalize     = g_io_module_finalize;
255
256   type_module_class->load    = g_io_module_load_module;
257   type_module_class->unload  = g_io_module_unload_module;
258 }
259
260 static void
261 g_io_module_init (GIOModule *module)
262 {
263 }
264
265 static void
266 g_io_module_finalize (GObject *object)
267 {
268   GIOModule *module = G_IO_MODULE (object);
269
270   g_free (module->filename);
271
272   G_OBJECT_CLASS (g_io_module_parent_class)->finalize (object);
273 }
274
275 static gboolean
276 g_io_module_load_module (GTypeModule *gmodule)
277 {
278   GIOModule *module = G_IO_MODULE (gmodule);
279
280   if (!module->filename)
281     {
282       g_warning ("GIOModule path not set");
283       return FALSE;
284     }
285
286   module->library = g_module_open (module->filename, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
287
288   if (!module->library)
289     {
290       g_printerr ("%s\n", g_module_error ());
291       return FALSE;
292     }
293
294   /* Make sure that the loaded library contains the required methods */
295   if (! g_module_symbol (module->library,
296                          "g_io_module_load",
297                          (gpointer) &module->load) ||
298       ! g_module_symbol (module->library,
299                          "g_io_module_unload",
300                          (gpointer) &module->unload))
301     {
302       g_printerr ("%s\n", g_module_error ());
303       g_module_close (module->library);
304
305       return FALSE;
306     }
307
308   /* Initialize the loaded module */
309   module->load (module);
310   module->initialized = TRUE;
311
312   return TRUE;
313 }
314
315 static void
316 g_io_module_unload_module (GTypeModule *gmodule)
317 {
318   GIOModule *module = G_IO_MODULE (gmodule);
319
320   module->unload (module);
321
322   g_module_close (module->library);
323   module->library = NULL;
324
325   module->load   = NULL;
326   module->unload = NULL;
327 }
328
329 /**
330  * g_io_module_new:
331  * @filename: filename of the shared library module.
332  * 
333  * Creates a new GIOModule that will load the specific
334  * shared library when in use.
335  * 
336  * Returns: a #GIOModule from given @filename, 
337  * or %NULL on error.
338  **/
339 GIOModule *
340 g_io_module_new (const gchar *filename)
341 {
342   GIOModule *module;
343
344   g_return_val_if_fail (filename != NULL, NULL);
345
346   module = g_object_new (G_IO_TYPE_MODULE, NULL);
347   module->filename = g_strdup (filename);
348
349   return module;
350 }
351
352 static gboolean
353 is_valid_module_name (const gchar        *basename,
354                       GIOModuleScope     *scope)
355 {
356   gboolean result;
357
358 #if !defined(G_OS_WIN32) && !defined(G_WITH_CYGWIN)
359   if (!g_str_has_prefix (basename, "lib") ||
360       !g_str_has_suffix (basename, ".so"))
361     return FALSE;
362 #else
363   if (!g_str_has_suffix (basename, ".dll"))
364     return FALSE;
365 #endif
366
367   result = TRUE;
368   if (scope)
369     {
370       result = _g_io_module_scope_contains (scope, basename) ? FALSE : TRUE;
371       if (result && (scope->flags & G_IO_MODULE_SCOPE_BLOCK_DUPLICATES))
372         g_io_module_scope_block (scope, basename);
373     }
374
375   return result;
376 }
377
378
379 /**
380  * g_io_modules_scan_all_in_directory_with_scope:
381  * @dirname: pathname for a directory containing modules to scan.
382  * @scope: a scope to use when scanning the modules
383  *
384  * Scans all the modules in the specified directory, ensuring that
385  * any extension point implemented by a module is registered.
386  *
387  * This may not actually load and initialize all the types in each
388  * module, some modules may be lazily loaded and initialized when
389  * an extension point it implementes is used with e.g.
390  * g_io_extension_point_get_extensions() or
391  * g_io_extension_point_get_extension_by_name().
392  *
393  * If you need to guarantee that all types are loaded in all the modules,
394  * use g_io_modules_load_all_in_directory().
395  *
396  * Since: 2.30
397  **/
398 void
399 g_io_modules_scan_all_in_directory_with_scope (const char     *dirname,
400                                                GIOModuleScope *scope)
401 {
402   const gchar *name;
403   char *filename;
404   GDir *dir;
405   GStatBuf statbuf;
406   char *data;
407   time_t cache_mtime;
408   GHashTable *cache;
409
410   if (!g_module_supported ())
411     return;
412
413   dir = g_dir_open (dirname, 0, NULL);
414   if (!dir)
415     return;
416
417   filename = g_build_filename (dirname, "giomodule.cache", NULL);
418
419   cache = g_hash_table_new_full (g_str_hash, g_str_equal,
420                                  g_free, (GDestroyNotify)g_strfreev);
421
422   cache_mtime = 0;
423   if (g_stat (filename, &statbuf) == 0 &&
424       g_file_get_contents (filename, &data, NULL, NULL))
425     {
426       char **lines;
427       int i;
428
429       /* Cache mtime is the time the cache file was created, any file
430        * that has a ctime before this was created then and not modified
431        * since then (userspace can't change ctime). Its possible to change
432        * the ctime forward without changing the file content, by e.g.
433        * chmoding the file, but this is uncommon and will only cause us
434        * to not use the cache so will not cause bugs.
435        */
436       cache_mtime = statbuf.st_mtime;
437
438       lines = g_strsplit (data, "\n", -1);
439       g_free (data);
440
441       for (i = 0;  lines[i] != NULL; i++)
442         {
443           char *line = lines[i];
444           char *file;
445           char *colon;
446           char **extension_points;
447
448           if (line[0] == '#')
449             continue;
450
451           colon = strchr (line, ':');
452           if (colon == NULL || line == colon)
453             continue; /* Invalid line, ignore */
454
455           *colon = 0; /* terminate filename */
456           file = g_strdup (line);
457           colon++; /* after colon */
458
459           while (g_ascii_isspace (*colon))
460             colon++;
461
462           extension_points = g_strsplit (colon, ",", -1);
463           g_hash_table_insert (cache, file, extension_points);
464         }
465       g_strfreev (lines);
466     }
467
468   while ((name = g_dir_read_name (dir)))
469     {
470       if (is_valid_module_name (name, scope))
471         {
472           GIOExtensionPoint *extension_point;
473           GIOModule *module;
474           gchar *path;
475           char **extension_points;
476           int i;
477
478           path = g_build_filename (dirname, name, NULL);
479           module = g_io_module_new (path);
480
481           extension_points = g_hash_table_lookup (cache, name);
482           if (extension_points != NULL &&
483               g_stat (path, &statbuf) == 0 &&
484               statbuf.st_ctime <= cache_mtime)
485             {
486               /* Lazy load/init the library when first required */
487               for (i = 0; extension_points[i] != NULL; i++)
488                 {
489                   extension_point =
490                     g_io_extension_point_register (extension_points[i]);
491                   extension_point->lazy_load_modules =
492                     g_list_prepend (extension_point->lazy_load_modules,
493                                     module);
494                 }
495             }
496           else
497             {
498               /* Try to load and init types */
499               if (g_type_module_use (G_TYPE_MODULE (module)))
500                 g_type_module_unuse (G_TYPE_MODULE (module)); /* Unload */
501               else
502                 { /* Failure to load */
503                   g_printerr ("Failed to load module: %s\n", path);
504                   g_object_unref (module);
505                   g_free (path);
506                   continue;
507                 }
508             }
509
510           g_free (path);
511         }
512     }
513
514   g_dir_close (dir);
515
516   g_hash_table_destroy (cache);
517
518   g_free (filename);
519 }
520
521 /**
522  * g_io_modules_scan_all_in_directory:
523  * @dirname: pathname for a directory containing modules to scan.
524  *
525  * Scans all the modules in the specified directory, ensuring that
526  * any extension point implemented by a module is registered.
527  *
528  * This may not actually load and initialize all the types in each
529  * module, some modules may be lazily loaded and initialized when
530  * an extension point it implementes is used with e.g.
531  * g_io_extension_point_get_extensions() or
532  * g_io_extension_point_get_extension_by_name().
533  *
534  * If you need to guarantee that all types are loaded in all the modules,
535  * use g_io_modules_load_all_in_directory().
536  *
537  * Since: 2.24
538  **/
539 void
540 g_io_modules_scan_all_in_directory (const char *dirname)
541 {
542   g_io_modules_scan_all_in_directory_with_scope (dirname, NULL);
543 }
544
545 /**
546  * g_io_modules_load_all_in_directory_with_scope:
547  * @dirname: pathname for a directory containing modules to load.
548  * @scope: a scope to use when scanning the modules.
549  *
550  * Loads all the modules in the specified directory.
551  *
552  * If don't require all modules to be initialized (and thus registering
553  * all gtypes) then you can use g_io_modules_scan_all_in_directory()
554  * which allows delayed/lazy loading of modules.
555  *
556  * Returns: (element-type GIOModule) (transfer full): a list of #GIOModules loaded
557  *      from the directory,
558  *      All the modules are loaded into memory, if you want to
559  *      unload them (enabling on-demand loading) you must call
560  *      g_type_module_unuse() on all the modules. Free the list
561  *      with g_list_free().
562  *
563  * Since: 2.30
564  **/
565 GList *
566 g_io_modules_load_all_in_directory_with_scope (const char     *dirname,
567                                                GIOModuleScope *scope)
568 {
569   const gchar *name;
570   GDir        *dir;
571   GList *modules;
572
573   if (!g_module_supported ())
574     return NULL;
575
576   dir = g_dir_open (dirname, 0, NULL);
577   if (!dir)
578     return NULL;
579
580   modules = NULL;
581   while ((name = g_dir_read_name (dir)))
582     {
583       if (is_valid_module_name (name, scope))
584         {
585           GIOModule *module;
586           gchar     *path;
587
588           path = g_build_filename (dirname, name, NULL);
589           module = g_io_module_new (path);
590
591           if (!g_type_module_use (G_TYPE_MODULE (module)))
592             {
593               g_printerr ("Failed to load module: %s\n", path);
594               g_object_unref (module);
595               g_free (path);
596               continue;
597             }
598           
599           g_free (path);
600
601           modules = g_list_prepend (modules, module);
602         }
603     }
604   
605   g_dir_close (dir);
606
607   return modules;
608 }
609
610 /**
611  * g_io_modules_load_all_in_directory:
612  * @dirname: pathname for a directory containing modules to load.
613  *
614  * Loads all the modules in the specified directory.
615  *
616  * If don't require all modules to be initialized (and thus registering
617  * all gtypes) then you can use g_io_modules_scan_all_in_directory()
618  * which allows delayed/lazy loading of modules.
619  *
620  * Returns: (element-type GIOModule) (transfer full): a list of #GIOModules loaded
621  *      from the directory,
622  *      All the modules are loaded into memory, if you want to
623  *      unload them (enabling on-demand loading) you must call
624  *      g_type_module_unuse() on all the modules. Free the list
625  *      with g_list_free().
626  **/
627 GList *
628 g_io_modules_load_all_in_directory (const char *dirname)
629 {
630   return g_io_modules_load_all_in_directory_with_scope (dirname, NULL);
631 }
632
633 GRecMutex default_modules_lock;
634 GHashTable *default_modules;
635
636 static gpointer
637 try_implementation (GIOExtension         *extension,
638                     GIOModuleVerifyFunc   verify_func)
639 {
640   GType type = g_io_extension_get_type (extension);
641   gpointer impl;
642
643   if (g_type_is_a (type, G_TYPE_INITABLE))
644     return g_initable_new (type, NULL, NULL, NULL);
645   else
646     {
647       impl = g_object_new (type, NULL);
648       if (!verify_func || verify_func (impl))
649         return impl;
650
651       g_object_unref (impl);
652       return NULL;
653     }
654 }
655
656 /**
657  * _g_io_module_get_default:
658  * @extension_point: the name of an extension point
659  * @envvar: (allow-none): the name of an environment variable to
660  *     override the default implementation.
661  * @verify_func: (allow-none): a function to call to verify that
662  *     a given implementation is usable in the current environment.
663  *
664  * Retrieves the default object implementing @extension_point.
665  *
666  * If @envvar is not %NULL, and the environment variable with that
667  * name is set, then the implementation it specifies will be tried
668  * first. After that, or if @envvar is not set, all other
669  * implementations will be tried in order of decreasing priority.
670  *
671  * If an extension point implementation implements #GInitable, then
672  * that implementation will only be used if it initializes
673  * successfully. Otherwise, if @verify_func is not %NULL, then it will
674  * be called on each candidate implementation after construction, to
675  * check if it is actually usable or not.
676  *
677  * The result is cached after it is generated the first time, and
678  * the function is thread-safe.
679  *
680  * Return value: (transfer none): an object implementing
681  *     @extension_point, or %NULL if there are no usable
682  *     implementations.
683  */
684 gpointer
685 _g_io_module_get_default (const gchar         *extension_point,
686                           const gchar         *envvar,
687                           GIOModuleVerifyFunc  verify_func)
688 {
689   const char *use_this;
690   GList *l;
691   GIOExtensionPoint *ep;
692   GIOExtension *extension, *preferred;
693   gpointer impl;
694
695   g_rec_mutex_lock (&default_modules_lock);
696   if (default_modules)
697     {
698       gpointer key;
699
700       if (g_hash_table_lookup_extended (default_modules, extension_point,
701                                         &key, &impl))
702         {
703           g_rec_mutex_unlock (&default_modules_lock);
704           return impl;
705         }
706     }
707   else
708     {
709       default_modules = g_hash_table_new (g_str_hash, g_str_equal);
710     }
711
712   _g_io_modules_ensure_loaded ();
713   ep = g_io_extension_point_lookup (extension_point);
714
715   if (!ep)
716     {
717       g_warn_if_reached ();
718       g_rec_mutex_unlock (&default_modules_lock);
719       return NULL;
720     }
721
722   use_this = envvar ? g_getenv (envvar) : NULL;
723   if (use_this)
724     {
725       preferred = g_io_extension_point_get_extension_by_name (ep, use_this);
726       if (preferred)
727         {
728           impl = try_implementation (preferred, verify_func);
729           if (impl)
730             goto done;
731         }
732       else
733         g_warning ("Can't find module '%s' specified in %s", use_this, envvar);
734     }
735   else
736     preferred = NULL;
737
738   for (l = g_io_extension_point_get_extensions (ep); l != NULL; l = l->next)
739     {
740       extension = l->data;
741       if (extension == preferred)
742         continue;
743
744       impl = try_implementation (extension, verify_func);
745       if (impl)
746         goto done;
747     }
748
749   impl = NULL;
750
751  done:
752   g_hash_table_insert (default_modules,
753                        g_strdup (extension_point),
754                        impl ? g_object_ref (impl) : NULL);
755   g_rec_mutex_unlock (&default_modules_lock);
756
757   return impl;
758 }
759
760 G_LOCK_DEFINE_STATIC (registered_extensions);
761 G_LOCK_DEFINE_STATIC (loaded_dirs);
762
763 extern GType _g_fen_directory_monitor_get_type (void);
764 extern GType _g_fen_file_monitor_get_type (void);
765 extern GType _g_inotify_directory_monitor_get_type (void);
766 extern GType _g_inotify_file_monitor_get_type (void);
767 extern GType _g_unix_volume_monitor_get_type (void);
768 extern GType _g_local_vfs_get_type (void);
769
770 extern GType _g_win32_volume_monitor_get_type (void);
771 extern GType g_win32_directory_monitor_get_type (void);
772 extern GType _g_winhttp_vfs_get_type (void);
773
774 extern GType _g_dummy_proxy_resolver_get_type (void);
775 extern GType _g_dummy_tls_backend_get_type (void);
776
777 #ifdef G_PLATFORM_WIN32
778
779 #include <windows.h>
780
781 static HMODULE gio_dll = NULL;
782
783 #ifdef DLL_EXPORT
784
785 BOOL WINAPI
786 DllMain (HINSTANCE hinstDLL,
787          DWORD     fdwReason,
788          LPVOID    lpvReserved)
789 {
790   if (fdwReason == DLL_PROCESS_ATTACH)
791       gio_dll = hinstDLL;
792
793   return TRUE;
794 }
795
796 #endif
797
798 #undef GIO_MODULE_DIR
799
800 /* GIO_MODULE_DIR is used only in code called just once,
801  * so no problem leaking this
802  */
803 #define GIO_MODULE_DIR \
804   g_build_filename (g_win32_get_package_installation_directory_of_module (gio_dll), \
805                     "lib/gio/modules", \
806                     NULL)
807
808 #endif
809
810 void
811 _g_io_modules_ensure_extension_points_registered (void)
812 {
813   static gboolean registered_extensions = FALSE;
814   GIOExtensionPoint *ep;
815
816   G_LOCK (registered_extensions);
817   
818   if (!registered_extensions)
819     {
820       registered_extensions = TRUE;
821       
822 #ifdef G_OS_UNIX
823 #if !GLIB_CHECK_VERSION (3, 0, 0)
824       ep = g_io_extension_point_register (G_DESKTOP_APP_INFO_LOOKUP_EXTENSION_POINT_NAME);
825       g_io_extension_point_set_required_type (ep, G_TYPE_DESKTOP_APP_INFO_LOOKUP);
826 #endif
827 #endif
828       
829       ep = g_io_extension_point_register (G_LOCAL_DIRECTORY_MONITOR_EXTENSION_POINT_NAME);
830       g_io_extension_point_set_required_type (ep, G_TYPE_LOCAL_DIRECTORY_MONITOR);
831       
832       ep = g_io_extension_point_register (G_LOCAL_FILE_MONITOR_EXTENSION_POINT_NAME);
833       g_io_extension_point_set_required_type (ep, G_TYPE_LOCAL_FILE_MONITOR);
834       
835       ep = g_io_extension_point_register (G_VOLUME_MONITOR_EXTENSION_POINT_NAME);
836       g_io_extension_point_set_required_type (ep, G_TYPE_VOLUME_MONITOR);
837       
838       ep = g_io_extension_point_register (G_NATIVE_VOLUME_MONITOR_EXTENSION_POINT_NAME);
839       g_io_extension_point_set_required_type (ep, G_TYPE_NATIVE_VOLUME_MONITOR);
840       
841       ep = g_io_extension_point_register (G_VFS_EXTENSION_POINT_NAME);
842       g_io_extension_point_set_required_type (ep, G_TYPE_VFS);
843
844       ep = g_io_extension_point_register ("gsettings-backend");
845       g_io_extension_point_set_required_type (ep, G_TYPE_OBJECT);
846
847       ep = g_io_extension_point_register (G_PROXY_RESOLVER_EXTENSION_POINT_NAME);
848       g_io_extension_point_set_required_type (ep, G_TYPE_PROXY_RESOLVER);
849
850       ep = g_io_extension_point_register (G_PROXY_EXTENSION_POINT_NAME);
851       g_io_extension_point_set_required_type (ep, G_TYPE_PROXY);
852
853       ep = g_io_extension_point_register (G_TLS_BACKEND_EXTENSION_POINT_NAME);
854       g_io_extension_point_set_required_type (ep, G_TYPE_TLS_BACKEND);
855     }
856   
857   G_UNLOCK (registered_extensions);
858  }
859
860 void
861 _g_io_modules_ensure_loaded (void)
862 {
863   static gboolean loaded_dirs = FALSE;
864   const char *module_path;
865   GIOModuleScope *scope;
866
867   _g_io_modules_ensure_extension_points_registered ();
868   
869   G_LOCK (loaded_dirs);
870
871   if (!loaded_dirs)
872     {
873       loaded_dirs = TRUE;
874       scope = g_io_module_scope_new (G_IO_MODULE_SCOPE_BLOCK_DUPLICATES);
875
876       /* First load any overrides, extras */
877       module_path = g_getenv ("GIO_EXTRA_MODULES");
878       if (module_path)
879         {
880           gchar **paths;
881           int i;
882
883           paths = g_strsplit (module_path, G_SEARCHPATH_SEPARATOR_S, 0);
884
885           for (i = 0; paths[i] != NULL; i++)
886             {
887               g_io_modules_scan_all_in_directory_with_scope (paths[i], scope);
888             }
889
890           g_strfreev (paths);
891         }
892
893       /* Then load the compiled in path */
894       g_io_modules_scan_all_in_directory_with_scope (GIO_MODULE_DIR, scope);
895
896       g_io_module_scope_free (scope);
897
898       /* Initialize types from built-in "modules" */
899       g_null_settings_backend_get_type ();
900       g_memory_settings_backend_get_type ();
901 #if defined(HAVE_SYS_INOTIFY_H) || defined(HAVE_LINUX_INOTIFY_H)
902       _g_inotify_directory_monitor_get_type ();
903       _g_inotify_file_monitor_get_type ();
904 #endif
905 #if defined(HAVE_FEN)
906       _g_fen_directory_monitor_get_type ();
907       _g_fen_file_monitor_get_type ();
908 #endif
909 #ifdef G_OS_WIN32
910       _g_win32_volume_monitor_get_type ();
911       g_win32_directory_monitor_get_type ();
912       g_registry_backend_get_type ();
913 #endif
914 #ifdef G_OS_UNIX
915       _g_unix_volume_monitor_get_type ();
916 #endif
917 #ifdef G_OS_WIN32
918       _g_winhttp_vfs_get_type ();
919 #endif
920       _g_local_vfs_get_type ();
921       _g_dummy_proxy_resolver_get_type ();
922       _g_socks4a_proxy_get_type ();
923       _g_socks4_proxy_get_type ();
924       _g_socks5_proxy_get_type ();
925       _g_dummy_tls_backend_get_type ();
926     }
927
928   G_UNLOCK (loaded_dirs);
929 }
930
931 static void
932 g_io_extension_point_free (GIOExtensionPoint *ep)
933 {
934   g_free (ep->name);
935   g_free (ep);
936 }
937
938 /**
939  * g_io_extension_point_register:
940  * @name: The name of the extension point
941  *
942  * Registers an extension point.
943  *
944  * Returns: (transfer none): the new #GIOExtensionPoint. This object is
945  *    owned by GIO and should not be freed.
946  */
947 GIOExtensionPoint *
948 g_io_extension_point_register (const char *name)
949 {
950   GIOExtensionPoint *ep;
951   
952   G_LOCK (extension_points);
953   if (extension_points == NULL)
954     extension_points = g_hash_table_new_full (g_str_hash,
955                                               g_str_equal,
956                                               NULL,
957                                               (GDestroyNotify)g_io_extension_point_free);
958
959   ep = g_hash_table_lookup (extension_points, name);
960   if (ep != NULL)
961     {
962       G_UNLOCK (extension_points);
963       return ep;
964     }
965
966   ep = g_new0 (GIOExtensionPoint, 1);
967   ep->name = g_strdup (name);
968   
969   g_hash_table_insert (extension_points, ep->name, ep);
970   
971   G_UNLOCK (extension_points);
972
973   return ep;
974 }
975
976 /**
977  * g_io_extension_point_lookup:
978  * @name: the name of the extension point
979  *
980  * Looks up an existing extension point.
981  *
982  * Returns: (transfer none): the #GIOExtensionPoint, or %NULL if there
983  *    is no registered extension point with the given name.
984  */
985 GIOExtensionPoint *
986 g_io_extension_point_lookup (const char *name)
987 {
988   GIOExtensionPoint *ep;
989
990   G_LOCK (extension_points);
991   ep = NULL;
992   if (extension_points != NULL)
993     ep = g_hash_table_lookup (extension_points, name);
994   
995   G_UNLOCK (extension_points);
996
997   return ep;
998   
999 }
1000
1001 /**
1002  * g_io_extension_point_set_required_type:
1003  * @extension_point: a #GIOExtensionPoint
1004  * @type: the #GType to require
1005  *
1006  * Sets the required type for @extension_point to @type. 
1007  * All implementations must henceforth have this type.
1008  */
1009 void
1010 g_io_extension_point_set_required_type (GIOExtensionPoint *extension_point,
1011                                         GType              type)
1012 {
1013   extension_point->required_type = type;
1014 }
1015
1016 /**
1017  * g_io_extension_point_get_required_type:
1018  * @extension_point: a #GIOExtensionPoint
1019  *
1020  * Gets the required type for @extension_point.
1021  *
1022  * Returns: the #GType that all implementations must have, 
1023  *     or #G_TYPE_INVALID if the extension point has no required type
1024  */
1025 GType
1026 g_io_extension_point_get_required_type (GIOExtensionPoint *extension_point)
1027 {
1028   return extension_point->required_type;
1029 }
1030
1031 void
1032 lazy_load_modules (GIOExtensionPoint *extension_point)
1033 {
1034   GIOModule *module;
1035   GList *l;
1036
1037   for (l = extension_point->lazy_load_modules; l != NULL; l = l->next)
1038     {
1039       module = l->data;
1040
1041       if (!module->initialized)
1042         {
1043           if (g_type_module_use (G_TYPE_MODULE (module)))
1044             g_type_module_unuse (G_TYPE_MODULE (module)); /* Unload */
1045           else
1046             g_printerr ("Failed to load module: %s\n",
1047                         module->filename);
1048         }
1049     }
1050 }
1051
1052 /**
1053  * g_io_extension_point_get_extensions:
1054  * @extension_point: a #GIOExtensionPoint
1055  *
1056  * Gets a list of all extensions that implement this extension point.
1057  * The list is sorted by priority, beginning with the highest priority.
1058  *
1059  * Returns: (element-type GIOExtension) (transfer none): a #GList of
1060  * #GIOExtension<!-- -->s. The list is owned by GIO and should not be
1061  * modified.
1062  */
1063 GList *
1064 g_io_extension_point_get_extensions (GIOExtensionPoint *extension_point)
1065 {
1066   lazy_load_modules (extension_point);
1067   return extension_point->extensions;
1068 }
1069
1070 /**
1071  * g_io_extension_point_get_extension_by_name:
1072  * @extension_point: a #GIOExtensionPoint
1073  * @name: the name of the extension to get
1074  *
1075  * Finds a #GIOExtension for an extension point by name.
1076  *
1077  * Returns: (transfer none): the #GIOExtension for @extension_point that has the
1078  *    given name, or %NULL if there is no extension with that name
1079  */
1080 GIOExtension *
1081 g_io_extension_point_get_extension_by_name (GIOExtensionPoint *extension_point,
1082                                             const char        *name)
1083 {
1084   GList *l;
1085
1086   lazy_load_modules (extension_point);
1087   for (l = extension_point->extensions; l != NULL; l = l->next)
1088     {
1089       GIOExtension *e = l->data;
1090
1091       if (e->name != NULL &&
1092           strcmp (e->name, name) == 0)
1093         return e;
1094     }
1095   
1096   return NULL;
1097 }
1098
1099 static gint
1100 extension_prio_compare (gconstpointer  a,
1101                         gconstpointer  b)
1102 {
1103   const GIOExtension *extension_a = a, *extension_b = b;
1104
1105   if (extension_a->priority > extension_b->priority)
1106     return -1;
1107
1108   if (extension_b->priority > extension_a->priority)
1109     return 1;
1110
1111   return 0;
1112 }
1113
1114 /**
1115  * g_io_extension_point_implement:
1116  * @extension_point_name: the name of the extension point
1117  * @type: the #GType to register as extension 
1118  * @extension_name: the name for the extension
1119  * @priority: the priority for the extension
1120  *
1121  * Registers @type as extension for the extension point with name
1122  * @extension_point_name. 
1123  *
1124  * If @type has already been registered as an extension for this 
1125  * extension point, the existing #GIOExtension object is returned.
1126  *
1127  * Returns: (transfer none): a #GIOExtension object for #GType
1128  */
1129 GIOExtension *
1130 g_io_extension_point_implement (const char *extension_point_name,
1131                                 GType       type,
1132                                 const char *extension_name,
1133                                 gint        priority)
1134 {
1135   GIOExtensionPoint *extension_point;
1136   GIOExtension *extension;
1137   GList *l;
1138
1139   g_return_val_if_fail (extension_point_name != NULL, NULL);
1140
1141   extension_point = g_io_extension_point_lookup (extension_point_name);
1142   if (extension_point == NULL)
1143     {
1144       g_warning ("Tried to implement non-registered extension point %s", extension_point_name);
1145       return NULL;
1146     }
1147   
1148   if (extension_point->required_type != 0 &&
1149       !g_type_is_a (type, extension_point->required_type))
1150     {
1151       g_warning ("Tried to register an extension of the type %s to extension point %s. "
1152                  "Expected type is %s.",
1153                  g_type_name (type),
1154                  extension_point_name, 
1155                  g_type_name (extension_point->required_type));
1156       return NULL;
1157     }      
1158
1159   /* It's safe to register the same type multiple times */
1160   for (l = extension_point->extensions; l != NULL; l = l->next)
1161     {
1162       extension = l->data;
1163       if (extension->type == type)
1164         return extension;
1165     }
1166   
1167   extension = g_slice_new0 (GIOExtension);
1168   extension->type = type;
1169   extension->name = g_strdup (extension_name);
1170   extension->priority = priority;
1171   
1172   extension_point->extensions = g_list_insert_sorted (extension_point->extensions,
1173                                                       extension, extension_prio_compare);
1174   
1175   return extension;
1176 }
1177
1178 /**
1179  * g_io_extension_ref_class:
1180  * @extension: a #GIOExtension
1181  *
1182  * Gets a reference to the class for the type that is 
1183  * associated with @extension.
1184  *
1185  * Returns: (transfer full): the #GTypeClass for the type of @extension
1186  */
1187 GTypeClass *
1188 g_io_extension_ref_class (GIOExtension *extension)
1189 {
1190   return g_type_class_ref (extension->type);
1191 }
1192
1193 /**
1194  * g_io_extension_get_type:
1195  * @extension: a #GIOExtension
1196  *
1197  * Gets the type associated with @extension.
1198  *
1199  * Returns: the type of @extension
1200  */
1201 GType
1202 g_io_extension_get_type (GIOExtension *extension)
1203 {
1204   return extension->type;
1205 }
1206
1207 /**
1208  * g_io_extension_get_name:
1209  * @extension: a #GIOExtension
1210  *
1211  * Gets the name under which @extension was registered.
1212  *
1213  * Note that the same type may be registered as extension
1214  * for multiple extension points, under different names.
1215  *
1216  * Returns: the name of @extension.
1217  */
1218 const char *
1219 g_io_extension_get_name (GIOExtension *extension)
1220 {
1221   return extension->name;
1222 }
1223
1224 /**
1225  * g_io_extension_get_priority:
1226  * @extension: a #GIOExtension
1227  *
1228  * Gets the priority with which @extension was registered.
1229  *
1230  * Returns: the priority of @extension
1231  */
1232 gint
1233 g_io_extension_get_priority (GIOExtension *extension)
1234 {
1235   return extension->priority;
1236 }