1 /* xmlrc.c
2  * Copyright (C) 2002-2004 Pascal Eberhard <pascal.ebo@netcourrier.com>
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public
15  * License along with this program; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19 
20 // ----------------------------------------------------------------------------
21 // ----------------------------------------------------------------------------
22 #include "common.h"
23 
24 #include <stdio.h>      /* define FILENAME_MAX */
25 #include <string.h>
26 #include <libxml/xmlmemory.h>
27 #include <libxml/parser.h>
28 #include <errno.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <fcntl.h>
32 #include <unistd.h>
33 #include <errno.h>
34 
35 
36 #include "xmlrcinline.inc"
37 
38 // ----------------------------------------------------------------------------
39 // .apwalrc.xml file:
40 //   apwalrc
41 //     apps
42 //       app
43 //       ...
44 //     iconsel_pref
45 //       icon_dirs
46 //         path
47 //         ...
48 //       file_exts
49 //         extension
50 //         ..
51 //     apwal_pref
52 //
53 //
54 // ----------------------------------------------------------------------------
55 
56 // only access filerc by xmlrc_set_resource_file/xmlrc_resource_file
57 static char g_xmlrc_filerc[FILENAME_MAX] = { 0 };
58 
59 static char*    xmlrc_resource_file(void);
60 
61 static app_list_t     * xmlrc_parse_apps(xmlDocPtr doc, xmlNodePtr cur);
62 static app_t          * xmlrc_parse_app(xmlDocPtr doc, xmlNodePtr cur);
63 
64 static apwal_pref_t   * xmlrc_parse_apwal_pref(xmlDocPtr doc, xmlNodePtr cur);
65 
66 static iconsel_pref_t * xmlrc_parse_iconsel_pref(xmlDocPtr doc, xmlNodePtr cur);
67 static GList          * xmlrc_parse_icon_dirs(xmlDocPtr doc, xmlNodePtr cur);
68 static icon_dir_t     * xmlrc_parse_icon_dir(xmlDocPtr doc, xmlNodePtr cur);
69 
70 static GList          * xmlrc_parse_file_exts(xmlDocPtr doc, xmlNodePtr cur);
71 static file_ext_t     * xmlrc_parse_file_ext(xmlDocPtr doc, xmlNodePtr cur);
72 
73 
74 // ----------------------------------------------------------------------------
75 // ----------------------------------------------------------------------------
xmlrc_load_from_file(app_list_t ** apps,iconsel_pref_t ** iconsel_pref,apwal_pref_t ** apwal_pref)76 void xmlrc_load_from_file(app_list_t **apps, iconsel_pref_t **iconsel_pref,
77                           apwal_pref_t **apwal_pref)
78 {
79   xmlDocPtr    doc;
80   xmlNodePtr   cur;
81   gboolean     apps_is_loaded = FALSE;
82   gboolean     iconsel_pref_is_loaded = FALSE;
83   gboolean     apwal_pref_is_loaded = FALSE;
84 
85   g_assert(apps != NULL && apwal_pref != NULL); // iconsel_pref NULL in launcher
86 
87   LIBXML_TEST_VERSION
88   xmlKeepBlanksDefault(0);
89 
90   // load tree from file
91   doc = xmlParseFile(xmlrc_resource_file());
92   if (doc == NULL)
93     ERR("xmlParseFile, file:%s invalid", xmlrc_resource_file());
94 
95   cur = xmlDocGetRootElement(doc);
96   if (cur == NULL)
97     ERR("xmlDocGetRootElement, empty document, file:%s", xmlrc_resource_file());
98 
99   if (xmlStrcmp(cur->name, (const xmlChar *) "apwalrc"))
100     ERR("xmlStrcmp, doc root:%s != apwalrc", cur->name);
101 
102   // load app list from tree
103   cur = cur->xmlChildrenNode;
104   while(cur != NULL)
105   {
106     if (xmlIsBlankNode(cur))
107     {
108       ERR("%s", "I just would like to know what is a xmlIsBlankNode");
109     }
110     if (!xmlStrcmp(cur->name, (const xmlChar *) "apps"))
111     {
112       if (apps_is_loaded == TRUE)
113         ERR("%s", "there are more that one <apps> node");
114       *apps = xmlrc_parse_apps(doc, cur);
115       apps_is_loaded = TRUE;
116 
117     }
118     else if (!xmlStrcmp(cur->name, (const xmlChar *) "iconsel_pref"))
119     {
120       if (iconsel_pref_is_loaded == TRUE)
121         ERR("%s", "there are more that one <iconsel_pref> node");
122       if (iconsel_pref != NULL) // the launcher will not ask for it
123         *iconsel_pref = xmlrc_parse_iconsel_pref(doc, cur);
124       iconsel_pref_is_loaded = TRUE;
125     }
126     else if (!xmlStrcmp(cur->name, (const xmlChar *) "apwal_pref"))
127     {
128       if (apwal_pref_is_loaded == TRUE)
129         ERR("%s", "there are more that one <apwal_pref> node");
130       if (apwal_pref != NULL) // the launcher will not ask for it
131         *apwal_pref = xmlrc_parse_apwal_pref(doc, cur);
132       apwal_pref_is_loaded = TRUE;
133     }
134     else
135       ERR("cur->name:%s invalid", cur->name);
136     cur = cur->next;
137   } //end while cur
138 
139   if (apps_is_loaded == FALSE)
140     ERR("apps section not found in rc file:%s", xmlrc_resource_file());
141   if (iconsel_pref_is_loaded == FALSE)
142     ERR("iconsel_pref section not found in rc file:%s", xmlrc_resource_file());
143   if (apwal_pref_is_loaded == FALSE)
144     ERR("apwal_pref section not found in rc file:%s", xmlrc_resource_file());
145 
146   // free tree
147   xmlFreeDoc(doc);
148   xmlCleanupParser();
149 }
150 
151 // ----------------------------------------------------------------------------
xmlrc_parse_apps(xmlDocPtr doc,xmlNodePtr cur)152 static app_list_t * xmlrc_parse_apps(xmlDocPtr doc, xmlNodePtr cur)
153 {
154   app_list_t *apps;
155   app_t      *app;
156   apps = app_list_new();
157   cur = cur->xmlChildrenNode;
158   while (cur)
159   {
160     if (xmlStrcmp(cur->name, (const xmlChar *) "app"))
161       ERR("cur->name:%s unknown", cur->name);
162     app = xmlrc_parse_app(doc, cur);
163     if (app != NULL)
164       app_list_add(apps, app);
165     cur = cur->next;
166   }
167   return apps;
168 }
169 // ----------------------------------------------------------------------------
xmlrc_parse_app(xmlDocPtr doc,xmlNodePtr cur)170 static app_t * xmlrc_parse_app(xmlDocPtr doc, xmlNodePtr cur)
171 {
172   app_t *app;
173   gchar *cmdline = NULL;
174   gchar *exec = NULL;
175   gchar *args = NULL;
176   gchar *path = NULL;
177   gchar *icon = NULL;
178   gint   x = 0;
179   gint   y = 0;
180   gchar *buf;
181 
182   cur = cur->xmlChildrenNode;
183   while (cur != NULL)
184   {
185     if (!xmlStrcmp(cur->name, (const xmlChar *)"cmdline"))
186       cmdline = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
187     else if (!xmlStrcmp(cur->name, (const xmlChar *)"name"))
188     {
189       // name property not used anymore starting from the v0.4.3
190     }
191     else if (!xmlStrcmp(cur->name, (const xmlChar *)"exec"))
192       exec = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
193     else if (!xmlStrcmp(cur->name, (const xmlChar *)"args"))
194       args = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
195     else if (!xmlStrcmp(cur->name, (const xmlChar *)"path"))
196       path = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
197     else if (!xmlStrcmp(cur->name, (const xmlChar *)"icon"))
198       icon = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
199     else if (!xmlStrcmp(cur->name, (const xmlChar *)"x"))
200     { buf = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
201       x = strtol(buf, (char **)NULL, 10);
202       g_free(buf);
203     }
204     else if (!xmlStrcmp(cur->name, (const xmlChar *)"y"))
205     { buf = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
206       y = strtol(buf, (char **)NULL, 10);
207       g_free(buf);
208     }
209     else
210       ERR("cur->name:%s unknown", cur->name);
211     cur = cur->next;
212   }
213 
214   // starting from the v0.4.3 cmdline replace exec and args
215   if (cmdline == NULL)
216   {
217     if (exec == NULL)
218     {
219       if (args != NULL)
220         cmdline = args;
221       else
222         cmdline = g_strdup("");
223     }
224     else if (args == NULL)
225       cmdline = exec;
226     else if (strcmp(args, "") == 0)
227     {
228       cmdline = exec;
229       g_free(args);
230     }
231     else
232     {
233       cmdline = g_strconcat(exec, " ", args, NULL);
234       g_free(exec);
235       g_free(args);
236     }
237 
238   }
239   if (path == NULL)
240     path = g_strdup("");
241   if (icon == NULL)
242     icon = g_strdup("");
243 
244   app = app_new(cmdline, path, icon, x, y);
245   app_dumpln(app);
246   return app;
247 }
248 // ----------------------------------------------------------------------------
xmlrc_parse_apwal_pref(xmlDocPtr doc,xmlNodePtr cur)249 static apwal_pref_t * xmlrc_parse_apwal_pref(xmlDocPtr doc, xmlNodePtr cur)
250 {
251   apwal_pref_t *apwal_pref;
252   gint      timeout = 1000;
253   gint      exit_at_app_launch = FALSE;
254   gboolean  activate_tooltips = TRUE;
255   gboolean  iconsel_in_a_separate_window = TRUE;
256   gboolean  iconsel_modal = FALSE;
257   char     *buf;
258 
259   cur = cur->xmlChildrenNode;
260   while (cur != NULL)
261   {
262     if (!xmlStrcmp(cur->name, (const xmlChar *)"timeout"))
263     { buf = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
264       timeout = strtol(buf, (char **)NULL, 10);
265       g_free(buf);
266     } else if (!xmlStrcmp(cur->name, (const xmlChar *)"exit_at_app_launch"))
267     { buf = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
268       exit_at_app_launch = strtol(buf, (char **)NULL, 10);
269       g_free(buf);
270     }
271     else if (!xmlStrcmp(cur->name, (const xmlChar *)"activate_tooltips"))
272     { buf = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
273       activate_tooltips = strtol(buf, (char **)NULL, 10);
274       g_free(buf);
275     }
276     else if (!xmlStrcmp(cur->name,
277                         (const xmlChar *)"iconsel_in_a_separate_window"))
278     { buf = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
279       iconsel_in_a_separate_window = strtol(buf, (char **)NULL, 10);
280       g_free(buf);
281     }
282     else if (!xmlStrcmp(cur->name, (const xmlChar *)"iconsel_modal"))
283     { buf = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
284       iconsel_modal = strtol(buf, (char **)NULL, 10);
285       g_free(buf);
286     }
287     else
288       ERR("cur->name:%s unknown", cur->name);
289 
290     cur = cur->next;
291   }//end while cur
292 
293   apwal_pref = apwal_pref_new(timeout, exit_at_app_launch, activate_tooltips,
294                               iconsel_in_a_separate_window, iconsel_modal);
295   return apwal_pref;
296 }
297 // ----------------------------------------------------------------------------
xmlrc_parse_iconsel_pref(xmlDocPtr doc,xmlNodePtr cur)298 static iconsel_pref_t * xmlrc_parse_iconsel_pref(xmlDocPtr doc, xmlNodePtr cur)
299 {
300   iconsel_pref_t *iconsel_pref;
301   GList    *icon_dirs = NULL;
302   GList    *file_exts = NULL;
303   gboolean  select_48 = TRUE;
304   gboolean  select_lt48 = TRUE;
305   gboolean  select_gt48 = TRUE;
306   gboolean  sort_mode = ICONSEL_SORT_DEFAULT;
307   char     *buf;
308   gboolean icon_dirs_are_loaded = FALSE;
309   gboolean file_exts_are_loaded = FALSE;
310 
311   cur = cur->xmlChildrenNode;
312   while (cur != NULL)
313   {
314     if (!xmlStrcmp(cur->name, (const xmlChar *) "icon_dirs"))
315     {
316       if (icon_dirs_are_loaded == TRUE)
317         ERR("%s", "there are more that one <icon_dirs> node");
318       icon_dirs = xmlrc_parse_icon_dirs(doc, cur);
319       icon_dirs_are_loaded = TRUE;
320     }
321     else if (!xmlStrcmp(cur->name, (const xmlChar *) "file_exts"))
322     {
323       if (file_exts_are_loaded == TRUE)
324         ERR("%s", "there are more that one <file_exts> node");
325       file_exts = xmlrc_parse_file_exts(doc, cur);
326       file_exts_are_loaded = TRUE;
327     }
328     else if (!xmlStrcmp(cur->name, (const xmlChar *)"select_48"))
329     { buf = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
330       select_48 = strtol(buf, (char **)NULL, 10);
331       g_free(buf);
332     }
333     else if (!xmlStrcmp(cur->name, (const xmlChar *)"select_lt48"))
334     { buf = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
335       select_lt48 = strtol(buf, (char **)NULL, 10);
336       g_free(buf);
337     }
338     else if (!xmlStrcmp(cur->name, (const xmlChar *)"select_gt48"))
339     { buf = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
340       select_gt48 = strtol(buf, (char **)NULL, 10);
341       g_free(buf);
342     }
343     else if (!xmlStrcmp(cur->name, (const xmlChar *)"sort_mode"))
344     { buf = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
345       sort_mode = strtol(buf, (char **)NULL, 10);
346       g_free(buf);
347     }
348     else
349       ERR("cur->name:%s unknown", cur->name);
350 
351     cur = cur->next;
352   }//end while cur
353 
354   iconsel_pref = iconsel_pref_new(icon_dirs, file_exts, select_48,
355                                   select_lt48, select_gt48, sort_mode);
356   return iconsel_pref;
357 }
358 // ----------------------------------------------------------------------------
xmlrc_parse_icon_dirs(xmlDocPtr doc,xmlNodePtr cur)359 static GList * xmlrc_parse_icon_dirs(xmlDocPtr doc, xmlNodePtr cur)
360 {
361   GList      *icon_dirs;
362   icon_dir_t *icon_dir;
363 
364   icon_dirs = NULL;
365   cur = cur->xmlChildrenNode;
366   while (cur)
367   {
368     if (xmlStrcmp(cur->name, (const xmlChar *) "icon_dir"))
369       ERR("cur->name:%s unknown", cur->name);
370     icon_dir = xmlrc_parse_icon_dir(doc, cur);
371     if (icon_dir != NULL)
372       icon_dirs = g_list_append(icon_dirs, icon_dir);
373 
374     cur = cur->next;
375   }
376   return icon_dirs;
377 }
378 // ----------------------------------------------------------------------------
xmlrc_parse_icon_dir(xmlDocPtr doc,xmlNodePtr cur)379 static icon_dir_t * xmlrc_parse_icon_dir(xmlDocPtr doc, xmlNodePtr cur)
380 {
381   icon_dir_t *icon_dir;
382   char       *path = NULL;
383   gboolean   selected = 1 ;
384   gboolean   recursive = FALSE;
385   char      *buf;
386 
387   cur = cur->xmlChildrenNode;
388   while (cur != NULL)
389   {
390     if (!xmlStrcmp(cur->name, (const xmlChar *) "path"))
391       path = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
392     else if (!xmlStrcmp(cur->name, (const xmlChar *)"selected"))
393     { buf = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
394       selected = strtol(buf, (char **)NULL, 10);
395       g_free(buf);
396     }
397     else if (!xmlStrcmp(cur->name, (const xmlChar *)"recursive"))
398     { buf = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
399       recursive = strtol(buf, (char **)NULL, 10);
400       g_free(buf);
401     }
402     else
403       ERR("cur->name:%s unknown", cur->name);
404 
405     cur = cur->next;
406   }//end while cur
407 
408   make_path_uniq(&path);
409   icon_dir = icon_dir_new(path, selected, recursive);
410 
411   return icon_dir;
412 }
413 // ----------------------------------------------------------------------------
xmlrc_parse_file_exts(xmlDocPtr doc,xmlNodePtr cur)414 static GList * xmlrc_parse_file_exts(xmlDocPtr doc, xmlNodePtr cur)
415 {
416   GList      *file_exts;
417   file_ext_t *file_ext;
418 
419   file_exts = NULL;
420   cur = cur->xmlChildrenNode;
421   while (cur)
422   {
423     if (xmlStrcmp(cur->name, (const xmlChar *) "file_ext"))
424       ERR("cur->name:%s unknown", cur->name);
425     file_ext = xmlrc_parse_file_ext(doc, cur);
426     if (file_ext != NULL)
427       file_exts = g_list_append(file_exts, file_ext);
428 
429     cur = cur->next;
430   }
431   return file_exts;
432 }
433 // ----------------------------------------------------------------------------
xmlrc_parse_file_ext(xmlDocPtr doc,xmlNodePtr cur)434 static file_ext_t * xmlrc_parse_file_ext(xmlDocPtr doc, xmlNodePtr cur)
435 {
436   file_ext_t *file_ext;
437   char       *extension = NULL;
438   gboolean   selected = 1 ;
439   char      *buf;
440 
441   cur = cur->xmlChildrenNode;
442   while (cur != NULL)
443   {
444     if (!xmlStrcmp(cur->name, (const xmlChar *) "extension"))
445       extension = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
446     else if (!xmlStrcmp(cur->name, (const xmlChar *)"selected"))
447     { buf = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
448       selected = strtol(buf, (char **)NULL, 10);
449       g_free(buf);
450     }
451     else
452       ERR("cur->name:%s unknown", cur->name);
453 
454     cur = cur->next;
455   }//end while cur
456 
457   file_ext = file_ext_new(extension, selected);
458   return file_ext;
459 }
460 // ----------------------------------------------------------------------------
461 // ----------------------------------------------------------------------------
462 // ----------------------------------------------------------------------------
463 // ----------------------------------------------------------------------------
464 // ----------------------------------------------------------------------------
xmlrc_save_to_file(app_list_t * apps,iconsel_pref_t * iconsel_pref,apwal_pref_t * apwal_pref)465 void xmlrc_save_to_file(app_list_t *apps, iconsel_pref_t *iconsel_pref,
466                         apwal_pref_t *apwal_pref)
467 {
468   xmlDocPtr   doc;
469   xmlNodePtr  node1;
470   xmlNodePtr  node2;
471   xmlNodePtr  node3;
472   app_t      *app;
473   GList      *hamster;
474   icon_dir_t *icon_dir;
475   file_ext_t *file_ext;
476   gint        cc;
477   char        buf[20];
478   char        flast[FILENAME_MAX];
479 
480   g_assert(apps != NULL && iconsel_pref != NULL && apwal_pref != NULL);
481 
482   // create new XML document
483   doc = xmlNewDoc("1.0");
484   doc->xmlRootNode = xmlNewDocNode(doc, NULL, "apwalrc", NULL);
485   node1 = xmlNewChild(doc->xmlRootNode, NULL, "apps", NULL);
486 
487   // save the list of applications
488   for (app=app_list_first(apps); app!=NULL; app=app_list_next(apps))
489   {
490     node2 = xmlNewChild(node1, NULL, "app", NULL);
491     xmlNewChild(node2, NULL, "cmdline", app->cmdline);
492     xmlNewChild(node2, NULL, "path", app->path);
493     xmlNewChild(node2, NULL, "icon", app->icon);
494     snprintf(buf, sizeof(buf), "%i", app->x);
495     xmlNewChild(node2, NULL, "x", buf);
496     snprintf(buf, sizeof(buf), "%i", app->y);
497     xmlNewChild(node2, NULL, "y", buf);
498   }
499 
500   // save the icon selection prefence
501   node1 = xmlNewChild(doc->xmlRootNode, NULL, "iconsel_pref", NULL);
502   snprintf(buf, sizeof(buf), "%i", iconsel_pref->select_48);
503   xmlNewChild(node1, NULL, "select_48", buf);
504   snprintf(buf, sizeof(buf), "%i", iconsel_pref->select_lt48);
505   xmlNewChild(node1, NULL, "select_lt48", buf);
506   snprintf(buf, sizeof(buf), "%i", iconsel_pref->select_gt48);
507   xmlNewChild(node1, NULL, "select_gt48", buf);
508   snprintf(buf, sizeof(buf), "%i", iconsel_pref->sort_mode);
509   xmlNewChild(node1, NULL, "sort_mode", buf);
510   node2 = xmlNewChild(node1, NULL, "icon_dirs", NULL);
511   hamster = iconsel_pref->icon_dirs;
512   while(hamster != NULL)
513   {
514     icon_dir = hamster->data;
515     // if the icon directory is empty it is not to save
516     if (strcmp(icon_dir->path, "") == 0)
517     {
518       hamster = g_list_next(hamster);
519       continue;
520     }
521     node3 = xmlNewChild(node2, NULL, "icon_dir", NULL);
522     xmlNewChild(node3, NULL, "path", icon_dir->path);
523     snprintf(buf, sizeof(buf), "%i", icon_dir->selected);
524     xmlNewChild(node3, NULL, "selected", buf);
525     snprintf(buf, sizeof(buf), "%i", icon_dir->recursive);
526     xmlNewChild(node3, NULL, "recursive", buf);
527     hamster = g_list_next(hamster);
528   }
529   node2 = xmlNewChild(node1, NULL, "file_exts", NULL);
530   hamster = iconsel_pref->file_exts;
531   while(hamster != NULL)
532   {
533     file_ext = hamster->data;
534     // if the file name extension is empty it is not to save
535     if (strcmp(file_ext->extension, "") == 0)
536     {
537       hamster = g_list_next(hamster);
538       continue;
539     }
540     node3 = xmlNewChild(node2, NULL, "file_ext", NULL);
541     xmlNewChild(node3, NULL, "extension", file_ext->extension);
542     snprintf(buf, sizeof(buf), "%i", file_ext->selected);
543     xmlNewChild(node3, NULL, "selected", buf);
544     hamster = g_list_next(hamster);
545   }
546 
547   // save the apwal preferences
548   node1 = xmlNewChild(doc->xmlRootNode, NULL, "apwal_pref", NULL);
549 
550   snprintf(buf, sizeof(buf), "%i", apwal_pref->timeout);
551   xmlNewChild(node1, NULL, "timeout", buf);
552 
553   snprintf(buf, sizeof(buf), "%i", apwal_pref->exit_at_app_launch);
554   xmlNewChild(node1, NULL, "exit_at_app_launch", buf);
555 
556   snprintf(buf, sizeof(buf), "%i", apwal_pref->activate_tooltips);
557   xmlNewChild(node1, NULL, "activate_tooltips", buf);
558 
559   snprintf(buf, sizeof(buf), "%i", apwal_pref->iconsel_in_a_separate_window);
560   xmlNewChild(node1, NULL, "iconsel_in_a_separate_window", buf);
561 
562   snprintf(buf, sizeof(buf), "%i", apwal_pref->iconsel_modal);
563   xmlNewChild(node1, NULL, "iconsel_modal", buf);
564 
565   // save XML file
566   strcpy(flast, xmlrc_resource_file());
567   strcat(flast, ".last");
568   cc = rename(xmlrc_resource_file(), flast);
569   if (cc != 0)
570     ERR("rename %s, %s, cc:%d, errno:%d",
571          xmlrc_resource_file(), flast, cc, errno);
572 
573   cc = xmlSaveFormatFile(xmlrc_resource_file(), doc, 1);
574   if (cc <= 0)
575     ERR("xmlSaveFormatFile, file:%s, cc:%d", xmlrc_resource_file(), cc);
576 
577 }
578 // ----------------------------------------------------------------------------
579 // ----------------------------------------------------------------------------
580 // ----------------------------------------------------------------------------
581 // ----------------------------------------------------------------------------
582 // ----------------------------------------------------------------------------
583 // ----------------------------------------------------------------------------
xmlrc_set_resource_file(char * config_file)584 void xmlrc_set_resource_file(char *config_file)
585 {
586   g_assert(g_xmlrc_filerc[0] == '\0'); // set filerc ONE time only
587   if (config_file != NULL)
588   {
589     if (strlen(config_file) >= FILENAME_MAX)
590       ERR("config file name:%d to big", strlen(config_file));
591     strcat(g_xmlrc_filerc, config_file);
592   }
593   else
594   {
595     char *home;
596     home = getenv("HOME");
597     if (home == NULL)
598       ERR("%s", "environement variable $HOME not set");
599     strcpy(g_xmlrc_filerc, home);
600     strcat(g_xmlrc_filerc, "/.apwalrc.xml");
601   }
602 }
603 // ----------------------------------------------------------------------------
xmlrc_resource_file(void)604 static char* xmlrc_resource_file(void)
605 {
606   g_assert(g_xmlrc_filerc[0] != '\0'); // filerc have to be set
607   return g_xmlrc_filerc;
608 }
609 // ----------------------------------------------------------------------------
xmlrc_resource_file_exist(void)610 gboolean xmlrc_resource_file_exist(void)
611 {
612   char *file;
613   gboolean is_exist;
614   file = xmlrc_resource_file();
615   is_exist = g_file_test(file, G_FILE_TEST_EXISTS);
616   return is_exist;
617 }
618 // ----------------------------------------------------------------------------
xmlrc_resource_file_create(void)619 void xmlrc_resource_file_create(void)
620 {
621   int len, fd, cc;
622   fd = creat(xmlrc_resource_file(), 0755);
623   if (fd < 0)
624     ERR("creation of the resource file failed. open cc:%d, errno:%d, file:%s",
625         fd, errno, xmlrc_resource_file());
626   len = strlen(XMLRC_DEFAULT);
627   cc = write(fd, XMLRC_DEFAULT, len);
628   if (cc != len)
629     ERR("creation of the resource file failed. write cc:%d, errno:%d, file:%s",
630         cc, errno, xmlrc_resource_file());
631   close(fd);
632 }
633 // ----------------------------------------------------------------------------
634 // ----------------------------------------------------------------------------
635 // ----------------------------------------------------------------------------
636