Clean up includes
[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 G_LOCK_DEFINE_STATIC (registered_extensions);
634 G_LOCK_DEFINE_STATIC (loaded_dirs);
635
636 extern GType _g_fen_directory_monitor_get_type (void);
637 extern GType _g_fen_file_monitor_get_type (void);
638 extern GType _g_inotify_directory_monitor_get_type (void);
639 extern GType _g_inotify_file_monitor_get_type (void);
640 extern GType _g_unix_volume_monitor_get_type (void);
641 extern GType _g_local_vfs_get_type (void);
642
643 extern GType _g_win32_volume_monitor_get_type (void);
644 extern GType g_win32_directory_monitor_get_type (void);
645 extern GType _g_winhttp_vfs_get_type (void);
646
647 extern GType _g_dummy_proxy_resolver_get_type (void);
648 extern GType _g_dummy_tls_backend_get_type (void);
649
650 #ifdef G_PLATFORM_WIN32
651
652 #include <windows.h>
653
654 static HMODULE gio_dll = NULL;
655
656 #ifdef DLL_EXPORT
657
658 BOOL WINAPI
659 DllMain (HINSTANCE hinstDLL,
660          DWORD     fdwReason,
661          LPVOID    lpvReserved)
662 {
663   if (fdwReason == DLL_PROCESS_ATTACH)
664       gio_dll = hinstDLL;
665
666   return TRUE;
667 }
668
669 #endif
670
671 #undef GIO_MODULE_DIR
672
673 /* GIO_MODULE_DIR is used only in code called just once,
674  * so no problem leaking this
675  */
676 #define GIO_MODULE_DIR \
677   g_build_filename (g_win32_get_package_installation_directory_of_module (gio_dll), \
678                     "lib/gio/modules", \
679                     NULL)
680
681 #endif
682
683 void
684 _g_io_modules_ensure_extension_points_registered (void)
685 {
686   static gboolean registered_extensions = FALSE;
687   GIOExtensionPoint *ep;
688
689   G_LOCK (registered_extensions);
690   
691   if (!registered_extensions)
692     {
693       registered_extensions = TRUE;
694       
695 #ifdef G_OS_UNIX
696 #if !GLIB_CHECK_VERSION (3, 0, 0)
697       ep = g_io_extension_point_register (G_DESKTOP_APP_INFO_LOOKUP_EXTENSION_POINT_NAME);
698       g_io_extension_point_set_required_type (ep, G_TYPE_DESKTOP_APP_INFO_LOOKUP);
699 #endif
700 #endif
701       
702       ep = g_io_extension_point_register (G_LOCAL_DIRECTORY_MONITOR_EXTENSION_POINT_NAME);
703       g_io_extension_point_set_required_type (ep, G_TYPE_LOCAL_DIRECTORY_MONITOR);
704       
705       ep = g_io_extension_point_register (G_LOCAL_FILE_MONITOR_EXTENSION_POINT_NAME);
706       g_io_extension_point_set_required_type (ep, G_TYPE_LOCAL_FILE_MONITOR);
707       
708       ep = g_io_extension_point_register (G_VOLUME_MONITOR_EXTENSION_POINT_NAME);
709       g_io_extension_point_set_required_type (ep, G_TYPE_VOLUME_MONITOR);
710       
711       ep = g_io_extension_point_register (G_NATIVE_VOLUME_MONITOR_EXTENSION_POINT_NAME);
712       g_io_extension_point_set_required_type (ep, G_TYPE_NATIVE_VOLUME_MONITOR);
713       
714       ep = g_io_extension_point_register (G_VFS_EXTENSION_POINT_NAME);
715       g_io_extension_point_set_required_type (ep, G_TYPE_VFS);
716
717       ep = g_io_extension_point_register ("gsettings-backend");
718       g_io_extension_point_set_required_type (ep, G_TYPE_OBJECT);
719
720       ep = g_io_extension_point_register (G_PROXY_RESOLVER_EXTENSION_POINT_NAME);
721       g_io_extension_point_set_required_type (ep, G_TYPE_PROXY_RESOLVER);
722
723       ep = g_io_extension_point_register (G_PROXY_EXTENSION_POINT_NAME);
724       g_io_extension_point_set_required_type (ep, G_TYPE_PROXY);
725
726       ep = g_io_extension_point_register (G_TLS_BACKEND_EXTENSION_POINT_NAME);
727       g_io_extension_point_set_required_type (ep, G_TYPE_TLS_BACKEND);
728     }
729   
730   G_UNLOCK (registered_extensions);
731  }
732
733 void
734 _g_io_modules_ensure_loaded (void)
735 {
736   static gboolean loaded_dirs = FALSE;
737   const char *module_path;
738   GIOModuleScope *scope;
739
740   _g_io_modules_ensure_extension_points_registered ();
741   
742   G_LOCK (loaded_dirs);
743
744   if (!loaded_dirs)
745     {
746       loaded_dirs = TRUE;
747       scope = g_io_module_scope_new (G_IO_MODULE_SCOPE_BLOCK_DUPLICATES);
748
749       /* First load any overrides, extras */
750       module_path = g_getenv ("GIO_EXTRA_MODULES");
751       if (module_path)
752         {
753           gchar **paths;
754           int i;
755
756           paths = g_strsplit (module_path, ":", 0);
757
758           for (i = 0; paths[i] != NULL; i++)
759             {
760               g_io_modules_scan_all_in_directory_with_scope (paths[i], scope);
761             }
762
763           g_strfreev (paths);
764         }
765
766       /* Then load the compiled in path */
767       g_io_modules_scan_all_in_directory_with_scope (GIO_MODULE_DIR, scope);
768
769       g_io_module_scope_free (scope);
770
771       /* Initialize types from built-in "modules" */
772       g_null_settings_backend_get_type ();
773       g_memory_settings_backend_get_type ();
774 #if defined(HAVE_SYS_INOTIFY_H) || defined(HAVE_LINUX_INOTIFY_H)
775       _g_inotify_directory_monitor_get_type ();
776       _g_inotify_file_monitor_get_type ();
777 #endif
778 #if defined(HAVE_FEN)
779       _g_fen_directory_monitor_get_type ();
780       _g_fen_file_monitor_get_type ();
781 #endif
782 #ifdef G_OS_WIN32
783       _g_win32_volume_monitor_get_type ();
784       g_win32_directory_monitor_get_type ();
785       g_registry_backend_get_type ();
786 #endif
787 #ifdef G_OS_UNIX
788       _g_unix_volume_monitor_get_type ();
789 #endif
790 #ifdef G_OS_WIN32
791       _g_winhttp_vfs_get_type ();
792 #endif
793       _g_local_vfs_get_type ();
794       _g_dummy_proxy_resolver_get_type ();
795       _g_socks4a_proxy_get_type ();
796       _g_socks4_proxy_get_type ();
797       _g_socks5_proxy_get_type ();
798       _g_dummy_tls_backend_get_type ();
799     }
800
801   G_UNLOCK (loaded_dirs);
802 }
803
804 static void
805 g_io_extension_point_free (GIOExtensionPoint *ep)
806 {
807   g_free (ep->name);
808   g_free (ep);
809 }
810
811 /**
812  * g_io_extension_point_register:
813  * @name: The name of the extension point
814  *
815  * Registers an extension point.
816  *
817  * Returns: (transfer none): the new #GIOExtensionPoint. This object is
818  *    owned by GIO and should not be freed.
819  */
820 GIOExtensionPoint *
821 g_io_extension_point_register (const char *name)
822 {
823   GIOExtensionPoint *ep;
824   
825   G_LOCK (extension_points);
826   if (extension_points == NULL)
827     extension_points = g_hash_table_new_full (g_str_hash,
828                                               g_str_equal,
829                                               NULL,
830                                               (GDestroyNotify)g_io_extension_point_free);
831
832   ep = g_hash_table_lookup (extension_points, name);
833   if (ep != NULL)
834     {
835       G_UNLOCK (extension_points);
836       return ep;
837     }
838
839   ep = g_new0 (GIOExtensionPoint, 1);
840   ep->name = g_strdup (name);
841   
842   g_hash_table_insert (extension_points, ep->name, ep);
843   
844   G_UNLOCK (extension_points);
845
846   return ep;
847 }
848
849 /**
850  * g_io_extension_point_lookup:
851  * @name: the name of the extension point
852  *
853  * Looks up an existing extension point.
854  *
855  * Returns: (transfer none): the #GIOExtensionPoint, or %NULL if there
856  *    is no registered extension point with the given name.
857  */
858 GIOExtensionPoint *
859 g_io_extension_point_lookup (const char *name)
860 {
861   GIOExtensionPoint *ep;
862
863   G_LOCK (extension_points);
864   ep = NULL;
865   if (extension_points != NULL)
866     ep = g_hash_table_lookup (extension_points, name);
867   
868   G_UNLOCK (extension_points);
869
870   return ep;
871   
872 }
873
874 /**
875  * g_io_extension_point_set_required_type:
876  * @extension_point: a #GIOExtensionPoint
877  * @type: the #GType to require
878  *
879  * Sets the required type for @extension_point to @type. 
880  * All implementations must henceforth have this type.
881  */
882 void
883 g_io_extension_point_set_required_type (GIOExtensionPoint *extension_point,
884                                         GType              type)
885 {
886   extension_point->required_type = type;
887 }
888
889 /**
890  * g_io_extension_point_get_required_type:
891  * @extension_point: a #GIOExtensionPoint
892  *
893  * Gets the required type for @extension_point.
894  *
895  * Returns: the #GType that all implementations must have, 
896  *     or #G_TYPE_INVALID if the extension point has no required type
897  */
898 GType
899 g_io_extension_point_get_required_type (GIOExtensionPoint *extension_point)
900 {
901   return extension_point->required_type;
902 }
903
904 void
905 lazy_load_modules (GIOExtensionPoint *extension_point)
906 {
907   GIOModule *module;
908   GList *l;
909
910   for (l = extension_point->lazy_load_modules; l != NULL; l = l->next)
911     {
912       module = l->data;
913
914       if (!module->initialized)
915         {
916           if (g_type_module_use (G_TYPE_MODULE (module)))
917             g_type_module_unuse (G_TYPE_MODULE (module)); /* Unload */
918           else
919             g_printerr ("Failed to load module: %s\n",
920                         module->filename);
921         }
922     }
923 }
924
925 /**
926  * g_io_extension_point_get_extensions:
927  * @extension_point: a #GIOExtensionPoint
928  *
929  * Gets a list of all extensions that implement this extension point.
930  * The list is sorted by priority, beginning with the highest priority.
931  *
932  * Returns: (element-type GIOExtension) (transfer none): a #GList of
933  * #GIOExtension<!-- -->s. The list is owned by GIO and should not be
934  * modified.
935  */
936 GList *
937 g_io_extension_point_get_extensions (GIOExtensionPoint *extension_point)
938 {
939   lazy_load_modules (extension_point);
940   return extension_point->extensions;
941 }
942
943 /**
944  * g_io_extension_point_get_extension_by_name:
945  * @extension_point: a #GIOExtensionPoint
946  * @name: the name of the extension to get
947  *
948  * Finds a #GIOExtension for an extension point by name.
949  *
950  * Returns: (transfer none): the #GIOExtension for @extension_point that has the
951  *    given name, or %NULL if there is no extension with that name
952  */
953 GIOExtension *
954 g_io_extension_point_get_extension_by_name (GIOExtensionPoint *extension_point,
955                                             const char        *name)
956 {
957   GList *l;
958
959   lazy_load_modules (extension_point);
960   for (l = extension_point->extensions; l != NULL; l = l->next)
961     {
962       GIOExtension *e = l->data;
963
964       if (e->name != NULL &&
965           strcmp (e->name, name) == 0)
966         return e;
967     }
968   
969   return NULL;
970 }
971
972 static gint
973 extension_prio_compare (gconstpointer  a,
974                         gconstpointer  b)
975 {
976   const GIOExtension *extension_a = a, *extension_b = b;
977
978   if (extension_a->priority > extension_b->priority)
979     return -1;
980
981   if (extension_b->priority > extension_a->priority)
982     return 1;
983
984   return 0;
985 }
986
987 /**
988  * g_io_extension_point_implement:
989  * @extension_point_name: the name of the extension point
990  * @type: the #GType to register as extension 
991  * @extension_name: the name for the extension
992  * @priority: the priority for the extension
993  *
994  * Registers @type as extension for the extension point with name
995  * @extension_point_name. 
996  *
997  * If @type has already been registered as an extension for this 
998  * extension point, the existing #GIOExtension object is returned.
999  *
1000  * Returns: (transfer none): a #GIOExtension object for #GType
1001  */
1002 GIOExtension *
1003 g_io_extension_point_implement (const char *extension_point_name,
1004                                 GType       type,
1005                                 const char *extension_name,
1006                                 gint        priority)
1007 {
1008   GIOExtensionPoint *extension_point;
1009   GIOExtension *extension;
1010   GList *l;
1011
1012   g_return_val_if_fail (extension_point_name != NULL, NULL);
1013
1014   extension_point = g_io_extension_point_lookup (extension_point_name);
1015   if (extension_point == NULL)
1016     {
1017       g_warning ("Tried to implement non-registered extension point %s", extension_point_name);
1018       return NULL;
1019     }
1020   
1021   if (extension_point->required_type != 0 &&
1022       !g_type_is_a (type, extension_point->required_type))
1023     {
1024       g_warning ("Tried to register an extension of the type %s to extension point %s. "
1025                  "Expected type is %s.",
1026                  g_type_name (type),
1027                  extension_point_name, 
1028                  g_type_name (extension_point->required_type));
1029       return NULL;
1030     }      
1031
1032   /* It's safe to register the same type multiple times */
1033   for (l = extension_point->extensions; l != NULL; l = l->next)
1034     {
1035       extension = l->data;
1036       if (extension->type == type)
1037         return extension;
1038     }
1039   
1040   extension = g_slice_new0 (GIOExtension);
1041   extension->type = type;
1042   extension->name = g_strdup (extension_name);
1043   extension->priority = priority;
1044   
1045   extension_point->extensions = g_list_insert_sorted (extension_point->extensions,
1046                                                       extension, extension_prio_compare);
1047   
1048   return extension;
1049 }
1050
1051 /**
1052  * g_io_extension_ref_class:
1053  * @extension: a #GIOExtension
1054  *
1055  * Gets a reference to the class for the type that is 
1056  * associated with @extension.
1057  *
1058  * Returns: (transfer full): the #GTypeClass for the type of @extension
1059  */
1060 GTypeClass *
1061 g_io_extension_ref_class (GIOExtension *extension)
1062 {
1063   return g_type_class_ref (extension->type);
1064 }
1065
1066 /**
1067  * g_io_extension_get_type:
1068  * @extension: a #GIOExtension
1069  *
1070  * Gets the type associated with @extension.
1071  *
1072  * Returns: the type of @extension
1073  */
1074 GType
1075 g_io_extension_get_type (GIOExtension *extension)
1076 {
1077   return extension->type;
1078 }
1079
1080 /**
1081  * g_io_extension_get_name:
1082  * @extension: a #GIOExtension
1083  *
1084  * Gets the name under which @extension was registered.
1085  *
1086  * Note that the same type may be registered as extension
1087  * for multiple extension points, under different names.
1088  *
1089  * Returns: the name of @extension.
1090  */
1091 const char *
1092 g_io_extension_get_name (GIOExtension *extension)
1093 {
1094   return extension->name;
1095 }
1096
1097 /**
1098  * g_io_extension_get_priority:
1099  * @extension: a #GIOExtension
1100  *
1101  * Gets the priority with which @extension was registered.
1102  *
1103  * Returns: the priority of @extension
1104  */
1105 gint
1106 g_io_extension_get_priority (GIOExtension *extension)
1107 {
1108   return extension->priority;
1109 }