Port pamusb-agent and pamusb-conf to UDisks.
[pam_usb.git] / src / hal.c
blob6f1201cd202aea93ba29f6ba2e5dfdc4847be83f
1 /*
2 * Copyright (c) 2003-2007 Andrea Luzzardi <scox@sig11.org>
4 * This file is part of the pam_usb project. pam_usb is free software;
5 * you can redistribute it and/or modify it under the terms of the GNU General
6 * Public License version 2, as published by the Free Software Foundation.
8 * pam_usb is distributed in the hope that it will be useful, but WITHOUT ANY
9 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
11 * details.
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
15 * Place, Suite 330, Boston, MA 02111-1307 USA
18 #include <string.h>
19 #include <stdarg.h>
20 #include <unistd.h>
21 #include <sys/types.h>
22 #include <dbus/dbus.h>
23 #include <libhal-storage.h>
24 #include "log.h"
26 DBusConnection *pusb_hal_dbus_connect(void)
28 DBusConnection *dbus = NULL;
29 DBusError error;
31 dbus_error_init(&error);
32 if (!(dbus = dbus_bus_get(DBUS_BUS_SYSTEM, &error)))
34 /* Workaround for https://bugs.freedesktop.org/show_bug.cgi?id=11876 */
35 uid_t ruid;
36 uid_t euid;
38 if (!(euid = geteuid()) && (ruid = getuid()))
40 dbus_error_free(&error);
41 setreuid(euid, euid);
42 dbus = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
43 setreuid(ruid, euid);
45 if (!dbus)
47 log_error("Cannot connect to system bus: %s\n",
48 error.message);
49 dbus_error_free(&error);
50 return (NULL);
53 return (dbus);
56 void pusb_hal_dbus_disconnect(DBusConnection *dbus)
58 dbus_connection_unref(dbus);
61 LibHalContext *pusb_hal_init(DBusConnection *dbus)
63 DBusError error;
64 LibHalContext *ctx = NULL;
66 dbus_error_init(&error);
67 if (!(ctx = libhal_ctx_new()))
69 log_error("Failed to create a HAL context\n");
70 return (NULL);
72 if (!libhal_ctx_set_dbus_connection(ctx, dbus))
74 log_error("Failed to attach dbus connection to hal\n");
75 libhal_ctx_free(ctx);
76 return (NULL);
78 if (!libhal_ctx_init(ctx, &error))
80 log_error("libhal_ctx_init: %s\n", error.name, error.message);
81 libhal_ctx_free(ctx);
82 return (NULL);
84 return (ctx);
87 void pusb_hal_destroy(LibHalContext *ctx)
89 libhal_ctx_free(ctx);
92 char *pusb_hal_get_property(LibHalContext *ctx,
93 const char *udi,
94 const char *name)
96 DBusError error;
97 char *data;
99 dbus_error_init(&error);
100 data = libhal_device_get_property_string(ctx, udi,
101 name, &error);
102 if (!data)
104 log_debug("%s\n", error.message);
105 dbus_error_free(&error);
106 return (NULL);
108 return (data);
111 int pusb_hal_check_property(LibHalContext *ctx,
112 const char *udi,
113 const char *name,
114 const char *value)
116 char *data;
117 int retval;
119 data = pusb_hal_get_property(ctx, udi, name);
120 if (!data)
121 return (0);
122 retval = (strcmp(data, value) == 0);
123 libhal_free_string(data);
124 return (retval);
127 char **pusb_hal_find_all_items(LibHalContext *ctx,
128 const char *property,
129 const char *value,
130 int *count)
133 DBusError error;
134 char **devices;
135 int n_devices;
137 dbus_error_init(&error);
138 *count = 0;
139 devices = libhal_manager_find_device_string_match(ctx,
140 property,
141 value,
142 &n_devices,
143 &error);
144 if (!devices)
146 log_error("Unable to find item \"%s\": %s\n", property,
147 error.message);
148 dbus_error_free(&error);
149 return (NULL);
151 if (!n_devices)
153 libhal_free_string_array(devices);
154 return (NULL);
156 *count = n_devices;
157 return (devices);
160 char *pusb_hal_find_item(LibHalContext *ctx,
161 const char *property,
162 const char *value,
163 ...)
165 char **devices;
166 int n_devices;
167 char *udi = NULL;
168 va_list ap;
169 int i;
171 devices = pusb_hal_find_all_items(ctx, property, value, &n_devices);
172 if (!devices)
173 return (NULL);
174 if (!n_devices)
175 return (NULL);
177 for (i = 0; i < n_devices; ++i)
179 char *key = NULL;
180 int match = 1;
182 va_start(ap, value);
183 while ((key = va_arg(ap, char *)))
185 char *value = NULL;
187 value = va_arg(ap, char *);
188 if (!value || *value == 0x0)
189 continue ;
190 if (!pusb_hal_check_property(ctx, devices[i],
191 key, value))
193 log_debug("%s did match, but property %s didn't (expecting \"%s\")\n",
194 property, key, value);
195 match = 0;
196 break;
199 if (match)
201 udi = strdup(devices[i]);
202 break;
204 va_end(ap);
206 libhal_free_string_array(devices);
207 return (udi);