Spelling fixes
[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  *
182  * Block modules with the given base name from being loaded when this scope
183  * is used with g_io_modules_scan_all_in_directory_with_scope() or
184  * g_io_modules_load_all_in_directory_with_scope().
185  *
186  * Since: 2.30
187  */
188 void
189 g_io_module_scope_block (GIOModuleScope *scope,
190                          const gchar    *basename)
191 {
192   gchar *key;
193
194   g_return_if_fail (scope != NULL);
195   g_return_if_fail (basename != NULL);
196
197   key = g_strdup (basename);
198   g_hash_table_insert (scope->basenames, key, key);
199 }
200
201 static gboolean
202 _g_io_module_scope_contains (GIOModuleScope *scope,
203                              const gchar    *basename)
204 {
205   return g_hash_table_lookup (scope->basenames, basename) ? TRUE : FALSE;
206 }
207
208 struct _GIOModule {
209   GTypeModule parent_instance;
210
211   gchar       *filename;
212   GModule     *library;
213   gboolean     initialized; /* The module was loaded at least once */
214
215   void (* load)   (GIOModule *module);
216   void (* unload) (GIOModule *module);
217 };
218
219 struct _GIOModuleClass
220 {
221   GTypeModuleClass parent_class;
222
223 };
224
225 static void      g_io_module_finalize      (GObject      *object);
226 static gboolean  g_io_module_load_module   (GTypeModule  *gmodule);
227 static void      g_io_module_unload_module (GTypeModule  *gmodule);
228
229 struct _GIOExtension {
230   char *name;
231   GType type;
232   gint priority;
233 };
234
235 struct _GIOExtensionPoint {
236   GType required_type;
237   char *name;
238   GList *extensions;
239   GList *lazy_load_modules;
240 };
241
242 static GHashTable *extension_points = NULL;
243 G_LOCK_DEFINE_STATIC(extension_points);
244
245 G_DEFINE_TYPE (GIOModule, g_io_module, G_TYPE_TYPE_MODULE);
246
247 static void
248 g_io_module_class_init (GIOModuleClass *class)
249 {
250   GObjectClass     *object_class      = G_OBJECT_CLASS (class);
251   GTypeModuleClass *type_module_class = G_TYPE_MODULE_CLASS (class);
252
253   object_class->finalize     = g_io_module_finalize;
254
255   type_module_class->load    = g_io_module_load_module;
256   type_module_class->unload  = g_io_module_unload_module;
257 }
258
259 static void
260 g_io_module_init (GIOModule *module)
261 {
262 }
263
264 static void
265 g_io_module_finalize (GObject *object)
266 {
267   GIOModule *module = G_IO_MODULE (object);
268
269   g_free (module->filename);
270
271   G_OBJECT_CLASS (g_io_module_parent_class)->finalize (object);
272 }
273
274 static gboolean
275 g_io_module_load_module (GTypeModule *gmodule)
276 {
277   GIOModule *module = G_IO_MODULE (gmodule);
278
279   if (!module->filename)
280     {
281       g_warning ("GIOModule path not set");
282       return FALSE;
283     }
284
285   module->library = g_module_open (module->filename, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
286
287   if (!module->library)
288     {
289       g_printerr ("%s\n", g_module_error ());
290       return FALSE;
291     }
292
293   /* Make sure that the loaded library contains the required methods */
294   if (! g_module_symbol (module->library,
295                          "g_io_module_load",
296                          (gpointer) &module->load) ||
297       ! g_module_symbol (module->library,
298                          "g_io_module_unload",
299                          (gpointer) &module->unload))
300     {
301       g_printerr ("%s\n", g_module_error ());
302       g_module_close (module->library);
303
304       return FALSE;
305     }
306
307   /* Initialize the loaded module */
308   module->load (module);
309   module->initialized = TRUE;
310
311   return TRUE;
312 }
313
314 static void
315 g_io_module_unload_module (GTypeModule *gmodule)
316 {
317   GIOModule *module = G_IO_MODULE (gmodule);
318
319   module->unload (module);
320
321   g_module_close (module->library);
322   module->library = NULL;
323
324   module->load   = NULL;
325   module->unload = NULL;
326 }
327
328 /**
329  * g_io_module_new:
330  * @filename: filename of the shared library module.
331  * 
332  * Creates a new GIOModule that will load the specific
333  * shared library when in use.
334  * 
335  * Returns: a #GIOModule from given @filename, 
336  * or %NULL on error.
337  **/
338 GIOModule *
339 g_io_module_new (const gchar *filename)
340 {
341   GIOModule *module;
342
343   g_return_val_if_fail (filename != NULL, NULL);
344
345   module = g_object_new (G_IO_TYPE_MODULE, NULL);
346   module->filename = g_strdup (filename);
347
348   return module;
349 }
350
351 static gboolean
352 is_valid_module_name (const gchar        *basename,
353                       GIOModuleScope     *scope)
354 {
355   gboolean result;
356
357 #if !defined(G_OS_WIN32) && !defined(G_WITH_CYGWIN)
358   if (!g_str_has_prefix (basename, "lib") ||
359       !g_str_has_suffix (basename, ".so"))
360     return FALSE;
361 #else
362   if (!g_str_has_suffix (basename, ".dll"))
363     return FALSE;
364 #endif
365
366   result = TRUE;
367   if (scope)
368     {
369       result = _g_io_module_scope_contains (scope, basename) ? FALSE : TRUE;
370       if (result && (scope->flags & G_IO_MODULE_SCOPE_BLOCK_DUPLICATES))
371         g_io_module_scope_block (scope, basename);
372     }
373
374   return result;
375 }
376
377
378 /**
379  * g_io_modules_scan_all_in_directory_with_scope:
380  * @dirname: pathname for a directory containing modules to scan.
381  * @scope: a scope to use when scanning the modules
382  *
383  * Scans all the modules in the specified directory, ensuring that
384  * any extension point implemented by a module is registered.
385  *
386  * This may not actually load and initialize all the types in each
387  * module, some modules may be lazily loaded and initialized when
388  * an extension point it implementes is used with e.g.
389  * g_io_extension_point_get_extensions() or
390  * g_io_extension_point_get_extension_by_name().
391  *
392  * If you need to guarantee that all types are loaded in all the modules,
393  * use g_io_modules_load_all_in_directory().
394  *
395  * Since: 2.30
396  **/
397 void
398 g_io_modules_scan_all_in_directory_with_scope (const char     *dirname,
399                                                GIOModuleScope *scope)
400 {
401   const gchar *name;
402   char *filename;
403   GDir *dir;
404   GStatBuf statbuf;
405   char *data;
406   time_t cache_mtime;
407   GHashTable *cache;
408
409   if (!g_module_supported ())
410     return;
411
412   dir = g_dir_open (dirname, 0, NULL);
413   if (!dir)
414     return;
415
416   filename = g_build_filename (dirname, "giomodule.cache", NULL);
417
418   cache = g_hash_table_new_full (g_str_hash, g_str_equal,
419                                  g_free, (GDestroyNotify)g_strfreev);
420
421   cache_mtime = 0;
422   if (g_stat (filename, &statbuf) == 0 &&
423       g_file_get_contents (filename, &data, NULL, NULL))
424     {
425       char **lines;
426       int i;
427
428       /* Cache mtime is the time the cache file was created, any file
429        * that has a ctime before this was created then and not modified
430        * since then (userspace can't change ctime). Its possible to change
431        * the ctime forward without changing the file content, by e.g.
432        * chmoding the file, but this is uncommon and will only cause us
433        * to not use the cache so will not cause bugs.
434        */
435       cache_mtime = statbuf.st_mtime;
436
437       lines = g_strsplit (data, "\n", -1);
438       g_free (data);
439
440       for (i = 0;  lines[i] != NULL; i++)
441         {
442           char *line = lines[i];
443           char *file;
444           char *colon;
445           char **extension_points;
446
447           if (line[0] == '#')
448             continue;
449
450           colon = strchr (line, ':');
451           if (colon == NULL || line == colon)
452             continue; /* Invalid line, ignore */
453
454           *colon = 0; /* terminate filename */
455           file = g_strdup (line);
456           colon++; /* after colon */
457
458           while (g_ascii_isspace (*colon))
459             colon++;
460
461           extension_points = g_strsplit (colon, ",", -1);
462           g_hash_table_insert (cache, file, extension_points);
463         }
464       g_strfreev (lines);
465     }
466
467   while ((name = g_dir_read_name (dir)))
468     {
469       if (is_valid_module_name (name, scope))
470         {
471           GIOExtensionPoint *extension_point;
472           GIOModule *module;
473           gchar *path;
474           char **extension_points;
475           int i;
476
477           path = g_build_filename (dirname, name, NULL);
478           module = g_io_module_new (path);
479
480           extension_points = g_hash_table_lookup (cache, name);
481           if (extension_points != NULL &&
482               g_stat (path, &statbuf) == 0 &&
483               statbuf.st_ctime <= cache_mtime)
484             {
485               /* Lazy load/init the library when first required */
486               for (i = 0; extension_points[i] != NULL; i++)
487                 {
488                   extension_point =
489                     g_io_extension_point_register (extension_points[i]);
490                   extension_point->lazy_load_modules =
491                     g_list_prepend (extension_point->lazy_load_modules,
492                                     module);
493                 }
494             }
495           else
496             {
497               /* Try to load and init types */
498               if (g_type_module_use (G_TYPE_MODULE (module)))
499                 g_type_module_unuse (G_TYPE_MODULE (module)); /* Unload */
500               else
501                 { /* Failure to load */
502                   g_printerr ("Failed to load module: %s\n", path);
503                   g_object_unref (module);
504                   g_free (path);
505                   continue;
506                 }
507             }
508
509           g_free (path);
510         }
511     }
512
513   g_dir_close (dir);
514
515   g_hash_table_destroy (cache);
516
517   g_free (filename);
518 }
519
520 /**
521  * g_io_modules_scan_all_in_directory:
522  * @dirname: pathname for a directory containing modules to scan.
523  *
524  * Scans all the modules in the specified directory, ensuring that
525  * any extension point implemented by a module is registered.
526  *
527  * This may not actually load and initialize all the types in each
528  * module, some modules may be lazily loaded and initialized when
529  * an extension point it implementes is used with e.g.
530  * g_io_extension_point_get_extensions() or
531  * g_io_extension_point_get_extension_by_name().
532  *
533  * If you need to guarantee that all types are loaded in all the modules,
534  * use g_io_modules_load_all_in_directory().
535  *
536  * Since: 2.24
537  **/
538 void
539 g_io_modules_scan_all_in_directory (const char *dirname)
540 {
541   g_io_modules_scan_all_in_directory_with_scope (dirname, NULL);
542 }
543
544 /**
545  * g_io_modules_load_all_in_directory_with_scope:
546  * @dirname: pathname for a directory containing modules to load.
547  * @scope: a scope to use when scanning the modules.
548  *
549  * Loads all the modules in the specified directory.
550  *
551  * If don't require all modules to be initialized (and thus registering
552  * all gtypes) then you can use g_io_modules_scan_all_in_directory()
553  * which allows delayed/lazy loading of modules.
554  *
555  * Returns: (element-type GIOModule) (transfer full): a list of #GIOModules loaded
556  *      from the directory,
557  *      All the modules are loaded into memory, if you want to
558  *      unload them (enabling on-demand loading) you must call
559  *      g_type_module_unuse() on all the modules. Free the list
560  *      with g_list_free().
561  *
562  * Since: 2.30
563  **/
564 GList *
565 g_io_modules_load_all_in_directory_with_scope (const char     *dirname,
566                                                GIOModuleScope *scope)
567 {
568   const gchar *name;
569   GDir        *dir;
570   GList *modules;
571
572   if (!g_module_supported ())
573     return NULL;
574
575   dir = g_dir_open (dirname, 0, NULL);
576   if (!dir)
577     return NULL;
578
579   modules = NULL;
580   while ((name = g_dir_read_name (dir)))
581     {
582       if (is_valid_module_name (name, scope))
583         {
584           GIOModule *module;
585           gchar     *path;
586
587           path = g_build_filename (dirname, name, NULL);
588           module = g_io_module_new (path);
589
590           if (!g_type_module_use (G_TYPE_MODULE (module)))
591             {
592               g_printerr ("Failed to load module: %s\n", path);
593               g_object_unref (module);
594               g_free (path);
595               continue;
596             }
597           
598           g_free (path);
599
600           modules = g_list_prepend (modules, module);
601         }
602     }
603   
604   g_dir_close (dir);
605
606   return modules;
607 }
608
609 /**
610  * g_io_modules_load_all_in_directory:
611  * @dirname: pathname for a directory containing modules to load.
612  *
613  * Loads all the modules in the specified directory.
614  *
615  * If don't require all modules to be initialized (and thus registering
616  * all gtypes) then you can use g_io_modules_scan_all_in_directory()
617  * which allows delayed/lazy loading of modules.
618  *
619  * Returns: (element-type GIOModule) (transfer full): a list of #GIOModules loaded
620  *      from the directory,
621  *      All the modules are loaded into memory, if you want to
622  *      unload them (enabling on-demand loading) you must call
623  *      g_type_module_unuse() on all the modules. Free the list
624  *      with g_list_free().
625  **/
626 GList *
627 g_io_modules_load_all_in_directory (const char *dirname)
628 {
629   return g_io_modules_load_all_in_directory_with_scope (dirname, NULL);
630 }
631
632 G_LOCK_DEFINE_STATIC (registered_extensions);
633 G_LOCK_DEFINE_STATIC (loaded_dirs);
634
635 extern GType _g_fen_directory_monitor_get_type (void);
636 extern GType _g_fen_file_monitor_get_type (void);
637 extern GType _g_inotify_directory_monitor_get_type (void);
638 extern GType _g_inotify_file_monitor_get_type (void);
639 extern GType _g_unix_volume_monitor_get_type (void);
640 extern GType _g_local_vfs_get_type (void);
641
642 extern GType _g_win32_volume_monitor_get_type (void);
643 extern GType g_win32_directory_monitor_get_type (void);
644 extern GType _g_winhttp_vfs_get_type (void);
645
646 extern GType _g_dummy_proxy_resolver_get_type (void);
647 extern GType _g_dummy_tls_backend_get_type (void);
648
649 #ifdef G_PLATFORM_WIN32
650
651 #include <windows.h>
652
653 static HMODULE gio_dll = NULL;
654
655 #ifdef DLL_EXPORT
656
657 BOOL WINAPI
658 DllMain (HINSTANCE hinstDLL,
659          DWORD     fdwReason,
660          LPVOID    lpvReserved)
661 {
662   if (fdwReason == DLL_PROCESS_ATTACH)
663       gio_dll = hinstDLL;
664
665   return TRUE;
666 }
667
668 #endif
669
670 #undef GIO_MODULE_DIR
671
672 /* GIO_MODULE_DIR is used only in code called just once,
673  * so no problem leaking this
674  */
675 #define GIO_MODULE_DIR \
676   g_build_filename (g_win32_get_package_installation_directory_of_module (gio_dll), \
677                     "lib/gio/modules", \
678                     NULL)
679
680 #endif
681
682 void
683 _g_io_modules_ensure_extension_points_registered (void)
684 {
685   static gboolean registered_extensions = FALSE;
686   GIOExtensionPoint *ep;
687
688   G_LOCK (registered_extensions);
689   
690   if (!registered_extensions)
691     {
692       registered_extensions = TRUE;
693       
694 #ifdef G_OS_UNIX
695 #if !GLIB_CHECK_VERSION (3, 0, 0)
696       ep = g_io_extension_point_register (G_DESKTOP_APP_INFO_LOOKUP_EXTENSION_POINT_NAME);
697       g_io_extension_point_set_required_type (ep, G_TYPE_DESKTOP_APP_INFO_LOOKUP);
698 #endif
699 #endif
700       
701       ep = g_io_extension_point_register (G_LOCAL_DIRECTORY_MONITOR_EXTENSION_POINT_NAME);
702       g_io_extension_point_set_required_type (ep, G_TYPE_LOCAL_DIRECTORY_MONITOR);
703       
704       ep = g_io_extension_point_register (G_LOCAL_FILE_MONITOR_EXTENSION_POINT_NAME);
705       g_io_extension_point_set_required_type (ep, G_TYPE_LOCAL_FILE_MONITOR);
706       
707       ep = g_io_extension_point_register (G_VOLUME_MONITOR_EXTENSION_POINT_NAME);
708       g_io_extension_point_set_required_type (ep, G_TYPE_VOLUME_MONITOR);
709       
710       ep = g_io_extension_point_register (G_NATIVE_VOLUME_MONITOR_EXTENSION_POINT_NAME);
711       g_io_extension_point_set_required_type (ep, G_TYPE_NATIVE_VOLUME_MONITOR);
712       
713       ep = g_io_extension_point_register (G_VFS_EXTENSION_POINT_NAME);
714       g_io_extension_point_set_required_type (ep, G_TYPE_VFS);
715
716       ep = g_io_extension_point_register ("gsettings-backend");
717       g_io_extension_point_set_required_type (ep, G_TYPE_OBJECT);
718
719       ep = g_io_extension_point_register (G_PROXY_RESOLVER_EXTENSION_POINT_NAME);
720       g_io_extension_point_set_required_type (ep, G_TYPE_PROXY_RESOLVER);
721
722       ep = g_io_extension_point_register (G_PROXY_EXTENSION_POINT_NAME);
723       g_io_extension_point_set_required_type (ep, G_TYPE_PROXY);
724
725       ep = g_io_extension_point_register (G_TLS_BACKEND_EXTENSION_POINT_NAME);
726       g_io_extension_point_set_required_type (ep, G_TYPE_TLS_BACKEND);
727     }
728   
729   G_UNLOCK (registered_extensions);
730  }
731
732 void
733 _g_io_modules_ensure_loaded (void)
734 {
735   static gboolean loaded_dirs = FALSE;
736   const char *module_path;
737   GIOModuleScope *scope;
738
739   _g_io_modules_ensure_extension_points_registered ();
740   
741   G_LOCK (loaded_dirs);
742
743   if (!loaded_dirs)
744     {
745       loaded_dirs = TRUE;
746       scope = g_io_module_scope_new (G_IO_MODULE_SCOPE_BLOCK_DUPLICATES);
747
748       /* First load any overrides, extras */
749       module_path = g_getenv ("GIO_EXTRA_MODULES");
750       if (module_path)
751         {
752           gchar **paths;
753           int i;
754
755           paths = g_strsplit (module_path, ":", 0);
756
757           for (i = 0; paths[i] != NULL; i++)
758             {
759               g_io_modules_scan_all_in_directory_with_scope (paths[i], scope);
760             }
761
762           g_strfreev (paths);
763         }
764
765       /* Then load the compiled in path */
766       g_io_modules_scan_all_in_directory_with_scope (GIO_MODULE_DIR, scope);
767
768       g_io_module_scope_free (scope);
769
770       /* Initialize types from built-in "modules" */
771       g_null_settings_backend_get_type ();
772       g_memory_settings_backend_get_type ();
773 #if defined(HAVE_SYS_INOTIFY_H) || defined(HAVE_LINUX_INOTIFY_H)
774       _g_inotify_directory_monitor_get_type ();
775       _g_inotify_file_monitor_get_type ();
776 #endif
777 #if defined(HAVE_FEN)
778       _g_fen_directory_monitor_get_type ();
779       _g_fen_file_monitor_get_type ();
780 #endif
781 #ifdef G_OS_WIN32
782       _g_win32_volume_monitor_get_type ();
783       g_win32_directory_monitor_get_type ();
784       g_registry_backend_get_type ();
785 #endif
786 #ifdef G_OS_UNIX
787       _g_unix_volume_monitor_get_type ();
788 #endif
789 #ifdef G_OS_WIN32
790       _g_winhttp_vfs_get_type ();
791 #endif
792       _g_local_vfs_get_type ();
793       _g_dummy_proxy_resolver_get_type ();
794       _g_socks4a_proxy_get_type ();
795       _g_socks4_proxy_get_type ();
796       _g_socks5_proxy_get_type ();
797       _g_dummy_tls_backend_get_type ();
798     }
799
800   G_UNLOCK (loaded_dirs);
801 }
802
803 static void
804 g_io_extension_point_free (GIOExtensionPoint *ep)
805 {
806   g_free (ep->name);
807   g_free (ep);
808 }
809
810 /**
811  * g_io_extension_point_register:
812  * @name: The name of the extension point
813  *
814  * Registers an extension point.
815  *
816  * Returns: (transfer none): the new #GIOExtensionPoint. This object is
817  *    owned by GIO and should not be freed.
818  */
819 GIOExtensionPoint *
820 g_io_extension_point_register (const char *name)
821 {
822   GIOExtensionPoint *ep;
823   
824   G_LOCK (extension_points);
825   if (extension_points == NULL)
826     extension_points = g_hash_table_new_full (g_str_hash,
827                                               g_str_equal,
828                                               NULL,
829                                               (GDestroyNotify)g_io_extension_point_free);
830
831   ep = g_hash_table_lookup (extension_points, name);
832   if (ep != NULL)
833     {
834       G_UNLOCK (extension_points);
835       return ep;
836     }
837
838   ep = g_new0 (GIOExtensionPoint, 1);
839   ep->name = g_strdup (name);
840   
841   g_hash_table_insert (extension_points, ep->name, ep);
842   
843   G_UNLOCK (extension_points);
844
845   return ep;
846 }
847
848 /**
849  * g_io_extension_point_lookup:
850  * @name: the name of the extension point
851  *
852  * Looks up an existing extension point.
853  *
854  * Returns: (transfer none): the #GIOExtensionPoint, or %NULL if there
855  *    is no registered extension point with the given name.
856  */
857 GIOExtensionPoint *
858 g_io_extension_point_lookup (const char *name)
859 {
860   GIOExtensionPoint *ep;
861
862   G_LOCK (extension_points);
863   ep = NULL;
864   if (extension_points != NULL)
865     ep = g_hash_table_lookup (extension_points, name);
866   
867   G_UNLOCK (extension_points);
868
869   return ep;
870   
871 }
872
873 /**
874  * g_io_extension_point_set_required_type:
875  * @extension_point: a #GIOExtensionPoint
876  * @type: the #GType to require
877  *
878  * Sets the required type for @extension_point to @type. 
879  * All implementations must henceforth have this type.
880  */
881 void
882 g_io_extension_point_set_required_type (GIOExtensionPoint *extension_point,
883                                         GType              type)
884 {
885   extension_point->required_type = type;
886 }
887
888 /**
889  * g_io_extension_point_get_required_type:
890  * @extension_point: a #GIOExtensionPoint
891  *
892  * Gets the required type for @extension_point.
893  *
894  * Returns: the #GType that all implementations must have, 
895  *     or #G_TYPE_INVALID if the extension point has no required type
896  */
897 GType
898 g_io_extension_point_get_required_type (GIOExtensionPoint *extension_point)
899 {
900   return extension_point->required_type;
901 }
902
903 void
904 lazy_load_modules (GIOExtensionPoint *extension_point)
905 {
906   GIOModule *module;
907   GList *l;
908
909   for (l = extension_point->lazy_load_modules; l != NULL; l = l->next)
910     {
911       module = l->data;
912
913       if (!module->initialized)
914         {
915           if (g_type_module_use (G_TYPE_MODULE (module)))
916             g_type_module_unuse (G_TYPE_MODULE (module)); /* Unload */
917           else
918             g_printerr ("Failed to load module: %s\n",
919                         module->filename);
920         }
921     }
922 }
923
924 /**
925  * g_io_extension_point_get_extensions:
926  * @extension_point: a #GIOExtensionPoint
927  *
928  * Gets a list of all extensions that implement this extension point.
929  * The list is sorted by priority, beginning with the highest priority.
930  *
931  * Returns: (element-type GIOExtension) (transfer none): a #GList of
932  * #GIOExtension<!-- -->s. The list is owned by GIO and should not be
933  * modified.
934  */
935 GList *
936 g_io_extension_point_get_extensions (GIOExtensionPoint *extension_point)
937 {
938   lazy_load_modules (extension_point);
939   return extension_point->extensions;
940 }
941
942 /**
943  * g_io_extension_point_get_extension_by_name:
944  * @extension_point: a #GIOExtensionPoint
945  * @name: the name of the extension to get
946  *
947  * Finds a #GIOExtension for an extension point by name.
948  *
949  * Returns: (transfer none): the #GIOExtension for @extension_point that has the
950  *    given name, or %NULL if there is no extension with that name
951  */
952 GIOExtension *
953 g_io_extension_point_get_extension_by_name (GIOExtensionPoint *extension_point,
954                                             const char        *name)
955 {
956   GList *l;
957
958   lazy_load_modules (extension_point);
959   for (l = extension_point->extensions; l != NULL; l = l->next)
960     {
961       GIOExtension *e = l->data;
962
963       if (e->name != NULL &&
964           strcmp (e->name, name) == 0)
965         return e;
966     }
967   
968   return NULL;
969 }
970
971 static gint
972 extension_prio_compare (gconstpointer  a,
973                         gconstpointer  b)
974 {
975   const GIOExtension *extension_a = a, *extension_b = b;
976
977   if (extension_a->priority > extension_b->priority)
978     return -1;
979
980   if (extension_b->priority > extension_a->priority)
981     return 1;
982
983   return 0;
984 }
985
986 /**
987  * g_io_extension_point_implement:
988  * @extension_point_name: the name of the extension point
989  * @type: the #GType to register as extension 
990  * @extension_name: the name for the extension
991  * @priority: the priority for the extension
992  *
993  * Registers @type as extension for the extension point with name
994  * @extension_point_name. 
995  *
996  * If @type has already been registered as an extension for this 
997  * extension point, the existing #GIOExtension object is returned.
998  *
999  * Returns: (transfer none): a #GIOExtension object for #GType
1000  */
1001 GIOExtension *
1002 g_io_extension_point_implement (const char *extension_point_name,
1003                                 GType       type,
1004                                 const char *extension_name,
1005                                 gint        priority)
1006 {
1007   GIOExtensionPoint *extension_point;
1008   GIOExtension *extension;
1009   GList *l;
1010
1011   g_return_val_if_fail (extension_point_name != NULL, NULL);
1012
1013   extension_point = g_io_extension_point_lookup (extension_point_name);
1014   if (extension_point == NULL)
1015     {
1016       g_warning ("Tried to implement non-registered extension point %s", extension_point_name);
1017       return NULL;
1018     }
1019   
1020   if (extension_point->required_type != 0 &&
1021       !g_type_is_a (type, extension_point->required_type))
1022     {
1023       g_warning ("Tried to register an extension of the type %s to extension point %s. "
1024                  "Expected type is %s.",
1025                  g_type_name (type),
1026                  extension_point_name, 
1027                  g_type_name (extension_point->required_type));
1028       return NULL;
1029     }      
1030
1031   /* It's safe to register the same type multiple times */
1032   for (l = extension_point->extensions; l != NULL; l = l->next)
1033     {
1034       extension = l->data;
1035       if (extension->type == type)
1036         return extension;
1037     }
1038   
1039   extension = g_slice_new0 (GIOExtension);
1040   extension->type = type;
1041   extension->name = g_strdup (extension_name);
1042   extension->priority = priority;
1043   
1044   extension_point->extensions = g_list_insert_sorted (extension_point->extensions,
1045                                                       extension, extension_prio_compare);
1046   
1047   return extension;
1048 }
1049
1050 /**
1051  * g_io_extension_ref_class:
1052  * @extension: a #GIOExtension
1053  *
1054  * Gets a reference to the class for the type that is 
1055  * associated with @extension.
1056  *
1057  * Returns: (transfer full): the #GTypeClass for the type of @extension
1058  */
1059 GTypeClass *
1060 g_io_extension_ref_class (GIOExtension *extension)
1061 {
1062   return g_type_class_ref (extension->type);
1063 }
1064
1065 /**
1066  * g_io_extension_get_type:
1067  * @extension: a #GIOExtension
1068  *
1069  * Gets the type associated with @extension.
1070  *
1071  * Returns: the type of @extension
1072  */
1073 GType
1074 g_io_extension_get_type (GIOExtension *extension)
1075 {
1076   return extension->type;
1077 }
1078
1079 /**
1080  * g_io_extension_get_name:
1081  * @extension: a #GIOExtension
1082  *
1083  * Gets the name under which @extension was registered.
1084  *
1085  * Note that the same type may be registered as extension
1086  * for multiple extension points, under different names.
1087  *
1088  * Returns: the name of @extension.
1089  */
1090 const char *
1091 g_io_extension_get_name (GIOExtension *extension)
1092 {
1093   return extension->name;
1094 }
1095
1096 /**
1097  * g_io_extension_get_priority:
1098  * @extension: a #GIOExtension
1099  *
1100  * Gets the priority with which @extension was registered.
1101  *
1102  * Returns: the priority of @extension
1103  */
1104 gint
1105 g_io_extension_get_priority (GIOExtension *extension)
1106 {
1107   return extension->priority;
1108 }