Browse Source

Probe volume matching the UUID specified in the configuration file.

Code cleanup.
master
Andrea Luzzardi 18 years ago
parent
commit
3ff74046c8
15 changed files with 183 additions and 225 deletions
  1. +15
    -10
      pam_usb/src/conf.c
  2. +1
    -0
      pam_usb/src/conf.h
  3. +3
    -10
      pam_usb/src/conf.xml
  4. +23
    -47
      pam_usb/src/device.c
  5. +1
    -1
      pam_usb/src/device.h
  6. +17
    -17
      pam_usb/src/hal.c
  7. +15
    -15
      pam_usb/src/hal.h
  8. +1
    -1
      pam_usb/src/log.h
  9. +23
    -21
      pam_usb/src/otp.c
  10. +1
    -2
      pam_usb/src/otp.h
  11. +1
    -1
      pam_usb/src/test.c
  12. +51
    -68
      pam_usb/src/volume.c
  13. +2
    -3
      pam_usb/src/volume.h
  14. +17
    -17
      pam_usb/src/xpath.c
  15. +12
    -12
      pam_usb/src/xpath.h

+ 15
- 10
pam_usb/src/conf.c View File

@ -29,9 +29,11 @@ static void pusb_conf_options_get_from(t_pusb_options *opts,
pusb_xpath_get_string_from(doc, from, "option[@name='hostname']",
opts->hostname, sizeof(opts->hostname));
pusb_xpath_get_string_from(doc, from, "option[@name='system_otp_directory']",
opts->system_otp_directory, sizeof(opts->system_otp_directory));
opts->system_otp_directory,
sizeof(opts->system_otp_directory));
pusb_xpath_get_string_from(doc, from, "option[@name='device_otp_directory']",
opts->device_otp_directory, sizeof(opts->device_otp_directory));
opts->device_otp_directory,
sizeof(opts->device_otp_directory));
pusb_xpath_get_bool_from(doc, from, "option[@name='debug']",
&(opts->debug));
pusb_xpath_get_bool_from(doc, from, "option[@name='enable']",
@ -112,6 +114,9 @@ static int pusb_conf_parse_device(t_pusb_options *opts, xmlDoc *doc)
if (!pusb_conf_device_get_property(opts, doc, "serial", opts->device.serial,
sizeof(opts->device.serial)))
return (0);
pusb_conf_device_get_property(opts, doc, "volume_uuid",
opts->device.volume_uuid,
sizeof(opts->device.volume_uuid));
return (1);
}
@ -136,14 +141,14 @@ int pusb_conf_init(t_pusb_options *opts)
static void pusb_conf_dump(t_pusb_options *opts)
{
log_debug("Configuration dump:\n");
log_debug("enable:\t\t\t%d\n", opts->enable);
log_debug("probe_timeout:\t\t%d\n", opts->probe_timeout);
log_debug("try_otp:\t\t\t%d\n", opts->try_otp);
log_debug("enforce_otp:\t\t%d\n", opts->enforce_otp);
log_debug("debug:\t\t\t%d\n", opts->debug);
log_debug("hostname:\t\t%s\n", opts->hostname);
log_debug("system_otp_directory:\t%s\n", opts->system_otp_directory);
log_debug("device_otp_directory:\t%s\n", opts->device_otp_directory);
log_debug("enable\t\t\t: %s\n", opts->enable ? "true" : "false");
log_debug("debug\t\t\t: %s\n", opts->debug ? "true" : "false");
log_debug("try_otp\t\t\t: %s\n", opts->try_otp ? "true" : "false");
log_debug("enforce_otp\t\t: %s\n", opts->enforce_otp ? "true" : "false");
log_debug("probe_timeout\t\t: %d\n", opts->probe_timeout);
log_debug("hostname\t\t\t: %s\n", opts->hostname);
log_debug("system_otp_directory\t: %s\n", opts->system_otp_directory);
log_debug("device_otp_directory\t: %s\n", opts->device_otp_directory);
}


+ 1
- 0
pam_usb/src/conf.h View File

@ -28,6 +28,7 @@ typedef struct pusb_device
char vendor[32];
char model[32];
char serial[64];
char volume_uuid[32];
} t_pusb_device;
typedef struct pusb_options


+ 3
- 10
pam_usb/src/conf.xml View File

