ftp://ftp.redhat.com/pub/redhat/linux/rawhide/SRPMS/SRPMS/gnome-vfs2-2.3.8-1.src.rpm
[gnome-vfs-httpcaptive.git] / modules / cdemenu-desktop-method.c
1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: 4; c-basic-offset: 4 -*- */
2
3 /* cdemenu-desktop--method.c
4
5         Author: Stephen Browne <stephen.browne@sun.com>
6
7    Copyright (C) 2002 Sun Microsystems, Inc.
8
9    The Gnome Library is free software; you can redistribute it and/or
10    modify it under the terms of the GNU Library General Public License as
11    published by the Free Software Foundation; either version 2 of the
12    License, or (at your option) any later version.
13
14    The Gnome Library is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17    Library General Public License for more details.
18
19    You should have received a copy of the GNU Library General Public
20    License along with the Gnome Library; see the file COPYING.LIB.  If not,
21    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22    Boston, MA 02111-1307, USA.
23 */
24
25 #ifdef HAVE_CONFIG_H
26 # include <config.h>
27 #endif
28
29 #include <glib.h>
30 #include <sys/types.h>
31 #include <dirent.h>
32 #include <errno.h>
33 #include <string.h>
34 #include <sys/stat.h>
35 #include <sys/wait.h>
36 #include <unistd.h>
37 #include <fcntl.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <locale.h>
41
42 #include <libgnomevfs/gnome-vfs-mime.h>
43
44 #include <libgnomevfs/gnome-vfs-module.h>
45 #include <libgnomevfs/gnome-vfs-method.h>
46 #include <libgnomevfs/gnome-vfs-utils.h>
47 #include <libgnomevfs/gnome-vfs-ops.h>
48 #include <libgnomevfs/gnome-vfs-module-shared.h>
49 #include <libgnomevfs/gnome-vfs-i18n.h>
50
51 #define LINESIZE 1024
52 #define CDE_ICON_NAME_CACHE "/.gnome/g-cdeiconnames"
53
54 static GSList *cdemenufiles;
55
56 typedef struct _DtFile DtFile;
57
58 struct _DtFile {
59         gchar *contents;
60         gchar *current;
61 };
62
63 static GnomeVFSMethod *parent_method = NULL;
64
65 static gchar *
66 find_title_for_menu (gchar *name)
67 {
68         GSList *filename;
69         char line[LINESIZE];
70         gboolean found=FALSE;
71         char *title="\0";
72     FILE *file = NULL;
73     gchar *tmp=NULL;
74
75     for (filename = cdemenufiles; filename !=NULL; filename=filename->next){
76                 file = fopen((gchar*)filename->data,"r");
77                 while (fgets(line,LINESIZE,file) != NULL){
78             if (strstr(line,"f.menu")  && strstr(line, name)) {
79                                 tmp = strstr (line, "f.menu");
80                                 *tmp = '\0';
81                                 title = strdup (line);
82                                 found = TRUE;
83                                 break;
84                         }
85                 }
86                 fclose (file);
87                 file = NULL;
88                 if (found) break;
89         }
90         return title;
91 }
92
93 static FILE *
94 open_and_find_pointer_to_menu(gchar *name)
95 {
96         GSList *filename;
97         gchar line[LINESIZE];
98         FILE *filesave = NULL, *file = NULL;
99         glong position = 0;
100         gboolean found = FALSE;
101         
102         for (filename = cdemenufiles; filename !=NULL; filename=filename->next){
103                 found = FALSE;
104                 file = fopen((gchar*)filename->data,"r");
105                 while (fgets(line,LINESIZE,file) != NULL){
106                         if (strstr(line,"Menu") == line) {
107                                 char *temp = NULL;
108
109                                 temp = (strtok(line," "));
110
111                                  if (!temp)
112                                         temp = (strtok(line,"\t"));
113
114                                  while (temp) {
115                                         temp = g_strstrip(temp);
116                                          if (temp && !(strcmp(temp,name))) {
117                                                 found = TRUE;
118                                                 position = ftell (file);
119                                                 break;
120                                         }
121                                         temp = (strtok (NULL," "));
122                                         if (!temp)
123                                                 temp = (strtok (NULL,"\t"));
124                                 }
125                         }
126                 }
127                 if (found) {
128                         fseek (file, position, SEEK_SET);
129                         if (filesave !=NULL) fclose(filesave);
130                         filesave = file;
131                         if (!strcmp(name, "DtRootMenu")) break;
132                 } else {
133                         fclose(file);
134                         file=NULL;
135                 }
136         }
137         return filesave;
138 }
139
140 static char *
141 expand_env_vars(char *s)
142 {
143         char **tokens, **token;
144         char *tmp, *tmp2;
145         const char *tmp3;
146         char *expanded;
147         tokens = g_strsplit(s,"/",30);
148         for (token = tokens; *token !=NULL; token++) {
149                 if (**token=='$'){
150                         tmp = *token+1;
151                         if (*tmp == '{'){
152                                 tmp++;
153                                 tmp2 = tmp+(strlen(tmp))-1; *tmp2='\0';
154                         }
155                         tmp3 = g_getenv(tmp);
156                         if (!tmp3 && strstr(tmp, "LC_CTYPE"))
157                                 /* It's not always the case $LC_CTYPE or $LANG is set */
158                                 tmp3 = (char*)setlocale(LC_CTYPE, NULL);
159                         g_free(*token);
160                         /* don't do g_strdup (s?s1:s2) as that doesn't work with
161                            certain gcc 2.96 versions */
162                         *token = tmp3 ? g_strdup(tmp3) : g_strdup("");
163                 }
164         }
165         expanded = g_strjoinv("/", tokens);
166         g_strfreev(tokens);
167         return expanded;
168 }
169
170 /* This function is only used to make the default CDE menu look nice */
171 static char*
172 get_icon_for_menu (char *name) 
173 {
174         /* Translate exactly the same in CDE's sys.dtwmrc file of the locale */
175         if (!strcmp(name, _("Applications")))
176                 return ("/usr/dt/appconfig/icons/C/Dtapps.m.pm");
177         /* Translate  exactly the same in CDE's sys.dtwmrc file of the locale */
178         if (!strcmp(name, _("Cards")))
179                 return ("/usr/dt/appconfig/icons/C/SDtCard.m.pm");
180         /* Translate  exactly the same in CDE's sys.dtwmrc file of the locale */
181         if (!strcmp(name, _("Files")))
182                 return ("/usr/dt/appconfig/icons/C/Dtdata.m.pm");
183         /* Translate  exactly the same in CDE's sys.dtwmrc file of the locale */
184         if (!strcmp(name, _("Folders")))
185                 return ("/usr/dt/appconfig/icons/C/DtdirB.m.pm");
186         /* Translate  exactly the same in CDE's sys.dtwmrc file of the locale */
187         if (!strcmp(name, _("Help")))
188                 return ("/usr/dt/appconfig/icons/C/Dthelp.m.pm");
189         /* Translate  exactly the same in CDE's sys.dtwmrc file of the locale */
190         if (!strcmp(name, _("Hosts")))
191                 return ("/usr/dt/appconfig/icons/C/Dtterm.m.pm");
192         /* Translate  exactly the same in CDE's sys.dtwmrc file of the locale */
193         if (!strcmp(name, _("Links")))
194                 return ("/usr/dt/appconfig/icons/C/SDturlweb.m.pm");
195         /* Translate  exactly the same in CDE's sys.dtwmrc file of the locale */
196         if (!strcmp(name, _("Mail")))
197                 return ("/usr/dt/appconfig/icons/C/Dtmail.m.pm");
198         /* Translate  exactly the same in CDE's sys.dtwmrc file of the locale */
199         if (!strcmp(name, _("Tools")))
200                 return ("/usr/dt/appconfig/icons/C/SDtGears.m.pm");
201         /* Translate exactly the same in CDE's sys.dtwmrc file of the locale */
202         if (!strcmp(name, _("Windows")))
203                 return ("/usr/dt/appconfig/icons/C/DtDtwm.m.pm");
204         return ("");
205 }
206
207 static char*
208 get_icon_for_action(char *action)
209 {
210         gchar line[LINESIZE];
211         FILE *file;
212         char **dir, *expandeddir, *fullpath=NULL;
213         char *tmp=NULL;
214         char *icon_name_cache_path;
215
216         char *iconsearchpath[] = {"/usr/dt/appconfig/icons/$LC_CTYPE",
217                        "/etc/dt/appconfig/icons/$LC_CTYPE",
218                        "$HOME/.dt/icons",
219                        "/usr/dt/appconfig/icons/C", NULL};
220
221         /*if action has arg strip the arg*/
222         if ((tmp=strchr(action,'\"'))) {*tmp='\0'; tmp=NULL;}
223         
224         /*Return NULL icon if icon DB does not exist*/
225         icon_name_cache_path = g_strconcat (g_get_home_dir (), CDE_ICON_NAME_CACHE, NULL);
226         file = fopen(icon_name_cache_path,"r");
227         g_free(icon_name_cache_path);
228         if (!file) return NULL;
229
230         while (fgets(line,LINESIZE,file) != NULL){
231                 if (strstr(line,action)){
232                         if (fgets(line,LINESIZE,file) != NULL) {
233                                 if (strstr(line,"ICON")){
234                                         tmp = strchr(line,':');
235                                         if (tmp == NULL) return NULL;
236                                         tmp++;
237                                         tmp = g_strstrip(tmp);
238                                         for (dir = iconsearchpath; *dir != NULL; dir++) {
239                                                 expandeddir = expand_env_vars(*dir);
240                                                 fullpath = g_strdup_printf("%s/%s.m.pm",
241                                                                                                         expandeddir, tmp);
242                                                 if (g_file_test(fullpath,G_FILE_TEST_EXISTS)){ 
243                                                         g_free(expandeddir);
244                                                         break;
245                                                 } else {
246                                                         g_free(fullpath);
247                                                         fullpath = g_strdup_printf("%s/%s.s.pm",
248                                                                                                                 expandeddir, tmp);
249                                                         if (g_file_test(fullpath,G_FILE_TEST_EXISTS)){ 
250                                                                                         g_free(expandeddir);
251                                                                 break;
252                                                         } else g_free (fullpath);
253                                                 }
254                                         }
255                                 }
256                         }
257                         break;
258                 }
259         }
260         fclose(file);
261         return fullpath;
262 }
263
264 static gchar *
265 get_title (gchar *line)
266 {
267         gchar *tmp;
268         tmp = strchr (line, '\"');
269         if (!tmp)
270                 tmp = g_strstrip (line);
271         else {
272                 gchar *tmp2;
273                 tmp ++;
274                 tmp2 = strchr (tmp, '\"');
275                 if(tmp2) *tmp2 = '\0';
276         }
277         return (g_strdup (tmp));
278 }
279
280 static GnomeVFSResult
281 do_open (GnomeVFSMethod *method,
282          GnomeVFSMethodHandle **method_handle,
283          GnomeVFSURI *uri,
284          GnomeVFSOpenMode mode,
285          GnomeVFSContext *context)
286 {
287         FILE *file;
288         gchar *tmp, *tmp2, *end;
289         gchar *unescaped;
290         gchar line[LINESIZE];
291         gchar *name, *title, *exec=NULL, *icon=NULL;
292         gchar *menuname = g_path_get_basename(g_path_get_dirname(uri->text));
293         DtFile *dtfile = g_new0(DtFile, 1);
294
295         *method_handle = (GnomeVFSMethodHandle *)dtfile;
296
297         if (strcmp(menuname,"/") == 0) menuname = "DtRootMenu";
298         unescaped = gnome_vfs_unescape_string (menuname, NULL);
299
300         name =  gnome_vfs_unescape_string (g_path_get_basename(uri->text), NULL);
301         /* Strip off the .desktop if this is a .desktop file */
302         tmp = strstr(name,".desktop"); if (tmp) *tmp='\0'; tmp=NULL;
303
304         file = open_and_find_pointer_to_menu (unescaped);
305
306         if (!file) {
307                 g_free (name);
308                 g_free (unescaped);
309                 return GNOME_VFS_ERROR_NOT_FOUND;
310         }
311
312         if (strcmp(name,".directory") == 0) {
313                                 char *utf8_name = NULL;
314
315                                 if (!strcmp (unescaped, "DtRootMenu"))
316                                         title = g_strdup_printf ("\"%s\"",unescaped);
317                                 else title = find_title_for_menu (unescaped);
318
319                                 tmp = get_title (title); 
320
321                                 utf8_name = g_locale_to_utf8 (tmp, -1,
322                                                               NULL, NULL,
323                                                               NULL);
324                                 /* fallback to avoid crash */
325                                 if (utf8_name == NULL)
326                                         utf8_name = g_strdup (tmp);
327
328                                 dtfile->contents = g_strdup_printf 
329                                         ("[Desktop Entry]\n"
330                                          "Encoding=UTF-8\n"
331                                          /* Note that we include the utf-8
332                                           * translated name without a language
333                                           * specifier, but that's OK, it will
334                                           * work */
335                                          "Name=%s\n"
336                                          "Comment=\n"
337                                          "Icon=%s\n"
338                                          "Type=Directory\n",
339                                          utf8_name, 
340                                          get_icon_for_menu(utf8_name));
341
342                                 g_free (utf8_name);
343                                 g_free (title);
344                                 g_free (tmp);
345         } else {
346                 while (fgets(line,LINESIZE,file) != NULL){
347                         if (line[0] == '#') continue;
348                         else if (line[0] == '}') break;
349                         else if (strstr(line,name)){
350                                 if((tmp = strstr(line,"f.action")) != NULL){
351                                         char *utf8_name = NULL;
352
353                                         tmp+=8;
354                                         end = strchr(tmp,'\n');
355                                         if (end) *end='\0';
356                                         exec=g_strdup_printf("dtaction %s",tmp);
357                                         icon=get_icon_for_action(tmp);
358                                         if (!icon) icon=g_strdup("NONE");
359
360                                         utf8_name = g_locale_to_utf8 (name, -1,
361                                                                       NULL,
362                                                                       NULL,
363                                                                       NULL);
364                                         /* fallback to avoid crash */
365                                         if (utf8_name == NULL)
366                                                 utf8_name = g_strdup (name);
367
368                                         dtfile->contents= g_strdup_printf
369                                                 ("[Desktop Entry]\n"
370                                                  "Encoding=UTF-8\n"
371                                                  /* Note that we include the
372                                                   * utf-8 translated name
373                                                   * without a language
374                                                   * specifier, but that's
375                                                   * OK, it will work */
376                                                  "Name=%s\n"
377                                                  "Comment=\n"
378                                                  "Exec=%s\n"
379                                                  "Icon=%s\n"
380                                                  "Terminal=0\n"
381                                                  "Type=Application\n",
382                                                   utf8_name,
383                                                  exec, icon);
384                                         g_free (utf8_name);
385                                         g_free(icon);
386                                 } else if ((tmp = strstr(line,"f.exec"))!=NULL){
387                                         char *utf8_name = NULL;
388
389                                         tmp+=6;
390                                         tmp = g_strstrip(tmp);
391                                         /* strip off quotes */
392                                         if (*tmp == '\"') tmp++;
393                                         end = tmp+(strlen(tmp))-1;
394                                         if (*end == '\"') *end = '\0';
395
396                                         utf8_name = g_locale_to_utf8 (name, -1,
397                                                                       NULL,
398                                                                       NULL,
399                                                                       NULL);
400                                         /* fallback to avoid crash */
401                                         if (utf8_name == NULL)
402                                                 utf8_name = g_strdup (name);
403
404                                         dtfile->contents= g_strdup_printf
405                                                 ("[Desktop Entry]\n"
406                                                  "Encoding=UTF-8\n"
407                                                  /* Note that we include the
408                                                   * utf-8 translated name
409                                                   * without a language
410                                                   * specifier, but that's
411                                                   * OK, it will work */
412                                                  "Name=%s\n"
413                                                  "Comment=\n"
414                                                  "Exec=%s\n"
415                                                  "Icon=\n"
416                                                  "Terminal=0\n"
417                                                  "Type=Application\n",
418                                                   utf8_name, tmp);
419                                         g_free (utf8_name);
420                                 }
421                         }
422                 }
423         }
424
425         fclose(file);
426
427         dtfile->current=dtfile->contents;
428
429         g_free (unescaped);
430
431         return GNOME_VFS_OK;
432 }
433
434 static GnomeVFSResult
435 do_close (GnomeVFSMethod *method,
436           GnomeVFSMethodHandle *method_handle,
437           GnomeVFSContext *context)
438 {
439
440         DtFile *dtfile = (DtFile*)method_handle;
441
442         g_free(dtfile->contents);       
443
444         return GNOME_VFS_OK;
445 }
446
447 static GnomeVFSResult
448 do_read (GnomeVFSMethod *method,
449          GnomeVFSMethodHandle *method_handle,
450          gpointer buffer,
451          GnomeVFSFileSize num_bytes,
452          GnomeVFSFileSize *bytes_read,
453          GnomeVFSContext *context)
454 {
455         int bytes;
456         DtFile *dtfile = (DtFile *)method_handle;
457         if (dtfile->current == NULL) return GNOME_VFS_ERROR_EOF;
458
459         bytes = snprintf(buffer, num_bytes, "%s",dtfile->current);
460         if (bytes == -1 ) dtfile->current+=num_bytes;
461         else dtfile->current=NULL;
462
463         *bytes_read=(GnomeVFSFileSize)bytes;
464         
465         return GNOME_VFS_OK;
466 }
467
468 static GnomeVFSResult
469 do_open_directory (GnomeVFSMethod *method,
470                    GnomeVFSMethodHandle **method_handle,
471                    GnomeVFSURI *uri,
472                    GnomeVFSFileInfoOptions options,
473                    GnomeVFSContext *context)
474 {
475         FILE *file;
476         gchar* unescaped;
477         gchar *menuname = g_path_get_basename(uri->text);
478         if (strcmp(menuname,"/") == 0) menuname = "DtRootMenu";
479         
480         unescaped = gnome_vfs_unescape_string (menuname, NULL);
481
482         file = open_and_find_pointer_to_menu(unescaped);
483
484         *method_handle = (GnomeVFSMethodHandle *)file;
485
486         g_free (unescaped);
487
488         return file ? GNOME_VFS_OK : GNOME_VFS_ERROR_NOT_FOUND;
489 }
490
491 static GnomeVFSResult
492 do_close_directory (GnomeVFSMethod *method,
493                     GnomeVFSMethodHandle *method_handle,
494                     GnomeVFSContext *context)
495 {
496         fclose((FILE *)method_handle);
497
498         return GNOME_VFS_OK;
499 }
500
501 static GnomeVFSResult
502 do_read_directory (GnomeVFSMethod *method,
503                    GnomeVFSMethodHandle *method_handle,
504                    GnomeVFSFileInfo *file_info,
505                    GnomeVFSContext *context)
506 {
507         gchar line[LINESIZE];
508         gchar *tmp, *tmp2,*escaped_str;
509         FILE *file = (FILE *)method_handle;
510         /*static int sep=0;*/
511         
512         file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_TYPE;
513
514         while (fgets(line,LINESIZE,file) != NULL){
515                         if (line[0] == '#') continue;
516                         else if (line[0] == '}') return GNOME_VFS_ERROR_EOF;
517                         else if (strstr(line,"f.action") && (strstr(line,"ExitSession")
518                                         || strstr(line,"LockDisplay") 
519                                         || strstr(line,"AddItemToMenu")
520                                         || strstr(line,"CustomizeWorkspaceMenu")
521                                         || strstr(line,"UpdateWorkspaceMenu"))) {
522                                         file_info->name = g_strdup("bogus.desktop");
523                                         file_info->type = GNOME_VFS_FILE_TYPE_REGULAR;
524                                         continue;
525                         }
526                         else if (strstr(line,"f.action") || strstr(line,"f.exec")) {
527                                         tmp2 = strstr (line, "f.");
528                                         *tmp2 = '\0';
529
530                                         tmp = get_title (line);
531                                         escaped_str = gnome_vfs_escape_string (tmp);
532                                         file_info->name = g_strdup_printf("%s.desktop",escaped_str);
533                                         file_info->type = GNOME_VFS_FILE_TYPE_REGULAR;
534                                         g_free (escaped_str);
535                                         g_free (tmp);
536                                         break;
537                         }
538                         /*
539                         else if (strstr(line,"f.separator")) {
540                                 file_info->name = g_strdup_printf("separator%d.desktop",
541                                         sep);
542                                 file_info->type = GNOME_VFS_FILE_TYPE_REGULAR;
543                                 sep++; if (sep>10) sep = 0;
544                                 break;
545                         }
546                         */
547                         else if  (strstr(line,"f.menu")) {
548                                 tmp = strstr(line,"f.menu");
549                                 tmp+=6;
550                                 tmp = g_strstrip(tmp);
551                                 file_info->name = gnome_vfs_escape_string (tmp);
552                                 file_info->type = GNOME_VFS_FILE_TYPE_DIRECTORY;
553                                 break;
554                         }       
555         }
556
557         return GNOME_VFS_OK;
558 }
559
560 static GnomeVFSResult
561 do_get_file_info (GnomeVFSMethod *method,
562                   GnomeVFSURI *uri,
563                   GnomeVFSFileInfo *file_info,
564                   GnomeVFSFileInfoOptions options,
565                   GnomeVFSContext *context)
566 {
567         GnomeVFSURI *file_uri;
568         GnomeVFSResult result;
569
570         char *s;
571
572         /* FIXME: This isnt right at all but it satisfies gnome-vfs for now */
573         s = gnome_vfs_get_uri_from_local_path(cdemenufiles->data);
574         file_uri = gnome_vfs_uri_new(s);
575         g_free(s);
576         
577         result = (* parent_method->get_file_info) (parent_method,
578                                                    file_uri,
579                                                    file_info,
580                                                    options,
581                                                    context); 
582         gnome_vfs_uri_unref (file_uri);
583
584         return result;
585 }
586
587 static gboolean
588 do_is_local (GnomeVFSMethod *method,
589              const GnomeVFSURI *uri)
590 {
591         /* FIXME: This isn't always true, some cde menu files are remote */
592         return TRUE;
593 }
594
595 /* gnome-vfs bureaucracy */
596 static GnomeVFSMethod method = {
597         sizeof (GnomeVFSMethod),
598         do_open,
599         NULL,                           /* create */
600         do_close,
601         do_read,
602         NULL,                           /* write */
603         NULL,                           /* seek */
604         NULL,                           /* tell */
605         NULL,                           /* truncate handle */
606         do_open_directory,
607         do_close_directory,
608         do_read_directory,
609         do_get_file_info,
610         NULL,                           /* file info from handle */
611         do_is_local,
612         NULL,                           /* make directory */
613         NULL,                           /* remove directory */
614         NULL,                           /* move */
615         NULL,                           /* unlink */
616         NULL,                           /* same fs */
617         NULL,                           /* set file info */
618         NULL,                           /* truncate */
619         NULL,                           /* find directory */
620         NULL                            /* symbolic link */
621 };
622
623 static void
624 find_all_included_files(gchar *filename)
625 {
626         FILE *file;
627         gchar line[LINESIZE];
628         gchar *tmp, *expanded;
629         file = fopen(filename,"r");
630         while (fgets(line,LINESIZE,file) != NULL){
631                 if (g_ascii_strncasecmp(line, "Include",7) == 0) {
632                         while (fgets(line,LINESIZE,file) !=NULL){
633                                 if (line[0] == '#') continue;
634                                 if (line[0] == '{') continue;
635                                 else if (line[0] == '}') break;
636                                 tmp = g_strstrip(line);
637                                 if (tmp[0] == '\0') continue;
638                                 expanded = expand_env_vars(tmp);
639                                 if (g_file_test(expanded,G_FILE_TEST_EXISTS)){
640                         cdemenufiles = g_slist_append(cdemenufiles, 
641                                                 g_strdup(expanded));
642                                         find_all_included_files(expanded);
643                                 }
644                                 free(expanded);
645                         }
646                 }
647         }
648         fclose(file);
649 }
650
651 static void
652 create_cde_icon_name_cache (void)
653 {
654         /* fork the dttypes command to create the icon name cache */
655         int fd, t;
656         mode_t old_mask;
657         char *icon_name_cache_path;
658         
659         if ((t = fork ()) < 0) {
660                 g_error ("Unable to fork.");
661         } else if (t) {
662                 /* On a Solaris box, waitpid() fails with an interrupted system call.
663                    Hence, loop till it succeeds. Avoids zombies
664                 */
665                 while ((waitpid (t,NULL,0) == -1) && errno == EINTR);
666         } else {
667                 icon_name_cache_path = g_strconcat (g_get_home_dir (), CDE_ICON_NAME_CACHE, NULL);
668                 old_mask = umask(033);
669                 fd = open (icon_name_cache_path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
670                 dup2 (fd, 1);
671                 fchmod (fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 
672                 g_free(icon_name_cache_path);
673                 umask(old_mask);
674                 execl("/usr/dt/bin/dttypes", "dttypes", "-w", "fld_name", "ICON",
675                           "-l", "fld_name", "ICON", NULL);
676         }
677 }
678
679 GnomeVFSMethod *
680 vfs_module_init (const char *method_name, 
681                  const char *args)
682 {
683         gchar *files[7];
684         int i;
685         char *icon_name_cache_path;
686
687         parent_method = gnome_vfs_method_get ("file");
688
689         if (parent_method == NULL) {
690                 g_error ("Could not find 'file' method for gnome-vfs");
691                 return NULL;
692         }
693
694         /* find the right cde menu file to start with */
695         cdemenufiles = NULL;
696         files[0] = expand_env_vars("$HOME/.dt/$LC_CTYPE/dtwmrc");
697         files[1] = expand_env_vars("$HOME/.dt/dtwmrc");
698         files[2] = expand_env_vars("/etc/dt/config/$LC_CTYPE/sys.dtwmrc");
699         files[3] = g_strdup("/etc/dt/config/sys.dtwmrc");
700         files[4] = expand_env_vars("/usr/dt/config/$LC_CTYPE/sys.dtwmrc");
701         files[5] = g_strdup("/usr/dt/config/sys.dtwmrc");
702         files[6] = g_strdup("/usr/dt/config/C/sys.dtwmrc");
703
704         for (i=0;i<7;i++){
705                 if (g_file_test(files[i],G_FILE_TEST_EXISTS)){
706                         cdemenufiles = g_slist_append(cdemenufiles,
707                                 g_strdup(files[i]));
708                         break;
709                 }       
710         }
711         for (i=0;i<7;i++) g_free(files[i]);
712
713         /* if didnt find any menu start file then we are fecked */
714         if (cdemenufiles == NULL) return NULL;
715
716         /* from that file find a list of all included files */
717         find_all_included_files(cdemenufiles->data);
718
719         /*create the icon name cache if it does not exist*/
720         icon_name_cache_path = g_strconcat (g_get_home_dir (), CDE_ICON_NAME_CACHE, NULL);
721         if (!g_file_test(icon_name_cache_path, G_FILE_TEST_EXISTS))
722                 create_cde_icon_name_cache();
723
724         g_free(icon_name_cache_path);
725         return &method;
726 }
727
728 void
729 vfs_module_shutdown (GnomeVFSMethod *method)
730 {
731         /* free up any stuff in here */
732
733         g_slist_foreach(cdemenufiles, (GFunc)g_free, NULL);
734         g_slist_free(cdemenufiles);
735 }
736