/***************************************************************************
* CVSID: $Id$
*
* util.c - Various utilities
*
* Copyright (C) 2004 David Zeuthen, <david@fubar.dk>
*
* Licensed under the Academic Free License version 2.1
*
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
**************************************************************************/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <ctype.h>
#include <stdint.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <glib.h>
#include <dbus/dbus-glib.h>
#include "osspec.h"
#include "logger.h"
#include "hald.h"
#include "hald_runner.h"
#include "hald_dbus.h"
#include "device_info.h"
#include "util.h"
/** Determine whether the given character is valid as the first character
* in a name.
*/
#define VALID_INITIAL_NAME_CHARACTER(c) \
(((c) >= 'A' && (c) <= 'Z') || \
((c) >= 'a' && (c) <= 'z') || \
((c) == '_'))
/** Determine whether the given character is valid as a second or later
* character in a name.
*/
#define VALID_NAME_CHARACTER(c) \
(((c) >= '0' && (c) <= '9') || \
((c) >= 'A' && (c) <= 'Z') || \
((c) >= 'a' && (c) <= 'z') || \
((c) == '_'))
{
return FALSE;
}
if (c == NULL) {
return 1;
}
if (*(c+1) == '\0')
*c = '\0';
return TRUE;
}
* foobar.
*
* @param path Path
* @return Pointer into given string
*/
const gchar *
{
int len;
const gchar *p;
for (p = s + len - 1; p > s; --p) {
if ((*p) == '/')
return p + 1;
}
return s;
}
/** Given a path, this functions finds the path representing the
* parent directory by truncation.
*
* @param path Path
* @return Path for parent or NULL. Must be freed by caller
*/
gchar *
{
guint i;
/* Find parent device by truncating our own path */
parent_path[i] = '\0';
}
parent_path[i] = '\0';
return parent_path;
}
gchar *
{
int len1;
int len2;
p2 += 3;
;
}
return NULL;
}
}
{
FILE *f;
f = NULL;
if (f == NULL) {
goto out;
}
goto out;
}
/* TODO: handle error condition */
out:
if (f != NULL)
fclose (f);
return ret;
}
hal_util_set_int_from_file (HalDevice *d, const gchar *key, const gchar *directory, const gchar *file, gint base)
{
return ret;
}
hal_util_get_uint64_from_file (const gchar *directory, const gchar *file, guint64 *result, gint base)
{
FILE *f;
f = NULL;
if (f == NULL) {
goto out;
}
goto out;
}
/* TODO: handle error condition */
out:
if (f != NULL)
fclose (f);
return ret;
}
hal_util_set_uint64_from_file (HalDevice *d, const gchar *key, const gchar *directory, const gchar *file, gint base)
{
return ret;
}
{
FILE *f;
gchar c;
guint i;
f = NULL;
if (f == NULL) {
goto out;
}
goto out;
}
left = 0;
if (g_ascii_isspace (buf[i])) {
if (passed_white_space)
break;
else
continue;
}
left *= 16;
c = buf[i];
digit = (int) (c - '0');
}
i++;
right = 0;
num_prec = 0;
for (; i < len; i++) {
if (g_ascii_isspace (buf[i]))
break;
* of precision */
break;
right *= 16;
c = buf[i];
digit = (int) (c - '0');
num_prec++;
}
right *= 16;
out:
if (f != NULL)
fclose (f);
return ret;
}
hal_util_set_bcd2_from_file (HalDevice *d, const gchar *key, const gchar *directory, const gchar *file)
{
return ret;
}
gchar *
{
FILE *f;
gint i;
f = NULL;
if (f == NULL) {
goto out;
}
buf[0] = '\0';
goto out;
}
if (len>0)
/* Clear remaining whitespace */
for (i = len - 2; i >= 0; --i) {
if (!g_ascii_isspace (buf[i]))
break;
buf[i] = '\0';
}
out:
if (f != NULL)
fclose (f);
return result;
}
hal_util_set_string_from_file (HalDevice *d, const gchar *key, const gchar *directory, const gchar *file)
{
return ret;
}
void
{
guint i;
"/_"
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"1234567890", '_');
goto out;
for (i = 0; ; i++) {
goto out;
}
out:
;
}
{
gchar *p;
return FALSE;
if (p == NULL)
return FALSE;
*p = '\0';
return TRUE;
}
void
{
}
/** Given a directory and filename, open the file and search for the
* first line that starts with the given linestart string. Returns
* the rest of the line as a string if found.
*
* @param file File, e.g. "info"
* @param linestart Start of line, e.g. "serial number"
* @param reuse Whether we should reuse the file contents
* if the file is the same; can be cleared
* with hal_util_grep_discard_existing_data()
* @return NULL if not found, otherwise the remainder
* of the line, e.g. ": 21805" if
* this line "serial number: 21805"
* The string is only valid until the next
* invocation of this function.
*/
gchar *
hal_util_grep_file (const gchar *directory, const gchar *file, const gchar *linestart, gboolean reuse)
{
static unsigned int bufsize;
gchar *p;
/* TODO: use reuse and _grep_can_reuse parameters to avoid loading
* the file again and again
*/
else
/* just reuse old file; e.g. bufsize, buf */
/*HAL_INFO (("hal_util_grep_file: reusing buf for %s", filename));*/
} else {
FILE *f;
if (f == NULL)
goto out;
fclose (f);
/*HAL_INFO (("hal_util_grep_file: read %s of %d bytes", filename, bufsize));*/
}
/* book keeping */
/* analyze buf */
p = buf;
do {
unsigned int linelen;
;
goto out;
}
}
p += linelen + 1;
out:
return result;
}
gchar *
{
guint i, j;
if (((line = hal_util_grep_file (directory, file, linestart, reuse)) == NULL) || (strlen (line) == 0))
goto out;
continue;
if (j == elem) {
goto out;
}
j++;
}
out:
g_strfreev (tokens);
return res;
}
{
int value;
goto out;
goto out;
}
out:
return value;
}
/** Get a string value from a formatted text file and assign it to
* a property on a device object.
*
* the line
*
* "design voltage: 10800 mV"
*
* then hal_util_set_string_elem_from_file (d, "battery.foo",
* the string "mV" to the property "battery.foo" on d.
*
* @param d Device object
* @param key Property name
* @param file File, e.g. "info"
* @param linestart Start of line, e.g. "design voltage"
* @param elem Element number after linestart to extract
* excluding whitespace and ':' characters.
* @return TRUE, if, and only if, the value could be
* extracted and the property was set
*/
{
if ((value = hal_util_grep_string_elem_from_file (directory, file, linestart, elem, reuse)) == NULL)
goto out;
out:
return res;
}
/** Get an integer value from a formatted text file and assign it to
* a property on a device object.
*
* the line
*
* "design voltage: 10800 mV"
*
* then hal_util_set_int_elem_from_file (d, "battery.foo",
* the integer 10800 to the property "battery.foo" on d.
*
* @param d Device object
* @param key Property name
* @param file File, e.g. "info"
* @param linestart Start of line, e.g. "design voltage"
* @param elem Element number after linestart to extract
* excluding whitespace and ':' characters.
* @return TRUE, if, and only if, the value could be
* extracted and the property was set
*/
{
int value;
goto out;
goto out;
out:
return res;
}
/** Get a value from a formatted text file, test it against a given
* value, and set a boolean property on a device object with the
* test result.
*
* the line
*
* "present: yes"
*
* then hal_util_set_bool_elem_from_file (d, "battery.baz",
* the boolean TRUE to the property "battery.baz" on d.
*
* If, instead, the line was
*
* "present: no"
*
* the value assigned will be FALSE.
*
* @param d Device object
* @param key Property name
* @param file File, e.g. "info"
* @param linestart Start of line, e.g. "design voltage"
* @param elem Element number after linestart to extract
* excluding whitespace and ':' characters.
* @param expected Value to test against
* @return TRUE, if, and only if, the value could be
* extracted and the property was set
*/
{
guint i, j;
if (((line = hal_util_grep_file (directory, file, linestart, reuse)) == NULL) || (strlen (line) == 0))
goto out;
continue;
if (j == elem) {
goto out;
}
j++;
}
out:
g_strfreev (tokens);
return res;
}
gchar **
{
guint j;
GSList *i;
}
return strv;
}
/* -------------------------------------------------------------------------------------------------------------- */
typedef struct {
HalDevice *d;
} Callout;
static void callout_do_next (Callout *c);
static void
{
Callout *c;
callout_do_next (c);
}
static void
{
/* Check if we're done */
HalDevice *d;
d = c->d;
g_strfreev (c->programs);
g_strfreev (c->extra_env);
g_free (c);
} else {
c->next_program++;
}
}
static void
{
Callout *c;
c->d = d;
c->next_program = 0;
callout_do_next (c);
}
void
hal_util_callout_device_add (HalDevice *d, HalCalloutsDone callback, gpointer userdata1, gpointer userdata2)
{
goto out;
}
out:
;
}
void
hal_util_callout_device_remove (HalDevice *d, HalCalloutsDone callback, gpointer userdata1, gpointer userdata2)
{
goto out;
}
out:
;
}
void
hal_util_callout_device_preprobe (HalDevice *d, HalCalloutsDone callback, gpointer userdata1, gpointer userdata2)
{
goto out;
}
out:
;
}
gchar *
{
char *endchar;
char *newstr;
unsigned int count = 0;
return NULL;
*endchar = '?';
count++;
}
return NULL;
else
return newstr;
}
void
{
unsigned int i;
unsigned int j;
unsigned int n;
n = 0;
while (n < size) {
printf ("0x%04x: ", n);
j = n;
for (i = 0; i < 16; i++) {
if (j >= size)
break;
j++;
}
for ( ; i < 16; i++) {
printf (" ");
}
printf (" ");
j = n;
for (i = 0; i < 16; i++) {
if (j >= size)
break;
j++;
}
printf ("\n");
n += 16;
}
}
{
int i;
int hal_mtab_len;
int num_read;
char *hal_mtab_buf;
char **lines;
hal_mtab_buf = NULL;
/*HAL_DEBUG (("examining /media/.hal-mtab for %s", mount_point));*/
HAL_ERROR (("Cannot open /media/.hal-mtab"));
goto out;
}
HAL_ERROR (("Cannot seek to end of /media/.hal-mtab"));
goto out;
}
if (hal_mtab_len < 0) {
HAL_ERROR (("Cannot determine size of /media/.hal-mtab"));
goto out;
}
if (num_read != hal_mtab_len) {
HAL_ERROR (("Cannot read from /media/.hal-mtab"));
goto out;
}
/*HAL_DEBUG (("hal_mtab = '%s'\n", hal_mtab_buf));*/
hal_mtab_buf = NULL;
/* find the entry we're going to unmount */
char **line_elements;
/*HAL_DEBUG ((" line = '%s'", lines[i]));*/
if ((lines[i])[0] == '#')
continue;
/*
HAL_DEBUG ((" devfile = '%s'", line_elements[0]));
HAL_DEBUG ((" uid = '%s'", line_elements[1]));
HAL_DEBUG ((" session id = '%s'", line_elements[2]));
HAL_DEBUG ((" fs = '%s'", line_elements[3]));
HAL_DEBUG ((" options = '%s'", line_elements[4]));
HAL_DEBUG ((" mount_point = '%s'", line_elements[5]));
HAL_DEBUG ((" (comparing against '%s')", mount_point));
*/
/*HAL_INFO (("device at '%s' is indeed mounted by HAL's Mount()", mount_point));*/
}
}
}
g_strfreev (lines);
out:
if (hal_mtab_buf != NULL)
return found;
}
void
{
GSList *i;
HalDevice *d;
if (claimed) {
} else {
}
d = HAL_DEVICE (i->data);
}
}
/** Given an interface name, check if it is valid.
* @param name A given interface name
* @return TRUE if name is valid, otherwise FALSE
*/
const char *end;
const char *last_dot;
return FALSE;
return FALSE;
else if (!VALID_INITIAL_NAME_CHARACTER (*name))
return FALSE;
else
name++;
if (*name == '.') {
return FALSE;
return FALSE;
name++; /* we just validated the next char, so skip two */
} else if (!VALID_NAME_CHARACTER (*name))
return FALSE;
name++;
}
return FALSE;
return TRUE;
}