Logo Search packages:      
Sourcecode: libpam-usb version File versions  Download package

xpath.c

/*
 * Copyright (c) 2003-2007 Andrea Luzzardi <scox@sig11.org>
 *
 * This file is part of the pam_usb project. pam_usb is free software;
 * you can redistribute it and/or modify it under the terms of the GNU General
 * Public License version 2, as published by the Free Software Foundation.
 *
 * pam_usb 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., 59 Temple
 * Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <libxml/xpath.h>
#include <ctype.h>
#include <string.h>
#include "xpath.h"
#include "log.h"

static xmlXPathObject *pusb_xpath_match(xmlDocPtr doc, const char *path)
{
      xmlXPathContext   *context = NULL;
      xmlXPathObject    *result = NULL;

      context = xmlXPathNewContext(doc);
      if (context == NULL)
      {
            log_error("Unable to create XML context\n");
            return (NULL);
      }
      result = xmlXPathEvalExpression((xmlChar *)path, context);
      xmlXPathFreeContext(context);
      if (result == NULL)
      {
            log_error("Error in xmlXPathEvalExpression\n");
            return (NULL);
      }
      if (xmlXPathNodeSetIsEmpty(result->nodesetval))
      {
            xmlXPathFreeObject(result);
            return (NULL);
      }
      return (result);
}

static int pusb_xpath_strip_string(char *dest, const char *src,
            size_t size)
{
      int         first_char = -1;
      int         last_char = -1;
      int         i;

      for (i = 0; src[i]; ++i)
      {
            if (isspace(src[i]))
                  continue ;

            if (first_char == -1)
                  first_char = i;
            last_char = i;
      }

      if (first_char == -1 || last_char == -1)
            return (0);

      if ((last_char - first_char) > (size - 1))
            return (0);

      memset(dest, 0x0, size);
      strncpy(dest, &(src[first_char]), last_char - first_char + 1);
      return (1);
}

int pusb_xpath_get_string(xmlDocPtr doc, const char *path,
            char *value, size_t size)
{
      xmlXPathObject    *result = NULL;
      xmlNode                 *node = NULL;
      xmlChar                 *result_string = NULL;

      if (!(result = pusb_xpath_match(doc, path)))
            return (0);

      if (result->nodesetval->nodeNr > 1)
      {
            xmlXPathFreeObject(result);
            log_debug("Syntax error: %s: more than one record found\n", path);
            return (0);
      }

      node = result->nodesetval->nodeTab[0]->xmlChildrenNode;
      result_string = xmlNodeListGetString(doc, node, 1);
      if (!result_string)
      {
            xmlXPathFreeObject(result);
            log_debug("Empty value for %s\n", path);
            return (0);
      }
      if (!pusb_xpath_strip_string(value, (const char *)result_string, size))
      {
            xmlFree(result_string);
            xmlXPathFreeObject(result);
            log_debug("Result for %s (%s) is too long (max: %d)\n",
                        path, (const char *)result_string, size);
            return (0);
      }
      xmlFree(result_string);
      xmlXPathFreeObject(result);
      return (1);
}

int pusb_xpath_get_string_from(xmlDocPtr doc,
            const char *base,
            const char *path,
            char *value, size_t size)
{
      char  *xpath = NULL;
      size_t      xpath_size;
      int         retval;

      xpath_size = strlen(base) + strlen(path) + 1;
      if (!(xpath = malloc(xpath_size)))
      {
            log_error("malloc error !\n");
            return (0);
      }
      memset(xpath, 0x00, xpath_size);
      snprintf(xpath, xpath_size, "%s%s", base, path);
      retval = pusb_xpath_get_string(doc, xpath, value, size);
      if (retval)
            log_debug("%s%s -> %s\n", base, path, value);
      free(xpath);
      return (retval);
}

int pusb_xpath_get_bool(xmlDocPtr doc, const char *path, int *value)
{
      char  ret[6]; /* strlen("false") + 1 */

      if (!pusb_xpath_get_string(doc, path, ret, sizeof(ret)))
            return (0);

      if (!strcmp(ret, "true"))
      {
            *value = 1;
            return (1);
      }

      if (!strcmp(ret, "false"))
      {
            *value = 0;
            return (1);
      }

      log_debug("Expecting a boolean, got %s\n", ret);
      return (0);
}

int pusb_xpath_get_bool_from(xmlDocPtr doc,
            const char *base,
            const char *path,
            int *value)
{
      char  *xpath = NULL;
      size_t      xpath_size;
      int         retval;

      xpath_size = strlen(base) + strlen(path) + 1;
      if (!(xpath = malloc(xpath_size)))
      {
            log_error("malloc error!\n");
            return (0);
      }
      memset(xpath, 0x00, xpath_size);
      snprintf(xpath, xpath_size, "%s%s", base, path);
      retval = pusb_xpath_get_bool(doc, xpath, value);
      free(xpath);
      return (retval);
}

int pusb_xpath_get_time(xmlDocPtr doc, const char *path, time_t *value)
{
      char  ret[64];
      char  *last;
      int         coef;

      if (!pusb_xpath_get_string(doc, path, ret, sizeof(ret)))
            return (0);

      last = &(ret[strlen(ret) - 1]);
      coef = 1;
      if (*last == 's')
            coef = 1;
      else if (*last == 'm')
            coef = 60;
      else if (*last == 'h')
            coef = 3600;
      else if (*last == 'd')
            coef = 3600 * 24;
      else
            if (!isdigit(*last))
            {
                  log_debug("Expecting a time modifier, got %c\n", *last);
                  return (0);
            }
      if (!isdigit(*last))
            *last = '\0';
      *value = atoi(ret) * coef;

      return (0);
}

int pusb_xpath_get_time_from(xmlDocPtr doc,
            const char *base,
            const char *path,
            time_t *value)
{
      char  *xpath = NULL;
      size_t      xpath_size;
      int         retval;

      xpath_size = strlen(base) + strlen(path) + 1;
      if (!(xpath = malloc(xpath_size)))
      {
            log_error("malloc error!\n");
            return (0);
      }
      memset(xpath, 0x00, xpath_size);
      snprintf(xpath, xpath_size, "%s%s", base, path);
      retval = pusb_xpath_get_time(doc, xpath, value);
      free(xpath);
      return (retval);
}

int pusb_xpath_get_int(xmlDocPtr doc, const char *path, int *value)
{
      char  ret[64];

      if (!pusb_xpath_get_string(doc, path, ret, sizeof(ret)))
            return (0);
      *value = atoi(ret);
      return (1);
}

int pusb_xpath_get_int_from(xmlDocPtr doc,
            const char *base,
            const char *path,
            int *value)
{
      char  *xpath = NULL;
      size_t      xpath_size;
      int         retval;

      xpath_size = strlen(base) + strlen(path) + 1;
      if (!(xpath = malloc(xpath_size)))
      {
            log_error("malloc error!\n");
            return (0);
      }
      memset(xpath, 0x00, xpath_size);
      snprintf(xpath, xpath_size, "%s%s", base, path);
      retval = pusb_xpath_get_int(doc, xpath, value);
      free(xpath);
      return (retval);
}

Generated by  Doxygen 1.6.0   Back to index