diff options
Diffstat (limited to 'src/3rd_party/dbus-1.7.8/bus/desktop-file.c')
-rw-r--r-- | src/3rd_party/dbus-1.7.8/bus/desktop-file.c | 808 |
1 files changed, 0 insertions, 808 deletions
diff --git a/src/3rd_party/dbus-1.7.8/bus/desktop-file.c b/src/3rd_party/dbus-1.7.8/bus/desktop-file.c deleted file mode 100644 index bfeb72e241..0000000000 --- a/src/3rd_party/dbus-1.7.8/bus/desktop-file.c +++ /dev/null @@ -1,808 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* desktop-file.c .desktop file parser - * - * Copyright (C) 2003 CodeFactory AB - * Copyright (C) 2003 Red Hat Inc. - * - * Licensed under the Academic Free License version 2.1 - * - * This program is free software; you can redistribute it and/or modify - * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include <config.h> -#include <dbus/dbus-sysdeps.h> -#include <dbus/dbus-internals.h> -#include "desktop-file.h" -#include "utils.h" - -typedef struct -{ - char *key; - char *value; -} BusDesktopFileLine; - -typedef struct -{ - char *section_name; - - int n_lines; - BusDesktopFileLine *lines; - int n_allocated_lines; -} BusDesktopFileSection; - -struct BusDesktopFile -{ - int n_sections; - BusDesktopFileSection *sections; - int n_allocated_sections; -}; - -/** - * Parser for service files. - */ -typedef struct -{ - DBusString data; /**< The data from the file */ - - BusDesktopFile *desktop_file; /**< The resulting object */ - int current_section; /**< The current section being parsed */ - - int pos; /**< Current position */ - int len; /**< Length */ - int line_num; /**< Current line number */ - -} BusDesktopFileParser; - -#define VALID_KEY_CHAR 1 -#define VALID_LOCALE_CHAR 2 -static unsigned char valid[256] = { - 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , - 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , - 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x3 , 0x2 , 0x0 , - 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , - 0x0 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , - 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x0 , 0x0 , 0x0 , 0x0 , 0x2 , - 0x0 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , - 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , - 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , - 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , - 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , - 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , - 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , - 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , - 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , - 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , -}; - -static void report_error (BusDesktopFileParser *parser, - char *message, - const char *error_name, - DBusError *error); - -static void -parser_free (BusDesktopFileParser *parser) -{ - bus_desktop_file_free (parser->desktop_file); - - _dbus_string_free (&parser->data); -} - -static void -bus_desktop_file_line_free (BusDesktopFileLine *line) -{ - dbus_free (line->key); - dbus_free (line->value); -} - -static void -bus_desktop_file_section_free (BusDesktopFileSection *section) -{ - int i; - - for (i = 0; i < section->n_lines; i++) - bus_desktop_file_line_free (§ion->lines[i]); - - dbus_free (section->lines); - dbus_free (section->section_name); -} - -void -bus_desktop_file_free (BusDesktopFile *desktop_file) -{ - int i; - - for (i = 0; i < desktop_file->n_sections; i++) - bus_desktop_file_section_free (&desktop_file->sections[i]); - dbus_free (desktop_file->sections); - - dbus_free (desktop_file); -} - -static dbus_bool_t -grow_lines_in_section (BusDesktopFileSection *section) -{ - BusDesktopFileLine *lines; - - int new_n_lines; - - if (section->n_allocated_lines == 0) - new_n_lines = 1; - else - new_n_lines = section->n_allocated_lines*2; - - lines = dbus_realloc (section->lines, - sizeof (BusDesktopFileLine) * new_n_lines); - - if (lines == NULL) - return FALSE; - - section->lines = lines; - section->n_allocated_lines = new_n_lines; - - return TRUE; -} - -static dbus_bool_t -grow_sections (BusDesktopFile *desktop_file) -{ - int new_n_sections; - BusDesktopFileSection *sections; - - if (desktop_file->n_allocated_sections == 0) - new_n_sections = 1; - else - new_n_sections = desktop_file->n_allocated_sections*2; - - sections = dbus_realloc (desktop_file->sections, - sizeof (BusDesktopFileSection) * new_n_sections); - if (sections == NULL) - return FALSE; - - desktop_file->sections = sections; - - desktop_file->n_allocated_sections = new_n_sections; - - return TRUE; -} - -static char * -unescape_string (BusDesktopFileParser *parser, - const DBusString *str, - int pos, - int end_pos, - DBusError *error) -{ - char *retval, *q; - - _DBUS_ASSERT_ERROR_IS_CLEAR (error); - - /* len + 1 is enough, because unescaping never makes the - * string longer - */ - retval = dbus_malloc (end_pos - pos + 1); - if (retval == NULL) - { - BUS_SET_OOM (error); - return NULL; - } - - q = retval; - - while (pos < end_pos) - { - if (_dbus_string_get_byte (str, pos) == 0) - { - /* Found an embedded null */ - dbus_free (retval); - report_error (parser, "Text to be unescaped contains embedded nul", - BUS_DESKTOP_PARSE_ERROR_INVALID_ESCAPES, error); - return NULL; - } - - if (_dbus_string_get_byte (str, pos) == '\\') - { - pos ++; - - if (pos >= end_pos) - { - /* Escape at end of string */ - dbus_free (retval); - report_error (parser, "Text to be unescaped ended in \\", - BUS_DESKTOP_PARSE_ERROR_INVALID_ESCAPES, error); - return NULL; - } - - switch (_dbus_string_get_byte (str, pos)) - { - case 's': - *q++ = ' '; - break; - case 't': - *q++ = '\t'; - break; - case 'n': - *q++ = '\n'; - break; - case 'r': - *q++ = '\r'; - break; - case '\\': - *q++ = '\\'; - break; - default: - /* Invalid escape code */ - dbus_free (retval); - report_error (parser, "Text to be unescaped had invalid escape sequence", - BUS_DESKTOP_PARSE_ERROR_INVALID_ESCAPES, error); - return NULL; - } - pos++; - } - else - { - *q++ =_dbus_string_get_byte (str, pos); - - pos++; - } - } - - *q = 0; - - return retval; -} - -static BusDesktopFileSection* -new_section (BusDesktopFile *desktop_file, - const char *name) -{ - int n; - char *name_copy; - - if (desktop_file->n_allocated_sections == desktop_file->n_sections) - { - if (!grow_sections (desktop_file)) - return NULL; - } - - name_copy = _dbus_strdup (name); - if (name_copy == NULL) - return NULL; - - n = desktop_file->n_sections; - desktop_file->sections[n].section_name = name_copy; - - desktop_file->sections[n].n_lines = 0; - desktop_file->sections[n].lines = NULL; - desktop_file->sections[n].n_allocated_lines = 0; - - if (!grow_lines_in_section (&desktop_file->sections[n])) - { - dbus_free (desktop_file->sections[n].section_name); - desktop_file->sections[n].section_name = NULL; - return NULL; - } - - desktop_file->n_sections += 1; - - return &desktop_file->sections[n]; -} - -static BusDesktopFileSection* -open_section (BusDesktopFileParser *parser, - char *name) -{ - BusDesktopFileSection *section; - - section = new_section (parser->desktop_file, name); - if (section == NULL) - return NULL; - - parser->current_section = parser->desktop_file->n_sections - 1; - _dbus_assert (&parser->desktop_file->sections[parser->current_section] == section); - - return section; -} - -static BusDesktopFileLine * -new_line (BusDesktopFileParser *parser) -{ - BusDesktopFileSection *section; - BusDesktopFileLine *line; - - section = &parser->desktop_file->sections[parser->current_section]; - - if (section->n_allocated_lines == section->n_lines) - { - if (!grow_lines_in_section (section)) - return NULL; - } - - line = §ion->lines[section->n_lines++]; - - _DBUS_ZERO(*line); - - return line; -} - -static dbus_bool_t -is_blank_line (BusDesktopFileParser *parser) -{ - int p; - char c; - - p = parser->pos; - - c = _dbus_string_get_byte (&parser->data, p); - - while (c && c != '\n') - { - if (!(c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f')) - return FALSE; - - p++; - c = _dbus_string_get_byte (&parser->data, p); - } - - return TRUE; -} - -static void -parse_comment_or_blank (BusDesktopFileParser *parser) -{ - int line_end, eol_len; - - if (!_dbus_string_find_eol (&parser->data, parser->pos, &line_end, &eol_len)) - line_end = parser->len; - - if (line_end == parser->len) - parser->pos = parser->len; - else - parser->pos = line_end + eol_len; - - parser->line_num += 1; -} - -static dbus_bool_t -is_valid_section_name (const char *name) -{ - /* 5. Group names may contain all ASCII characters except for control characters and '[' and ']'. */ - - while (*name) - { - if (!((*name >= 'A' && *name <= 'Z') || (*name >= 'a' || *name <= 'z') || - *name == '\n' || *name == '\t')) - return FALSE; - - name++; - } - - return TRUE; -} - -static dbus_bool_t -parse_section_start (BusDesktopFileParser *parser, DBusError *error) -{ - int line_end, eol_len; - char *section_name; - - _DBUS_ASSERT_ERROR_IS_CLEAR (error); - - if (!_dbus_string_find_eol (&parser->data, parser->pos, &line_end, &eol_len)) - line_end = parser->len; - - if (line_end - parser->pos <= 2 || - _dbus_string_get_byte (&parser->data, line_end - 1) != ']') - { - report_error (parser, "Invalid syntax for section header", BUS_DESKTOP_PARSE_ERROR_INVALID_SYNTAX, error); - parser_free (parser); - return FALSE; - } - - section_name = unescape_string (parser, - &parser->data, parser->pos + 1, line_end - 1, - error); - - if (section_name == NULL) - { - parser_free (parser); - return FALSE; - } - - if (!is_valid_section_name (section_name)) - { - report_error (parser, "Invalid characters in section name", BUS_DESKTOP_PARSE_ERROR_INVALID_CHARS, error); - parser_free (parser); - dbus_free (section_name); - return FALSE; - } - - if (open_section (parser, section_name) == NULL) - { - dbus_free (section_name); - parser_free (parser); - BUS_SET_OOM (error); - return FALSE; - } - - if (line_end == parser->len) - parser->pos = parser->len; - else - parser->pos = line_end + eol_len; - - parser->line_num += 1; - - dbus_free (section_name); - - return TRUE; -} - -static dbus_bool_t -parse_key_value (BusDesktopFileParser *parser, DBusError *error) -{ - int line_end, eol_len; - int key_start, key_end; - int value_start; - int p; - char *value, *tmp; - DBusString key; - BusDesktopFileLine *line; - - _DBUS_ASSERT_ERROR_IS_CLEAR (error); - - if (!_dbus_string_find_eol (&parser->data, parser->pos, &line_end, &eol_len)) - line_end = parser->len; - - p = parser->pos; - key_start = p; - while (p < line_end && - (valid[_dbus_string_get_byte (&parser->data, p)] & VALID_KEY_CHAR)) - p++; - key_end = p; - - if (key_start == key_end) - { - report_error (parser, "Empty key name", BUS_DESKTOP_PARSE_ERROR_INVALID_SYNTAX, error); - parser_free (parser); - return FALSE; - } - - /* We ignore locales for now */ - if (p < line_end && _dbus_string_get_byte (&parser->data, p) == '[') - { - if (line_end == parser->len) - parser->pos = parser->len; - else - parser->pos = line_end + eol_len; - - parser->line_num += 1; - - return TRUE; - } - - /* Skip space before '=' */ - while (p < line_end && _dbus_string_get_byte (&parser->data, p) == ' ') - p++; - - if (p < line_end && _dbus_string_get_byte (&parser->data, p) != '=') - { - report_error (parser, "Invalid characters in key name", BUS_DESKTOP_PARSE_ERROR_INVALID_CHARS, error); - parser_free (parser); - return FALSE; - } - - if (p == line_end) - { - report_error (parser, "No '=' in key/value pair", BUS_DESKTOP_PARSE_ERROR_INVALID_SYNTAX, error); - parser_free (parser); - return FALSE; - } - - /* Skip the '=' */ - p++; - - /* Skip space after '=' */ - while (p < line_end && _dbus_string_get_byte (&parser->data, p) == ' ') - p++; - - value_start = p; - - value = unescape_string (parser, &parser->data, value_start, line_end, error); - if (value == NULL) - { - parser_free (parser); - return FALSE; - } - - line = new_line (parser); - if (line == NULL) - { - dbus_free (value); - parser_free (parser); - BUS_SET_OOM (error); - return FALSE; - } - - if (!_dbus_string_init (&key)) - { - dbus_free (value); - parser_free (parser); - BUS_SET_OOM (error); - return FALSE; - } - - if (!_dbus_string_copy_len (&parser->data, key_start, key_end - key_start, - &key, 0)) - { - _dbus_string_free (&key); - dbus_free (value); - parser_free (parser); - BUS_SET_OOM (error); - return FALSE; - } - - if (!_dbus_string_steal_data (&key, &tmp)) - { - _dbus_string_free (&key); - dbus_free (value); - parser_free (parser); - BUS_SET_OOM (error); - return FALSE; - } - - _dbus_string_free (&key); - - line->key = tmp; - line->value = value; - - if (line_end == parser->len) - parser->pos = parser->len; - else - parser->pos = line_end + eol_len; - - parser->line_num += 1; - - return TRUE; -} - -static void -report_error (BusDesktopFileParser *parser, - char *message, - const char *error_name, - DBusError *error) -{ - const char *section_name = NULL; - - _DBUS_ASSERT_ERROR_IS_CLEAR (error); - - if (parser->current_section != -1) - section_name = parser->desktop_file->sections[parser->current_section].section_name; - - if (section_name) - dbus_set_error (error, error_name, - "Error in section %s at line %d: %s\n", section_name, parser->line_num, message); - else - dbus_set_error (error, error_name, - "Error at line %d: %s\n", parser->line_num, message); -} - -#if 0 -static void -dump_desktop_file (BusDesktopFile *file) -{ - int i; - - for (i = 0; i < file->n_sections; i++) - { - int j; - - printf ("[%s]\n", file->sections[i].section_name); - - for (j = 0; j < file->sections[i].n_lines; j++) - { - printf ("%s=%s\n", file->sections[i].lines[j].key, - file->sections[i].lines[j].value); - } - } -} -#endif - -BusDesktopFile* -bus_desktop_file_load (DBusString *filename, - DBusError *error) -{ - DBusString str; - BusDesktopFileParser parser; - DBusStat sb; - - _DBUS_ASSERT_ERROR_IS_CLEAR (error); - - /* Clearly there's a race here, but it's just to make it unlikely - * that we do something silly, we still handle doing it below. - */ - if (!_dbus_stat (filename, &sb, error)) - return NULL; - - if (sb.size > _DBUS_ONE_KILOBYTE * 128) - { - dbus_set_error (error, DBUS_ERROR_FAILED, - "Desktop file size (%ld bytes) is too large", (long) sb.size); - return NULL; - } - - if (!_dbus_string_init (&str)) - { - BUS_SET_OOM (error); - return NULL; - } - - if (!_dbus_file_get_contents (&str, filename, error)) - { - _dbus_string_free (&str); - return NULL; - } - - if (!_dbus_string_validate_utf8 (&str, 0, _dbus_string_get_length (&str))) - { - _dbus_string_free (&str); - dbus_set_error (error, DBUS_ERROR_FAILED, - "invalid UTF-8"); - return NULL; - } - - parser.desktop_file = dbus_new0 (BusDesktopFile, 1); - if (parser.desktop_file == NULL) - { - _dbus_string_free (&str); - BUS_SET_OOM (error); - return NULL; - } - - parser.data = str; - parser.line_num = 1; - parser.pos = 0; - parser.len = _dbus_string_get_length (&parser.data); - parser.current_section = -1; - - while (parser.pos < parser.len) - { - if (_dbus_string_get_byte (&parser.data, parser.pos) == '[') - { - if (!parse_section_start (&parser, error)) - { - return NULL; - } - } - else if (is_blank_line (&parser) || - _dbus_string_get_byte (&parser.data, parser.pos) == '#') - parse_comment_or_blank (&parser); - else if (parser.current_section < 0) - { - dbus_set_error(error, DBUS_ERROR_FAILED, - "invalid service file: key=value before [Section]"); - return NULL; - } - else - { - if (!parse_key_value (&parser, error)) - { - return NULL; - } - } - } - - _dbus_string_free (&parser.data); - - return parser.desktop_file; -} - -static BusDesktopFileSection * -lookup_section (BusDesktopFile *desktop_file, - const char *section_name) -{ - BusDesktopFileSection *section; - int i; - - if (section_name == NULL) - return NULL; - - for (i = 0; i < desktop_file->n_sections; i ++) - { - section = &desktop_file->sections[i]; - - if (strcmp (section->section_name, section_name) == 0) - return section; - } - - return NULL; -} - -static BusDesktopFileLine * -lookup_line (BusDesktopFile *desktop_file, - BusDesktopFileSection *section, - const char *keyname) -{ - BusDesktopFileLine *line; - int i; - - for (i = 0; i < section->n_lines; i++) - { - line = §ion->lines[i]; - - if (strcmp (line->key, keyname) == 0) - return line; - } - - return NULL; -} - -dbus_bool_t -bus_desktop_file_get_raw (BusDesktopFile *desktop_file, - const char *section_name, - const char *keyname, - const char **val) -{ - BusDesktopFileSection *section; - BusDesktopFileLine *line; - - *val = NULL; - - section = lookup_section (desktop_file, section_name); - - if (!section) - return FALSE; - - line = lookup_line (desktop_file, - section, - keyname); - - if (!line) - return FALSE; - - *val = line->value; - - return TRUE; -} - -dbus_bool_t -bus_desktop_file_get_string (BusDesktopFile *desktop_file, - const char *section, - const char *keyname, - char **val, - DBusError *error) -{ - const char *raw; - - _DBUS_ASSERT_ERROR_IS_CLEAR (error); - - *val = NULL; - - if (!bus_desktop_file_get_raw (desktop_file, section, keyname, &raw)) - { - dbus_set_error (error, DBUS_ERROR_FAILED, - "No \"%s\" key in .service file\n", keyname); - return FALSE; - } - - *val = _dbus_strdup (raw); - - if (*val == NULL) - { - BUS_SET_OOM (error); - return FALSE; - } - - return TRUE; -} |