12912Sartem /***************************************************************************
22912Sartem * CVSID: $Id$
32912Sartem *
42912Sartem * util.c - Various utilities
52912Sartem *
62912Sartem * Copyright (C) 2004 David Zeuthen, <david@fubar.dk>
72912Sartem *
82912Sartem * Licensed under the Academic Free License version 2.1
92912Sartem *
102912Sartem * This program is free software; you can redistribute it and/or modify
112912Sartem * it under the terms of the GNU General Public License as published by
122912Sartem * the Free Software Foundation; either version 2 of the License, or
132912Sartem * (at your option) any later version.
142912Sartem *
152912Sartem * This program is distributed in the hope that it will be useful,
162912Sartem * but WITHOUT ANY WARRANTY; without even the implied warranty of
172912Sartem * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
182912Sartem * GNU General Public License for more details.
192912Sartem *
202912Sartem * You should have received a copy of the GNU General Public License
212912Sartem * along with this program; if not, write to the Free Software
222912Sartem * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
232912Sartem *
242912Sartem **************************************************************************/
252912Sartem
262912Sartem #ifdef HAVE_CONFIG_H
272912Sartem # include <config.h>
282912Sartem #endif
292912Sartem
302912Sartem #include <stdio.h>
312912Sartem #include <stdarg.h>
322912Sartem #include <string.h>
332912Sartem #include <errno.h>
342912Sartem #include <time.h>
352912Sartem #include <ctype.h>
362912Sartem #include <stdint.h>
372912Sartem #include <sys/stat.h>
382912Sartem #include <unistd.h>
392912Sartem #include <fcntl.h>
402912Sartem #include <signal.h>
412912Sartem #include <sys/wait.h>
422912Sartem #include <sys/file.h>
432912Sartem
442912Sartem #include <glib.h>
452912Sartem #include <dbus/dbus.h>
462912Sartem #include <dbus/dbus-glib.h>
472912Sartem
482912Sartem #include "osspec.h"
492912Sartem #include "logger.h"
502912Sartem #include "hald.h"
512912Sartem #include "hald_runner.h"
522912Sartem #include "hald_dbus.h"
532912Sartem #include "device_info.h"
542912Sartem
552912Sartem #include "util.h"
562912Sartem
57*10659SXiao-Lin.Zhang@Sun.COM /** Determine whether the given character is valid as the first character
58*10659SXiao-Lin.Zhang@Sun.COM * in a name.
59*10659SXiao-Lin.Zhang@Sun.COM */
60*10659SXiao-Lin.Zhang@Sun.COM #define VALID_INITIAL_NAME_CHARACTER(c) \
61*10659SXiao-Lin.Zhang@Sun.COM (((c) >= 'A' && (c) <= 'Z') || \
62*10659SXiao-Lin.Zhang@Sun.COM ((c) >= 'a' && (c) <= 'z') || \
63*10659SXiao-Lin.Zhang@Sun.COM ((c) == '_'))
64*10659SXiao-Lin.Zhang@Sun.COM
65*10659SXiao-Lin.Zhang@Sun.COM /** Determine whether the given character is valid as a second or later
66*10659SXiao-Lin.Zhang@Sun.COM * character in a name.
67*10659SXiao-Lin.Zhang@Sun.COM */
68*10659SXiao-Lin.Zhang@Sun.COM #define VALID_NAME_CHARACTER(c) \
69*10659SXiao-Lin.Zhang@Sun.COM (((c) >= '0' && (c) <= '9') || \
70*10659SXiao-Lin.Zhang@Sun.COM ((c) >= 'A' && (c) <= 'Z') || \
71*10659SXiao-Lin.Zhang@Sun.COM ((c) >= 'a' && (c) <= 'z') || \
72*10659SXiao-Lin.Zhang@Sun.COM ((c) == '_'))
73*10659SXiao-Lin.Zhang@Sun.COM
742912Sartem gboolean
hal_util_remove_trailing_slash(gchar * path)752912Sartem hal_util_remove_trailing_slash (gchar *path)
762912Sartem {
772912Sartem gchar *c = NULL;
782912Sartem
792912Sartem if (path == NULL) {
802912Sartem return FALSE;
812912Sartem }
822912Sartem
832912Sartem c = strrchr (path, '/');
842912Sartem if (c == NULL) {
852912Sartem HAL_WARNING (("Invalid path %s", path));
862912Sartem return 1;
872912Sartem }
882912Sartem if (*(c+1) == '\0')
892912Sartem *c = '\0';
902912Sartem
912912Sartem return TRUE;
922912Sartem }
932912Sartem
942912Sartem /** Given a path, /foo/bar/bat/foobar, return the last element, e.g.
952912Sartem * foobar.
962912Sartem *
972912Sartem * @param path Path
982912Sartem * @return Pointer into given string
992912Sartem */
1002912Sartem const gchar *
hal_util_get_last_element(const gchar * s)1012912Sartem hal_util_get_last_element (const gchar *s)
1022912Sartem {
1032912Sartem int len;
1042912Sartem const gchar *p;
1052912Sartem
1062912Sartem len = strlen (s);
1072912Sartem for (p = s + len - 1; p > s; --p) {
1082912Sartem if ((*p) == '/')
1092912Sartem return p + 1;
1102912Sartem }
1112912Sartem
1122912Sartem return s;
1132912Sartem }
1142912Sartem
1152912Sartem /** Given a path, this functions finds the path representing the
1162912Sartem * parent directory by truncation.
1172912Sartem *
1182912Sartem * @param path Path
1192912Sartem * @return Path for parent or NULL. Must be freed by caller
1202912Sartem */
1212912Sartem gchar *
hal_util_get_parent_path(const gchar * path)1222912Sartem hal_util_get_parent_path (const gchar *path)
1232912Sartem {
1242912Sartem guint i;
1252912Sartem guint len;
1262912Sartem gchar *parent_path;
1272912Sartem
1282912Sartem /* Find parent device by truncating our own path */
1292912Sartem parent_path = g_strndup (path, HAL_PATH_MAX);
1302912Sartem len = strlen (parent_path);
1312912Sartem for (i = len - 1; parent_path[i] != '/'; --i) {
1322912Sartem parent_path[i] = '\0';
1332912Sartem }
1342912Sartem parent_path[i] = '\0';
1352912Sartem
1362912Sartem return parent_path;
1372912Sartem }
1382912Sartem
1392912Sartem gchar *
hal_util_get_normalized_path(const gchar * path1,const gchar * path2)1402912Sartem hal_util_get_normalized_path (const gchar *path1, const gchar *path2)
1412912Sartem {
1422912Sartem int len1;
1432912Sartem int len2;
1442912Sartem const gchar *p1;
1452912Sartem const gchar *p2;
1462912Sartem gchar buf[HAL_PATH_MAX];
1472912Sartem
1482912Sartem len1 = strlen (path1);
1492912Sartem len2 = strlen (path2);
1502912Sartem
1512912Sartem p1 = path1 + len1;
1522912Sartem
1532912Sartem p2 = path2;
1542912Sartem while (p2 < path2 + len2 && strncmp (p2, "../", 3) == 0) {
1552912Sartem p2 += 3;
1562912Sartem
1572912Sartem while (p1 >= path1 && *(--p1)!='/')
1582912Sartem ;
1592912Sartem }
1602912Sartem
1612912Sartem if ((p1-path1) < 0) {
1622912Sartem HAL_ERROR (("Could not normalize '%s' and '%s', return 'NULL'", path1, path2));
1632912Sartem return NULL;
1642912Sartem }
1652912Sartem
1662912Sartem strncpy (buf, path1, (p1-path1));
1672912Sartem buf[p1-path1] = '\0';
1682912Sartem
1692912Sartem return g_strdup_printf ("%s/%s", buf, p2);
1702912Sartem }
1712912Sartem
1722912Sartem gboolean
hal_util_get_int_from_file(const gchar * directory,const gchar * file,gint * result,gint base)1732912Sartem hal_util_get_int_from_file (const gchar *directory, const gchar *file, gint *result, gint base)
1742912Sartem {
1752912Sartem FILE *f;
1762912Sartem char buf[64];
1772912Sartem gchar path[HAL_PATH_MAX];
1782912Sartem gboolean ret;
1792912Sartem
1802912Sartem f = NULL;
1812912Sartem ret = FALSE;
1822912Sartem
1832912Sartem g_snprintf (path, sizeof (path), "%s/%s", directory, file);
1842912Sartem
1852912Sartem f = fopen (path, "rb");
1862912Sartem if (f == NULL) {
1872912Sartem HAL_ERROR (("Cannot open '%s'", path));
1882912Sartem goto out;
1892912Sartem }
1902912Sartem
1912912Sartem if (fgets (buf, sizeof (buf), f) == NULL) {
1922912Sartem HAL_ERROR (("Cannot read from '%s'", path));
1932912Sartem goto out;
1942912Sartem }
1952912Sartem
1962912Sartem /* TODO: handle error condition */
1972912Sartem *result = strtol (buf, NULL, base);
1982912Sartem ret = TRUE;
1992912Sartem
2002912Sartem out:
2012912Sartem if (f != NULL)
2022912Sartem fclose (f);
2032912Sartem
2042912Sartem return ret;
2052912Sartem }
2062912Sartem
2072912Sartem gboolean
hal_util_set_int_from_file(HalDevice * d,const gchar * key,const gchar * directory,const gchar * file,gint base)2082912Sartem hal_util_set_int_from_file (HalDevice *d, const gchar *key, const gchar *directory, const gchar *file, gint base)
2092912Sartem {
2102912Sartem gint value;
2112912Sartem gboolean ret;
2122912Sartem
2132912Sartem ret = FALSE;
2142912Sartem
2152912Sartem if (hal_util_get_int_from_file (directory, file, &value, base))
2162912Sartem ret = hal_device_property_set_int (d, key, value);
2172912Sartem
2182912Sartem return ret;
2192912Sartem }
2202912Sartem
2212912Sartem
2222912Sartem gboolean
hal_util_get_uint64_from_file(const gchar * directory,const gchar * file,guint64 * result,gint base)2232912Sartem hal_util_get_uint64_from_file (const gchar *directory, const gchar *file, guint64 *result, gint base)
2242912Sartem {
2252912Sartem FILE *f;
2262912Sartem char buf[64];
2272912Sartem gchar path[HAL_PATH_MAX];
2282912Sartem gboolean ret;
2292912Sartem
2302912Sartem f = NULL;
2312912Sartem ret = FALSE;
2322912Sartem
2332912Sartem g_snprintf (path, sizeof (path), "%s/%s", directory, file);
2342912Sartem
2352912Sartem f = fopen (path, "rb");
2362912Sartem if (f == NULL) {
2372912Sartem HAL_ERROR (("Cannot open '%s'", path));
2382912Sartem goto out;
2392912Sartem }
2402912Sartem
2412912Sartem if (fgets (buf, sizeof (buf), f) == NULL) {
2422912Sartem HAL_ERROR (("Cannot read from '%s'", path));
2432912Sartem goto out;
2442912Sartem }
2452912Sartem
2462912Sartem /* TODO: handle error condition */
2472912Sartem *result = strtoll (buf, NULL, base);
2482912Sartem
2492912Sartem ret = TRUE;
2502912Sartem
2512912Sartem out:
2522912Sartem if (f != NULL)
2532912Sartem fclose (f);
2542912Sartem
2552912Sartem return ret;
2562912Sartem }
2572912Sartem
2582912Sartem gboolean
hal_util_set_uint64_from_file(HalDevice * d,const gchar * key,const gchar * directory,const gchar * file,gint base)2592912Sartem hal_util_set_uint64_from_file (HalDevice *d, const gchar *key, const gchar *directory, const gchar *file, gint base)
2602912Sartem {
2612912Sartem guint64 value;
2622912Sartem gboolean ret;
2632912Sartem
2642912Sartem ret = FALSE;
2652912Sartem
2662912Sartem if (hal_util_get_uint64_from_file (directory, file, &value, base))
2672912Sartem ret = hal_device_property_set_uint64 (d, key, value);
2682912Sartem
2692912Sartem return ret;
2702912Sartem }
2712912Sartem
2722912Sartem gboolean
hal_util_get_bcd2_from_file(const gchar * directory,const gchar * file,gint * result)2732912Sartem hal_util_get_bcd2_from_file (const gchar *directory, const gchar *file, gint *result)
2742912Sartem {
2752912Sartem FILE *f;
2762912Sartem char buf[64];
2772912Sartem gchar path[HAL_PATH_MAX];
2782912Sartem gboolean ret;
2792912Sartem gint digit;
2802912Sartem gint left, right;
2812912Sartem gboolean passed_white_space;
2822912Sartem gint num_prec;
2832912Sartem gsize len;
2842912Sartem gchar c;
2852912Sartem guint i;
2862912Sartem
2872912Sartem f = NULL;
2882912Sartem ret = FALSE;
2892912Sartem
2902912Sartem g_snprintf (path, sizeof (path), "%s/%s", directory, file);
2912912Sartem
2922912Sartem f = fopen (path, "rb");
2932912Sartem if (f == NULL) {
2942912Sartem HAL_ERROR (("Cannot open '%s'", path));
2952912Sartem goto out;
2962912Sartem }
2972912Sartem
2982912Sartem if (fgets (buf, sizeof (buf), f) == NULL) {
2992912Sartem HAL_ERROR (("Cannot read from '%s'", path));
3002912Sartem goto out;
3012912Sartem }
3022912Sartem
3032912Sartem left = 0;
3042912Sartem len = strlen (buf);
3052912Sartem passed_white_space = FALSE;
3062912Sartem for (i = 0; i < len && buf[i] != '.'; i++) {
3072912Sartem if (g_ascii_isspace (buf[i])) {
3082912Sartem if (passed_white_space)
3092912Sartem break;
3102912Sartem else
3112912Sartem continue;
3122912Sartem }
3132912Sartem passed_white_space = TRUE;
3142912Sartem left *= 16;
3152912Sartem c = buf[i];
3162912Sartem digit = (int) (c - '0');
3172912Sartem left += digit;
3182912Sartem }
3192912Sartem i++;
3202912Sartem right = 0;
3212912Sartem num_prec = 0;
3222912Sartem for (; i < len; i++) {
3232912Sartem if (g_ascii_isspace (buf[i]))
3242912Sartem break;
3252912Sartem if (num_prec == 2) /* Only care about two digits
3262912Sartem * of precision */
3272912Sartem break;
3282912Sartem right *= 16;
3292912Sartem c = buf[i];
3302912Sartem digit = (int) (c - '0');
3312912Sartem right += digit;
3322912Sartem num_prec++;
3332912Sartem }
3342912Sartem
3352912Sartem for (; num_prec < 2; num_prec++)
3362912Sartem right *= 16;
3372912Sartem
3382912Sartem *result = left * 256 + (right & 255);
3392912Sartem ret = TRUE;
3402912Sartem
3412912Sartem out:
3422912Sartem if (f != NULL)
3432912Sartem fclose (f);
3442912Sartem
3452912Sartem return ret;
3462912Sartem }
3472912Sartem
3482912Sartem gboolean
hal_util_set_bcd2_from_file(HalDevice * d,const gchar * key,const gchar * directory,const gchar * file)3492912Sartem hal_util_set_bcd2_from_file (HalDevice *d, const gchar *key, const gchar *directory, const gchar *file)
3502912Sartem {
3512912Sartem gint value;
3522912Sartem gboolean ret;
3532912Sartem
3542912Sartem ret = FALSE;
3552912Sartem
3562912Sartem if (hal_util_get_bcd2_from_file (directory, file, &value))
3572912Sartem ret = hal_device_property_set_int (d, key, value);
3582912Sartem
3592912Sartem return ret;
3602912Sartem }
3612912Sartem
3622912Sartem gchar *
hal_util_get_string_from_file(const gchar * directory,const gchar * file)3632912Sartem hal_util_get_string_from_file (const gchar *directory, const gchar *file)
3642912Sartem {
3652912Sartem FILE *f;
3662912Sartem static gchar buf[256];
3672912Sartem gchar path[HAL_PATH_MAX];
3682912Sartem gchar *result;
3692912Sartem gsize len;
3702912Sartem gint i;
3712912Sartem
3722912Sartem f = NULL;
3732912Sartem result = NULL;
3742912Sartem
3752912Sartem g_snprintf (path, sizeof (path), "%s/%s", directory, file);
3762912Sartem
3772912Sartem f = fopen (path, "rb");
3782912Sartem if (f == NULL) {
3792912Sartem HAL_ERROR (("Cannot open '%s'", path));
3802912Sartem goto out;
3812912Sartem }
3822912Sartem
3832912Sartem buf[0] = '\0';
3842912Sartem if (fgets (buf, sizeof (buf), f) == NULL) {
3852912Sartem HAL_ERROR (("Cannot read from '%s'", path));
3862912Sartem goto out;
3872912Sartem }
3882912Sartem
3892912Sartem len = strlen (buf);
3902912Sartem if (len>0)
3912912Sartem buf[len-1] = '\0';
3922912Sartem
3932912Sartem /* Clear remaining whitespace */
3942912Sartem for (i = len - 2; i >= 0; --i) {
3952912Sartem if (!g_ascii_isspace (buf[i]))
3962912Sartem break;
3972912Sartem buf[i] = '\0';
3982912Sartem }
3992912Sartem
4002912Sartem result = buf;
4012912Sartem
4022912Sartem out:
4032912Sartem if (f != NULL)
4042912Sartem fclose (f);
4052912Sartem
4062912Sartem return result;
4072912Sartem }
4082912Sartem
4092912Sartem gboolean
hal_util_set_string_from_file(HalDevice * d,const gchar * key,const gchar * directory,const gchar * file)4102912Sartem hal_util_set_string_from_file (HalDevice *d, const gchar *key, const gchar *directory, const gchar *file)
4112912Sartem {
4122912Sartem gchar *buf;
4132912Sartem gboolean ret;
4142912Sartem
4152912Sartem ret = FALSE;
4162912Sartem
4172912Sartem if ((buf = hal_util_get_string_from_file (directory, file)) != NULL)
4182912Sartem ret = hal_device_property_set_string (d, key, buf);
4192912Sartem
4202912Sartem return ret;
4212912Sartem }
4222912Sartem
4232912Sartem void
hal_util_compute_udi(HalDeviceStore * store,gchar * dst,gsize dstsize,const gchar * format,...)4242912Sartem hal_util_compute_udi (HalDeviceStore *store, gchar *dst, gsize dstsize, const gchar *format, ...)
4252912Sartem {
4262912Sartem guint i;
4272912Sartem va_list args;
4282912Sartem gchar buf[256];
4292912Sartem
4302912Sartem va_start (args, format);
4312912Sartem g_vsnprintf (buf, sizeof (buf), format, args);
4322912Sartem va_end (args);
4332912Sartem
4342912Sartem g_strcanon (buf,
4352912Sartem "/_"
4362912Sartem "abcdefghijklmnopqrstuvwxyz"
4372912Sartem "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
4382912Sartem "1234567890", '_');
4392912Sartem
4402912Sartem g_strlcpy (dst, buf, dstsize);
4412912Sartem if (hal_device_store_find (store, dst) == NULL)
4422912Sartem goto out;
4432912Sartem
4442912Sartem for (i = 0; ; i++) {
4452912Sartem g_snprintf (dst, dstsize, "%s_%d", buf, i);
4462912Sartem if (hal_device_store_find (store, dst) == NULL)
4472912Sartem goto out;
4482912Sartem }
4492912Sartem
4502912Sartem out:
4512912Sartem ;
4522912Sartem }
4532912Sartem
4542912Sartem
4552912Sartem gboolean
hal_util_path_ascend(gchar * path)4562912Sartem hal_util_path_ascend (gchar *path)
4572912Sartem {
4582912Sartem gchar *p;
4592912Sartem
4602912Sartem if (path == NULL)
4612912Sartem return FALSE;
4622912Sartem
4632912Sartem p = strrchr (path, '/');
4642912Sartem if (p == NULL)
4652912Sartem return FALSE;
4662912Sartem
4672912Sartem *p = '\0';
4682912Sartem return TRUE;
4692912Sartem }
4702912Sartem
4712912Sartem static gboolean _grep_can_reuse = FALSE;
4722912Sartem
4732912Sartem void
hal_util_grep_discard_existing_data(void)4742912Sartem hal_util_grep_discard_existing_data (void)
4752912Sartem {
4762912Sartem _grep_can_reuse = FALSE;
4772912Sartem }
4782912Sartem
4792912Sartem /** Given a directory and filename, open the file and search for the
4802912Sartem * first line that starts with the given linestart string. Returns
4812912Sartem * the rest of the line as a string if found.
4822912Sartem *
4832912Sartem * @param directory Directory, e.g. "/proc/acpi/battery/BAT0"
4842912Sartem * @param file File, e.g. "info"
4852912Sartem * @param linestart Start of line, e.g. "serial number"
4862912Sartem * @param reuse Whether we should reuse the file contents
4872912Sartem * if the file is the same; can be cleared
4882912Sartem * with hal_util_grep_discard_existing_data()
4892912Sartem * @return NULL if not found, otherwise the remainder
4902912Sartem * of the line, e.g. ": 21805" if
4912912Sartem * the file /proc/acpi/battery/BAT0 contains
4922912Sartem * this line "serial number: 21805"
4932912Sartem * The string is only valid until the next
4942912Sartem * invocation of this function.
4952912Sartem */
4962912Sartem gchar *
hal_util_grep_file(const gchar * directory,const gchar * file,const gchar * linestart,gboolean reuse)4972912Sartem hal_util_grep_file (const gchar *directory, const gchar *file, const gchar *linestart, gboolean reuse)
4982912Sartem {
4992912Sartem static gchar buf[2048];
5002912Sartem static unsigned int bufsize;
5012912Sartem static gchar filename[HAL_PATH_MAX];
5022912Sartem static gchar oldfilename[HAL_PATH_MAX];
5032912Sartem gchar *result;
5042912Sartem gsize linestart_len;
5052912Sartem gchar *p;
5062912Sartem
5072912Sartem result = NULL;
5082912Sartem
5092912Sartem /* TODO: use reuse and _grep_can_reuse parameters to avoid loading
5102912Sartem * the file again and again
5112912Sartem */
5122912Sartem
5132912Sartem if (file != NULL && strlen (file) > 0)
5142912Sartem snprintf (filename, sizeof (filename), "%s/%s", directory, file);
5152912Sartem else
5162912Sartem strncpy (filename, directory, sizeof (filename));
5172912Sartem
5182912Sartem if (_grep_can_reuse && reuse && strcmp (oldfilename, filename) == 0) {
5192912Sartem /* just reuse old file; e.g. bufsize, buf */
5202912Sartem /*HAL_INFO (("hal_util_grep_file: reusing buf for %s", filename));*/
5212912Sartem } else {
5222912Sartem FILE *f;
5232912Sartem
5242912Sartem f = fopen (filename, "r");
5252912Sartem if (f == NULL)
5262912Sartem goto out;
5272912Sartem bufsize = fread (buf, sizeof (char), sizeof (buf) - 1, f);
5282912Sartem buf[bufsize] = '\0';
5292912Sartem fclose (f);
5302912Sartem
5312912Sartem /*HAL_INFO (("hal_util_grep_file: read %s of %d bytes", filename, bufsize));*/
5322912Sartem }
5332912Sartem
5342912Sartem /* book keeping */
5352912Sartem _grep_can_reuse = TRUE;
5362912Sartem strncpy (oldfilename, filename, sizeof(oldfilename));
5372912Sartem
5382912Sartem linestart_len = strlen (linestart);
5392912Sartem
5402912Sartem /* analyze buf */
5412912Sartem p = buf;
5422912Sartem do {
5432912Sartem unsigned int linelen;
5442912Sartem static char line[256];
5452912Sartem
5462912Sartem for (linelen = 0; p[linelen] != '\n' && p[linelen] != '\0'; linelen++)
5472912Sartem ;
5482912Sartem
5492912Sartem if (linelen < sizeof (line)) {
5502912Sartem
5512912Sartem strncpy (line, p, linelen);
5522912Sartem line[linelen] = '\0';
5532912Sartem
5542912Sartem if (strncmp (line, linestart, linestart_len) == 0) {
5552912Sartem result = line + linestart_len;
5562912Sartem goto out;
5572912Sartem }
5582912Sartem }
5592912Sartem
5602912Sartem p += linelen + 1;
5612912Sartem
5622912Sartem } while (p < buf + bufsize);
5632912Sartem
5642912Sartem out:
5652912Sartem return result;
5662912Sartem }
5672912Sartem
5682912Sartem gchar *
hal_util_grep_string_elem_from_file(const gchar * directory,const gchar * file,const gchar * linestart,guint elem,gboolean reuse)5692912Sartem hal_util_grep_string_elem_from_file (const gchar *directory, const gchar *file,
5702912Sartem const gchar *linestart, guint elem, gboolean reuse)
5712912Sartem {
5722912Sartem gchar *line;
5732912Sartem gchar *res;
5742912Sartem static gchar buf[256];
5752912Sartem gchar **tokens;
5762912Sartem guint i, j;
5772912Sartem
5782912Sartem res = NULL;
5792912Sartem tokens = NULL;
5802912Sartem
5812912Sartem if (((line = hal_util_grep_file (directory, file, linestart, reuse)) == NULL) || (strlen (line) == 0))
5822912Sartem goto out;
5832912Sartem
5842912Sartem tokens = g_strsplit_set (line, " \t:", 0);
5852912Sartem for (i = 0, j = 0; tokens[i] != NULL; i++) {
5862912Sartem if (strlen (tokens[i]) == 0)
5872912Sartem continue;
5882912Sartem if (j == elem) {
5892912Sartem strncpy (buf, tokens[i], sizeof (buf));
5902912Sartem res = buf;
5912912Sartem goto out;
5922912Sartem }
5932912Sartem j++;
5942912Sartem }
5952912Sartem
5962912Sartem out:
5972912Sartem if (tokens != NULL)
5982912Sartem g_strfreev (tokens);
5992912Sartem
6002912Sartem return res;
6012912Sartem }
6022912Sartem
6032912Sartem gint
hal_util_grep_int_elem_from_file(const gchar * directory,const gchar * file,const gchar * linestart,guint elem,guint base,gboolean reuse)6042912Sartem hal_util_grep_int_elem_from_file (const gchar *directory, const gchar *file,
6052912Sartem const gchar *linestart, guint elem, guint base, gboolean reuse)
6062912Sartem {
6072912Sartem gchar *endptr;
6082912Sartem gchar *strvalue;
6092912Sartem int value;
6102912Sartem
6112912Sartem value = G_MAXINT;
6122912Sartem
6132912Sartem strvalue = hal_util_grep_string_elem_from_file (directory, file, linestart, elem, reuse);
6142912Sartem if (strvalue == NULL)
6152912Sartem goto out;
6162912Sartem
6172912Sartem value = strtol (strvalue, &endptr, base);
6182912Sartem if (endptr == strvalue) {
6192912Sartem value = G_MAXINT;
6202912Sartem goto out;
6212912Sartem }
6222912Sartem
6232912Sartem out:
6242912Sartem return value;
6252912Sartem }
6262912Sartem
6272912Sartem /** Get a string value from a formatted text file and assign it to
6282912Sartem * a property on a device object.
6292912Sartem *
6302912Sartem * Example: Given that the file /proc/acpi/battery/BAT0/info contains
6312912Sartem * the line
6322912Sartem *
6332912Sartem * "design voltage: 10800 mV"
6342912Sartem *
6352912Sartem * then hal_util_set_string_elem_from_file (d, "battery.foo",
6362912Sartem * "/proc/acpi/battery/BAT0", "info", "design voltage", 1) will assign
6372912Sartem * the string "mV" to the property "battery.foo" on d.
6382912Sartem *
6392912Sartem * @param d Device object
6402912Sartem * @param key Property name
6412912Sartem * @param directory Directory, e.g. "/proc/acpi/battery/BAT0"
6422912Sartem * @param file File, e.g. "info"
6432912Sartem * @param linestart Start of line, e.g. "design voltage"
6442912Sartem * @param elem Element number after linestart to extract
6452912Sartem * excluding whitespace and ':' characters.
6462912Sartem * @return TRUE, if, and only if, the value could be
6472912Sartem * extracted and the property was set
6482912Sartem */
6492912Sartem gboolean
hal_util_set_string_elem_from_file(HalDevice * d,const gchar * key,const gchar * directory,const gchar * file,const gchar * linestart,guint elem,gboolean reuse)6502912Sartem hal_util_set_string_elem_from_file (HalDevice *d, const gchar *key,
6512912Sartem const gchar *directory, const gchar *file,
6522912Sartem const gchar *linestart, guint elem, gboolean reuse)
6532912Sartem {
6542912Sartem gboolean res;
6552912Sartem gchar *value;
6562912Sartem
6572912Sartem res = FALSE;
6582912Sartem
6592912Sartem if ((value = hal_util_grep_string_elem_from_file (directory, file, linestart, elem, reuse)) == NULL)
6602912Sartem goto out;
6612912Sartem
6622912Sartem res = hal_device_property_set_string (d, key, value);
6632912Sartem out:
6642912Sartem return res;
6652912Sartem }
6662912Sartem
6672912Sartem /** Get an integer value from a formatted text file and assign it to
6682912Sartem * a property on a device object.
6692912Sartem *
6702912Sartem * Example: Given that the file /proc/acpi/battery/BAT0/info contains
6712912Sartem * the line
6722912Sartem *
6732912Sartem * "design voltage: 10800 mV"
6742912Sartem *
6752912Sartem * then hal_util_set_int_elem_from_file (d, "battery.foo",
6762912Sartem * "/proc/acpi/battery/BAT0", "info", "design voltage", 0) will assign
6772912Sartem * the integer 10800 to the property "battery.foo" on d.
6782912Sartem *
6792912Sartem * @param d Device object
6802912Sartem * @param key Property name
6812912Sartem * @param directory Directory, e.g. "/proc/acpi/battery/BAT0"
6822912Sartem * @param file File, e.g. "info"
6832912Sartem * @param linestart Start of line, e.g. "design voltage"
6842912Sartem * @param elem Element number after linestart to extract
6852912Sartem * excluding whitespace and ':' characters.
6862912Sartem * @return TRUE, if, and only if, the value could be
6872912Sartem * extracted and the property was set
6882912Sartem */
6892912Sartem gboolean
hal_util_set_int_elem_from_file(HalDevice * d,const gchar * key,const gchar * directory,const gchar * file,const gchar * linestart,guint elem,guint base,gboolean reuse)6902912Sartem hal_util_set_int_elem_from_file (HalDevice *d, const gchar *key,
6912912Sartem const gchar *directory, const gchar *file,
6922912Sartem const gchar *linestart, guint elem, guint base, gboolean reuse)
6932912Sartem {
6942912Sartem gchar *endptr;
6952912Sartem gboolean res;
6962912Sartem gchar *strvalue;
6972912Sartem int value;
6982912Sartem
6992912Sartem res = FALSE;
7002912Sartem
7012912Sartem strvalue = hal_util_grep_string_elem_from_file (directory, file, linestart, elem, reuse);
7022912Sartem if (strvalue == NULL)
7032912Sartem goto out;
7042912Sartem
7052912Sartem value = strtol (strvalue, &endptr, base);
7062912Sartem if (endptr == strvalue)
7072912Sartem goto out;
7082912Sartem
7092912Sartem res = hal_device_property_set_int (d, key, value);
7102912Sartem
7112912Sartem out:
7122912Sartem return res;
7132912Sartem
7142912Sartem }
7152912Sartem
7162912Sartem /** Get a value from a formatted text file, test it against a given
7172912Sartem * value, and set a boolean property on a device object with the
7182912Sartem * test result.
7192912Sartem *
7202912Sartem * Example: Given that the file /proc/acpi/battery/BAT0/info contains
7212912Sartem * the line
7222912Sartem *
7232912Sartem * "present: yes"
7242912Sartem *
7252912Sartem * then hal_util_set_bool_elem_from_file (d, "battery.baz",
7262912Sartem * "/proc/acpi/battery/BAT0", "info", "present", 0, "yes") will assign
7272912Sartem * the boolean TRUE to the property "battery.baz" on d.
7282912Sartem *
7292912Sartem * If, instead, the line was
7302912Sartem *
7312912Sartem * "present: no"
7322912Sartem *
7332912Sartem * the value assigned will be FALSE.
7342912Sartem *
7352912Sartem * @param d Device object
7362912Sartem * @param key Property name
7372912Sartem * @param directory Directory, e.g. "/proc/acpi/battery/BAT0"
7382912Sartem * @param file File, e.g. "info"
7392912Sartem * @param linestart Start of line, e.g. "design voltage"
7402912Sartem * @param elem Element number after linestart to extract
7412912Sartem * excluding whitespace and ':' characters.
7422912Sartem * @param expected Value to test against
7432912Sartem * @return TRUE, if, and only if, the value could be
7442912Sartem * extracted and the property was set
7452912Sartem */
7462912Sartem gboolean
hal_util_set_bool_elem_from_file(HalDevice * d,const gchar * key,const gchar * directory,const gchar * file,const gchar * linestart,guint elem,const gchar * expected,gboolean reuse)7472912Sartem hal_util_set_bool_elem_from_file (HalDevice *d, const gchar *key,
7482912Sartem const gchar *directory, const gchar *file,
7492912Sartem const gchar *linestart, guint elem, const gchar *expected, gboolean reuse)
7502912Sartem {
7512912Sartem gchar *line;
7522912Sartem gboolean res;
7532912Sartem gchar **tokens;
7542912Sartem guint i, j;
7552912Sartem
7562912Sartem res = FALSE;
7572912Sartem tokens = NULL;
7582912Sartem
7592912Sartem if (((line = hal_util_grep_file (directory, file, linestart, reuse)) == NULL) || (strlen (line) == 0))
7602912Sartem goto out;
7612912Sartem
7622912Sartem tokens = g_strsplit_set (line, " \t:", 0);
7632912Sartem
7642912Sartem for (i = 0, j = 0; tokens[i] != NULL; i++) {
7652912Sartem if (strlen (tokens[i]) == 0)
7662912Sartem continue;
7672912Sartem if (j == elem) {
7682912Sartem hal_device_property_set_bool (d, key, strcmp (tokens[i], expected) == 0);
7692912Sartem res = TRUE;
7702912Sartem goto out;
7712912Sartem }
7722912Sartem j++;
7732912Sartem }
7742912Sartem
7752912Sartem
7762912Sartem out:
7772912Sartem if (tokens != NULL)
7782912Sartem g_strfreev (tokens);
7792912Sartem
7802912Sartem return res;
7812912Sartem }
7822912Sartem
7832912Sartem gchar **
hal_util_dup_strv_from_g_slist(GSList * strlist)7842912Sartem hal_util_dup_strv_from_g_slist (GSList *strlist)
7852912Sartem {
7862912Sartem guint j;
7872912Sartem guint len;
7882912Sartem gchar **strv;
7892912Sartem GSList *i;
7902912Sartem
7912912Sartem len = g_slist_length (strlist);
7922912Sartem strv = g_new (char *, len + 1);
7932912Sartem
7942912Sartem for (i = strlist, j = 0; i != NULL; i = g_slist_next (i), j++) {
7952912Sartem strv[j] = g_strdup ((const gchar *) i->data);
7962912Sartem }
7972912Sartem strv[j] = NULL;
7982912Sartem
7992912Sartem return strv;
8002912Sartem }
8012912Sartem
8022912Sartem /* -------------------------------------------------------------------------------------------------------------- */
8032912Sartem
8042912Sartem typedef struct {
8052912Sartem HalDevice *d;
8062912Sartem gchar **programs;
8072912Sartem gchar **extra_env;
8082912Sartem guint next_program;
8092912Sartem
8102912Sartem HalCalloutsDone callback;
8112912Sartem gpointer userdata1;
8122912Sartem gpointer userdata2;
8132912Sartem
8142912Sartem } Callout;
8152912Sartem
8162912Sartem static void callout_do_next (Callout *c);
8172912Sartem
8182912Sartem static void
callout_terminated(HalDevice * d,guint32 exit_type,gint return_code,gchar ** error,gpointer data1,gpointer data2)8192912Sartem callout_terminated (HalDevice *d, guint32 exit_type,
8202912Sartem gint return_code, gchar **error,
8212912Sartem gpointer data1, gpointer data2)
8222912Sartem {
8232912Sartem Callout *c;
8242912Sartem
8252912Sartem c = (Callout *) data1;
8262912Sartem callout_do_next (c);
8272912Sartem }
8282912Sartem
8292912Sartem static void
callout_do_next(Callout * c)8302912Sartem callout_do_next (Callout *c)
8312912Sartem {
8322912Sartem
8332912Sartem /* Check if we're done */
8342912Sartem if (c->programs[c->next_program] == NULL) {
8352912Sartem HalDevice *d;
8362912Sartem gpointer userdata1;
8372912Sartem gpointer userdata2;
8382912Sartem HalCalloutsDone callback;
8392912Sartem
8402912Sartem d = c->d;
8412912Sartem userdata1 = c->userdata1;
8422912Sartem userdata2 = c->userdata2;
8432912Sartem callback = c->callback;
8442912Sartem
8452912Sartem g_strfreev (c->programs);
8462912Sartem g_strfreev (c->extra_env);
8472912Sartem g_free (c);
8482912Sartem
8492912Sartem callback (d, userdata1, userdata2);
8502912Sartem
8512912Sartem } else {
8522912Sartem hald_runner_run(c->d, c->programs[c->next_program], c->extra_env,
8532912Sartem HAL_HELPER_TIMEOUT, callout_terminated,
8542912Sartem (gpointer)c, NULL);
8552912Sartem c->next_program++;
8562912Sartem }
8572912Sartem }
8582912Sartem
8592912Sartem static void
hal_callout_device(HalDevice * d,HalCalloutsDone callback,gpointer userdata1,gpointer userdata2,GSList * programs,gchar ** extra_env)8602912Sartem hal_callout_device (HalDevice *d, HalCalloutsDone callback, gpointer userdata1, gpointer userdata2,
8612912Sartem GSList *programs, gchar **extra_env)
8622912Sartem {
8632912Sartem Callout *c;
8642912Sartem
8652912Sartem c = g_new0 (Callout, 1);
8662912Sartem c->d = d;
8672912Sartem c->callback = callback;
8682912Sartem c->userdata1 = userdata1;
8692912Sartem c->userdata2 = userdata2;
8702912Sartem c->programs = hal_util_dup_strv_from_g_slist (programs);
8712912Sartem c->extra_env = g_strdupv (extra_env);
8722912Sartem c->next_program = 0;
8732912Sartem
8742912Sartem callout_do_next (c);
8752912Sartem }
8762912Sartem
8772912Sartem void
hal_util_callout_device_add(HalDevice * d,HalCalloutsDone callback,gpointer userdata1,gpointer userdata2)8782912Sartem hal_util_callout_device_add (HalDevice *d, HalCalloutsDone callback, gpointer userdata1, gpointer userdata2)
8792912Sartem {
8802912Sartem GSList *programs;
8812912Sartem gchar *extra_env[2] = {"HALD_ACTION=add", NULL};
8822912Sartem
8832912Sartem if ((programs = hal_device_property_get_strlist (d, "info.callouts.add")) == NULL) {
8842912Sartem callback (d, userdata1, userdata2);
8852912Sartem goto out;
8862912Sartem }
8872912Sartem
8882912Sartem HAL_INFO (("Add callouts for udi=%s", d->udi));
8892912Sartem
8902912Sartem hal_callout_device (d, callback, userdata1, userdata2, programs, extra_env);
8912912Sartem out:
8922912Sartem ;
8932912Sartem }
8942912Sartem
8952912Sartem void
hal_util_callout_device_remove(HalDevice * d,HalCalloutsDone callback,gpointer userdata1,gpointer userdata2)8962912Sartem hal_util_callout_device_remove (HalDevice *d, HalCalloutsDone callback, gpointer userdata1, gpointer userdata2)
8972912Sartem {
8982912Sartem GSList *programs;
8992912Sartem gchar *extra_env[2] = {"HALD_ACTION=remove", NULL};
9002912Sartem
9012912Sartem if ((programs = hal_device_property_get_strlist (d, "info.callouts.remove")) == NULL) {
9022912Sartem callback (d, userdata1, userdata2);
9032912Sartem goto out;
9042912Sartem }
9052912Sartem
9062912Sartem HAL_INFO (("Remove callouts for udi=%s", d->udi));
9072912Sartem
9082912Sartem hal_callout_device (d, callback, userdata1, userdata2, programs, extra_env);
9092912Sartem out:
9102912Sartem ;
9112912Sartem }
9122912Sartem
9132912Sartem void
hal_util_callout_device_preprobe(HalDevice * d,HalCalloutsDone callback,gpointer userdata1,gpointer userdata2)9142912Sartem hal_util_callout_device_preprobe (HalDevice *d, HalCalloutsDone callback, gpointer userdata1, gpointer userdata2)
9152912Sartem {
9162912Sartem GSList *programs;
9172912Sartem gchar *extra_env[2] = {"HALD_ACTION=preprobe", NULL};
9182912Sartem
9192912Sartem if ((programs = hal_device_property_get_strlist (d, "info.callouts.preprobe")) == NULL) {
9202912Sartem callback (d, userdata1, userdata2);
9212912Sartem goto out;
9222912Sartem }
9232912Sartem
9242912Sartem HAL_INFO (("Preprobe callouts for udi=%s", d->udi));
9252912Sartem
9262912Sartem hal_callout_device (d, callback, userdata1, userdata2, programs, extra_env);
9272912Sartem out:
9282912Sartem ;
9292912Sartem }
9302912Sartem
9312912Sartem gchar *
hal_util_strdup_valid_utf8(const char * str)9322912Sartem hal_util_strdup_valid_utf8 (const char *str)
9332912Sartem {
9342912Sartem char *endchar;
9352912Sartem char *newstr;
9362912Sartem unsigned int count = 0;
9372912Sartem
9382912Sartem if (str == NULL)
9392912Sartem return NULL;
9402912Sartem
9412912Sartem newstr = g_strdup (str);
9422912Sartem
9432912Sartem while (!g_utf8_validate (newstr, -1, (const char **) &endchar)) {
9442912Sartem *endchar = '?';
9452912Sartem count++;
9462912Sartem }
9472912Sartem
9482912Sartem if (strlen(newstr) == count)
9492912Sartem return NULL;
9502912Sartem else
9512912Sartem return newstr;
9522912Sartem }
9532912Sartem
9542912Sartem void
hal_util_hexdump(const void * mem,unsigned int size)9552912Sartem hal_util_hexdump (const void *mem, unsigned int size)
9562912Sartem {
9572912Sartem unsigned int i;
9582912Sartem unsigned int j;
9592912Sartem unsigned int n;
9602912Sartem const char *buf = (const char *) mem;
9612912Sartem
9622912Sartem n = 0;
9632912Sartem printf ("Dumping %d=0x%x bytes\n", size, size);
9642912Sartem while (n < size) {
9652912Sartem
9662912Sartem printf ("0x%04x: ", n);
9672912Sartem
9682912Sartem j = n;
9692912Sartem for (i = 0; i < 16; i++) {
9702912Sartem if (j >= size)
9712912Sartem break;
9722912Sartem printf ("%02x ", buf[j]);
9732912Sartem j++;
9742912Sartem }
9752912Sartem
9762912Sartem for ( ; i < 16; i++) {
9772912Sartem printf (" ");
9782912Sartem }
9792912Sartem
9802912Sartem printf (" ");
9812912Sartem
9822912Sartem j = n;
9832912Sartem for (i = 0; i < 16; i++) {
9842912Sartem if (j >= size)
9852912Sartem break;
9862912Sartem printf ("%c", isprint(buf[j]) ? buf[j] : '.');
9872912Sartem j++;
9882912Sartem }
9892912Sartem
9902912Sartem printf ("\n");
9912912Sartem
9922912Sartem n += 16;
9932912Sartem }
9942912Sartem }
9952912Sartem
9962912Sartem gboolean
hal_util_is_mounted_by_hald(const char * mount_point)9972912Sartem hal_util_is_mounted_by_hald (const char *mount_point)
9982912Sartem {
9992912Sartem int i;
10002912Sartem FILE *hal_mtab;
10012912Sartem int hal_mtab_len;
10022912Sartem int num_read;
10032912Sartem char *hal_mtab_buf;
10042912Sartem char **lines;
10052912Sartem gboolean found;
10062912Sartem
10072912Sartem hal_mtab = NULL;
10082912Sartem hal_mtab_buf = NULL;
10092912Sartem found = FALSE;
10102912Sartem
10112912Sartem /*HAL_DEBUG (("examining /media/.hal-mtab for %s", mount_point));*/
10122912Sartem
10132912Sartem hal_mtab = fopen ("/media/.hal-mtab", "r");
10142912Sartem if (hal_mtab == NULL) {
10152912Sartem HAL_ERROR (("Cannot open /media/.hal-mtab"));
10162912Sartem goto out;
10172912Sartem }
10182912Sartem if (fseek (hal_mtab, 0L, SEEK_END) != 0) {
10192912Sartem HAL_ERROR (("Cannot seek to end of /media/.hal-mtab"));
10202912Sartem goto out;
10212912Sartem }
10222912Sartem hal_mtab_len = ftell (hal_mtab);
10232912Sartem if (hal_mtab_len < 0) {
10242912Sartem HAL_ERROR (("Cannot determine size of /media/.hal-mtab"));
10252912Sartem goto out;
10262912Sartem }
10272912Sartem rewind (hal_mtab);
10282912Sartem
10292912Sartem hal_mtab_buf = g_new0 (char, hal_mtab_len + 1);
10302912Sartem num_read = fread (hal_mtab_buf, 1, hal_mtab_len, hal_mtab);
10312912Sartem if (num_read != hal_mtab_len) {
10322912Sartem HAL_ERROR (("Cannot read from /media/.hal-mtab"));
10332912Sartem goto out;
10342912Sartem }
10352912Sartem fclose (hal_mtab);
10362912Sartem hal_mtab = NULL;
10372912Sartem
10382912Sartem /*HAL_DEBUG (("hal_mtab = '%s'\n", hal_mtab_buf));*/
10392912Sartem
10402912Sartem lines = g_strsplit (hal_mtab_buf, "\n", 0);
10412912Sartem g_free (hal_mtab_buf);
10422912Sartem hal_mtab_buf = NULL;
10432912Sartem
10442912Sartem /* find the entry we're going to unmount */
10452912Sartem for (i = 0; lines[i] != NULL && !found; i++) {
10462912Sartem char **line_elements;
10472912Sartem
10482912Sartem /*HAL_DEBUG ((" line = '%s'", lines[i]));*/
10492912Sartem
10502912Sartem if ((lines[i])[0] == '#')
10512912Sartem continue;
10522912Sartem
10532912Sartem line_elements = g_strsplit (lines[i], "\t", 6);
10542912Sartem if (g_strv_length (line_elements) == 6) {
10552912Sartem /*
10562912Sartem HAL_DEBUG ((" devfile = '%s'", line_elements[0]));
10572912Sartem HAL_DEBUG ((" uid = '%s'", line_elements[1]));
10582912Sartem HAL_DEBUG ((" session id = '%s'", line_elements[2]));
10592912Sartem HAL_DEBUG ((" fs = '%s'", line_elements[3]));
10602912Sartem HAL_DEBUG ((" options = '%s'", line_elements[4]));
10612912Sartem HAL_DEBUG ((" mount_point = '%s'", line_elements[5]));
10622912Sartem HAL_DEBUG ((" (comparing against '%s')", mount_point));
10632912Sartem */
10642912Sartem
10652912Sartem if (strcmp (line_elements[5], mount_point) == 0) {
10662912Sartem found = TRUE;
10672912Sartem /*HAL_INFO (("device at '%s' is indeed mounted by HAL's Mount()", mount_point));*/
10682912Sartem }
10692912Sartem
10702912Sartem }
10712912Sartem
10722912Sartem g_strfreev (line_elements);
10732912Sartem }
10742912Sartem
10752912Sartem g_strfreev (lines);
10762912Sartem
10772912Sartem out:
10782912Sartem if (hal_mtab != NULL)
10792912Sartem fclose (hal_mtab);
10802912Sartem if (hal_mtab_buf != NULL)
10812912Sartem g_free (hal_mtab_buf);
10822912Sartem
10832912Sartem return found;
10842912Sartem }
10852912Sartem
10862912Sartem void
hal_util_branch_claim(HalDeviceStore * store,HalDevice * root,dbus_bool_t claimed,const char * service,int uid)10872912Sartem hal_util_branch_claim (HalDeviceStore *store, HalDevice *root, dbus_bool_t claimed,
10882912Sartem const char *service, int uid)
10892912Sartem {
10902912Sartem GSList *children;
10912912Sartem GSList *i;
10922912Sartem HalDevice *d;
10932912Sartem
10942912Sartem if (claimed) {
10952912Sartem hal_device_property_set_bool (root, "info.claimed", claimed);
10962912Sartem hal_device_property_set_string (root, "info.claimed.service", service);
10972912Sartem hal_device_property_set_int (root, "info.claimed.uid", uid);
10982912Sartem } else {
10992912Sartem hal_device_property_remove (root, "info.claimed");
11002912Sartem hal_device_property_remove (root, "info.claimed.service");
11012912Sartem hal_device_property_remove (root, "info.claimed.uid");
11022912Sartem }
11032912Sartem
11042912Sartem
11052912Sartem children = hal_device_store_match_multiple_key_value_string (store,
11062912Sartem "info.parent", root->udi);
11072912Sartem
11082912Sartem for (i = children; i != NULL; i = g_slist_next (i)) {
11092912Sartem d = HAL_DEVICE (i->data);
11102912Sartem hal_util_branch_claim (store, d, claimed, service, uid);
11112912Sartem }
11122912Sartem
11132912Sartem g_slist_free (children);
11142912Sartem }
1115*10659SXiao-Lin.Zhang@Sun.COM
1116*10659SXiao-Lin.Zhang@Sun.COM /** Given an interface name, check if it is valid.
1117*10659SXiao-Lin.Zhang@Sun.COM * @param name A given interface name
1118*10659SXiao-Lin.Zhang@Sun.COM * @return TRUE if name is valid, otherwise FALSE
1119*10659SXiao-Lin.Zhang@Sun.COM */
1120*10659SXiao-Lin.Zhang@Sun.COM gboolean
is_valid_interface_name(const char * name)1121*10659SXiao-Lin.Zhang@Sun.COM is_valid_interface_name(const char *name) {
1122*10659SXiao-Lin.Zhang@Sun.COM
1123*10659SXiao-Lin.Zhang@Sun.COM const char *end;
1124*10659SXiao-Lin.Zhang@Sun.COM const char *last_dot;
1125*10659SXiao-Lin.Zhang@Sun.COM
1126*10659SXiao-Lin.Zhang@Sun.COM last_dot = NULL;
1127*10659SXiao-Lin.Zhang@Sun.COM
1128*10659SXiao-Lin.Zhang@Sun.COM if (strlen(name) == 0)
1129*10659SXiao-Lin.Zhang@Sun.COM return FALSE;
1130*10659SXiao-Lin.Zhang@Sun.COM
1131*10659SXiao-Lin.Zhang@Sun.COM end = name + strlen(name);
1132*10659SXiao-Lin.Zhang@Sun.COM
1133*10659SXiao-Lin.Zhang@Sun.COM if (*name == '.') /* disallow starting with a . */
1134*10659SXiao-Lin.Zhang@Sun.COM return FALSE;
1135*10659SXiao-Lin.Zhang@Sun.COM else if (!VALID_INITIAL_NAME_CHARACTER (*name))
1136*10659SXiao-Lin.Zhang@Sun.COM return FALSE;
1137*10659SXiao-Lin.Zhang@Sun.COM else
1138*10659SXiao-Lin.Zhang@Sun.COM name++;
1139*10659SXiao-Lin.Zhang@Sun.COM
1140*10659SXiao-Lin.Zhang@Sun.COM while (name != end) {
1141*10659SXiao-Lin.Zhang@Sun.COM if (*name == '.') {
1142*10659SXiao-Lin.Zhang@Sun.COM if ((name + 1) == end)
1143*10659SXiao-Lin.Zhang@Sun.COM return FALSE;
1144*10659SXiao-Lin.Zhang@Sun.COM else if (!VALID_INITIAL_NAME_CHARACTER (*(name + 1)))
1145*10659SXiao-Lin.Zhang@Sun.COM return FALSE;
1146*10659SXiao-Lin.Zhang@Sun.COM last_dot = name;
1147*10659SXiao-Lin.Zhang@Sun.COM name++; /* we just validated the next char, so skip two */
1148*10659SXiao-Lin.Zhang@Sun.COM } else if (!VALID_NAME_CHARACTER (*name))
1149*10659SXiao-Lin.Zhang@Sun.COM return FALSE;
1150*10659SXiao-Lin.Zhang@Sun.COM name++;
1151*10659SXiao-Lin.Zhang@Sun.COM }
1152*10659SXiao-Lin.Zhang@Sun.COM if (last_dot == NULL)
1153*10659SXiao-Lin.Zhang@Sun.COM return FALSE;
1154*10659SXiao-Lin.Zhang@Sun.COM
1155*10659SXiao-Lin.Zhang@Sun.COM return TRUE;
1156*10659SXiao-Lin.Zhang@Sun.COM }
1157