118c2aff7Sartem /***************************************************************************
218c2aff7Sartem * CVSID: $Id$
318c2aff7Sartem *
418c2aff7Sartem * util.c - Various utilities
518c2aff7Sartem *
618c2aff7Sartem * Copyright (C) 2004 David Zeuthen, <david@fubar.dk>
718c2aff7Sartem *
818c2aff7Sartem * Licensed under the Academic Free License version 2.1
918c2aff7Sartem *
1018c2aff7Sartem * This program is free software; you can redistribute it and/or modify
1118c2aff7Sartem * it under the terms of the GNU General Public License as published by
1218c2aff7Sartem * the Free Software Foundation; either version 2 of the License, or
1318c2aff7Sartem * (at your option) any later version.
1418c2aff7Sartem *
1518c2aff7Sartem * This program is distributed in the hope that it will be useful,
1618c2aff7Sartem * but WITHOUT ANY WARRANTY; without even the implied warranty of
1718c2aff7Sartem * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1818c2aff7Sartem * GNU General Public License for more details.
1918c2aff7Sartem *
2018c2aff7Sartem * You should have received a copy of the GNU General Public License
2118c2aff7Sartem * along with this program; if not, write to the Free Software
2218c2aff7Sartem * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2318c2aff7Sartem *
2418c2aff7Sartem **************************************************************************/
2518c2aff7Sartem
2618c2aff7Sartem #ifdef HAVE_CONFIG_H
2718c2aff7Sartem # include <config.h>
2818c2aff7Sartem #endif
2918c2aff7Sartem
3018c2aff7Sartem #include <stdio.h>
3118c2aff7Sartem #include <stdarg.h>
3218c2aff7Sartem #include <string.h>
3318c2aff7Sartem #include <errno.h>
3418c2aff7Sartem #include <time.h>
3518c2aff7Sartem #include <ctype.h>
3618c2aff7Sartem #include <stdint.h>
3718c2aff7Sartem #include <sys/stat.h>
3818c2aff7Sartem #include <unistd.h>
3918c2aff7Sartem #include <fcntl.h>
4018c2aff7Sartem #include <signal.h>
4118c2aff7Sartem #include <sys/wait.h>
4218c2aff7Sartem #include <sys/file.h>
4318c2aff7Sartem
4418c2aff7Sartem #include <glib.h>
4518c2aff7Sartem #include <dbus/dbus.h>
4618c2aff7Sartem #include <dbus/dbus-glib.h>
4718c2aff7Sartem
4818c2aff7Sartem #include "osspec.h"
4918c2aff7Sartem #include "logger.h"
5018c2aff7Sartem #include "hald.h"
5118c2aff7Sartem #include "hald_runner.h"
5218c2aff7Sartem #include "hald_dbus.h"
5318c2aff7Sartem #include "device_info.h"
5418c2aff7Sartem
5518c2aff7Sartem #include "util.h"
5618c2aff7Sartem
57*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China /** Determine whether the given character is valid as the first character
58*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China * in a name.
59*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China */
60*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China #define VALID_INITIAL_NAME_CHARACTER(c) \
61*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China (((c) >= 'A' && (c) <= 'Z') || \
62*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China ((c) >= 'a' && (c) <= 'z') || \
63*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China ((c) == '_'))
64*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China
65*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China /** Determine whether the given character is valid as a second or later
66*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China * character in a name.
67*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China */
68*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China #define VALID_NAME_CHARACTER(c) \
69*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China (((c) >= '0' && (c) <= '9') || \
70*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China ((c) >= 'A' && (c) <= 'Z') || \
71*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China ((c) >= 'a' && (c) <= 'z') || \
72*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China ((c) == '_'))
73*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China
7418c2aff7Sartem gboolean
hal_util_remove_trailing_slash(gchar * path)7518c2aff7Sartem hal_util_remove_trailing_slash (gchar *path)
7618c2aff7Sartem {
7718c2aff7Sartem gchar *c = NULL;
7818c2aff7Sartem
7918c2aff7Sartem if (path == NULL) {
8018c2aff7Sartem return FALSE;
8118c2aff7Sartem }
8218c2aff7Sartem
8318c2aff7Sartem c = strrchr (path, '/');
8418c2aff7Sartem if (c == NULL) {
8518c2aff7Sartem HAL_WARNING (("Invalid path %s", path));
8618c2aff7Sartem return 1;
8718c2aff7Sartem }
8818c2aff7Sartem if (*(c+1) == '\0')
8918c2aff7Sartem *c = '\0';
9018c2aff7Sartem
9118c2aff7Sartem return TRUE;
9218c2aff7Sartem }
9318c2aff7Sartem
9418c2aff7Sartem /** Given a path, /foo/bar/bat/foobar, return the last element, e.g.
9518c2aff7Sartem * foobar.
9618c2aff7Sartem *
9718c2aff7Sartem * @param path Path
9818c2aff7Sartem * @return Pointer into given string
9918c2aff7Sartem */
10018c2aff7Sartem const gchar *
hal_util_get_last_element(const gchar * s)10118c2aff7Sartem hal_util_get_last_element (const gchar *s)
10218c2aff7Sartem {
10318c2aff7Sartem int len;
10418c2aff7Sartem const gchar *p;
10518c2aff7Sartem
10618c2aff7Sartem len = strlen (s);
10718c2aff7Sartem for (p = s + len - 1; p > s; --p) {
10818c2aff7Sartem if ((*p) == '/')
10918c2aff7Sartem return p + 1;
11018c2aff7Sartem }
11118c2aff7Sartem
11218c2aff7Sartem return s;
11318c2aff7Sartem }
11418c2aff7Sartem
11518c2aff7Sartem /** Given a path, this functions finds the path representing the
11618c2aff7Sartem * parent directory by truncation.
11718c2aff7Sartem *
11818c2aff7Sartem * @param path Path
11918c2aff7Sartem * @return Path for parent or NULL. Must be freed by caller
12018c2aff7Sartem */
12118c2aff7Sartem gchar *
hal_util_get_parent_path(const gchar * path)12218c2aff7Sartem hal_util_get_parent_path (const gchar *path)
12318c2aff7Sartem {
12418c2aff7Sartem guint i;
12518c2aff7Sartem guint len;
12618c2aff7Sartem gchar *parent_path;
12718c2aff7Sartem
12818c2aff7Sartem /* Find parent device by truncating our own path */
12918c2aff7Sartem parent_path = g_strndup (path, HAL_PATH_MAX);
13018c2aff7Sartem len = strlen (parent_path);
13118c2aff7Sartem for (i = len - 1; parent_path[i] != '/'; --i) {
13218c2aff7Sartem parent_path[i] = '\0';
13318c2aff7Sartem }
13418c2aff7Sartem parent_path[i] = '\0';
13518c2aff7Sartem
13618c2aff7Sartem return parent_path;
13718c2aff7Sartem }
13818c2aff7Sartem
13918c2aff7Sartem gchar *
hal_util_get_normalized_path(const gchar * path1,const gchar * path2)14018c2aff7Sartem hal_util_get_normalized_path (const gchar *path1, const gchar *path2)
14118c2aff7Sartem {
14218c2aff7Sartem int len1;
14318c2aff7Sartem int len2;
14418c2aff7Sartem const gchar *p1;
14518c2aff7Sartem const gchar *p2;
14618c2aff7Sartem gchar buf[HAL_PATH_MAX];
14718c2aff7Sartem
14818c2aff7Sartem len1 = strlen (path1);
14918c2aff7Sartem len2 = strlen (path2);
15018c2aff7Sartem
15118c2aff7Sartem p1 = path1 + len1;
15218c2aff7Sartem
15318c2aff7Sartem p2 = path2;
15418c2aff7Sartem while (p2 < path2 + len2 && strncmp (p2, "../", 3) == 0) {
15518c2aff7Sartem p2 += 3;
15618c2aff7Sartem
15718c2aff7Sartem while (p1 >= path1 && *(--p1)!='/')
15818c2aff7Sartem ;
15918c2aff7Sartem }
16018c2aff7Sartem
16118c2aff7Sartem if ((p1-path1) < 0) {
16218c2aff7Sartem HAL_ERROR (("Could not normalize '%s' and '%s', return 'NULL'", path1, path2));
16318c2aff7Sartem return NULL;
16418c2aff7Sartem }
16518c2aff7Sartem
16618c2aff7Sartem strncpy (buf, path1, (p1-path1));
16718c2aff7Sartem buf[p1-path1] = '\0';
16818c2aff7Sartem
16918c2aff7Sartem return g_strdup_printf ("%s/%s", buf, p2);
17018c2aff7Sartem }
17118c2aff7Sartem
17218c2aff7Sartem gboolean
hal_util_get_int_from_file(const gchar * directory,const gchar * file,gint * result,gint base)17318c2aff7Sartem hal_util_get_int_from_file (const gchar *directory, const gchar *file, gint *result, gint base)
17418c2aff7Sartem {
17518c2aff7Sartem FILE *f;
17618c2aff7Sartem char buf[64];
17718c2aff7Sartem gchar path[HAL_PATH_MAX];
17818c2aff7Sartem gboolean ret;
17918c2aff7Sartem
18018c2aff7Sartem f = NULL;
18118c2aff7Sartem ret = FALSE;
18218c2aff7Sartem
18318c2aff7Sartem g_snprintf (path, sizeof (path), "%s/%s", directory, file);
18418c2aff7Sartem
18518c2aff7Sartem f = fopen (path, "rb");
18618c2aff7Sartem if (f == NULL) {
18718c2aff7Sartem HAL_ERROR (("Cannot open '%s'", path));
18818c2aff7Sartem goto out;
18918c2aff7Sartem }
19018c2aff7Sartem
19118c2aff7Sartem if (fgets (buf, sizeof (buf), f) == NULL) {
19218c2aff7Sartem HAL_ERROR (("Cannot read from '%s'", path));
19318c2aff7Sartem goto out;
19418c2aff7Sartem }
19518c2aff7Sartem
19618c2aff7Sartem /* TODO: handle error condition */
19718c2aff7Sartem *result = strtol (buf, NULL, base);
19818c2aff7Sartem ret = TRUE;
19918c2aff7Sartem
20018c2aff7Sartem out:
20118c2aff7Sartem if (f != NULL)
20218c2aff7Sartem fclose (f);
20318c2aff7Sartem
20418c2aff7Sartem return ret;
20518c2aff7Sartem }
20618c2aff7Sartem
20718c2aff7Sartem gboolean
hal_util_set_int_from_file(HalDevice * d,const gchar * key,const gchar * directory,const gchar * file,gint base)20818c2aff7Sartem hal_util_set_int_from_file (HalDevice *d, const gchar *key, const gchar *directory, const gchar *file, gint base)
20918c2aff7Sartem {
21018c2aff7Sartem gint value;
21118c2aff7Sartem gboolean ret;
21218c2aff7Sartem
21318c2aff7Sartem ret = FALSE;
21418c2aff7Sartem
21518c2aff7Sartem if (hal_util_get_int_from_file (directory, file, &value, base))
21618c2aff7Sartem ret = hal_device_property_set_int (d, key, value);
21718c2aff7Sartem
21818c2aff7Sartem return ret;
21918c2aff7Sartem }
22018c2aff7Sartem
22118c2aff7Sartem
22218c2aff7Sartem gboolean
hal_util_get_uint64_from_file(const gchar * directory,const gchar * file,guint64 * result,gint base)22318c2aff7Sartem hal_util_get_uint64_from_file (const gchar *directory, const gchar *file, guint64 *result, gint base)
22418c2aff7Sartem {
22518c2aff7Sartem FILE *f;
22618c2aff7Sartem char buf[64];
22718c2aff7Sartem gchar path[HAL_PATH_MAX];
22818c2aff7Sartem gboolean ret;
22918c2aff7Sartem
23018c2aff7Sartem f = NULL;
23118c2aff7Sartem ret = FALSE;
23218c2aff7Sartem
23318c2aff7Sartem g_snprintf (path, sizeof (path), "%s/%s", directory, file);
23418c2aff7Sartem
23518c2aff7Sartem f = fopen (path, "rb");
23618c2aff7Sartem if (f == NULL) {
23718c2aff7Sartem HAL_ERROR (("Cannot open '%s'", path));
23818c2aff7Sartem goto out;
23918c2aff7Sartem }
24018c2aff7Sartem
24118c2aff7Sartem if (fgets (buf, sizeof (buf), f) == NULL) {
24218c2aff7Sartem HAL_ERROR (("Cannot read from '%s'", path));
24318c2aff7Sartem goto out;
24418c2aff7Sartem }
24518c2aff7Sartem
24618c2aff7Sartem /* TODO: handle error condition */
24718c2aff7Sartem *result = strtoll (buf, NULL, base);
24818c2aff7Sartem
24918c2aff7Sartem ret = TRUE;
25018c2aff7Sartem
25118c2aff7Sartem out:
25218c2aff7Sartem if (f != NULL)
25318c2aff7Sartem fclose (f);
25418c2aff7Sartem
25518c2aff7Sartem return ret;
25618c2aff7Sartem }
25718c2aff7Sartem
25818c2aff7Sartem gboolean
hal_util_set_uint64_from_file(HalDevice * d,const gchar * key,const gchar * directory,const gchar * file,gint base)25918c2aff7Sartem hal_util_set_uint64_from_file (HalDevice *d, const gchar *key, const gchar *directory, const gchar *file, gint base)
26018c2aff7Sartem {
26118c2aff7Sartem guint64 value;
26218c2aff7Sartem gboolean ret;
26318c2aff7Sartem
26418c2aff7Sartem ret = FALSE;
26518c2aff7Sartem
26618c2aff7Sartem if (hal_util_get_uint64_from_file (directory, file, &value, base))
26718c2aff7Sartem ret = hal_device_property_set_uint64 (d, key, value);
26818c2aff7Sartem
26918c2aff7Sartem return ret;
27018c2aff7Sartem }
27118c2aff7Sartem
27218c2aff7Sartem gboolean
hal_util_get_bcd2_from_file(const gchar * directory,const gchar * file,gint * result)27318c2aff7Sartem hal_util_get_bcd2_from_file (const gchar *directory, const gchar *file, gint *result)
27418c2aff7Sartem {
27518c2aff7Sartem FILE *f;
27618c2aff7Sartem char buf[64];
27718c2aff7Sartem gchar path[HAL_PATH_MAX];
27818c2aff7Sartem gboolean ret;
27918c2aff7Sartem gint digit;
28018c2aff7Sartem gint left, right;
28118c2aff7Sartem gboolean passed_white_space;
28218c2aff7Sartem gint num_prec;
28318c2aff7Sartem gsize len;
28418c2aff7Sartem gchar c;
28518c2aff7Sartem guint i;
28618c2aff7Sartem
28718c2aff7Sartem f = NULL;
28818c2aff7Sartem ret = FALSE;
28918c2aff7Sartem
29018c2aff7Sartem g_snprintf (path, sizeof (path), "%s/%s", directory, file);
29118c2aff7Sartem
29218c2aff7Sartem f = fopen (path, "rb");
29318c2aff7Sartem if (f == NULL) {
29418c2aff7Sartem HAL_ERROR (("Cannot open '%s'", path));
29518c2aff7Sartem goto out;
29618c2aff7Sartem }
29718c2aff7Sartem
29818c2aff7Sartem if (fgets (buf, sizeof (buf), f) == NULL) {
29918c2aff7Sartem HAL_ERROR (("Cannot read from '%s'", path));
30018c2aff7Sartem goto out;
30118c2aff7Sartem }
30218c2aff7Sartem
30318c2aff7Sartem left = 0;
30418c2aff7Sartem len = strlen (buf);
30518c2aff7Sartem passed_white_space = FALSE;
30618c2aff7Sartem for (i = 0; i < len && buf[i] != '.'; i++) {
30718c2aff7Sartem if (g_ascii_isspace (buf[i])) {
30818c2aff7Sartem if (passed_white_space)
30918c2aff7Sartem break;
31018c2aff7Sartem else
31118c2aff7Sartem continue;
31218c2aff7Sartem }
31318c2aff7Sartem passed_white_space = TRUE;
31418c2aff7Sartem left *= 16;
31518c2aff7Sartem c = buf[i];
31618c2aff7Sartem digit = (int) (c - '0');
31718c2aff7Sartem left += digit;
31818c2aff7Sartem }
31918c2aff7Sartem i++;
32018c2aff7Sartem right = 0;
32118c2aff7Sartem num_prec = 0;
32218c2aff7Sartem for (; i < len; i++) {
32318c2aff7Sartem if (g_ascii_isspace (buf[i]))
32418c2aff7Sartem break;
32518c2aff7Sartem if (num_prec == 2) /* Only care about two digits
32618c2aff7Sartem * of precision */
32718c2aff7Sartem break;
32818c2aff7Sartem right *= 16;
32918c2aff7Sartem c = buf[i];
33018c2aff7Sartem digit = (int) (c - '0');
33118c2aff7Sartem right += digit;
33218c2aff7Sartem num_prec++;
33318c2aff7Sartem }
33418c2aff7Sartem
33518c2aff7Sartem for (; num_prec < 2; num_prec++)
33618c2aff7Sartem right *= 16;
33718c2aff7Sartem
33818c2aff7Sartem *result = left * 256 + (right & 255);
33918c2aff7Sartem ret = TRUE;
34018c2aff7Sartem
34118c2aff7Sartem out:
34218c2aff7Sartem if (f != NULL)
34318c2aff7Sartem fclose (f);
34418c2aff7Sartem
34518c2aff7Sartem return ret;
34618c2aff7Sartem }
34718c2aff7Sartem
34818c2aff7Sartem gboolean
hal_util_set_bcd2_from_file(HalDevice * d,const gchar * key,const gchar * directory,const gchar * file)34918c2aff7Sartem hal_util_set_bcd2_from_file (HalDevice *d, const gchar *key, const gchar *directory, const gchar *file)
35018c2aff7Sartem {
35118c2aff7Sartem gint value;
35218c2aff7Sartem gboolean ret;
35318c2aff7Sartem
35418c2aff7Sartem ret = FALSE;
35518c2aff7Sartem
35618c2aff7Sartem if (hal_util_get_bcd2_from_file (directory, file, &value))
35718c2aff7Sartem ret = hal_device_property_set_int (d, key, value);
35818c2aff7Sartem
35918c2aff7Sartem return ret;
36018c2aff7Sartem }
36118c2aff7Sartem
36218c2aff7Sartem gchar *
hal_util_get_string_from_file(const gchar * directory,const gchar * file)36318c2aff7Sartem hal_util_get_string_from_file (const gchar *directory, const gchar *file)
36418c2aff7Sartem {
36518c2aff7Sartem FILE *f;
36618c2aff7Sartem static gchar buf[256];
36718c2aff7Sartem gchar path[HAL_PATH_MAX];
36818c2aff7Sartem gchar *result;
36918c2aff7Sartem gsize len;
37018c2aff7Sartem gint i;
37118c2aff7Sartem
37218c2aff7Sartem f = NULL;
37318c2aff7Sartem result = NULL;
37418c2aff7Sartem
37518c2aff7Sartem g_snprintf (path, sizeof (path), "%s/%s", directory, file);
37618c2aff7Sartem
37718c2aff7Sartem f = fopen (path, "rb");
37818c2aff7Sartem if (f == NULL) {
37918c2aff7Sartem HAL_ERROR (("Cannot open '%s'", path));
38018c2aff7Sartem goto out;
38118c2aff7Sartem }
38218c2aff7Sartem
38318c2aff7Sartem buf[0] = '\0';
38418c2aff7Sartem if (fgets (buf, sizeof (buf), f) == NULL) {
38518c2aff7Sartem HAL_ERROR (("Cannot read from '%s'", path));
38618c2aff7Sartem goto out;
38718c2aff7Sartem }
38818c2aff7Sartem
38918c2aff7Sartem len = strlen (buf);
39018c2aff7Sartem if (len>0)
39118c2aff7Sartem buf[len-1] = '\0';
39218c2aff7Sartem
39318c2aff7Sartem /* Clear remaining whitespace */
39418c2aff7Sartem for (i = len - 2; i >= 0; --i) {
39518c2aff7Sartem if (!g_ascii_isspace (buf[i]))
39618c2aff7Sartem break;
39718c2aff7Sartem buf[i] = '\0';
39818c2aff7Sartem }
39918c2aff7Sartem
40018c2aff7Sartem result = buf;
40118c2aff7Sartem
40218c2aff7Sartem out:
40318c2aff7Sartem if (f != NULL)
40418c2aff7Sartem fclose (f);
40518c2aff7Sartem
40618c2aff7Sartem return result;
40718c2aff7Sartem }
40818c2aff7Sartem
40918c2aff7Sartem gboolean
hal_util_set_string_from_file(HalDevice * d,const gchar * key,const gchar * directory,const gchar * file)41018c2aff7Sartem hal_util_set_string_from_file (HalDevice *d, const gchar *key, const gchar *directory, const gchar *file)
41118c2aff7Sartem {
41218c2aff7Sartem gchar *buf;
41318c2aff7Sartem gboolean ret;
41418c2aff7Sartem
41518c2aff7Sartem ret = FALSE;
41618c2aff7Sartem
41718c2aff7Sartem if ((buf = hal_util_get_string_from_file (directory, file)) != NULL)
41818c2aff7Sartem ret = hal_device_property_set_string (d, key, buf);
41918c2aff7Sartem
42018c2aff7Sartem return ret;
42118c2aff7Sartem }
42218c2aff7Sartem
42318c2aff7Sartem void
hal_util_compute_udi(HalDeviceStore * store,gchar * dst,gsize dstsize,const gchar * format,...)42418c2aff7Sartem hal_util_compute_udi (HalDeviceStore *store, gchar *dst, gsize dstsize, const gchar *format, ...)
42518c2aff7Sartem {
42618c2aff7Sartem guint i;
42718c2aff7Sartem va_list args;
42818c2aff7Sartem gchar buf[256];
42918c2aff7Sartem
43018c2aff7Sartem va_start (args, format);
43118c2aff7Sartem g_vsnprintf (buf, sizeof (buf), format, args);
43218c2aff7Sartem va_end (args);
43318c2aff7Sartem
43418c2aff7Sartem g_strcanon (buf,
43518c2aff7Sartem "/_"
43618c2aff7Sartem "abcdefghijklmnopqrstuvwxyz"
43718c2aff7Sartem "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
43818c2aff7Sartem "1234567890", '_');
43918c2aff7Sartem
44018c2aff7Sartem g_strlcpy (dst, buf, dstsize);
44118c2aff7Sartem if (hal_device_store_find (store, dst) == NULL)
44218c2aff7Sartem goto out;
44318c2aff7Sartem
44418c2aff7Sartem for (i = 0; ; i++) {
44518c2aff7Sartem g_snprintf (dst, dstsize, "%s_%d", buf, i);
44618c2aff7Sartem if (hal_device_store_find (store, dst) == NULL)
44718c2aff7Sartem goto out;
44818c2aff7Sartem }
44918c2aff7Sartem
45018c2aff7Sartem out:
45118c2aff7Sartem ;
45218c2aff7Sartem }
45318c2aff7Sartem
45418c2aff7Sartem
45518c2aff7Sartem gboolean
hal_util_path_ascend(gchar * path)45618c2aff7Sartem hal_util_path_ascend (gchar *path)
45718c2aff7Sartem {
45818c2aff7Sartem gchar *p;
45918c2aff7Sartem
46018c2aff7Sartem if (path == NULL)
46118c2aff7Sartem return FALSE;
46218c2aff7Sartem
46318c2aff7Sartem p = strrchr (path, '/');
46418c2aff7Sartem if (p == NULL)
46518c2aff7Sartem return FALSE;
46618c2aff7Sartem
46718c2aff7Sartem *p = '\0';
46818c2aff7Sartem return TRUE;
46918c2aff7Sartem }
47018c2aff7Sartem
47118c2aff7Sartem static gboolean _grep_can_reuse = FALSE;
47218c2aff7Sartem
47318c2aff7Sartem void
hal_util_grep_discard_existing_data(void)47418c2aff7Sartem hal_util_grep_discard_existing_data (void)
47518c2aff7Sartem {
47618c2aff7Sartem _grep_can_reuse = FALSE;
47718c2aff7Sartem }
47818c2aff7Sartem
47918c2aff7Sartem /** Given a directory and filename, open the file and search for the
48018c2aff7Sartem * first line that starts with the given linestart string. Returns
48118c2aff7Sartem * the rest of the line as a string if found.
48218c2aff7Sartem *
48318c2aff7Sartem * @param directory Directory, e.g. "/proc/acpi/battery/BAT0"
48418c2aff7Sartem * @param file File, e.g. "info"
48518c2aff7Sartem * @param linestart Start of line, e.g. "serial number"
48618c2aff7Sartem * @param reuse Whether we should reuse the file contents
48718c2aff7Sartem * if the file is the same; can be cleared
48818c2aff7Sartem * with hal_util_grep_discard_existing_data()
48918c2aff7Sartem * @return NULL if not found, otherwise the remainder
49018c2aff7Sartem * of the line, e.g. ": 21805" if
49118c2aff7Sartem * the file /proc/acpi/battery/BAT0 contains
49218c2aff7Sartem * this line "serial number: 21805"
49318c2aff7Sartem * The string is only valid until the next
49418c2aff7Sartem * invocation of this function.
49518c2aff7Sartem */
49618c2aff7Sartem gchar *
hal_util_grep_file(const gchar * directory,const gchar * file,const gchar * linestart,gboolean reuse)49718c2aff7Sartem hal_util_grep_file (const gchar *directory, const gchar *file, const gchar *linestart, gboolean reuse)
49818c2aff7Sartem {
49918c2aff7Sartem static gchar buf[2048];
50018c2aff7Sartem static unsigned int bufsize;
50118c2aff7Sartem static gchar filename[HAL_PATH_MAX];
50218c2aff7Sartem static gchar oldfilename[HAL_PATH_MAX];
50318c2aff7Sartem gchar *result;
50418c2aff7Sartem gsize linestart_len;
50518c2aff7Sartem gchar *p;
50618c2aff7Sartem
50718c2aff7Sartem result = NULL;
50818c2aff7Sartem
50918c2aff7Sartem /* TODO: use reuse and _grep_can_reuse parameters to avoid loading
51018c2aff7Sartem * the file again and again
51118c2aff7Sartem */
51218c2aff7Sartem
51318c2aff7Sartem if (file != NULL && strlen (file) > 0)
51418c2aff7Sartem snprintf (filename, sizeof (filename), "%s/%s", directory, file);
51518c2aff7Sartem else
51618c2aff7Sartem strncpy (filename, directory, sizeof (filename));
51718c2aff7Sartem
51818c2aff7Sartem if (_grep_can_reuse && reuse && strcmp (oldfilename, filename) == 0) {
51918c2aff7Sartem /* just reuse old file; e.g. bufsize, buf */
52018c2aff7Sartem /*HAL_INFO (("hal_util_grep_file: reusing buf for %s", filename));*/
52118c2aff7Sartem } else {
52218c2aff7Sartem FILE *f;
52318c2aff7Sartem
52418c2aff7Sartem f = fopen (filename, "r");
52518c2aff7Sartem if (f == NULL)
52618c2aff7Sartem goto out;
52718c2aff7Sartem bufsize = fread (buf, sizeof (char), sizeof (buf) - 1, f);
52818c2aff7Sartem buf[bufsize] = '\0';
52918c2aff7Sartem fclose (f);
53018c2aff7Sartem
53118c2aff7Sartem /*HAL_INFO (("hal_util_grep_file: read %s of %d bytes", filename, bufsize));*/
53218c2aff7Sartem }
53318c2aff7Sartem
53418c2aff7Sartem /* book keeping */
53518c2aff7Sartem _grep_can_reuse = TRUE;
53618c2aff7Sartem strncpy (oldfilename, filename, sizeof(oldfilename));
53718c2aff7Sartem
53818c2aff7Sartem linestart_len = strlen (linestart);
53918c2aff7Sartem
54018c2aff7Sartem /* analyze buf */
54118c2aff7Sartem p = buf;
54218c2aff7Sartem do {
54318c2aff7Sartem unsigned int linelen;
54418c2aff7Sartem static char line[256];
54518c2aff7Sartem
54618c2aff7Sartem for (linelen = 0; p[linelen] != '\n' && p[linelen] != '\0'; linelen++)
54718c2aff7Sartem ;
54818c2aff7Sartem
54918c2aff7Sartem if (linelen < sizeof (line)) {
55018c2aff7Sartem
55118c2aff7Sartem strncpy (line, p, linelen);
55218c2aff7Sartem line[linelen] = '\0';
55318c2aff7Sartem
55418c2aff7Sartem if (strncmp (line, linestart, linestart_len) == 0) {
55518c2aff7Sartem result = line + linestart_len;
55618c2aff7Sartem goto out;
55718c2aff7Sartem }
55818c2aff7Sartem }
55918c2aff7Sartem
56018c2aff7Sartem p += linelen + 1;
56118c2aff7Sartem
56218c2aff7Sartem } while (p < buf + bufsize);
56318c2aff7Sartem
56418c2aff7Sartem out:
56518c2aff7Sartem return result;
56618c2aff7Sartem }
56718c2aff7Sartem
56818c2aff7Sartem gchar *
hal_util_grep_string_elem_from_file(const gchar * directory,const gchar * file,const gchar * linestart,guint elem,gboolean reuse)56918c2aff7Sartem hal_util_grep_string_elem_from_file (const gchar *directory, const gchar *file,
57018c2aff7Sartem const gchar *linestart, guint elem, gboolean reuse)
57118c2aff7Sartem {
57218c2aff7Sartem gchar *line;
57318c2aff7Sartem gchar *res;
57418c2aff7Sartem static gchar buf[256];
57518c2aff7Sartem gchar **tokens;
57618c2aff7Sartem guint i, j;
57718c2aff7Sartem
57818c2aff7Sartem res = NULL;
57918c2aff7Sartem tokens = NULL;
58018c2aff7Sartem
58118c2aff7Sartem if (((line = hal_util_grep_file (directory, file, linestart, reuse)) == NULL) || (strlen (line) == 0))
58218c2aff7Sartem goto out;
58318c2aff7Sartem
58418c2aff7Sartem tokens = g_strsplit_set (line, " \t:", 0);
58518c2aff7Sartem for (i = 0, j = 0; tokens[i] != NULL; i++) {
58618c2aff7Sartem if (strlen (tokens[i]) == 0)
58718c2aff7Sartem continue;
58818c2aff7Sartem if (j == elem) {
58918c2aff7Sartem strncpy (buf, tokens[i], sizeof (buf));
59018c2aff7Sartem res = buf;
59118c2aff7Sartem goto out;
59218c2aff7Sartem }
59318c2aff7Sartem j++;
59418c2aff7Sartem }
59518c2aff7Sartem
59618c2aff7Sartem out:
59718c2aff7Sartem if (tokens != NULL)
59818c2aff7Sartem g_strfreev (tokens);
59918c2aff7Sartem
60018c2aff7Sartem return res;
60118c2aff7Sartem }
60218c2aff7Sartem
60318c2aff7Sartem gint
hal_util_grep_int_elem_from_file(const gchar * directory,const gchar * file,const gchar * linestart,guint elem,guint base,gboolean reuse)60418c2aff7Sartem hal_util_grep_int_elem_from_file (const gchar *directory, const gchar *file,
60518c2aff7Sartem const gchar *linestart, guint elem, guint base, gboolean reuse)
60618c2aff7Sartem {
60718c2aff7Sartem gchar *endptr;
60818c2aff7Sartem gchar *strvalue;
60918c2aff7Sartem int value;
61018c2aff7Sartem
61118c2aff7Sartem value = G_MAXINT;
61218c2aff7Sartem
61318c2aff7Sartem strvalue = hal_util_grep_string_elem_from_file (directory, file, linestart, elem, reuse);
61418c2aff7Sartem if (strvalue == NULL)
61518c2aff7Sartem goto out;
61618c2aff7Sartem
61718c2aff7Sartem value = strtol (strvalue, &endptr, base);
61818c2aff7Sartem if (endptr == strvalue) {
61918c2aff7Sartem value = G_MAXINT;
62018c2aff7Sartem goto out;
62118c2aff7Sartem }
62218c2aff7Sartem
62318c2aff7Sartem out:
62418c2aff7Sartem return value;
62518c2aff7Sartem }
62618c2aff7Sartem
62718c2aff7Sartem /** Get a string value from a formatted text file and assign it to
62818c2aff7Sartem * a property on a device object.
62918c2aff7Sartem *
63018c2aff7Sartem * Example: Given that the file /proc/acpi/battery/BAT0/info contains
63118c2aff7Sartem * the line
63218c2aff7Sartem *
63318c2aff7Sartem * "design voltage: 10800 mV"
63418c2aff7Sartem *
63518c2aff7Sartem * then hal_util_set_string_elem_from_file (d, "battery.foo",
63618c2aff7Sartem * "/proc/acpi/battery/BAT0", "info", "design voltage", 1) will assign
63718c2aff7Sartem * the string "mV" to the property "battery.foo" on d.
63818c2aff7Sartem *
63918c2aff7Sartem * @param d Device object
64018c2aff7Sartem * @param key Property name
64118c2aff7Sartem * @param directory Directory, e.g. "/proc/acpi/battery/BAT0"
64218c2aff7Sartem * @param file File, e.g. "info"
64318c2aff7Sartem * @param linestart Start of line, e.g. "design voltage"
64418c2aff7Sartem * @param elem Element number after linestart to extract
64518c2aff7Sartem * excluding whitespace and ':' characters.
64618c2aff7Sartem * @return TRUE, if, and only if, the value could be
64718c2aff7Sartem * extracted and the property was set
64818c2aff7Sartem */
64918c2aff7Sartem 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)65018c2aff7Sartem hal_util_set_string_elem_from_file (HalDevice *d, const gchar *key,
65118c2aff7Sartem const gchar *directory, const gchar *file,
65218c2aff7Sartem const gchar *linestart, guint elem, gboolean reuse)
65318c2aff7Sartem {
65418c2aff7Sartem gboolean res;
65518c2aff7Sartem gchar *value;
65618c2aff7Sartem
65718c2aff7Sartem res = FALSE;
65818c2aff7Sartem
65918c2aff7Sartem if ((value = hal_util_grep_string_elem_from_file (directory, file, linestart, elem, reuse)) == NULL)
66018c2aff7Sartem goto out;
66118c2aff7Sartem
66218c2aff7Sartem res = hal_device_property_set_string (d, key, value);
66318c2aff7Sartem out:
66418c2aff7Sartem return res;
66518c2aff7Sartem }
66618c2aff7Sartem
66718c2aff7Sartem /** Get an integer value from a formatted text file and assign it to
66818c2aff7Sartem * a property on a device object.
66918c2aff7Sartem *
67018c2aff7Sartem * Example: Given that the file /proc/acpi/battery/BAT0/info contains
67118c2aff7Sartem * the line
67218c2aff7Sartem *
67318c2aff7Sartem * "design voltage: 10800 mV"
67418c2aff7Sartem *
67518c2aff7Sartem * then hal_util_set_int_elem_from_file (d, "battery.foo",
67618c2aff7Sartem * "/proc/acpi/battery/BAT0", "info", "design voltage", 0) will assign
67718c2aff7Sartem * the integer 10800 to the property "battery.foo" on d.
67818c2aff7Sartem *
67918c2aff7Sartem * @param d Device object
68018c2aff7Sartem * @param key Property name
68118c2aff7Sartem * @param directory Directory, e.g. "/proc/acpi/battery/BAT0"
68218c2aff7Sartem * @param file File, e.g. "info"
68318c2aff7Sartem * @param linestart Start of line, e.g. "design voltage"
68418c2aff7Sartem * @param elem Element number after linestart to extract
68518c2aff7Sartem * excluding whitespace and ':' characters.
68618c2aff7Sartem * @return TRUE, if, and only if, the value could be
68718c2aff7Sartem * extracted and the property was set
68818c2aff7Sartem */
68918c2aff7Sartem 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)69018c2aff7Sartem hal_util_set_int_elem_from_file (HalDevice *d, const gchar *key,
69118c2aff7Sartem const gchar *directory, const gchar *file,
69218c2aff7Sartem const gchar *linestart, guint elem, guint base, gboolean reuse)
69318c2aff7Sartem {
69418c2aff7Sartem gchar *endptr;
69518c2aff7Sartem gboolean res;
69618c2aff7Sartem gchar *strvalue;
69718c2aff7Sartem int value;
69818c2aff7Sartem
69918c2aff7Sartem res = FALSE;
70018c2aff7Sartem
70118c2aff7Sartem strvalue = hal_util_grep_string_elem_from_file (directory, file, linestart, elem, reuse);
70218c2aff7Sartem if (strvalue == NULL)
70318c2aff7Sartem goto out;
70418c2aff7Sartem
70518c2aff7Sartem value = strtol (strvalue, &endptr, base);
70618c2aff7Sartem if (endptr == strvalue)
70718c2aff7Sartem goto out;
70818c2aff7Sartem
70918c2aff7Sartem res = hal_device_property_set_int (d, key, value);
71018c2aff7Sartem
71118c2aff7Sartem out:
71218c2aff7Sartem return res;
71318c2aff7Sartem
71418c2aff7Sartem }
71518c2aff7Sartem
71618c2aff7Sartem /** Get a value from a formatted text file, test it against a given
71718c2aff7Sartem * value, and set a boolean property on a device object with the
71818c2aff7Sartem * test result.
71918c2aff7Sartem *
72018c2aff7Sartem * Example: Given that the file /proc/acpi/battery/BAT0/info contains
72118c2aff7Sartem * the line
72218c2aff7Sartem *
72318c2aff7Sartem * "present: yes"
72418c2aff7Sartem *
72518c2aff7Sartem * then hal_util_set_bool_elem_from_file (d, "battery.baz",
72618c2aff7Sartem * "/proc/acpi/battery/BAT0", "info", "present", 0, "yes") will assign
72718c2aff7Sartem * the boolean TRUE to the property "battery.baz" on d.
72818c2aff7Sartem *
72918c2aff7Sartem * If, instead, the line was
73018c2aff7Sartem *
73118c2aff7Sartem * "present: no"
73218c2aff7Sartem *
73318c2aff7Sartem * the value assigned will be FALSE.
73418c2aff7Sartem *
73518c2aff7Sartem * @param d Device object
73618c2aff7Sartem * @param key Property name
73718c2aff7Sartem * @param directory Directory, e.g. "/proc/acpi/battery/BAT0"
73818c2aff7Sartem * @param file File, e.g. "info"
73918c2aff7Sartem * @param linestart Start of line, e.g. "design voltage"
74018c2aff7Sartem * @param elem Element number after linestart to extract
74118c2aff7Sartem * excluding whitespace and ':' characters.
74218c2aff7Sartem * @param expected Value to test against
74318c2aff7Sartem * @return TRUE, if, and only if, the value could be
74418c2aff7Sartem * extracted and the property was set
74518c2aff7Sartem */
74618c2aff7Sartem 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)74718c2aff7Sartem hal_util_set_bool_elem_from_file (HalDevice *d, const gchar *key,
74818c2aff7Sartem const gchar *directory, const gchar *file,
74918c2aff7Sartem const gchar *linestart, guint elem, const gchar *expected, gboolean reuse)
75018c2aff7Sartem {
75118c2aff7Sartem gchar *line;
75218c2aff7Sartem gboolean res;
75318c2aff7Sartem gchar **tokens;
75418c2aff7Sartem guint i, j;
75518c2aff7Sartem
75618c2aff7Sartem res = FALSE;
75718c2aff7Sartem tokens = NULL;
75818c2aff7Sartem
75918c2aff7Sartem if (((line = hal_util_grep_file (directory, file, linestart, reuse)) == NULL) || (strlen (line) == 0))
76018c2aff7Sartem goto out;
76118c2aff7Sartem
76218c2aff7Sartem tokens = g_strsplit_set (line, " \t:", 0);
76318c2aff7Sartem
76418c2aff7Sartem for (i = 0, j = 0; tokens[i] != NULL; i++) {
76518c2aff7Sartem if (strlen (tokens[i]) == 0)
76618c2aff7Sartem continue;
76718c2aff7Sartem if (j == elem) {
76818c2aff7Sartem hal_device_property_set_bool (d, key, strcmp (tokens[i], expected) == 0);
76918c2aff7Sartem res = TRUE;
77018c2aff7Sartem goto out;
77118c2aff7Sartem }
77218c2aff7Sartem j++;
77318c2aff7Sartem }
77418c2aff7Sartem
77518c2aff7Sartem
77618c2aff7Sartem out:
77718c2aff7Sartem if (tokens != NULL)
77818c2aff7Sartem g_strfreev (tokens);
77918c2aff7Sartem
78018c2aff7Sartem return res;
78118c2aff7Sartem }
78218c2aff7Sartem
78318c2aff7Sartem gchar **
hal_util_dup_strv_from_g_slist(GSList * strlist)78418c2aff7Sartem hal_util_dup_strv_from_g_slist (GSList *strlist)
78518c2aff7Sartem {
78618c2aff7Sartem guint j;
78718c2aff7Sartem guint len;
78818c2aff7Sartem gchar **strv;
78918c2aff7Sartem GSList *i;
79018c2aff7Sartem
79118c2aff7Sartem len = g_slist_length (strlist);
79218c2aff7Sartem strv = g_new (char *, len + 1);
79318c2aff7Sartem
79418c2aff7Sartem for (i = strlist, j = 0; i != NULL; i = g_slist_next (i), j++) {
79518c2aff7Sartem strv[j] = g_strdup ((const gchar *) i->data);
79618c2aff7Sartem }
79718c2aff7Sartem strv[j] = NULL;
79818c2aff7Sartem
79918c2aff7Sartem return strv;
80018c2aff7Sartem }
80118c2aff7Sartem
80218c2aff7Sartem /* -------------------------------------------------------------------------------------------------------------- */
80318c2aff7Sartem
80418c2aff7Sartem typedef struct {
80518c2aff7Sartem HalDevice *d;
80618c2aff7Sartem gchar **programs;
80718c2aff7Sartem gchar **extra_env;
80818c2aff7Sartem guint next_program;
80918c2aff7Sartem
81018c2aff7Sartem HalCalloutsDone callback;
81118c2aff7Sartem gpointer userdata1;
81218c2aff7Sartem gpointer userdata2;
81318c2aff7Sartem
81418c2aff7Sartem } Callout;
81518c2aff7Sartem
81618c2aff7Sartem static void callout_do_next (Callout *c);
81718c2aff7Sartem
81818c2aff7Sartem static void
callout_terminated(HalDevice * d,guint32 exit_type,gint return_code,gchar ** error,gpointer data1,gpointer data2)81918c2aff7Sartem callout_terminated (HalDevice *d, guint32 exit_type,
82018c2aff7Sartem gint return_code, gchar **error,
82118c2aff7Sartem gpointer data1, gpointer data2)
82218c2aff7Sartem {
82318c2aff7Sartem Callout *c;
82418c2aff7Sartem
82518c2aff7Sartem c = (Callout *) data1;
82618c2aff7Sartem callout_do_next (c);
82718c2aff7Sartem }
82818c2aff7Sartem
82918c2aff7Sartem static void
callout_do_next(Callout * c)83018c2aff7Sartem callout_do_next (Callout *c)
83118c2aff7Sartem {
83218c2aff7Sartem
83318c2aff7Sartem /* Check if we're done */
83418c2aff7Sartem if (c->programs[c->next_program] == NULL) {
83518c2aff7Sartem HalDevice *d;
83618c2aff7Sartem gpointer userdata1;
83718c2aff7Sartem gpointer userdata2;
83818c2aff7Sartem HalCalloutsDone callback;
83918c2aff7Sartem
84018c2aff7Sartem d = c->d;
84118c2aff7Sartem userdata1 = c->userdata1;
84218c2aff7Sartem userdata2 = c->userdata2;
84318c2aff7Sartem callback = c->callback;
84418c2aff7Sartem
84518c2aff7Sartem g_strfreev (c->programs);
84618c2aff7Sartem g_strfreev (c->extra_env);
84718c2aff7Sartem g_free (c);
84818c2aff7Sartem
84918c2aff7Sartem callback (d, userdata1, userdata2);
85018c2aff7Sartem
85118c2aff7Sartem } else {
85218c2aff7Sartem hald_runner_run(c->d, c->programs[c->next_program], c->extra_env,
85318c2aff7Sartem HAL_HELPER_TIMEOUT, callout_terminated,
85418c2aff7Sartem (gpointer)c, NULL);
85518c2aff7Sartem c->next_program++;
85618c2aff7Sartem }
85718c2aff7Sartem }
85818c2aff7Sartem
85918c2aff7Sartem static void
hal_callout_device(HalDevice * d,HalCalloutsDone callback,gpointer userdata1,gpointer userdata2,GSList * programs,gchar ** extra_env)86018c2aff7Sartem hal_callout_device (HalDevice *d, HalCalloutsDone callback, gpointer userdata1, gpointer userdata2,
86118c2aff7Sartem GSList *programs, gchar **extra_env)
86218c2aff7Sartem {
86318c2aff7Sartem Callout *c;
86418c2aff7Sartem
86518c2aff7Sartem c = g_new0 (Callout, 1);
86618c2aff7Sartem c->d = d;
86718c2aff7Sartem c->callback = callback;
86818c2aff7Sartem c->userdata1 = userdata1;
86918c2aff7Sartem c->userdata2 = userdata2;
87018c2aff7Sartem c->programs = hal_util_dup_strv_from_g_slist (programs);
87118c2aff7Sartem c->extra_env = g_strdupv (extra_env);
87218c2aff7Sartem c->next_program = 0;
87318c2aff7Sartem
87418c2aff7Sartem callout_do_next (c);
87518c2aff7Sartem }
87618c2aff7Sartem
87718c2aff7Sartem void
hal_util_callout_device_add(HalDevice * d,HalCalloutsDone callback,gpointer userdata1,gpointer userdata2)87818c2aff7Sartem hal_util_callout_device_add (HalDevice *d, HalCalloutsDone callback, gpointer userdata1, gpointer userdata2)
87918c2aff7Sartem {
88018c2aff7Sartem GSList *programs;
88118c2aff7Sartem gchar *extra_env[2] = {"HALD_ACTION=add", NULL};
88218c2aff7Sartem
88318c2aff7Sartem if ((programs = hal_device_property_get_strlist (d, "info.callouts.add")) == NULL) {
88418c2aff7Sartem callback (d, userdata1, userdata2);
88518c2aff7Sartem goto out;
88618c2aff7Sartem }
88718c2aff7Sartem
88818c2aff7Sartem HAL_INFO (("Add callouts for udi=%s", d->udi));
88918c2aff7Sartem
89018c2aff7Sartem hal_callout_device (d, callback, userdata1, userdata2, programs, extra_env);
89118c2aff7Sartem out:
89218c2aff7Sartem ;
89318c2aff7Sartem }
89418c2aff7Sartem
89518c2aff7Sartem void
hal_util_callout_device_remove(HalDevice * d,HalCalloutsDone callback,gpointer userdata1,gpointer userdata2)89618c2aff7Sartem hal_util_callout_device_remove (HalDevice *d, HalCalloutsDone callback, gpointer userdata1, gpointer userdata2)
89718c2aff7Sartem {
89818c2aff7Sartem GSList *programs;
89918c2aff7Sartem gchar *extra_env[2] = {"HALD_ACTION=remove", NULL};
90018c2aff7Sartem
90118c2aff7Sartem if ((programs = hal_device_property_get_strlist (d, "info.callouts.remove")) == NULL) {
90218c2aff7Sartem callback (d, userdata1, userdata2);
90318c2aff7Sartem goto out;
90418c2aff7Sartem }
90518c2aff7Sartem
90618c2aff7Sartem HAL_INFO (("Remove callouts for udi=%s", d->udi));
90718c2aff7Sartem
90818c2aff7Sartem hal_callout_device (d, callback, userdata1, userdata2, programs, extra_env);
90918c2aff7Sartem out:
91018c2aff7Sartem ;
91118c2aff7Sartem }
91218c2aff7Sartem
91318c2aff7Sartem void
hal_util_callout_device_preprobe(HalDevice * d,HalCalloutsDone callback,gpointer userdata1,gpointer userdata2)91418c2aff7Sartem hal_util_callout_device_preprobe (HalDevice *d, HalCalloutsDone callback, gpointer userdata1, gpointer userdata2)
91518c2aff7Sartem {
91618c2aff7Sartem GSList *programs;
91718c2aff7Sartem gchar *extra_env[2] = {"HALD_ACTION=preprobe", NULL};
91818c2aff7Sartem
91918c2aff7Sartem if ((programs = hal_device_property_get_strlist (d, "info.callouts.preprobe")) == NULL) {
92018c2aff7Sartem callback (d, userdata1, userdata2);
92118c2aff7Sartem goto out;
92218c2aff7Sartem }
92318c2aff7Sartem
92418c2aff7Sartem HAL_INFO (("Preprobe callouts for udi=%s", d->udi));
92518c2aff7Sartem
92618c2aff7Sartem hal_callout_device (d, callback, userdata1, userdata2, programs, extra_env);
92718c2aff7Sartem out:
92818c2aff7Sartem ;
92918c2aff7Sartem }
93018c2aff7Sartem
93118c2aff7Sartem gchar *
hal_util_strdup_valid_utf8(const char * str)93218c2aff7Sartem hal_util_strdup_valid_utf8 (const char *str)
93318c2aff7Sartem {
93418c2aff7Sartem char *endchar;
93518c2aff7Sartem char *newstr;
93618c2aff7Sartem unsigned int count = 0;
93718c2aff7Sartem
93818c2aff7Sartem if (str == NULL)
93918c2aff7Sartem return NULL;
94018c2aff7Sartem
94118c2aff7Sartem newstr = g_strdup (str);
94218c2aff7Sartem
94318c2aff7Sartem while (!g_utf8_validate (newstr, -1, (const char **) &endchar)) {
94418c2aff7Sartem *endchar = '?';
94518c2aff7Sartem count++;
94618c2aff7Sartem }
94718c2aff7Sartem
94818c2aff7Sartem if (strlen(newstr) == count)
94918c2aff7Sartem return NULL;
95018c2aff7Sartem else
95118c2aff7Sartem return newstr;
95218c2aff7Sartem }
95318c2aff7Sartem
95418c2aff7Sartem void
hal_util_hexdump(const void * mem,unsigned int size)95518c2aff7Sartem hal_util_hexdump (const void *mem, unsigned int size)
95618c2aff7Sartem {
95718c2aff7Sartem unsigned int i;
95818c2aff7Sartem unsigned int j;
95918c2aff7Sartem unsigned int n;
96018c2aff7Sartem const char *buf = (const char *) mem;
96118c2aff7Sartem
96218c2aff7Sartem n = 0;
96318c2aff7Sartem printf ("Dumping %d=0x%x bytes\n", size, size);
96418c2aff7Sartem while (n < size) {
96518c2aff7Sartem
96618c2aff7Sartem printf ("0x%04x: ", n);
96718c2aff7Sartem
96818c2aff7Sartem j = n;
96918c2aff7Sartem for (i = 0; i < 16; i++) {
97018c2aff7Sartem if (j >= size)
97118c2aff7Sartem break;
97218c2aff7Sartem printf ("%02x ", buf[j]);
97318c2aff7Sartem j++;
97418c2aff7Sartem }
97518c2aff7Sartem
97618c2aff7Sartem for ( ; i < 16; i++) {
97718c2aff7Sartem printf (" ");
97818c2aff7Sartem }
97918c2aff7Sartem
98018c2aff7Sartem printf (" ");
98118c2aff7Sartem
98218c2aff7Sartem j = n;
98318c2aff7Sartem for (i = 0; i < 16; i++) {
98418c2aff7Sartem if (j >= size)
98518c2aff7Sartem break;
98618c2aff7Sartem printf ("%c", isprint(buf[j]) ? buf[j] : '.');
98718c2aff7Sartem j++;
98818c2aff7Sartem }
98918c2aff7Sartem
99018c2aff7Sartem printf ("\n");
99118c2aff7Sartem
99218c2aff7Sartem n += 16;
99318c2aff7Sartem }
99418c2aff7Sartem }
99518c2aff7Sartem
99618c2aff7Sartem gboolean
hal_util_is_mounted_by_hald(const char * mount_point)99718c2aff7Sartem hal_util_is_mounted_by_hald (const char *mount_point)
99818c2aff7Sartem {
99918c2aff7Sartem int i;
100018c2aff7Sartem FILE *hal_mtab;
100118c2aff7Sartem int hal_mtab_len;
100218c2aff7Sartem int num_read;
100318c2aff7Sartem char *hal_mtab_buf;
100418c2aff7Sartem char **lines;
100518c2aff7Sartem gboolean found;
100618c2aff7Sartem
100718c2aff7Sartem hal_mtab = NULL;
100818c2aff7Sartem hal_mtab_buf = NULL;
100918c2aff7Sartem found = FALSE;
101018c2aff7Sartem
101118c2aff7Sartem /*HAL_DEBUG (("examining /media/.hal-mtab for %s", mount_point));*/
101218c2aff7Sartem
101318c2aff7Sartem hal_mtab = fopen ("/media/.hal-mtab", "r");
101418c2aff7Sartem if (hal_mtab == NULL) {
101518c2aff7Sartem HAL_ERROR (("Cannot open /media/.hal-mtab"));
101618c2aff7Sartem goto out;
101718c2aff7Sartem }
101818c2aff7Sartem if (fseek (hal_mtab, 0L, SEEK_END) != 0) {
101918c2aff7Sartem HAL_ERROR (("Cannot seek to end of /media/.hal-mtab"));
102018c2aff7Sartem goto out;
102118c2aff7Sartem }
102218c2aff7Sartem hal_mtab_len = ftell (hal_mtab);
102318c2aff7Sartem if (hal_mtab_len < 0) {
102418c2aff7Sartem HAL_ERROR (("Cannot determine size of /media/.hal-mtab"));
102518c2aff7Sartem goto out;
102618c2aff7Sartem }
102718c2aff7Sartem rewind (hal_mtab);
102818c2aff7Sartem
102918c2aff7Sartem hal_mtab_buf = g_new0 (char, hal_mtab_len + 1);
103018c2aff7Sartem num_read = fread (hal_mtab_buf, 1, hal_mtab_len, hal_mtab);
103118c2aff7Sartem if (num_read != hal_mtab_len) {
103218c2aff7Sartem HAL_ERROR (("Cannot read from /media/.hal-mtab"));
103318c2aff7Sartem goto out;
103418c2aff7Sartem }
103518c2aff7Sartem fclose (hal_mtab);
103618c2aff7Sartem hal_mtab = NULL;
103718c2aff7Sartem
103818c2aff7Sartem /*HAL_DEBUG (("hal_mtab = '%s'\n", hal_mtab_buf));*/
103918c2aff7Sartem
104018c2aff7Sartem lines = g_strsplit (hal_mtab_buf, "\n", 0);
104118c2aff7Sartem g_free (hal_mtab_buf);
104218c2aff7Sartem hal_mtab_buf = NULL;
104318c2aff7Sartem
104418c2aff7Sartem /* find the entry we're going to unmount */
104518c2aff7Sartem for (i = 0; lines[i] != NULL && !found; i++) {
104618c2aff7Sartem char **line_elements;
104718c2aff7Sartem
104818c2aff7Sartem /*HAL_DEBUG ((" line = '%s'", lines[i]));*/
104918c2aff7Sartem
105018c2aff7Sartem if ((lines[i])[0] == '#')
105118c2aff7Sartem continue;
105218c2aff7Sartem
105318c2aff7Sartem line_elements = g_strsplit (lines[i], "\t", 6);
105418c2aff7Sartem if (g_strv_length (line_elements) == 6) {
105518c2aff7Sartem /*
105618c2aff7Sartem HAL_DEBUG ((" devfile = '%s'", line_elements[0]));
105718c2aff7Sartem HAL_DEBUG ((" uid = '%s'", line_elements[1]));
105818c2aff7Sartem HAL_DEBUG ((" session id = '%s'", line_elements[2]));
105918c2aff7Sartem HAL_DEBUG ((" fs = '%s'", line_elements[3]));
106018c2aff7Sartem HAL_DEBUG ((" options = '%s'", line_elements[4]));
106118c2aff7Sartem HAL_DEBUG ((" mount_point = '%s'", line_elements[5]));
106218c2aff7Sartem HAL_DEBUG ((" (comparing against '%s')", mount_point));
106318c2aff7Sartem */
106418c2aff7Sartem
106518c2aff7Sartem if (strcmp (line_elements[5], mount_point) == 0) {
106618c2aff7Sartem found = TRUE;
106718c2aff7Sartem /*HAL_INFO (("device at '%s' is indeed mounted by HAL's Mount()", mount_point));*/
106818c2aff7Sartem }
106918c2aff7Sartem
107018c2aff7Sartem }
107118c2aff7Sartem
107218c2aff7Sartem g_strfreev (line_elements);
107318c2aff7Sartem }
107418c2aff7Sartem
107518c2aff7Sartem g_strfreev (lines);
107618c2aff7Sartem
107718c2aff7Sartem out:
107818c2aff7Sartem if (hal_mtab != NULL)
107918c2aff7Sartem fclose (hal_mtab);
108018c2aff7Sartem if (hal_mtab_buf != NULL)
108118c2aff7Sartem g_free (hal_mtab_buf);
108218c2aff7Sartem
108318c2aff7Sartem return found;
108418c2aff7Sartem }
108518c2aff7Sartem
108618c2aff7Sartem void
hal_util_branch_claim(HalDeviceStore * store,HalDevice * root,dbus_bool_t claimed,const char * service,int uid)108718c2aff7Sartem hal_util_branch_claim (HalDeviceStore *store, HalDevice *root, dbus_bool_t claimed,
108818c2aff7Sartem const char *service, int uid)
108918c2aff7Sartem {
109018c2aff7Sartem GSList *children;
109118c2aff7Sartem GSList *i;
109218c2aff7Sartem HalDevice *d;
109318c2aff7Sartem
109418c2aff7Sartem if (claimed) {
109518c2aff7Sartem hal_device_property_set_bool (root, "info.claimed", claimed);
109618c2aff7Sartem hal_device_property_set_string (root, "info.claimed.service", service);
109718c2aff7Sartem hal_device_property_set_int (root, "info.claimed.uid", uid);
109818c2aff7Sartem } else {
109918c2aff7Sartem hal_device_property_remove (root, "info.claimed");
110018c2aff7Sartem hal_device_property_remove (root, "info.claimed.service");
110118c2aff7Sartem hal_device_property_remove (root, "info.claimed.uid");
110218c2aff7Sartem }
110318c2aff7Sartem
110418c2aff7Sartem
110518c2aff7Sartem children = hal_device_store_match_multiple_key_value_string (store,
110618c2aff7Sartem "info.parent", root->udi);
110718c2aff7Sartem
110818c2aff7Sartem for (i = children; i != NULL; i = g_slist_next (i)) {
110918c2aff7Sartem d = HAL_DEVICE (i->data);
111018c2aff7Sartem hal_util_branch_claim (store, d, claimed, service, uid);
111118c2aff7Sartem }
111218c2aff7Sartem
111318c2aff7Sartem g_slist_free (children);
111418c2aff7Sartem }
1115*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China
1116*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China /** Given an interface name, check if it is valid.
1117*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China * @param name A given interface name
1118*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China * @return TRUE if name is valid, otherwise FALSE
1119*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China */
1120*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China gboolean
is_valid_interface_name(const char * name)1121*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China is_valid_interface_name(const char *name) {
1122*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China
1123*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China const char *end;
1124*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China const char *last_dot;
1125*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China
1126*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China last_dot = NULL;
1127*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China
1128*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China if (strlen(name) == 0)
1129*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China return FALSE;
1130*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China
1131*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China end = name + strlen(name);
1132*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China
1133*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China if (*name == '.') /* disallow starting with a . */
1134*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China return FALSE;
1135*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China else if (!VALID_INITIAL_NAME_CHARACTER (*name))
1136*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China return FALSE;
1137*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China else
1138*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China name++;
1139*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China
1140*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China while (name != end) {
1141*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China if (*name == '.') {
1142*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China if ((name + 1) == end)
1143*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China return FALSE;
1144*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China else if (!VALID_INITIAL_NAME_CHARACTER (*(name + 1)))
1145*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China return FALSE;
1146*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China last_dot = name;
1147*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China name++; /* we just validated the next char, so skip two */
1148*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China } else if (!VALID_NAME_CHARACTER (*name))
1149*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China return FALSE;
1150*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China name++;
1151*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China }
1152*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China if (last_dot == NULL)
1153*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China return FALSE;
1154*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China
1155*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China return TRUE;
1156*97191cecSXiaolin Zhang - Sun Microsystems - Beijing China }
1157