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

Generated on Mon Sep 29 21:31:02 2003 for D-BUS by doxygen1.2.15