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