Branch data Line data Source code
1 : : /* GIO - GLib Input, Output and Streaming Library
2 : : *
3 : : * Copyright (C) 2006-2007 Red Hat, Inc.
4 : : *
5 : : * SPDX-License-Identifier: LGPL-2.1-or-later
6 : : *
7 : : * This library is free software; you can redistribute it and/or
8 : : * modify it under the terms of the GNU Lesser General Public
9 : : * License as published by the Free Software Foundation; either
10 : : * version 2.1 of the License, or (at your option) any later version.
11 : : *
12 : : * This library is distributed in the hope that it will be useful,
13 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 : : * Lesser General Public License for more details.
16 : : *
17 : : * You should have received a copy of the GNU Lesser General
18 : : * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 : : *
20 : : * Author: Alexander Larsson <alexl@redhat.com>
21 : : */
22 : :
23 : : #include "config.h"
24 : :
25 : : #include <gio/gio.h>
26 : : #include "giomodule-priv.h"
27 : :
28 : : #include <gstdio.h>
29 : : #include <errno.h>
30 : : #include <locale.h>
31 : :
32 : : #include "glib/glib-private.h"
33 : :
34 : : static gboolean
35 : 0 : is_valid_module_name (const gchar *basename)
36 : : {
37 : : #if !defined(G_OS_WIN32) && !defined(G_WITH_CYGWIN)
38 : : #if defined(__APPLE__)
39 : : return g_str_has_prefix (basename, "lib") &&
40 : : (g_str_has_suffix (basename, ".so") ||
41 : : g_str_has_suffix (basename, ".dylib"));
42 : : #else
43 : : return
44 : 0 : g_str_has_prefix (basename, "lib") &&
45 : 0 : g_str_has_suffix (basename, ".so");
46 : : #endif
47 : : #else
48 : : return g_str_has_suffix (basename, ".dll");
49 : : #endif
50 : : }
51 : :
52 : : static void
53 : 0 : query_dir (const char *dirname)
54 : : {
55 : : GString *data;
56 : : GDir *dir;
57 : 0 : GList *list = NULL, *iterator = NULL;
58 : : const char *name;
59 : : char *cachename;
60 : : char **(* query) (void);
61 : : GError *error;
62 : : int i;
63 : :
64 : 0 : if (!g_module_supported ())
65 : 0 : return;
66 : :
67 : 0 : error = NULL;
68 : 0 : dir = g_dir_open (dirname, 0, &error);
69 : 0 : if (!dir)
70 : : {
71 : 0 : g_printerr ("Unable to open directory %s: %s\n", dirname, error->message);
72 : 0 : g_error_free (error);
73 : 0 : return;
74 : : }
75 : :
76 : 0 : data = g_string_new ("");
77 : :
78 : 0 : while ((name = g_dir_read_name (dir)))
79 : 0 : list = g_list_prepend (list, g_strdup (name));
80 : :
81 : 0 : list = g_list_sort (list, (GCompareFunc) g_strcmp0);
82 : 0 : for (iterator = list; iterator; iterator = iterator->next)
83 : : {
84 : : GModule *module;
85 : : gchar *path;
86 : : char **extension_points;
87 : :
88 : 0 : name = iterator->data;
89 : 0 : if (!is_valid_module_name (name))
90 : 0 : continue;
91 : :
92 : 0 : path = g_build_filename (dirname, name, NULL);
93 : 0 : module = g_module_open_full (path, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL, &error);
94 : 0 : g_free (path);
95 : :
96 : 0 : if (module)
97 : : {
98 : : gchar *modulename;
99 : : gchar *symname;
100 : :
101 : 0 : modulename = _g_io_module_extract_name (name);
102 : 0 : symname = g_strconcat ("g_io_", modulename, "_query", NULL);
103 : 0 : g_module_symbol (module, symname, (gpointer) &query);
104 : 0 : g_free (symname);
105 : 0 : g_free (modulename);
106 : :
107 : 0 : if (!query)
108 : : {
109 : : /* Fallback to old name */
110 : 0 : g_module_symbol (module, "g_io_module_query", (gpointer) &query);
111 : : }
112 : :
113 : 0 : if (query)
114 : : {
115 : 0 : extension_points = query ();
116 : :
117 : 0 : if (extension_points)
118 : : {
119 : 0 : g_string_append_printf (data, "%s: ", name);
120 : :
121 : 0 : for (i = 0; extension_points[i] != NULL; i++)
122 : 0 : g_string_append_printf (data, "%s%s", i == 0 ? "" : ",", extension_points[i]);
123 : :
124 : 0 : g_string_append (data, "\n");
125 : 0 : g_strfreev (extension_points);
126 : : }
127 : : }
128 : :
129 : 0 : g_module_close (module);
130 : : }
131 : : else
132 : : {
133 : 0 : g_debug ("Failed to open module %s: %s", name, error->message);
134 : : }
135 : :
136 : 0 : g_clear_error (&error);
137 : : }
138 : :
139 : 0 : g_dir_close (dir);
140 : 0 : g_list_free_full (list, g_free);
141 : :
142 : 0 : cachename = g_build_filename (dirname, "giomodule.cache", NULL);
143 : :
144 : 0 : if (data->len > 0)
145 : : {
146 : 0 : error = NULL;
147 : :
148 : 0 : if (!g_file_set_contents (cachename, data->str, data->len, &error))
149 : : {
150 : 0 : g_printerr ("Unable to create %s: %s\n", cachename, error->message);
151 : 0 : g_error_free (error);
152 : : }
153 : : }
154 : : else
155 : : {
156 : 0 : if (g_unlink (cachename) != 0 && errno != ENOENT)
157 : : {
158 : 0 : int errsv = errno;
159 : 0 : g_printerr ("Unable to unlink %s: %s\n", cachename, g_strerror (errsv));
160 : : }
161 : : }
162 : :
163 : 0 : g_free (cachename);
164 : 0 : g_string_free (data, TRUE);
165 : : }
166 : :
167 : : int
168 : 0 : main (gint argc,
169 : : gchar *argv[])
170 : : {
171 : : int i;
172 : :
173 : 0 : if (argc <= 1)
174 : : {
175 : 0 : g_print ("Usage: gio-querymodules <directory1> [<directory2> ...]\n");
176 : 0 : g_print ("Will update giomodule.cache in the listed directories\n");
177 : 0 : return 1;
178 : : }
179 : :
180 : 0 : setlocale (LC_ALL, GLIB_DEFAULT_LOCALE);
181 : :
182 : : /* Be defensive and ensure we're linked to GObject */
183 : 0 : g_type_ensure (G_TYPE_OBJECT);
184 : :
185 : 0 : for (i = 1; i < argc; i++)
186 : 0 : query_dir (argv[i]);
187 : :
188 : 0 : return 0;
189 : : }
|