Main Page   Modules   Data Structures   File List   Data Fields   Related Pages  

desktop-file.c

00001 /* -*- mode: C; c-file-style: "gnu" -*- */
00002 /* desktop-file.c  .desktop file parser
00003  *
00004  * Copyright (C) 2003  CodeFactory AB
00005  * Copyright (C) 2003  Red Hat Inc.
00006  *
00007  * Licensed under the Academic Free License version 1.2
00008  * 
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  * 
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022  *
00023  */
00024 #include <dbus/dbus-sysdeps.h>
00025 #include <dbus/dbus-internals.h>
00026 #include "desktop-file.h"
00027 #include "utils.h"
00028 
00029 typedef struct
00030 {
00031   char *key;
00032   char *value;
00033 } BusDesktopFileLine;
00034 
00035 typedef struct
00036 {
00037   char *section_name;
00038   
00039   int n_lines;
00040   BusDesktopFileLine *lines;
00041   int n_allocated_lines;  
00042 } BusDesktopFileSection;
00043 
00044 struct BusDesktopFile
00045 {
00046   int n_sections;
00047   BusDesktopFileSection *sections;
00048   int n_allocated_sections;
00049 };
00050 
00051 typedef struct
00052 {
00053   DBusString data;
00054 
00055   BusDesktopFile *desktop_file;
00056   int current_section;
00057   
00058   int pos, len;
00059   int line_num;
00060   
00061 } BusDesktopFileParser;
00062 
00063 #define VALID_KEY_CHAR 1
00064 #define VALID_LOCALE_CHAR 2
00065 unsigned char valid[256] = { 
00066    0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 
00067    0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 
00068    0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x3 , 0x2 , 0x0 , 
00069    0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 
00070    0x0 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 
00071    0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x0 , 0x0 , 0x0 , 0x0 , 0x2 , 
00072    0x0 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 
00073    0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 
00074    0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 
00075    0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 
00076    0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 
00077    0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 
00078    0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 
00079    0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 
00080    0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 
00081    0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 
00082 };
00083 
00084 static void report_error (BusDesktopFileParser *parser,
00085                           char                 *message,
00086                           const char           *error_name,
00087                           DBusError            *error);
00088 
00089 static void
00090 parser_free (BusDesktopFileParser *parser)
00091 {
00092   bus_desktop_file_free (parser->desktop_file);
00093   
00094   _dbus_string_free (&parser->data);
00095 }
00096 
00097 static void
00098 bus_desktop_file_line_free (BusDesktopFileLine *line)
00099 {
00100   dbus_free (line->key);
00101   dbus_free (line->value);
00102 }
00103 
00104 static void
00105 bus_desktop_file_section_free (BusDesktopFileSection *section)
00106 {
00107   int i;
00108 
00109   for (i = 0; i < section->n_lines; i++)
00110     bus_desktop_file_line_free (&section->lines[i]);
00111 
00112   dbus_free (section->lines);
00113   dbus_free (section->section_name);
00114 }
00115 
00116 void
00117 bus_desktop_file_free (BusDesktopFile *desktop_file)
00118 {
00119   int i;
00120 
00121   for (i = 0; i < desktop_file->n_sections; i++)
00122     bus_desktop_file_section_free (&desktop_file->sections[i]);
00123   dbus_free (desktop_file->sections);
00124 
00125   dbus_free (desktop_file);
00126 }
00127 
00128 static dbus_bool_t
00129 grow_lines_in_section (BusDesktopFileSection *section)
00130 {
00131   BusDesktopFileLine *lines;
00132   
00133   int new_n_lines;
00134 
00135   if (section->n_allocated_lines == 0)
00136     new_n_lines = 1;
00137   else
00138     new_n_lines = section->n_allocated_lines*2;
00139 
00140   lines = dbus_realloc (section->lines,
00141                         sizeof (BusDesktopFileLine) * new_n_lines);
00142 
00143   if (lines == NULL)
00144     return FALSE;
00145   
00146   section->lines = lines;
00147   section->n_allocated_lines = new_n_lines;
00148 
00149   return TRUE;
00150 }
00151 
00152 static dbus_bool_t
00153 grow_sections (BusDesktopFile *desktop_file)
00154 {
00155   int new_n_sections;
00156   BusDesktopFileSection *sections;
00157   
00158   if (desktop_file->n_allocated_sections == 0)
00159     new_n_sections = 1;
00160   else
00161     new_n_sections = desktop_file->n_allocated_sections*2;
00162 
00163   sections = dbus_realloc (desktop_file->sections,
00164                            sizeof (BusDesktopFileSection) * new_n_sections);
00165   if (sections == NULL)
00166     return FALSE;
00167   
00168   desktop_file->sections = sections;
00169   
00170   desktop_file->n_allocated_sections = new_n_sections;
00171 
00172   return TRUE;
00173 }
00174 
00175 static char *
00176 unescape_string (BusDesktopFileParser *parser,
00177                  const DBusString     *str,
00178                  int                   pos,
00179                  int                   end_pos,
00180                  DBusError            *error)
00181 {
00182   char *retval, *q;
00183 
00184   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00185   
00186   /* len + 1 is enough, because unescaping never makes the
00187    * string longer
00188    */
00189   retval = dbus_malloc (end_pos - pos + 1);
00190   if (retval == NULL)
00191     {
00192       BUS_SET_OOM (error);
00193       return NULL;
00194     }
00195 
00196   q = retval;
00197   
00198   while (pos < end_pos)
00199     {
00200       if (_dbus_string_get_byte (str, pos) == 0)
00201         {
00202           /* Found an embedded null */
00203           dbus_free (retval);
00204           report_error (parser, "Text to be unescaped contains embedded nul",
00205                         BUS_DESKTOP_PARSE_ERROR_INVALID_ESCAPES, error);
00206           return NULL;
00207         }
00208 
00209       if (_dbus_string_get_byte (str, pos) == '\\')
00210         {
00211           pos ++;
00212 
00213           if (pos >= end_pos)
00214             {
00215               /* Escape at end of string */
00216               dbus_free (retval);
00217               report_error (parser, "Text to be unescaped ended in \\",
00218                             BUS_DESKTOP_PARSE_ERROR_INVALID_ESCAPES, error);
00219               return NULL;
00220             }
00221 
00222           switch (_dbus_string_get_byte (str, pos))
00223             {
00224             case 's':
00225               *q++ = ' ';
00226               break;
00227            case 't':
00228               *q++ = '\t';
00229               break;
00230            case 'n':
00231               *q++ = '\n';
00232               break;
00233            case 'r':
00234               *q++ = '\r';
00235               break;
00236            case '\\':
00237               *q++ = '\\';
00238               break;
00239            default:
00240              /* Invalid escape code */
00241              dbus_free (retval);
00242              report_error (parser, "Text to be unescaped had invalid escape sequence",
00243                            BUS_DESKTOP_PARSE_ERROR_INVALID_ESCAPES, error);
00244              return NULL;
00245             }
00246           pos++;
00247         }
00248       else
00249         {
00250           *q++ =_dbus_string_get_byte (str, pos);
00251 
00252           pos++;
00253         }
00254     }
00255 
00256   *q = 0;
00257 
00258   return retval;
00259 }
00260 
00261 static BusDesktopFileSection* 
00262 new_section (BusDesktopFile *desktop_file,
00263              const char     *name)
00264 {
00265   int n;
00266   char *name_copy;
00267   
00268   if (desktop_file->n_allocated_sections == desktop_file->n_sections)
00269     {
00270       if (!grow_sections (desktop_file))
00271         return NULL;
00272     }
00273 
00274   name_copy = _dbus_strdup (name);
00275   if (name_copy == NULL)
00276     return NULL;
00277 
00278   n = desktop_file->n_sections;
00279   desktop_file->sections[n].section_name = name_copy;
00280 
00281   desktop_file->sections[n].n_lines = 0;
00282   desktop_file->sections[n].lines = NULL;
00283   desktop_file->sections[n].n_allocated_lines = 0;
00284 
00285   if (!grow_lines_in_section (&desktop_file->sections[n]))
00286     {
00287       dbus_free (desktop_file->sections[n].section_name);
00288       desktop_file->sections[n].section_name = NULL;
00289       return NULL;
00290     }
00291 
00292   desktop_file->n_sections += 1;
00293   
00294   return &desktop_file->sections[n];  
00295 }
00296 
00297 static BusDesktopFileSection* 
00298 open_section (BusDesktopFileParser *parser,
00299               char                 *name)
00300 {  
00301   BusDesktopFileSection *section;
00302 
00303   section = new_section (parser->desktop_file, name);
00304   if (section == NULL)
00305     return NULL;
00306   
00307   parser->current_section = parser->desktop_file->n_sections - 1;
00308   _dbus_assert (&parser->desktop_file->sections[parser->current_section] == section);
00309   
00310   return section;
00311 }
00312 
00313 static BusDesktopFileLine *
00314 new_line (BusDesktopFileParser *parser)
00315 {
00316   BusDesktopFileSection *section;
00317   BusDesktopFileLine *line;
00318   
00319   section = &parser->desktop_file->sections[parser->current_section];
00320 
00321   if (section->n_allocated_lines == section->n_lines)
00322     {
00323       if (!grow_lines_in_section (section))
00324         return NULL;
00325     }
00326 
00327   line = &section->lines[section->n_lines++];
00328 
00329   memset (line, 0, sizeof (BusDesktopFileLine));
00330     
00331   return line;
00332 }
00333 
00334 static dbus_bool_t
00335 is_blank_line (BusDesktopFileParser *parser)
00336 {
00337   int p;
00338   char c;
00339   
00340   p = parser->pos;
00341 
00342   c = _dbus_string_get_byte (&parser->data, p);
00343 
00344   while (c && c != '\n')
00345     {
00346       if (!(c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f'))
00347         return FALSE;
00348       
00349       p++;
00350       c = _dbus_string_get_byte (&parser->data, p);
00351     }
00352 
00353   return TRUE;
00354 }
00355 
00356 static void
00357 parse_comment_or_blank (BusDesktopFileParser *parser)
00358 {
00359   int line_end;
00360   
00361   if (!_dbus_string_find (&parser->data, parser->pos, "\n", &line_end))
00362     line_end = parser->len;
00363 
00364   if (line_end == parser->len)
00365     parser->pos = parser->len;
00366   else
00367     parser->pos = line_end + 1;
00368   
00369   parser->line_num += 1;
00370 }
00371 
00372 static dbus_bool_t
00373 is_valid_section_name (const char *name)
00374 {
00375   /* 5. Group names may contain all ASCII characters except for control characters and '[' and ']'. */
00376 
00377   while (*name)
00378     {
00379       if (!((*name >= 'A' && *name <= 'Z') || (*name >= 'a' || *name <= 'z') ||
00380             *name == '\n' || *name == '\t'))
00381         return FALSE;
00382       
00383       name++;
00384     }
00385 
00386   return TRUE;
00387 }
00388 
00389 static dbus_bool_t
00390 parse_section_start (BusDesktopFileParser *parser, DBusError *error)
00391 {
00392   int line_end;
00393   char *section_name;
00394 
00395   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00396   
00397   if (!_dbus_string_find (&parser->data, parser->pos, "\n", &line_end))
00398     line_end = parser->len;
00399   
00400   if (line_end - parser->pos <= 2 ||
00401       _dbus_string_get_byte (&parser->data, line_end - 1) != ']')
00402     {
00403       report_error (parser, "Invalid syntax for section header", BUS_DESKTOP_PARSE_ERROR_INVALID_SYNTAX, error);
00404       parser_free (parser);
00405       return FALSE;
00406     }
00407 
00408   section_name = unescape_string (parser,
00409                                   &parser->data, parser->pos + 1, line_end - 1,
00410                                   error);
00411 
00412   if (section_name == NULL)
00413     {
00414       parser_free (parser);
00415       return FALSE;
00416     }
00417 
00418   if (!is_valid_section_name (section_name))
00419     {
00420       report_error (parser, "Invalid characters in section name", BUS_DESKTOP_PARSE_ERROR_INVALID_CHARS, error);
00421       parser_free (parser);
00422       dbus_free (section_name);
00423       return FALSE;
00424     }
00425 
00426   if (open_section (parser, section_name) == NULL)
00427     {
00428       dbus_free (section_name);
00429       return FALSE;
00430     }
00431 
00432   if (line_end == parser->len)
00433     parser->pos = parser->len;
00434   else
00435     parser->pos = line_end + 1;
00436   
00437   parser->line_num += 1;
00438 
00439   dbus_free (section_name);
00440   
00441   return TRUE;
00442 }
00443 
00444 static dbus_bool_t
00445 parse_key_value (BusDesktopFileParser *parser, DBusError *error)
00446 {
00447   int line_end;
00448   int key_start, key_end;
00449   int value_start;
00450   int p;
00451   char *value, *tmp;
00452   DBusString key;
00453   BusDesktopFileLine *line;
00454 
00455   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00456   
00457   if (!_dbus_string_find (&parser->data, parser->pos, "\n", &line_end))
00458     line_end = parser->len;
00459 
00460   p = parser->pos;
00461   key_start = p;
00462   while (p < line_end &&
00463          (valid[_dbus_string_get_byte (&parser->data, p)] & VALID_KEY_CHAR))
00464     p++;
00465   key_end = p;
00466   
00467   if (key_start == key_end)
00468     {
00469       report_error (parser, "Empty key name", BUS_DESKTOP_PARSE_ERROR_INVALID_SYNTAX, error);
00470       parser_free (parser);
00471       return FALSE;
00472     }
00473 
00474   /* We ignore locales for now */
00475   
00476   /* Skip space before '=' */
00477   while (p < line_end && _dbus_string_get_byte (&parser->data, p) == ' ')
00478     p++;
00479 
00480   if (p < line_end && _dbus_string_get_byte (&parser->data, p) != '=')
00481     {
00482       report_error (parser, "Invalid characters in key name", BUS_DESKTOP_PARSE_ERROR_INVALID_CHARS, error);
00483       parser_free (parser);
00484       return FALSE;
00485     }
00486 
00487   if (p == line_end)
00488     {
00489       report_error (parser, "No '=' in key/value pair", BUS_DESKTOP_PARSE_ERROR_INVALID_SYNTAX, error);
00490       parser_free (parser);
00491       return FALSE;
00492     }
00493 
00494   /* Skip the '=' */
00495   p++;
00496 
00497   /* Skip space after '=' */
00498   while (p < line_end && _dbus_string_get_byte (&parser->data, p) == ' ')
00499     p++;
00500 
00501   value_start = p;
00502   
00503   value = unescape_string (parser, &parser->data, value_start, line_end, error);
00504   if (value == NULL)
00505     {
00506       parser_free (parser);
00507       return FALSE;
00508     }
00509 
00510   line = new_line (parser);
00511   if (line == NULL)
00512     {
00513       parser_free (parser);
00514       return FALSE;
00515     }
00516   
00517   if (!_dbus_string_init (&key))
00518     {
00519       parser_free (parser);
00520       return FALSE;
00521     }
00522   
00523   if (!_dbus_string_copy_len (&parser->data, key_start, key_end - key_start,
00524                               &key, 0))
00525     {
00526       parser_free (parser);
00527       return FALSE;
00528     }
00529   
00530   if (!_dbus_string_steal_data (&key, &tmp))
00531     {
00532       parser_free (parser);
00533       return FALSE;
00534     }
00535   
00536   _dbus_string_free (&key);
00537   
00538   line->key = tmp;
00539   line->value = value;
00540 
00541   if (line_end == parser->len)
00542     parser->pos = parser->len;
00543   else
00544     parser->pos = line_end + 1;
00545   
00546   parser->line_num += 1;
00547 
00548   return TRUE;
00549 }
00550 
00551 static void
00552 report_error (BusDesktopFileParser *parser,
00553               char                 *message,
00554               const char           *error_name,
00555               DBusError            *error)
00556 {
00557   const char *section_name = NULL;
00558 
00559   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00560   
00561   if (parser->current_section != -1)
00562     section_name = parser->desktop_file->sections[parser->current_section].section_name;
00563 
00564   if (section_name)
00565     dbus_set_error (error, error_name,
00566                     "Error in section %s at line %d: %s\n", section_name, parser->line_num, message);
00567   else
00568     dbus_set_error (error, error_name,
00569                     "Error at line %d: %s\n", parser->line_num, message);
00570 }
00571 
00572 #if 0
00573 static void
00574 dump_desktop_file (BusDesktopFile *file)
00575 {
00576   int i;
00577 
00578   for (i = 0; i < file->n_sections; i++)
00579     {
00580       int j;
00581       
00582       printf ("[%s]\n", file->sections[i].section_name);
00583 
00584       for (j = 0; j < file->sections[i].n_lines; j++)
00585         {
00586           printf ("%s=%s\n", file->sections[i].lines[j].key,
00587                   file->sections[i].lines[j].value);
00588         }
00589     }
00590 }
00591 #endif
00592 
00593 BusDesktopFile*
00594 bus_desktop_file_load (DBusString *filename,
00595                        DBusError  *error)
00596 {
00597   DBusString str;
00598   BusDesktopFileParser parser;
00599   DBusStat sb;
00600 
00601   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00602   
00603   /* Clearly there's a race here, but it's just to make it unlikely
00604    * that we do something silly, we still handle doing it below.
00605    */
00606   if (!_dbus_stat (filename, &sb, error))
00607     return NULL;
00608 
00609   if (sb.size > _DBUS_ONE_KILOBYTE * 128)
00610     {
00611       dbus_set_error (error, DBUS_ERROR_FAILED,
00612                       "Desktop file size (%ld bytes) is too large", (long) sb.size);
00613       return NULL;
00614     }
00615   
00616   if (!_dbus_string_init (&str))
00617     return NULL;
00618   
00619   if (!_dbus_file_get_contents (&str, filename, error))
00620     {
00621       _dbus_string_free (&str);
00622       return NULL;
00623     }
00624 
00625   if (!_dbus_string_validate_utf8 (&str, 0, _dbus_string_get_length (&str)))
00626     {
00627       _dbus_string_free (&str);
00628       dbus_set_error (error, DBUS_ERROR_FAILED,
00629                       "invalid UTF-8");   
00630       return NULL;
00631     }
00632   
00633   parser.desktop_file = dbus_new0 (BusDesktopFile, 1);
00634   if (parser.desktop_file == NULL)
00635     {
00636       _dbus_string_free (&str);
00637       BUS_SET_OOM (error);
00638       return NULL;
00639     }
00640   
00641   parser.data = str;
00642   parser.line_num = 1;
00643   parser.pos = 0;
00644   parser.len = _dbus_string_get_length (&parser.data);
00645   parser.current_section = -1;
00646   
00647   while (parser.pos < parser.len)
00648     {
00649       if (_dbus_string_get_byte (&parser.data, parser.pos) == '[')
00650         {
00651           if (!parse_section_start (&parser, error))
00652             {
00653               _dbus_string_free (&parser.data);
00654               return NULL;
00655             }
00656         }
00657       else if (is_blank_line (&parser) ||
00658                _dbus_string_get_byte (&parser.data, parser.pos) == '#')
00659         parse_comment_or_blank (&parser);
00660       else
00661         {
00662           if (!parse_key_value (&parser, error))
00663             {
00664               _dbus_string_free (&parser.data);
00665               return NULL;
00666             }
00667         }
00668     }
00669 
00670   _dbus_string_free (&parser.data);
00671 
00672   return parser.desktop_file;
00673 }
00674 
00675 static BusDesktopFileSection *
00676 lookup_section (BusDesktopFile *desktop_file,
00677                 const char     *section_name)
00678 {
00679   BusDesktopFileSection *section;
00680   int i;
00681   
00682   if (section_name == NULL)
00683     return NULL;
00684   
00685   for (i = 0; i < desktop_file->n_sections; i ++)
00686     {
00687       section = &desktop_file->sections[i];
00688 
00689       if (strcmp (section->section_name, section_name) == 0)
00690         return section;
00691     }
00692   
00693   return NULL;
00694 }
00695 
00696 static BusDesktopFileLine *
00697 lookup_line (BusDesktopFile        *desktop_file,
00698              BusDesktopFileSection *section,
00699              const char            *keyname)
00700 {
00701   BusDesktopFileLine *line;
00702   int i;
00703 
00704   for (i = 0; i < section->n_lines; i++)
00705     {
00706       line = &section->lines[i];
00707       
00708       if (strcmp (line->key, keyname) == 0)
00709         return line;
00710     }
00711   
00712   return NULL;
00713 }
00714 
00715 dbus_bool_t
00716 bus_desktop_file_get_raw (BusDesktopFile  *desktop_file,
00717                           const char      *section_name,
00718                           const char      *keyname,
00719                           const char     **val)
00720 {
00721   BusDesktopFileSection *section;
00722   BusDesktopFileLine *line;
00723 
00724   *val = NULL;
00725 
00726   section = lookup_section (desktop_file, section_name);
00727   
00728   if (!section)
00729     return FALSE;
00730 
00731   line = lookup_line (desktop_file,
00732                       section,
00733                       keyname);
00734 
00735   if (!line)
00736     return FALSE;
00737   
00738   *val = line->value;
00739   
00740   return TRUE;
00741 }
00742 
00743 dbus_bool_t
00744 bus_desktop_file_get_string (BusDesktopFile  *desktop_file,
00745                              const char      *section,
00746                              const char      *keyname,
00747                              char           **val)
00748 {
00749   const char *raw;
00750   
00751   *val = NULL;
00752   
00753   if (!bus_desktop_file_get_raw (desktop_file, section, keyname, &raw))
00754     return FALSE;
00755 
00756   *val = _dbus_strdup (raw);
00757 
00758   /* FIXME we don't distinguish "key not found" from "out of memory" here,
00759    * which is broken.
00760    */
00761   if (*val == NULL)
00762     return FALSE;
00763   
00764   return TRUE;
00765 }

Generated on Wed Oct 22 14:05:05 2003 for D-BUS by doxygen1.3-rc3