@ -1,27 +1,20 @@
<configuration>
<defaults>
<option name="hostname">foobar</option>
<option name="debug">true</option>
<option name="try_otp">true</option>
<option name="enforce_otp">false</option>
<option name="probe_timeout">10</option>
<option name="debug">false</option>
<!-- <option name="system_otp_directory">.</option>
<option name="device_otp_directory">.auth</option> -->
</defaults>
<devices>
<device id="foobar">
<vendor>SanDisk</vendor>
<model>Cruzer Titanium</model>
<serial>SanDisk_Cruzer_Titanium_SNDKB882652FC4A03701</serial>
</device>
</devices>
<devices>
<device id="foobar2">
<vendor>SanDisk Corp.</vendor>
<model>Cruzer Titanium</model>
<serial>SNDKB882652FC4A03701</serial>
<volume_uuid>3B69-1AFD</volume_uuid>
</device>
</devices>
@ -32,7 +25,7 @@
</user>
<user id="root">
<device>foobar2</device>
<device>foobar</device>
<option name="enforce_otp">true</option>
</user>
</users>


+ 23
- 47
pam_usb/src/device.c View File

@ -17,6 +17,7 @@
#include <unistd.h>
#include <string.h>
#include <dbus/dbus.h>
#include <libhal-storage.h>
#include "conf.h"
#include "hal.h"
@ -24,73 +25,51 @@
#include "otp.h"
#include "device.h"
static LibHalDrive *pusb_device_get_storage(t_pusb_options *opts, LibHalContext *ctx,
const char *udi)
static int pusb_device_connected(t_pusb_options *opts, LibHalContext *ctx)
{
char *phy_udi = NULL;
char *storage_udi = NULL;
int maxloop = 0;
LibHalDrive *drive = NULL;
char *udi = NULL;
log_info("Probing storage device (this could take a while)...\n");
while (!(phy_udi = pusb_hal_find_item(ctx,
"info.parent", udi,
"info.bus", "usb",
NULL)))
usleep(250000);
maxloop = ((opts->probe_timeout * 1000000) / 250000);
while (maxloop > 0 &&
(!(storage_udi = pusb_hal_find_item(ctx,
"storage.physical_device", phy_udi,
"info.category", "storage",
NULL)) || strstr(storage_udi, "temp")))
{
if (storage_udi)
libhal_free_string(storage_udi);
--maxloop;
usleep(250000);
}
libhal_free_string(phy_udi);
if (storage_udi)
log_debug("Searching for \"%s\" in the hardware database...\n",
opts->device.name);
udi = pusb_hal_find_item(ctx,
"usb_device.serial", opts->device.serial,
"usb_device.vendor", opts->device.vendor,
"info.product", opts->device.model,
NULL);
if (!udi)
{
drive = libhal_drive_from_udi(ctx, storage_udi);
libhal_free_string(storage_udi);
log_error("Device \"%s\" is not connected.\n",
opts->device.name);
return (0);
}
return (drive);
libhal_free_string(udi);
log_info("Device \"%s\" is connected (good).\n", opts->device.name);
return (1);
}
int pusb_device_check(t_pusb_options *opts)
{
DBusConnection *dbus = NULL;
LibHalContext *ctx = NULL;
LibHalDrive *drive = NULL;
char *udi = NULL;
int retval = 0;
log_debug("Connecting to HAL...\n");
if (!(dbus = pusb_hal_dbus_connect()))
return (0);
if (!(ctx = pusb_hal_init(dbus)))
{
pusb_hal_dbus_disconnect(dbus);
return (0);
}
log_debug("Searching for \"%s\" in the hardware database...\n",
opts->device.name);
udi = pusb_hal_find_item(ctx,
"usb_device.serial", opts->device.serial,
"usb_device.vendor", opts->device.vendor,
"info.product", opts->device.model,
NULL);
if (!udi)
if (!pusb_device_connected(opts, ctx))
{
log_error("Device \"%s\" is not connected.\n",
opts->device.name);
pusb_hal_dbus_disconnect(dbus);
libhal_ctx_free(ctx);
return (0);
}
log_info("Device \"%s\" is connected (good).\n", opts->device.name);
if (!opts->try_otp && !opts->enforce_otp)
{
log_debug("One time pad is disabled, no more verifications to do.\n");
@ -99,12 +78,9 @@ int pusb_device_check(t_pusb_options *opts)
else
{
log_info("Performing one time pad verification...\n");
if (!(drive = pusb_device_get_storage(opts, ctx, udi)))
retval = !opts->enforce_otp;
else
retval = pusb_otp_check(opts, ctx, drive);
retval = pusb_otp_check(opts, ctx);
}
libhal_free_string(udi);
pusb_hal_dbus_disconnect(dbus);
libhal_ctx_free(ctx);
return (retval);


+ 1
- 1
pam_usb/src/device.h View File

@ -18,6 +18,6 @@
#ifndef PUSB_DEVICE_H_
# define PUSB_DEVICE_H_
int pusb_device_check(t_pusb_options *opts);
int pusb_device_check(t_pusb_options *opts);
#endif /* !PUSB_DEVICE_H_ */

+ 17
- 17
pam_usb/src/hal.c View File

@ -37,17 +37,17 @@ DBusConnection *pusb_hal_dbus_connect(void)
return (dbus);
}
void pusb_hal_dbus_disconnect(DBusConnection *dbus)
void pusb_hal_dbus_disconnect(DBusConnection *dbus)
{
dbus_connection_close(dbus);
dbus_connection_unref(dbus);
dbus_shutdown();
}
LibHalContext *pusb_hal_init(DBusConnection *dbus)
LibHalContext *pusb_hal_init(DBusConnection *dbus)
{
DBusError error;
LibHalContext *ctx = NULL;
DBusError error;
LibHalContext *ctx = NULL;
dbus_error_init(&error);
if (!(ctx = libhal_ctx_new()))
@ -70,17 +70,17 @@ LibHalContext *pusb_hal_init(DBusConnection *dbus)
return (ctx);
}
void pusb_hal_destroy(LibHalContext *ctx)
void pusb_hal_destroy(LibHalContext *ctx)
{
libhal_ctx_free(ctx);
}
char *pusb_hal_get_property(LibHalContext *ctx,
const char *udi,
const char *name)
char *pusb_hal_get_property(LibHalContext *ctx,
const char *udi,
const char *name)
{
DBusError error;
char *data;
DBusError error;
char *data;
dbus_error_init(&error);
data = libhal_device_get_property_string(ctx, udi,
@ -94,13 +94,13 @@ char *pusb_hal_get_property(LibHalContext *ctx,
return (data);
}
int pusb_hal_check_property(LibHalContext *ctx,
const char *udi,
const char *name,
const char *value)
int pusb_hal_check_property(LibHalContext *ctx,
const char *udi,
const char *name,
const char *value)
{
char *data;
int retval;
char *data;
int retval;
data = pusb_hal_get_property(ctx, udi, name);
if (!data)
@ -163,7 +163,7 @@ char *pusb_hal_find_item(LibHalContext *ctx,
for (i = 0; i < n_devices; ++i)
{
char *key = NULL;
int match = 0;
int match = 1;
va_start(ap, value);
while ((key = va_arg(ap, char *)))


+ 15
- 15
pam_usb/src/hal.h View File

@ -18,20 +18,20 @@
#ifndef PUSB_HAL_H_
# define PUSB_HAL_H_
DBusConnection *pusb_hal_dbus_connect(void);
void pusb_hal_dbus_disconnect(DBusConnection *dbus);
LibHalContext *pusb_hal_init(DBusConnection *dbus);
void pusb_hal_destroy(LibHalContext *ctx);
char *pusb_hal_get_property(LibHalContext *ctx,
const char *udi,
const char *name);
int pusb_hal_check_property(LibHalContext *ctx,
const char *udi,
const char *name,
const char *value);
char *pusb_hal_find_item(LibHalContext *ctx,
const char *property,
const char *value,
...);
DBusConnection *pusb_hal_dbus_connect(void);
void pusb_hal_dbus_disconnect(DBusConnection *dbus);
LibHalContext *pusb_hal_init(DBusConnection *dbus);
void pusb_hal_destroy(LibHalContext *ctx);
char *pusb_hal_get_property(LibHalContext *ctx,
const char *udi,
const char *name);
int pusb_hal_check_property(LibHalContext *ctx,
const char *udi,
const char *name,
const char *value);
char *pusb_hal_find_item(LibHalContext *ctx,
const char *property,
const char *value,
...);
#endif /* !PUSB_HAL_H_ */

+ 1
- 1
pam_usb/src/log.h View File

@ -17,9 +17,9 @@
#ifndef PUSB_LOG_H_
# define PUSB_LOG_H_
# define log_debug(s, ...) __log_debug(__FILE__, __LINE__, s, ##__VA_ARGS__)
void __log_debug(const char *file, int line, const char *fmt, ...);
#define log_debug(s, ...) __log_debug(__FILE__, __LINE__, s, ##__VA_ARGS__)
void log_error(const char *fmt, ...);
void log_info(const char *fmt, ...);


+ 23
- 21
pam_usb/src/otp.c View File

@ -28,8 +28,8 @@
#include "volume.h"
#include "otp.h"
static FILE *pusb_otp_open_device(t_pusb_options *opts, LibHalVolume *volume,
const char *mode)
static FILE *pusb_otp_open_device(t_pusb_options *opts,
LibHalVolume *volume, const char *mode)
{
FILE *f;
char *path;
@ -39,8 +39,8 @@ static FILE *pusb_otp_open_device(t_pusb_options *opts, LibHalVolume *volume,
mnt_point = (char *)libhal_volume_get_mount_point(volume);
if (!mnt_point)
return (NULL);
path_size = strlen(mnt_point) + 1 + strlen(opts->device_otp_directory) + 1 + \
strlen(opts->hostname) + strlen(".otp") + 1;
path_size = strlen(mnt_point) + 1 + strlen(opts->device_otp_directory) + \
1 + strlen(opts->hostname) + strlen(".otp") + 1;
if (!(path = malloc(path_size)))
{
log_error("malloc error!\n");
@ -59,7 +59,7 @@ static FILE *pusb_otp_open_device(t_pusb_options *opts, LibHalVolume *volume,
return (f);
}
static FILE *pusb_otp_open_system(t_pusb_options *opts, const char *mode)
static FILE *pusb_otp_open_system(t_pusb_options *opts, const char *mode)
{
FILE *f;
char *path;
@ -85,12 +85,13 @@ static FILE *pusb_otp_open_system(t_pusb_options *opts, const char *mode)
return (f);
}
static void pusb_otp_update(t_pusb_options *opts, LibHalVolume *volume)
static void pusb_otp_update(t_pusb_options *opts,
LibHalVolume *volume)
{
FILE *f_device = NULL;
FILE *f_system = NULL;
int magic[1024];
int i;
FILE *f_device = NULL;
FILE *f_system = NULL;
int magic[1024];
int i;
if (!(f_device = pusb_otp_open_device(opts, volume, "w+")))
{
@ -118,13 +119,13 @@ static void pusb_otp_update(t_pusb_options *opts, LibHalVolume *volume)
log_debug("One time pads updated.\n");
}
static int pusb_otp_compare(t_pusb_options *opts, LibHalVolume *volume)
static int pusb_otp_compare(t_pusb_options *opts, LibHalVolume *volume)
{
FILE *f_device = NULL;
FILE *f_system = NULL;
int magic_device[1024];
int magic_system[1024];
int retval;
FILE *f_device = NULL;
FILE *f_system = NULL;
int magic_device[1024];
int magic_system[1024];
int retval;
if (!(f_system = pusb_otp_open_system(opts, "r")))
return (1);
@ -134,22 +135,23 @@ static int pusb_otp_compare(t_pusb_options *opts, LibHalVolume *volume)
return (0);
}
log_debug("Loading device pad...\n");
fread(magic_device, sizeof(int), sizeof(magic_device) / sizeof(int), f_device);
fread(magic_device, sizeof(int), sizeof(magic_device) / sizeof(int),
f_device);
log_debug("Loading system pad...\n");
fread(magic_system, sizeof(int), sizeof(magic_system) / sizeof(int), f_system);
fread(magic_system, sizeof(int), sizeof(magic_system) / sizeof(int),
f_system);
retval = memcmp(magic_system, magic_device, sizeof(magic_system));
fclose(f_system);
fclose(f_device);
return (retval == 0);
}
int pusb_otp_check(t_pusb_options *opts, LibHalContext *ctx,
LibHalDrive *drive)
int pusb_otp_check(t_pusb_options *opts, LibHalContext *ctx)
{
LibHalVolume *volume = NULL;
int retval;
volume = pusb_volume_find(opts, ctx, drive);
volume = pusb_volume_get(opts, ctx);
if (!volume)
return (!opts->enforce_otp);
retval = pusb_otp_compare(opts, volume);


+ 1
- 2
pam_usb/src/otp.h View File

@ -18,7 +18,6 @@
#ifndef PUSB_OTP_H_
# define PUSB_OTP_H_
int pusb_otp_check(t_pusb_options *opts, LibHalContext *ctx,
LibHalDrive *drive);
int pusb_otp_check(t_pusb_options *opts, LibHalContext *ctx);
#endif /* !PUSB_OTP_H_ */

+ 1
- 1
pam_usb/src/test.c View File

@ -20,7 +20,7 @@
#include "log.h"
#include "device.h"
int main(int argc, char **argv)
int main(int argc, char **argv)
{
t_pusb_options opts;
int retval;


+ 51
- 68
pam_usb/src/volume.c View File

@ -25,14 +25,16 @@
#include <libhal-storage.h>
#include "conf.h"
#include "log.h"
#include "hal.h"
#include "volume.h"
static int pusb_volume_mount(t_pusb_options *opts, LibHalVolume **volume,
LibHalContext *ctx)
static int pusb_volume_mount(t_pusb_options *opts, LibHalVolume **volume,
LibHalContext *ctx)
{
char command[1024];
char tempname[32];
const char *devname;
const char *udi;
snprintf(tempname, sizeof(tempname), "pam_usb%d", getpid());
if (!(devname = libhal_volume_get_device_file(*volume)))
@ -50,93 +52,74 @@ static int pusb_volume_mount(t_pusb_options *opts, LibHalVolume **volume,
log_error("Mount failed\n");
return (0);
}
else
udi = libhal_volume_get_udi(*volume);
if (!udi)
{
const char *udi;
udi = libhal_volume_get_udi(*volume);
if (!udi)
{
log_error("Unable to retrieve volume UDI\n");
return (0);
}
udi = strdup(udi);
libhal_volume_free(*volume);
*volume = libhal_volume_from_udi(ctx, udi);
free((char *)udi);
log_error("Unable to retrieve volume UDI\n");
return (0);
}
udi = strdup(udi);
libhal_volume_free(*volume);
*volume = libhal_volume_from_udi(ctx, udi);
free((char *)udi);
log_debug("Mount succeeded.\n");
return (1);
}
static int __pusb_volume_find(t_pusb_options *opts, LibHalContext *ctx,
LibHalDrive *drive, LibHalVolume **out)
static LibHalVolume *pusb_volume_probe(t_pusb_options *opts,
LibHalContext *ctx)
{
char **volumes;
int n_volumes = 0;
int i;
LibHalVolume *volume = NULL;
int maxtries = 0;
int i;
*out = NULL;
volumes = libhal_drive_find_all_volumes(ctx, drive, &n_volumes);
if (!n_volumes)
log_debug("Searching for volume with uuid %s\n", opts->device.volume_uuid);
maxtries = ((opts->probe_timeout * 1000000) / 250000);
for (i = 0; i < maxtries; ++i)
{
libhal_free_string_array(volumes);
log_debug("No volumes found\n");
return (1);
}
for (i = 0; i < n_volumes; ++i)
{
LibHalVolume *volume;
char *udi = NULL;
volume = libhal_volume_from_udi(ctx,
volumes[i]);
if (!volume)
continue;
if (libhal_volume_should_ignore(volume))
if (i == 1)
log_info("Probing volume (this could take a while)...\n");
udi = pusb_hal_find_item(ctx,
"volume.uuid", opts->device.volume_uuid,
NULL);
if (!udi)
{
libhal_volume_free(volume);
usleep(250000);
continue;
}
*out = volume;
libhal_free_string_array(volumes);
if (libhal_volume_is_mounted(volume))
{
log_debug("Volume is already mounted\n");
return (1);
}
else
{
if (pusb_volume_mount(opts, &volume, ctx))
return (1);
return (0);
}
volume = libhal_volume_from_udi(ctx, udi);
libhal_free_string(udi);
if (!libhal_volume_should_ignore(volume))
return (volume);
libhal_volume_free(volume);
usleep(250000);
}
libhal_free_string_array(volumes);
return (1);
return (NULL);
}
LibHalVolume *pusb_volume_find(t_pusb_options *opts, LibHalContext *ctx,
LibHalDrive *drive)
LibHalVolume *pusb_volume_get(t_pusb_options *opts, LibHalContext *ctx)
{
LibHalVolume *volume = NULL;
int maxtries = 0;
int i;
LibHalVolume *volume;
maxtries = ((opts->probe_timeout * 1000000) / 250000);
for (i = 0; i < maxtries; ++i)
{
log_debug("Waiting for volumes to come up...\n");
if (!__pusb_volume_find(opts, ctx, drive, &volume))
return (NULL);
if (volume)
break;
usleep(250000);
}
return (volume);
if (!(volume = pusb_volume_probe(opts, ctx)))
return (NULL);
log_debug("Found volume %s\n", opts->device.volume_uuid);
if (libhal_volume_is_mounted(volume))
{
log_debug("Volume is already mounted.\n");
return (volume);
}
if (!pusb_volume_mount(opts, &volume, ctx))
{
libhal_volume_free(volume);
return (NULL);
}
return (volume);
}
void pusb_volume_destroy(LibHalVolume *volume)
void pusb_volume_destroy(LibHalVolume *volume)
{
const char *mntpoint;


+ 2
- 3
pam_usb/src/volume.h View File

@ -18,8 +18,7 @@
#ifndef VOLUME_H_
# define VOLUME_H_
LibHalVolume *pusb_volume_find(t_pusb_options *opts, LibHalContext *ctx,
LibHalDrive *drive);
void pusb_volume_destroy(LibHalVolume *volume);
LibHalVolume *pusb_volume_get(t_pusb_options *opts, LibHalContext *ctx);
void pusb_volume_destroy(LibHalVolume *volume);
#endif /* !VOLUME_H_ */

+ 17
- 17
pam_usb/src/xpath.c View File

@ -80,14 +80,14 @@ int pusb_xpath_get_string(xmlDocPtr doc, const char *path,
return (1);
}
int pusb_xpath_get_string_from(xmlDocPtr doc,
const char *base,
const char *path,
char *value, size_t size)
int pusb_xpath_get_string_from(xmlDocPtr doc,
const char *base,
const char *path,
char *value, size_t size)
{
char *xpath = NULL;
size_t xpath_size;
int retval;
char *xpath = NULL;
size_t xpath_size;
int retval;
xpath_size = strlen(base) + strlen(path) + 1;
if (!(xpath = malloc(xpath_size)))
@ -127,10 +127,10 @@ int pusb_xpath_get_bool(xmlDocPtr doc, const char *path, int *value)
return (0);
}
int pusb_xpath_get_bool_from(xmlDocPtr doc,
const char *base,
const char *path,
int *value)
int pusb_xpath_get_bool_from(xmlDocPtr doc,
const char *base,
const char *path,
int *value)
{
char *xpath = NULL;
size_t xpath_size;
@ -151,9 +151,9 @@ int pusb_xpath_get_bool_from(xmlDocPtr doc,
return (retval);
}
int pusb_xpath_get_int(xmlDocPtr doc, const char *path, int *value)
int pusb_xpath_get_int(xmlDocPtr doc, const char *path, int *value)
{
char ret[64]; /* strlen("false") + 1 */
char ret[64]; /* strlen("false") + 1 */
if (!pusb_xpath_get_string(doc, path, ret, sizeof(ret)))
return (0);
@ -161,10 +161,10 @@ int pusb_xpath_get_int(xmlDocPtr doc, const char *path, int *value)
return (1);
}
int pusb_xpath_get_int_from(xmlDocPtr doc,
const char *base,
const char *path,
int *value)
int pusb_xpath_get_int_from(xmlDocPtr doc,
const char *base,
const char *path,
int *value)
{
char *xpath = NULL;
size_t xpath_size;


+ 12
- 12
pam_usb/src/xpath.h View File

@ -19,17 +19,17 @@
# define PUSB_XPATH_H_
# include <libxml/parser.h>
int pusb_xpath_get_string(xmlDocPtr doc, const char *path, char *value,
size_t size);
int pusb_xpath_get_bool(xmlDocPtr doc, const char *path, int *value);
int pusb_xpath_get_string_from(xmlDocPtr doc, const char *base,
const char *path, char *value, size_t size);
int pusb_xpath_get_bool_from(xmlDocPtr doc, const char *base, const char *path,
int *value);
int pusb_xpath_get_int(xmlDocPtr doc, const char *path, int *value);
int pusb_xpath_get_int_from(xmlDocPtr doc,
const char *base,
const char *path,
int *value);
int pusb_xpath_get_string(xmlDocPtr doc, const char *path, char *value,
size_t size);
int pusb_xpath_get_bool(xmlDocPtr doc, const char *path, int *value);
int pusb_xpath_get_string_from(xmlDocPtr doc, const char *base,
const char *path, char *value, size_t size);
int pusb_xpath_get_bool_from(xmlDocPtr doc, const char *base,
const char *path, int *value);
int pusb_xpath_get_int(xmlDocPtr doc, const char *path, int *value);
int pusb_xpath_get_int_from(xmlDocPtr doc,
const char *base,
const char *path,
int *value);
#endif /* !PUSB_XPATH_H_ */

Loading…
Cancel
Save