1*18c2aff7Sartem /*************************************************************************** 2*18c2aff7Sartem * CVSID: $Id$ 3*18c2aff7Sartem * 4*18c2aff7Sartem * util.c - Various utilities 5*18c2aff7Sartem * 6*18c2aff7Sartem * Copyright (C) 2004 David Zeuthen, <david@fubar.dk> 7*18c2aff7Sartem * 8*18c2aff7Sartem * Licensed under the Academic Free License version 2.1 9*18c2aff7Sartem * 10*18c2aff7Sartem * This program is free software; you can redistribute it and/or modify 11*18c2aff7Sartem * it under the terms of the GNU General Public License as published by 12*18c2aff7Sartem * the Free Software Foundation; either version 2 of the License, or 13*18c2aff7Sartem * (at your option) any later version. 14*18c2aff7Sartem * 15*18c2aff7Sartem * This program is distributed in the hope that it will be useful, 16*18c2aff7Sartem * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*18c2aff7Sartem * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*18c2aff7Sartem * GNU General Public License for more details. 19*18c2aff7Sartem * 20*18c2aff7Sartem * You should have received a copy of the GNU General Public License 21*18c2aff7Sartem * along with this program; if not, write to the Free Software 22*18c2aff7Sartem * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 23*18c2aff7Sartem * 24*18c2aff7Sartem **************************************************************************/ 25*18c2aff7Sartem 26*18c2aff7Sartem #ifdef HAVE_CONFIG_H 27*18c2aff7Sartem # include <config.h> 28*18c2aff7Sartem #endif 29*18c2aff7Sartem 30*18c2aff7Sartem #include <stdio.h> 31*18c2aff7Sartem #include <stdarg.h> 32*18c2aff7Sartem #include <string.h> 33*18c2aff7Sartem #include <errno.h> 34*18c2aff7Sartem #include <time.h> 35*18c2aff7Sartem #include <ctype.h> 36*18c2aff7Sartem #include <stdint.h> 37*18c2aff7Sartem #include <sys/stat.h> 38*18c2aff7Sartem #include <unistd.h> 39*18c2aff7Sartem #include <fcntl.h> 40*18c2aff7Sartem #include <signal.h> 41*18c2aff7Sartem #include <sys/wait.h> 42*18c2aff7Sartem #include <sys/file.h> 43*18c2aff7Sartem 44*18c2aff7Sartem #include <glib.h> 45*18c2aff7Sartem #include <dbus/dbus.h> 46*18c2aff7Sartem #include <dbus/dbus-glib.h> 47*18c2aff7Sartem 48*18c2aff7Sartem #include "osspec.h" 49*18c2aff7Sartem #include "logger.h" 50*18c2aff7Sartem #include "hald.h" 51*18c2aff7Sartem #include "hald_runner.h" 52*18c2aff7Sartem #include "hald_dbus.h" 53*18c2aff7Sartem #include "device_info.h" 54*18c2aff7Sartem 55*18c2aff7Sartem #include "util.h" 56*18c2aff7Sartem 57*18c2aff7Sartem gboolean 58*18c2aff7Sartem hal_util_remove_trailing_slash (gchar *path) 59*18c2aff7Sartem { 60*18c2aff7Sartem gchar *c = NULL; 61*18c2aff7Sartem 62*18c2aff7Sartem if (path == NULL) { 63*18c2aff7Sartem return FALSE; 64*18c2aff7Sartem } 65*18c2aff7Sartem 66*18c2aff7Sartem c = strrchr (path, '/'); 67*18c2aff7Sartem if (c == NULL) { 68*18c2aff7Sartem HAL_WARNING (("Invalid path %s", path)); 69*18c2aff7Sartem return 1; 70*18c2aff7Sartem } 71*18c2aff7Sartem if (*(c+1) == '\0') 72*18c2aff7Sartem *c = '\0'; 73*18c2aff7Sartem 74*18c2aff7Sartem return TRUE; 75*18c2aff7Sartem } 76*18c2aff7Sartem 77*18c2aff7Sartem /** Given a path, /foo/bar/bat/foobar, return the last element, e.g. 78*18c2aff7Sartem * foobar. 79*18c2aff7Sartem * 80*18c2aff7Sartem * @param path Path 81*18c2aff7Sartem * @return Pointer into given string 82*18c2aff7Sartem */ 83*18c2aff7Sartem const gchar * 84*18c2aff7Sartem hal_util_get_last_element (const gchar *s) 85*18c2aff7Sartem { 86*18c2aff7Sartem int len; 87*18c2aff7Sartem const gchar *p; 88*18c2aff7Sartem 89*18c2aff7Sartem len = strlen (s); 90*18c2aff7Sartem for (p = s + len - 1; p > s; --p) { 91*18c2aff7Sartem if ((*p) == '/') 92*18c2aff7Sartem return p + 1; 93*18c2aff7Sartem } 94*18c2aff7Sartem 95*18c2aff7Sartem return s; 96*18c2aff7Sartem } 97*18c2aff7Sartem 98*18c2aff7Sartem /** Given a path, this functions finds the path representing the 99*18c2aff7Sartem * parent directory by truncation. 100*18c2aff7Sartem * 101*18c2aff7Sartem * @param path Path 102*18c2aff7Sartem * @return Path for parent or NULL. Must be freed by caller 103*18c2aff7Sartem */ 104*18c2aff7Sartem gchar * 105*18c2aff7Sartem hal_util_get_parent_path (const gchar *path) 106*18c2aff7Sartem { 107*18c2aff7Sartem guint i; 108*18c2aff7Sartem guint len; 109*18c2aff7Sartem gchar *parent_path; 110*18c2aff7Sartem 111*18c2aff7Sartem /* Find parent device by truncating our own path */ 112*18c2aff7Sartem parent_path = g_strndup (path, HAL_PATH_MAX); 113*18c2aff7Sartem len = strlen (parent_path); 114*18c2aff7Sartem for (i = len - 1; parent_path[i] != '/'; --i) { 115*18c2aff7Sartem parent_path[i] = '\0'; 116*18c2aff7Sartem } 117*18c2aff7Sartem parent_path[i] = '\0'; 118*18c2aff7Sartem 119*18c2aff7Sartem return parent_path; 120*18c2aff7Sartem } 121*18c2aff7Sartem 122*18c2aff7Sartem gchar * 123*18c2aff7Sartem hal_util_get_normalized_path (const gchar *path1, const gchar *path2) 124*18c2aff7Sartem { 125*18c2aff7Sartem int len1; 126*18c2aff7Sartem int len2; 127*18c2aff7Sartem const gchar *p1; 128*18c2aff7Sartem const gchar *p2; 129*18c2aff7Sartem gchar buf[HAL_PATH_MAX]; 130*18c2aff7Sartem 131*18c2aff7Sartem len1 = strlen (path1); 132*18c2aff7Sartem len2 = strlen (path2); 133*18c2aff7Sartem 134*18c2aff7Sartem p1 = path1 + len1; 135*18c2aff7Sartem 136*18c2aff7Sartem p2 = path2; 137*18c2aff7Sartem while (p2 < path2 + len2 && strncmp (p2, "../", 3) == 0) { 138*18c2aff7Sartem p2 += 3; 139*18c2aff7Sartem 140*18c2aff7Sartem while (p1 >= path1 && *(--p1)!='/') 141*18c2aff7Sartem ; 142*18c2aff7Sartem } 143*18c2aff7Sartem 144*18c2aff7Sartem if ((p1-path1) < 0) { 145*18c2aff7Sartem HAL_ERROR (("Could not normalize '%s' and '%s', return 'NULL'", path1, path2)); 146*18c2aff7Sartem return NULL; 147*18c2aff7Sartem } 148*18c2aff7Sartem 149*18c2aff7Sartem strncpy (buf, path1, (p1-path1)); 150*18c2aff7Sartem buf[p1-path1] = '\0'; 151*18c2aff7Sartem 152*18c2aff7Sartem return g_strdup_printf ("%s/%s", buf, p2); 153*18c2aff7Sartem } 154*18c2aff7Sartem 155*18c2aff7Sartem gboolean 156*18c2aff7Sartem hal_util_get_int_from_file (const gchar *directory, const gchar *file, gint *result, gint base) 157*18c2aff7Sartem { 158*18c2aff7Sartem FILE *f; 159*18c2aff7Sartem char buf[64]; 160*18c2aff7Sartem gchar path[HAL_PATH_MAX]; 161*18c2aff7Sartem gboolean ret; 162*18c2aff7Sartem 163*18c2aff7Sartem f = NULL; 164*18c2aff7Sartem ret = FALSE; 165*18c2aff7Sartem 166*18c2aff7Sartem g_snprintf (path, sizeof (path), "%s/%s", directory, file); 167*18c2aff7Sartem 168*18c2aff7Sartem f = fopen (path, "rb"); 169*18c2aff7Sartem if (f == NULL) { 170*18c2aff7Sartem HAL_ERROR (("Cannot open '%s'", path)); 171*18c2aff7Sartem goto out; 172*18c2aff7Sartem } 173*18c2aff7Sartem 174*18c2aff7Sartem if (fgets (buf, sizeof (buf), f) == NULL) { 175*18c2aff7Sartem HAL_ERROR (("Cannot read from '%s'", path)); 176*18c2aff7Sartem goto out; 177*18c2aff7Sartem } 178*18c2aff7Sartem 179*18c2aff7Sartem /* TODO: handle error condition */ 180*18c2aff7Sartem *result = strtol (buf, NULL, base); 181*18c2aff7Sartem ret = TRUE; 182*18c2aff7Sartem 183*18c2aff7Sartem out: 184*18c2aff7Sartem if (f != NULL) 185*18c2aff7Sartem fclose (f); 186*18c2aff7Sartem 187*18c2aff7Sartem return ret; 188*18c2aff7Sartem } 189*18c2aff7Sartem 190*18c2aff7Sartem gboolean 191*18c2aff7Sartem hal_util_set_int_from_file (HalDevice *d, const gchar *key, const gchar *directory, const gchar *file, gint base) 192*18c2aff7Sartem { 193*18c2aff7Sartem gint value; 194*18c2aff7Sartem gboolean ret; 195*18c2aff7Sartem 196*18c2aff7Sartem ret = FALSE; 197*18c2aff7Sartem 198*18c2aff7Sartem if (hal_util_get_int_from_file (directory, file, &value, base)) 199*18c2aff7Sartem ret = hal_device_property_set_int (d, key, value); 200*18c2aff7Sartem 201*18c2aff7Sartem return ret; 202*18c2aff7Sartem } 203*18c2aff7Sartem 204*18c2aff7Sartem 205*18c2aff7Sartem gboolean 206*18c2aff7Sartem hal_util_get_uint64_from_file (const gchar *directory, const gchar *file, guint64 *result, gint base) 207*18c2aff7Sartem { 208*18c2aff7Sartem FILE *f; 209*18c2aff7Sartem char buf[64]; 210*18c2aff7Sartem gchar path[HAL_PATH_MAX]; 211*18c2aff7Sartem gboolean ret; 212*18c2aff7Sartem 213*18c2aff7Sartem f = NULL; 214*18c2aff7Sartem ret = FALSE; 215*18c2aff7Sartem 216*18c2aff7Sartem g_snprintf (path, sizeof (path), "%s/%s", directory, file); 217*18c2aff7Sartem 218*18c2aff7Sartem f = fopen (path, "rb"); 219*18c2aff7Sartem if (f == NULL) { 220*18c2aff7Sartem HAL_ERROR (("Cannot open '%s'", path)); 221*18c2aff7Sartem goto out; 222*18c2aff7Sartem } 223*18c2aff7Sartem 224*18c2aff7Sartem if (fgets (buf, sizeof (buf), f) == NULL) { 225*18c2aff7Sartem HAL_ERROR (("Cannot read from '%s'", path)); 226*18c2aff7Sartem goto out; 227*18c2aff7Sartem } 228*18c2aff7Sartem 229*18c2aff7Sartem /* TODO: handle error condition */ 230*18c2aff7Sartem *result = strtoll (buf, NULL, base); 231*18c2aff7Sartem 232*18c2aff7Sartem ret = TRUE; 233*18c2aff7Sartem 234*18c2aff7Sartem out: 235*18c2aff7Sartem if (f != NULL) 236*18c2aff7Sartem fclose (f); 237*18c2aff7Sartem 238*18c2aff7Sartem return ret; 239*18c2aff7Sartem } 240*18c2aff7Sartem 241*18c2aff7Sartem gboolean 242*18c2aff7Sartem hal_util_set_uint64_from_file (HalDevice *d, const gchar *key, const gchar *directory, const gchar *file, gint base) 243*18c2aff7Sartem { 244*18c2aff7Sartem guint64 value; 245*18c2aff7Sartem gboolean ret; 246*18c2aff7Sartem 247*18c2aff7Sartem ret = FALSE; 248*18c2aff7Sartem 249*18c2aff7Sartem if (hal_util_get_uint64_from_file (directory, file, &value, base)) 250*18c2aff7Sartem ret = hal_device_property_set_uint64 (d, key, value); 251*18c2aff7Sartem 252*18c2aff7Sartem return ret; 253*18c2aff7Sartem } 254*18c2aff7Sartem 255*18c2aff7Sartem gboolean 256*18c2aff7Sartem hal_util_get_bcd2_from_file (const gchar *directory, const gchar *file, gint *result) 257*18c2aff7Sartem { 258*18c2aff7Sartem FILE *f; 259*18c2aff7Sartem char buf[64]; 260*18c2aff7Sartem gchar path[HAL_PATH_MAX]; 261*18c2aff7Sartem gboolean ret; 262*18c2aff7Sartem gint digit; 263*18c2aff7Sartem gint left, right; 264*18c2aff7Sartem gboolean passed_white_space; 265*18c2aff7Sartem gint num_prec; 266*18c2aff7Sartem gsize len; 267*18c2aff7Sartem gchar c; 268*18c2aff7Sartem guint i; 269*18c2aff7Sartem 270*18c2aff7Sartem f = NULL; 271*18c2aff7Sartem ret = FALSE; 272*18c2aff7Sartem 273*18c2aff7Sartem g_snprintf (path, sizeof (path), "%s/%s", directory, file); 274*18c2aff7Sartem 275*18c2aff7Sartem f = fopen (path, "rb"); 276*18c2aff7Sartem if (f == NULL) { 277*18c2aff7Sartem HAL_ERROR (("Cannot open '%s'", path)); 278*18c2aff7Sartem goto out; 279*18c2aff7Sartem } 280*18c2aff7Sartem 281*18c2aff7Sartem if (fgets (buf, sizeof (buf), f) == NULL) { 282*18c2aff7Sartem HAL_ERROR (("Cannot read from '%s'", path)); 283*18c2aff7Sartem goto out; 284*18c2aff7Sartem } 285*18c2aff7Sartem 286*18c2aff7Sartem left = 0; 287*18c2aff7Sartem len = strlen (buf); 288*18c2aff7Sartem passed_white_space = FALSE; 289*18c2aff7Sartem for (i = 0; i < len && buf[i] != '.'; i++) { 290*18c2aff7Sartem if (g_ascii_isspace (buf[i])) { 291*18c2aff7Sartem if (passed_white_space) 292*18c2aff7Sartem break; 293*18c2aff7Sartem else 294*18c2aff7Sartem continue; 295*18c2aff7Sartem } 296*18c2aff7Sartem passed_white_space = TRUE; 297*18c2aff7Sartem left *= 16; 298*18c2aff7Sartem c = buf[i]; 299*18c2aff7Sartem digit = (int) (c - '0'); 300*18c2aff7Sartem left += digit; 301*18c2aff7Sartem } 302*18c2aff7Sartem i++; 303*18c2aff7Sartem right = 0; 304*18c2aff7Sartem num_prec = 0; 305*18c2aff7Sartem for (; i < len; i++) { 306*18c2aff7Sartem if (g_ascii_isspace (buf[i])) 307*18c2aff7Sartem break; 308*18c2aff7Sartem if (num_prec == 2) /* Only care about two digits 309*18c2aff7Sartem * of precision */ 310*18c2aff7Sartem break; 311*18c2aff7Sartem right *= 16; 312*18c2aff7Sartem c = buf[i]; 313*18c2aff7Sartem digit = (int) (c - '0'); 314*18c2aff7Sartem right += digit; 315*18c2aff7Sartem num_prec++; 316*18c2aff7Sartem } 317*18c2aff7Sartem 318*18c2aff7Sartem for (; num_prec < 2; num_prec++) 319*18c2aff7Sartem right *= 16; 320*18c2aff7Sartem 321*18c2aff7Sartem *result = left * 256 + (right & 255); 322*18c2aff7Sartem ret = TRUE; 323*18c2aff7Sartem 324*18c2aff7Sartem out: 325*18c2aff7Sartem if (f != NULL) 326*18c2aff7Sartem fclose (f); 327*18c2aff7Sartem 328*18c2aff7Sartem return ret; 329*18c2aff7Sartem } 330*18c2aff7Sartem 331*18c2aff7Sartem gboolean 332*18c2aff7Sartem hal_util_set_bcd2_from_file (HalDevice *d, const gchar *key, const gchar *directory, const gchar *file) 333*18c2aff7Sartem { 334*18c2aff7Sartem gint value; 335*18c2aff7Sartem gboolean ret; 336*18c2aff7Sartem 337*18c2aff7Sartem ret = FALSE; 338*18c2aff7Sartem 339*18c2aff7Sartem if (hal_util_get_bcd2_from_file (directory, file, &value)) 340*18c2aff7Sartem ret = hal_device_property_set_int (d, key, value); 341*18c2aff7Sartem 342*18c2aff7Sartem return ret; 343*18c2aff7Sartem } 344*18c2aff7Sartem 345*18c2aff7Sartem gchar * 346*18c2aff7Sartem hal_util_get_string_from_file (const gchar *directory, const gchar *file) 347*18c2aff7Sartem { 348*18c2aff7Sartem FILE *f; 349*18c2aff7Sartem static gchar buf[256]; 350*18c2aff7Sartem gchar path[HAL_PATH_MAX]; 351*18c2aff7Sartem gchar *result; 352*18c2aff7Sartem gsize len; 353*18c2aff7Sartem gint i; 354*18c2aff7Sartem 355*18c2aff7Sartem f = NULL; 356*18c2aff7Sartem result = NULL; 357*18c2aff7Sartem 358*18c2aff7Sartem g_snprintf (path, sizeof (path), "%s/%s", directory, file); 359*18c2aff7Sartem 360*18c2aff7Sartem f = fopen (path, "rb"); 361*18c2aff7Sartem if (f == NULL) { 362*18c2aff7Sartem HAL_ERROR (("Cannot open '%s'", path)); 363*18c2aff7Sartem goto out; 364*18c2aff7Sartem } 365*18c2aff7Sartem 366*18c2aff7Sartem buf[0] = '\0'; 367*18c2aff7Sartem if (fgets (buf, sizeof (buf), f) == NULL) { 368*18c2aff7Sartem HAL_ERROR (("Cannot read from '%s'", path)); 369*18c2aff7Sartem goto out; 370*18c2aff7Sartem } 371*18c2aff7Sartem 372*18c2aff7Sartem len = strlen (buf); 373*18c2aff7Sartem if (len>0) 374*18c2aff7Sartem buf[len-1] = '\0'; 375*18c2aff7Sartem 376*18c2aff7Sartem /* Clear remaining whitespace */ 377*18c2aff7Sartem for (i = len - 2; i >= 0; --i) { 378*18c2aff7Sartem if (!g_ascii_isspace (buf[i])) 379*18c2aff7Sartem break; 380*18c2aff7Sartem buf[i] = '\0'; 381*18c2aff7Sartem } 382*18c2aff7Sartem 383*18c2aff7Sartem result = buf; 384*18c2aff7Sartem 385*18c2aff7Sartem out: 386*18c2aff7Sartem if (f != NULL) 387*18c2aff7Sartem fclose (f); 388*18c2aff7Sartem 389*18c2aff7Sartem return result; 390*18c2aff7Sartem } 391*18c2aff7Sartem 392*18c2aff7Sartem gboolean 393*18c2aff7Sartem hal_util_set_string_from_file (HalDevice *d, const gchar *key, const gchar *directory, const gchar *file) 394*18c2aff7Sartem { 395*18c2aff7Sartem gchar *buf; 396*18c2aff7Sartem gboolean ret; 397*18c2aff7Sartem 398*18c2aff7Sartem ret = FALSE; 399*18c2aff7Sartem 400*18c2aff7Sartem if ((buf = hal_util_get_string_from_file (directory, file)) != NULL) 401*18c2aff7Sartem ret = hal_device_property_set_string (d, key, buf); 402*18c2aff7Sartem 403*18c2aff7Sartem return ret; 404*18c2aff7Sartem } 405*18c2aff7Sartem 406*18c2aff7Sartem void 407*18c2aff7Sartem hal_util_compute_udi (HalDeviceStore *store, gchar *dst, gsize dstsize, const gchar *format, ...) 408*18c2aff7Sartem { 409*18c2aff7Sartem guint i; 410*18c2aff7Sartem va_list args; 411*18c2aff7Sartem gchar buf[256]; 412*18c2aff7Sartem 413*18c2aff7Sartem va_start (args, format); 414*18c2aff7Sartem g_vsnprintf (buf, sizeof (buf), format, args); 415*18c2aff7Sartem va_end (args); 416*18c2aff7Sartem 417*18c2aff7Sartem g_strcanon (buf, 418*18c2aff7Sartem "/_" 419*18c2aff7Sartem "abcdefghijklmnopqrstuvwxyz" 420*18c2aff7Sartem "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 421*18c2aff7Sartem "1234567890", '_'); 422*18c2aff7Sartem 423*18c2aff7Sartem g_strlcpy (dst, buf, dstsize); 424*18c2aff7Sartem if (hal_device_store_find (store, dst) == NULL) 425*18c2aff7Sartem goto out; 426*18c2aff7Sartem 427*18c2aff7Sartem for (i = 0; ; i++) { 428*18c2aff7Sartem g_snprintf (dst, dstsize, "%s_%d", buf, i); 429*18c2aff7Sartem if (hal_device_store_find (store, dst) == NULL) 430*18c2aff7Sartem goto out; 431*18c2aff7Sartem } 432*18c2aff7Sartem 433*18c2aff7Sartem out: 434*18c2aff7Sartem ; 435*18c2aff7Sartem } 436*18c2aff7Sartem 437*18c2aff7Sartem 438*18c2aff7Sartem gboolean 439*18c2aff7Sartem hal_util_path_ascend (gchar *path) 440*18c2aff7Sartem { 441*18c2aff7Sartem gchar *p; 442*18c2aff7Sartem 443*18c2aff7Sartem if (path == NULL) 444*18c2aff7Sartem return FALSE; 445*18c2aff7Sartem 446*18c2aff7Sartem p = strrchr (path, '/'); 447*18c2aff7Sartem if (p == NULL) 448*18c2aff7Sartem return FALSE; 449*18c2aff7Sartem 450*18c2aff7Sartem *p = '\0'; 451*18c2aff7Sartem return TRUE; 452*18c2aff7Sartem } 453*18c2aff7Sartem 454*18c2aff7Sartem static gboolean _grep_can_reuse = FALSE; 455*18c2aff7Sartem 456*18c2aff7Sartem void 457*18c2aff7Sartem hal_util_grep_discard_existing_data (void) 458*18c2aff7Sartem { 459*18c2aff7Sartem _grep_can_reuse = FALSE; 460*18c2aff7Sartem } 461*18c2aff7Sartem 462*18c2aff7Sartem /** Given a directory and filename, open the file and search for the 463*18c2aff7Sartem * first line that starts with the given linestart string. Returns 464*18c2aff7Sartem * the rest of the line as a string if found. 465*18c2aff7Sartem * 466*18c2aff7Sartem * @param directory Directory, e.g. "/proc/acpi/battery/BAT0" 467*18c2aff7Sartem * @param file File, e.g. "info" 468*18c2aff7Sartem * @param linestart Start of line, e.g. "serial number" 469*18c2aff7Sartem * @param reuse Whether we should reuse the file contents 470*18c2aff7Sartem * if the file is the same; can be cleared 471*18c2aff7Sartem * with hal_util_grep_discard_existing_data() 472*18c2aff7Sartem * @return NULL if not found, otherwise the remainder 473*18c2aff7Sartem * of the line, e.g. ": 21805" if 474*18c2aff7Sartem * the file /proc/acpi/battery/BAT0 contains 475*18c2aff7Sartem * this line "serial number: 21805" 476*18c2aff7Sartem * The string is only valid until the next 477*18c2aff7Sartem * invocation of this function. 478*18c2aff7Sartem */ 479*18c2aff7Sartem gchar * 480*18c2aff7Sartem hal_util_grep_file (const gchar *directory, const gchar *file, const gchar *linestart, gboolean reuse) 481*18c2aff7Sartem { 482*18c2aff7Sartem static gchar buf[2048]; 483*18c2aff7Sartem static unsigned int bufsize; 484*18c2aff7Sartem static gchar filename[HAL_PATH_MAX]; 485*18c2aff7Sartem static gchar oldfilename[HAL_PATH_MAX]; 486*18c2aff7Sartem gchar *result; 487*18c2aff7Sartem gsize linestart_len; 488*18c2aff7Sartem gchar *p; 489*18c2aff7Sartem 490*18c2aff7Sartem result = NULL; 491*18c2aff7Sartem 492*18c2aff7Sartem /* TODO: use reuse and _grep_can_reuse parameters to avoid loading 493*18c2aff7Sartem * the file again and again 494*18c2aff7Sartem */ 495*18c2aff7Sartem 496*18c2aff7Sartem if (file != NULL && strlen (file) > 0) 497*18c2aff7Sartem snprintf (filename, sizeof (filename), "%s/%s", directory, file); 498*18c2aff7Sartem else 499*18c2aff7Sartem strncpy (filename, directory, sizeof (filename)); 500*18c2aff7Sartem 501*18c2aff7Sartem if (_grep_can_reuse && reuse && strcmp (oldfilename, filename) == 0) { 502*18c2aff7Sartem /* just reuse old file; e.g. bufsize, buf */ 503*18c2aff7Sartem /*HAL_INFO (("hal_util_grep_file: reusing buf for %s", filename));*/ 504*18c2aff7Sartem } else { 505*18c2aff7Sartem FILE *f; 506*18c2aff7Sartem 507*18c2aff7Sartem f = fopen (filename, "r"); 508*18c2aff7Sartem if (f == NULL) 509*18c2aff7Sartem goto out; 510*18c2aff7Sartem bufsize = fread (buf, sizeof (char), sizeof (buf) - 1, f); 511*18c2aff7Sartem buf[bufsize] = '\0'; 512*18c2aff7Sartem fclose (f); 513*18c2aff7Sartem 514*18c2aff7Sartem /*HAL_INFO (("hal_util_grep_file: read %s of %d bytes", filename, bufsize));*/ 515*18c2aff7Sartem } 516*18c2aff7Sartem 517*18c2aff7Sartem /* book keeping */ 518*18c2aff7Sartem _grep_can_reuse = TRUE; 519*18c2aff7Sartem strncpy (oldfilename, filename, sizeof(oldfilename)); 520*18c2aff7Sartem 521*18c2aff7Sartem linestart_len = strlen (linestart); 522*18c2aff7Sartem 523*18c2aff7Sartem /* analyze buf */ 524*18c2aff7Sartem p = buf; 525*18c2aff7Sartem do { 526*18c2aff7Sartem unsigned int linelen; 527*18c2aff7Sartem static char line[256]; 528*18c2aff7Sartem 529*18c2aff7Sartem for (linelen = 0; p[linelen] != '\n' && p[linelen] != '\0'; linelen++) 530*18c2aff7Sartem ; 531*18c2aff7Sartem 532*18c2aff7Sartem if (linelen < sizeof (line)) { 533*18c2aff7Sartem 534*18c2aff7Sartem strncpy (line, p, linelen); 535*18c2aff7Sartem line[linelen] = '\0'; 536*18c2aff7Sartem 537*18c2aff7Sartem if (strncmp (line, linestart, linestart_len) == 0) { 538*18c2aff7Sartem result = line + linestart_len; 539*18c2aff7Sartem goto out; 540*18c2aff7Sartem } 541*18c2aff7Sartem } 542*18c2aff7Sartem 543*18c2aff7Sartem p += linelen + 1; 544*18c2aff7Sartem 545*18c2aff7Sartem } while (p < buf + bufsize); 546*18c2aff7Sartem 547*18c2aff7Sartem out: 548*18c2aff7Sartem return result; 549*18c2aff7Sartem } 550*18c2aff7Sartem 551*18c2aff7Sartem gchar * 552*18c2aff7Sartem hal_util_grep_string_elem_from_file (const gchar *directory, const gchar *file, 553*18c2aff7Sartem const gchar *linestart, guint elem, gboolean reuse) 554*18c2aff7Sartem { 555*18c2aff7Sartem gchar *line; 556*18c2aff7Sartem gchar *res; 557*18c2aff7Sartem static gchar buf[256]; 558*18c2aff7Sartem gchar **tokens; 559*18c2aff7Sartem guint i, j; 560*18c2aff7Sartem 561*18c2aff7Sartem res = NULL; 562*18c2aff7Sartem tokens = NULL; 563*18c2aff7Sartem 564*18c2aff7Sartem if (((line = hal_util_grep_file (directory, file, linestart, reuse)) == NULL) || (strlen (line) == 0)) 565*18c2aff7Sartem goto out; 566*18c2aff7Sartem 567*18c2aff7Sartem tokens = g_strsplit_set (line, " \t:", 0); 568*18c2aff7Sartem for (i = 0, j = 0; tokens[i] != NULL; i++) { 569*18c2aff7Sartem if (strlen (tokens[i]) == 0) 570*18c2aff7Sartem continue; 571*18c2aff7Sartem if (j == elem) { 572*18c2aff7Sartem strncpy (buf, tokens[i], sizeof (buf)); 573*18c2aff7Sartem res = buf; 574*18c2aff7Sartem goto out; 575*18c2aff7Sartem } 576*18c2aff7Sartem j++; 577*18c2aff7Sartem } 578*18c2aff7Sartem 579*18c2aff7Sartem out: 580*18c2aff7Sartem if (tokens != NULL) 581*18c2aff7Sartem g_strfreev (tokens); 582*18c2aff7Sartem 583*18c2aff7Sartem return res; 584*18c2aff7Sartem } 585*18c2aff7Sartem 586*18c2aff7Sartem gint 587*18c2aff7Sartem hal_util_grep_int_elem_from_file (const gchar *directory, const gchar *file, 588*18c2aff7Sartem const gchar *linestart, guint elem, guint base, gboolean reuse) 589*18c2aff7Sartem { 590*18c2aff7Sartem gchar *endptr; 591*18c2aff7Sartem gchar *strvalue; 592*18c2aff7Sartem int value; 593*18c2aff7Sartem 594*18c2aff7Sartem value = G_MAXINT; 595*18c2aff7Sartem 596*18c2aff7Sartem strvalue = hal_util_grep_string_elem_from_file (directory, file, linestart, elem, reuse); 597*18c2aff7Sartem if (strvalue == NULL) 598*18c2aff7Sartem goto out; 599*18c2aff7Sartem 600*18c2aff7Sartem value = strtol (strvalue, &endptr, base); 601*18c2aff7Sartem if (endptr == strvalue) { 602*18c2aff7Sartem value = G_MAXINT; 603*18c2aff7Sartem goto out; 604*18c2aff7Sartem } 605*18c2aff7Sartem 606*18c2aff7Sartem out: 607*18c2aff7Sartem return value; 608*18c2aff7Sartem } 609*18c2aff7Sartem 610*18c2aff7Sartem /** Get a string value from a formatted text file and assign it to 611*18c2aff7Sartem * a property on a device object. 612*18c2aff7Sartem * 613*18c2aff7Sartem * Example: Given that the file /proc/acpi/battery/BAT0/info contains 614*18c2aff7Sartem * the line 615*18c2aff7Sartem * 616*18c2aff7Sartem * "design voltage: 10800 mV" 617*18c2aff7Sartem * 618*18c2aff7Sartem * then hal_util_set_string_elem_from_file (d, "battery.foo", 619*18c2aff7Sartem * "/proc/acpi/battery/BAT0", "info", "design voltage", 1) will assign 620*18c2aff7Sartem * the string "mV" to the property "battery.foo" on d. 621*18c2aff7Sartem * 622*18c2aff7Sartem * @param d Device object 623*18c2aff7Sartem * @param key Property name 624*18c2aff7Sartem * @param directory Directory, e.g. "/proc/acpi/battery/BAT0" 625*18c2aff7Sartem * @param file File, e.g. "info" 626*18c2aff7Sartem * @param linestart Start of line, e.g. "design voltage" 627*18c2aff7Sartem * @param elem Element number after linestart to extract 628*18c2aff7Sartem * excluding whitespace and ':' characters. 629*18c2aff7Sartem * @return TRUE, if, and only if, the value could be 630*18c2aff7Sartem * extracted and the property was set 631*18c2aff7Sartem */ 632*18c2aff7Sartem gboolean 633*18c2aff7Sartem hal_util_set_string_elem_from_file (HalDevice *d, const gchar *key, 634*18c2aff7Sartem const gchar *directory, const gchar *file, 635*18c2aff7Sartem const gchar *linestart, guint elem, gboolean reuse) 636*18c2aff7Sartem { 637*18c2aff7Sartem gboolean res; 638*18c2aff7Sartem gchar *value; 639*18c2aff7Sartem 640*18c2aff7Sartem res = FALSE; 641*18c2aff7Sartem 642*18c2aff7Sartem if ((value = hal_util_grep_string_elem_from_file (directory, file, linestart, elem, reuse)) == NULL) 643*18c2aff7Sartem goto out; 644*18c2aff7Sartem 645*18c2aff7Sartem res = hal_device_property_set_string (d, key, value); 646*18c2aff7Sartem out: 647*18c2aff7Sartem return res; 648*18c2aff7Sartem } 649*18c2aff7Sartem 650*18c2aff7Sartem /** Get an integer value from a formatted text file and assign it to 651*18c2aff7Sartem * a property on a device object. 652*18c2aff7Sartem * 653*18c2aff7Sartem * Example: Given that the file /proc/acpi/battery/BAT0/info contains 654*18c2aff7Sartem * the line 655*18c2aff7Sartem * 656*18c2aff7Sartem * "design voltage: 10800 mV" 657*18c2aff7Sartem * 658*18c2aff7Sartem * then hal_util_set_int_elem_from_file (d, "battery.foo", 659*18c2aff7Sartem * "/proc/acpi/battery/BAT0", "info", "design voltage", 0) will assign 660*18c2aff7Sartem * the integer 10800 to the property "battery.foo" on d. 661*18c2aff7Sartem * 662*18c2aff7Sartem * @param d Device object 663*18c2aff7Sartem * @param key Property name 664*18c2aff7Sartem * @param directory Directory, e.g. "/proc/acpi/battery/BAT0" 665*18c2aff7Sartem * @param file File, e.g. "info" 666*18c2aff7Sartem * @param linestart Start of line, e.g. "design voltage" 667*18c2aff7Sartem * @param elem Element number after linestart to extract 668*18c2aff7Sartem * excluding whitespace and ':' characters. 669*18c2aff7Sartem * @return TRUE, if, and only if, the value could be 670*18c2aff7Sartem * extracted and the property was set 671*18c2aff7Sartem */ 672*18c2aff7Sartem gboolean 673*18c2aff7Sartem hal_util_set_int_elem_from_file (HalDevice *d, const gchar *key, 674*18c2aff7Sartem const gchar *directory, const gchar *file, 675*18c2aff7Sartem const gchar *linestart, guint elem, guint base, gboolean reuse) 676*18c2aff7Sartem { 677*18c2aff7Sartem gchar *endptr; 678*18c2aff7Sartem gboolean res; 679*18c2aff7Sartem gchar *strvalue; 680*18c2aff7Sartem int value; 681*18c2aff7Sartem 682*18c2aff7Sartem res = FALSE; 683*18c2aff7Sartem 684*18c2aff7Sartem strvalue = hal_util_grep_string_elem_from_file (directory, file, linestart, elem, reuse); 685*18c2aff7Sartem if (strvalue == NULL) 686*18c2aff7Sartem goto out; 687*18c2aff7Sartem 688*18c2aff7Sartem value = strtol (strvalue, &endptr, base); 689*18c2aff7Sartem if (endptr == strvalue) 690*18c2aff7Sartem goto out; 691*18c2aff7Sartem 692*18c2aff7Sartem res = hal_device_property_set_int (d, key, value); 693*18c2aff7Sartem 694*18c2aff7Sartem out: 695*18c2aff7Sartem return res; 696*18c2aff7Sartem 697*18c2aff7Sartem } 698*18c2aff7Sartem 699*18c2aff7Sartem /** Get a value from a formatted text file, test it against a given 700*18c2aff7Sartem * value, and set a boolean property on a device object with the 701*18c2aff7Sartem * test result. 702*18c2aff7Sartem * 703*18c2aff7Sartem * Example: Given that the file /proc/acpi/battery/BAT0/info contains 704*18c2aff7Sartem * the line 705*18c2aff7Sartem * 706*18c2aff7Sartem * "present: yes" 707*18c2aff7Sartem * 708*18c2aff7Sartem * then hal_util_set_bool_elem_from_file (d, "battery.baz", 709*18c2aff7Sartem * "/proc/acpi/battery/BAT0", "info", "present", 0, "yes") will assign 710*18c2aff7Sartem * the boolean TRUE to the property "battery.baz" on d. 711*18c2aff7Sartem * 712*18c2aff7Sartem * If, instead, the line was 713*18c2aff7Sartem * 714*18c2aff7Sartem * "present: no" 715*18c2aff7Sartem * 716*18c2aff7Sartem * the value assigned will be FALSE. 717*18c2aff7Sartem * 718*18c2aff7Sartem * @param d Device object 719*18c2aff7Sartem * @param key Property name 720*18c2aff7Sartem * @param directory Directory, e.g. "/proc/acpi/battery/BAT0" 721*18c2aff7Sartem * @param file File, e.g. "info" 722*18c2aff7Sartem * @param linestart Start of line, e.g. "design voltage" 723*18c2aff7Sartem * @param elem Element number after linestart to extract 724*18c2aff7Sartem * excluding whitespace and ':' characters. 725*18c2aff7Sartem * @param expected Value to test against 726*18c2aff7Sartem * @return TRUE, if, and only if, the value could be 727*18c2aff7Sartem * extracted and the property was set 728*18c2aff7Sartem */ 729*18c2aff7Sartem gboolean 730*18c2aff7Sartem hal_util_set_bool_elem_from_file (HalDevice *d, const gchar *key, 731*18c2aff7Sartem const gchar *directory, const gchar *file, 732*18c2aff7Sartem const gchar *linestart, guint elem, const gchar *expected, gboolean reuse) 733*18c2aff7Sartem { 734*18c2aff7Sartem gchar *line; 735*18c2aff7Sartem gboolean res; 736*18c2aff7Sartem gchar **tokens; 737*18c2aff7Sartem guint i, j; 738*18c2aff7Sartem 739*18c2aff7Sartem res = FALSE; 740*18c2aff7Sartem tokens = NULL; 741*18c2aff7Sartem 742*18c2aff7Sartem if (((line = hal_util_grep_file (directory, file, linestart, reuse)) == NULL) || (strlen (line) == 0)) 743*18c2aff7Sartem goto out; 744*18c2aff7Sartem 745*18c2aff7Sartem tokens = g_strsplit_set (line, " \t:", 0); 746*18c2aff7Sartem 747*18c2aff7Sartem for (i = 0, j = 0; tokens[i] != NULL; i++) { 748*18c2aff7Sartem if (strlen (tokens[i]) == 0) 749*18c2aff7Sartem continue; 750*18c2aff7Sartem if (j == elem) { 751*18c2aff7Sartem hal_device_property_set_bool (d, key, strcmp (tokens[i], expected) == 0); 752*18c2aff7Sartem res = TRUE; 753*18c2aff7Sartem goto out; 754*18c2aff7Sartem } 755*18c2aff7Sartem j++; 756*18c2aff7Sartem } 757*18c2aff7Sartem 758*18c2aff7Sartem 759*18c2aff7Sartem out: 760*18c2aff7Sartem if (tokens != NULL) 761*18c2aff7Sartem g_strfreev (tokens); 762*18c2aff7Sartem 763*18c2aff7Sartem return res; 764*18c2aff7Sartem } 765*18c2aff7Sartem 766*18c2aff7Sartem gchar ** 767*18c2aff7Sartem hal_util_dup_strv_from_g_slist (GSList *strlist) 768*18c2aff7Sartem { 769*18c2aff7Sartem guint j; 770*18c2aff7Sartem guint len; 771*18c2aff7Sartem gchar **strv; 772*18c2aff7Sartem GSList *i; 773*18c2aff7Sartem 774*18c2aff7Sartem len = g_slist_length (strlist); 775*18c2aff7Sartem strv = g_new (char *, len + 1); 776*18c2aff7Sartem 777*18c2aff7Sartem for (i = strlist, j = 0; i != NULL; i = g_slist_next (i), j++) { 778*18c2aff7Sartem strv[j] = g_strdup ((const gchar *) i->data); 779*18c2aff7Sartem } 780*18c2aff7Sartem strv[j] = NULL; 781*18c2aff7Sartem 782*18c2aff7Sartem return strv; 783*18c2aff7Sartem } 784*18c2aff7Sartem 785*18c2aff7Sartem /* -------------------------------------------------------------------------------------------------------------- */ 786*18c2aff7Sartem 787*18c2aff7Sartem typedef struct { 788*18c2aff7Sartem HalDevice *d; 789*18c2aff7Sartem gchar **programs; 790*18c2aff7Sartem gchar **extra_env; 791*18c2aff7Sartem guint next_program; 792*18c2aff7Sartem 793*18c2aff7Sartem HalCalloutsDone callback; 794*18c2aff7Sartem gpointer userdata1; 795*18c2aff7Sartem gpointer userdata2; 796*18c2aff7Sartem 797*18c2aff7Sartem } Callout; 798*18c2aff7Sartem 799*18c2aff7Sartem static void callout_do_next (Callout *c); 800*18c2aff7Sartem 801*18c2aff7Sartem static void 802*18c2aff7Sartem callout_terminated (HalDevice *d, guint32 exit_type, 803*18c2aff7Sartem gint return_code, gchar **error, 804*18c2aff7Sartem gpointer data1, gpointer data2) 805*18c2aff7Sartem { 806*18c2aff7Sartem Callout *c; 807*18c2aff7Sartem 808*18c2aff7Sartem c = (Callout *) data1; 809*18c2aff7Sartem callout_do_next (c); 810*18c2aff7Sartem } 811*18c2aff7Sartem 812*18c2aff7Sartem static void 813*18c2aff7Sartem callout_do_next (Callout *c) 814*18c2aff7Sartem { 815*18c2aff7Sartem 816*18c2aff7Sartem /* Check if we're done */ 817*18c2aff7Sartem if (c->programs[c->next_program] == NULL) { 818*18c2aff7Sartem HalDevice *d; 819*18c2aff7Sartem gpointer userdata1; 820*18c2aff7Sartem gpointer userdata2; 821*18c2aff7Sartem HalCalloutsDone callback; 822*18c2aff7Sartem 823*18c2aff7Sartem d = c->d; 824*18c2aff7Sartem userdata1 = c->userdata1; 825*18c2aff7Sartem userdata2 = c->userdata2; 826*18c2aff7Sartem callback = c->callback; 827*18c2aff7Sartem 828*18c2aff7Sartem g_strfreev (c->programs); 829*18c2aff7Sartem g_strfreev (c->extra_env); 830*18c2aff7Sartem g_free (c); 831*18c2aff7Sartem 832*18c2aff7Sartem callback (d, userdata1, userdata2); 833*18c2aff7Sartem 834*18c2aff7Sartem } else { 835*18c2aff7Sartem hald_runner_run(c->d, c->programs[c->next_program], c->extra_env, 836*18c2aff7Sartem HAL_HELPER_TIMEOUT, callout_terminated, 837*18c2aff7Sartem (gpointer)c, NULL); 838*18c2aff7Sartem c->next_program++; 839*18c2aff7Sartem } 840*18c2aff7Sartem } 841*18c2aff7Sartem 842*18c2aff7Sartem static void 843*18c2aff7Sartem hal_callout_device (HalDevice *d, HalCalloutsDone callback, gpointer userdata1, gpointer userdata2, 844*18c2aff7Sartem GSList *programs, gchar **extra_env) 845*18c2aff7Sartem { 846*18c2aff7Sartem Callout *c; 847*18c2aff7Sartem 848*18c2aff7Sartem c = g_new0 (Callout, 1); 849*18c2aff7Sartem c->d = d; 850*18c2aff7Sartem c->callback = callback; 851*18c2aff7Sartem c->userdata1 = userdata1; 852*18c2aff7Sartem c->userdata2 = userdata2; 853*18c2aff7Sartem c->programs = hal_util_dup_strv_from_g_slist (programs); 854*18c2aff7Sartem c->extra_env = g_strdupv (extra_env); 855*18c2aff7Sartem c->next_program = 0; 856*18c2aff7Sartem 857*18c2aff7Sartem callout_do_next (c); 858*18c2aff7Sartem } 859*18c2aff7Sartem 860*18c2aff7Sartem void 861*18c2aff7Sartem hal_util_callout_device_add (HalDevice *d, HalCalloutsDone callback, gpointer userdata1, gpointer userdata2) 862*18c2aff7Sartem { 863*18c2aff7Sartem GSList *programs; 864*18c2aff7Sartem gchar *extra_env[2] = {"HALD_ACTION=add", NULL}; 865*18c2aff7Sartem 866*18c2aff7Sartem if ((programs = hal_device_property_get_strlist (d, "info.callouts.add")) == NULL) { 867*18c2aff7Sartem callback (d, userdata1, userdata2); 868*18c2aff7Sartem goto out; 869*18c2aff7Sartem } 870*18c2aff7Sartem 871*18c2aff7Sartem HAL_INFO (("Add callouts for udi=%s", d->udi)); 872*18c2aff7Sartem 873*18c2aff7Sartem hal_callout_device (d, callback, userdata1, userdata2, programs, extra_env); 874*18c2aff7Sartem out: 875*18c2aff7Sartem ; 876*18c2aff7Sartem } 877*18c2aff7Sartem 878*18c2aff7Sartem void 879*18c2aff7Sartem hal_util_callout_device_remove (HalDevice *d, HalCalloutsDone callback, gpointer userdata1, gpointer userdata2) 880*18c2aff7Sartem { 881*18c2aff7Sartem GSList *programs; 882*18c2aff7Sartem gchar *extra_env[2] = {"HALD_ACTION=remove", NULL}; 883*18c2aff7Sartem 884*18c2aff7Sartem if ((programs = hal_device_property_get_strlist (d, "info.callouts.remove")) == NULL) { 885*18c2aff7Sartem callback (d, userdata1, userdata2); 886*18c2aff7Sartem goto out; 887*18c2aff7Sartem } 888*18c2aff7Sartem 889*18c2aff7Sartem HAL_INFO (("Remove callouts for udi=%s", d->udi)); 890*18c2aff7Sartem 891*18c2aff7Sartem hal_callout_device (d, callback, userdata1, userdata2, programs, extra_env); 892*18c2aff7Sartem out: 893*18c2aff7Sartem ; 894*18c2aff7Sartem } 895*18c2aff7Sartem 896*18c2aff7Sartem void 897*18c2aff7Sartem hal_util_callout_device_preprobe (HalDevice *d, HalCalloutsDone callback, gpointer userdata1, gpointer userdata2) 898*18c2aff7Sartem { 899*18c2aff7Sartem GSList *programs; 900*18c2aff7Sartem gchar *extra_env[2] = {"HALD_ACTION=preprobe", NULL}; 901*18c2aff7Sartem 902*18c2aff7Sartem if ((programs = hal_device_property_get_strlist (d, "info.callouts.preprobe")) == NULL) { 903*18c2aff7Sartem callback (d, userdata1, userdata2); 904*18c2aff7Sartem goto out; 905*18c2aff7Sartem } 906*18c2aff7Sartem 907*18c2aff7Sartem HAL_INFO (("Preprobe callouts for udi=%s", d->udi)); 908*18c2aff7Sartem 909*18c2aff7Sartem hal_callout_device (d, callback, userdata1, userdata2, programs, extra_env); 910*18c2aff7Sartem out: 911*18c2aff7Sartem ; 912*18c2aff7Sartem } 913*18c2aff7Sartem 914*18c2aff7Sartem gchar * 915*18c2aff7Sartem hal_util_strdup_valid_utf8 (const char *str) 916*18c2aff7Sartem { 917*18c2aff7Sartem char *endchar; 918*18c2aff7Sartem char *newstr; 919*18c2aff7Sartem unsigned int count = 0; 920*18c2aff7Sartem 921*18c2aff7Sartem if (str == NULL) 922*18c2aff7Sartem return NULL; 923*18c2aff7Sartem 924*18c2aff7Sartem newstr = g_strdup (str); 925*18c2aff7Sartem 926*18c2aff7Sartem while (!g_utf8_validate (newstr, -1, (const char **) &endchar)) { 927*18c2aff7Sartem *endchar = '?'; 928*18c2aff7Sartem count++; 929*18c2aff7Sartem } 930*18c2aff7Sartem 931*18c2aff7Sartem if (strlen(newstr) == count) 932*18c2aff7Sartem return NULL; 933*18c2aff7Sartem else 934*18c2aff7Sartem return newstr; 935*18c2aff7Sartem } 936*18c2aff7Sartem 937*18c2aff7Sartem void 938*18c2aff7Sartem hal_util_hexdump (const void *mem, unsigned int size) 939*18c2aff7Sartem { 940*18c2aff7Sartem unsigned int i; 941*18c2aff7Sartem unsigned int j; 942*18c2aff7Sartem unsigned int n; 943*18c2aff7Sartem const char *buf = (const char *) mem; 944*18c2aff7Sartem 945*18c2aff7Sartem n = 0; 946*18c2aff7Sartem printf ("Dumping %d=0x%x bytes\n", size, size); 947*18c2aff7Sartem while (n < size) { 948*18c2aff7Sartem 949*18c2aff7Sartem printf ("0x%04x: ", n); 950*18c2aff7Sartem 951*18c2aff7Sartem j = n; 952*18c2aff7Sartem for (i = 0; i < 16; i++) { 953*18c2aff7Sartem if (j >= size) 954*18c2aff7Sartem break; 955*18c2aff7Sartem printf ("%02x ", buf[j]); 956*18c2aff7Sartem j++; 957*18c2aff7Sartem } 958*18c2aff7Sartem 959*18c2aff7Sartem for ( ; i < 16; i++) { 960*18c2aff7Sartem printf (" "); 961*18c2aff7Sartem } 962*18c2aff7Sartem 963*18c2aff7Sartem printf (" "); 964*18c2aff7Sartem 965*18c2aff7Sartem j = n; 966*18c2aff7Sartem for (i = 0; i < 16; i++) { 967*18c2aff7Sartem if (j >= size) 968*18c2aff7Sartem break; 969*18c2aff7Sartem printf ("%c", isprint(buf[j]) ? buf[j] : '.'); 970*18c2aff7Sartem j++; 971*18c2aff7Sartem } 972*18c2aff7Sartem 973*18c2aff7Sartem printf ("\n"); 974*18c2aff7Sartem 975*18c2aff7Sartem n += 16; 976*18c2aff7Sartem } 977*18c2aff7Sartem } 978*18c2aff7Sartem 979*18c2aff7Sartem gboolean 980*18c2aff7Sartem hal_util_is_mounted_by_hald (const char *mount_point) 981*18c2aff7Sartem { 982*18c2aff7Sartem int i; 983*18c2aff7Sartem FILE *hal_mtab; 984*18c2aff7Sartem int hal_mtab_len; 985*18c2aff7Sartem int num_read; 986*18c2aff7Sartem char *hal_mtab_buf; 987*18c2aff7Sartem char **lines; 988*18c2aff7Sartem gboolean found; 989*18c2aff7Sartem 990*18c2aff7Sartem hal_mtab = NULL; 991*18c2aff7Sartem hal_mtab_buf = NULL; 992*18c2aff7Sartem found = FALSE; 993*18c2aff7Sartem 994*18c2aff7Sartem /*HAL_DEBUG (("examining /media/.hal-mtab for %s", mount_point));*/ 995*18c2aff7Sartem 996*18c2aff7Sartem hal_mtab = fopen ("/media/.hal-mtab", "r"); 997*18c2aff7Sartem if (hal_mtab == NULL) { 998*18c2aff7Sartem HAL_ERROR (("Cannot open /media/.hal-mtab")); 999*18c2aff7Sartem goto out; 1000*18c2aff7Sartem } 1001*18c2aff7Sartem if (fseek (hal_mtab, 0L, SEEK_END) != 0) { 1002*18c2aff7Sartem HAL_ERROR (("Cannot seek to end of /media/.hal-mtab")); 1003*18c2aff7Sartem goto out; 1004*18c2aff7Sartem } 1005*18c2aff7Sartem hal_mtab_len = ftell (hal_mtab); 1006*18c2aff7Sartem if (hal_mtab_len < 0) { 1007*18c2aff7Sartem HAL_ERROR (("Cannot determine size of /media/.hal-mtab")); 1008*18c2aff7Sartem goto out; 1009*18c2aff7Sartem } 1010*18c2aff7Sartem rewind (hal_mtab); 1011*18c2aff7Sartem 1012*18c2aff7Sartem hal_mtab_buf = g_new0 (char, hal_mtab_len + 1); 1013*18c2aff7Sartem num_read = fread (hal_mtab_buf, 1, hal_mtab_len, hal_mtab); 1014*18c2aff7Sartem if (num_read != hal_mtab_len) { 1015*18c2aff7Sartem HAL_ERROR (("Cannot read from /media/.hal-mtab")); 1016*18c2aff7Sartem goto out; 1017*18c2aff7Sartem } 1018*18c2aff7Sartem fclose (hal_mtab); 1019*18c2aff7Sartem hal_mtab = NULL; 1020*18c2aff7Sartem 1021*18c2aff7Sartem /*HAL_DEBUG (("hal_mtab = '%s'\n", hal_mtab_buf));*/ 1022*18c2aff7Sartem 1023*18c2aff7Sartem lines = g_strsplit (hal_mtab_buf, "\n", 0); 1024*18c2aff7Sartem g_free (hal_mtab_buf); 1025*18c2aff7Sartem hal_mtab_buf = NULL; 1026*18c2aff7Sartem 1027*18c2aff7Sartem /* find the entry we're going to unmount */ 1028*18c2aff7Sartem for (i = 0; lines[i] != NULL && !found; i++) { 1029*18c2aff7Sartem char **line_elements; 1030*18c2aff7Sartem 1031*18c2aff7Sartem /*HAL_DEBUG ((" line = '%s'", lines[i]));*/ 1032*18c2aff7Sartem 1033*18c2aff7Sartem if ((lines[i])[0] == '#') 1034*18c2aff7Sartem continue; 1035*18c2aff7Sartem 1036*18c2aff7Sartem line_elements = g_strsplit (lines[i], "\t", 6); 1037*18c2aff7Sartem if (g_strv_length (line_elements) == 6) { 1038*18c2aff7Sartem /* 1039*18c2aff7Sartem HAL_DEBUG ((" devfile = '%s'", line_elements[0])); 1040*18c2aff7Sartem HAL_DEBUG ((" uid = '%s'", line_elements[1])); 1041*18c2aff7Sartem HAL_DEBUG ((" session id = '%s'", line_elements[2])); 1042*18c2aff7Sartem HAL_DEBUG ((" fs = '%s'", line_elements[3])); 1043*18c2aff7Sartem HAL_DEBUG ((" options = '%s'", line_elements[4])); 1044*18c2aff7Sartem HAL_DEBUG ((" mount_point = '%s'", line_elements[5])); 1045*18c2aff7Sartem HAL_DEBUG ((" (comparing against '%s')", mount_point)); 1046*18c2aff7Sartem */ 1047*18c2aff7Sartem 1048*18c2aff7Sartem if (strcmp (line_elements[5], mount_point) == 0) { 1049*18c2aff7Sartem found = TRUE; 1050*18c2aff7Sartem /*HAL_INFO (("device at '%s' is indeed mounted by HAL's Mount()", mount_point));*/ 1051*18c2aff7Sartem } 1052*18c2aff7Sartem 1053*18c2aff7Sartem } 1054*18c2aff7Sartem 1055*18c2aff7Sartem g_strfreev (line_elements); 1056*18c2aff7Sartem } 1057*18c2aff7Sartem 1058*18c2aff7Sartem g_strfreev (lines); 1059*18c2aff7Sartem 1060*18c2aff7Sartem out: 1061*18c2aff7Sartem if (hal_mtab != NULL) 1062*18c2aff7Sartem fclose (hal_mtab); 1063*18c2aff7Sartem if (hal_mtab_buf != NULL) 1064*18c2aff7Sartem g_free (hal_mtab_buf); 1065*18c2aff7Sartem 1066*18c2aff7Sartem return found; 1067*18c2aff7Sartem } 1068*18c2aff7Sartem 1069*18c2aff7Sartem void 1070*18c2aff7Sartem hal_util_branch_claim (HalDeviceStore *store, HalDevice *root, dbus_bool_t claimed, 1071*18c2aff7Sartem const char *service, int uid) 1072*18c2aff7Sartem { 1073*18c2aff7Sartem GSList *children; 1074*18c2aff7Sartem GSList *i; 1075*18c2aff7Sartem HalDevice *d; 1076*18c2aff7Sartem 1077*18c2aff7Sartem if (claimed) { 1078*18c2aff7Sartem hal_device_property_set_bool (root, "info.claimed", claimed); 1079*18c2aff7Sartem hal_device_property_set_string (root, "info.claimed.service", service); 1080*18c2aff7Sartem hal_device_property_set_int (root, "info.claimed.uid", uid); 1081*18c2aff7Sartem } else { 1082*18c2aff7Sartem hal_device_property_remove (root, "info.claimed"); 1083*18c2aff7Sartem hal_device_property_remove (root, "info.claimed.service"); 1084*18c2aff7Sartem hal_device_property_remove (root, "info.claimed.uid"); 1085*18c2aff7Sartem } 1086*18c2aff7Sartem 1087*18c2aff7Sartem 1088*18c2aff7Sartem children = hal_device_store_match_multiple_key_value_string (store, 1089*18c2aff7Sartem "info.parent", root->udi); 1090*18c2aff7Sartem 1091*18c2aff7Sartem for (i = children; i != NULL; i = g_slist_next (i)) { 1092*18c2aff7Sartem d = HAL_DEVICE (i->data); 1093*18c2aff7Sartem hal_util_branch_claim (store, d, claimed, service, uid); 1094*18c2aff7Sartem } 1095*18c2aff7Sartem 1096*18c2aff7Sartem g_slist_free (children); 1097*18c2aff7Sartem } 1098