r1996: Cope slightly better with invalid filenames in various places (reported by
[rox-filer.git] / ROX-Filer / src / choices.c
blob35def4d02267c11a3528a4cf1c0a34925465e7d0
1 /*
2 * $Id$
4 * ROX-Filer, filer for the ROX desktop project
5 * Copyright (C) 2002, the ROX-Filer team.
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 2 of the License, or (at your option)
10 * any later version.
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19 * Place, Suite 330, Boston, MA 02111-1307 USA
21 /* choices.c - code for handling loading and saving of user choices */
23 #include "config.h"
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <sys/param.h>
28 #include <fcntl.h>
29 #include <errno.h>
31 #include "global.h"
33 #include "choices.h"
35 static gboolean saving_disabled = TRUE;
36 static gchar **dir_list = NULL;
38 /* Static prototypes */
39 static gboolean exists(char *path);
42 /****************************************************************
43 * EXTERNAL INTERFACE *
44 ****************************************************************/
47 /* Reads in CHOICESPATH and constructs the directory list table.
48 * You must call this before using any other choices_* functions.
50 * If CHOICESPATH does not exist then a suitable default is used.
52 void choices_init(void)
54 char *choices;
56 g_return_if_fail(dir_list == NULL);
58 choices = getenv("CHOICESPATH");
60 if (choices)
62 if (*choices != ':' && *choices != '\0')
63 saving_disabled = FALSE;
65 while (*choices == ':')
66 choices++;
68 if (*choices == '\0')
70 dir_list = g_new(char *, 1);
71 dir_list[0] = NULL;
73 else
74 dir_list = g_strsplit(choices, ":", 0);
76 else
78 saving_disabled = FALSE;
80 dir_list = g_new(gchar *, 4);
81 dir_list[0] = g_strconcat(getenv("HOME"), "/Choices", NULL);
82 dir_list[1] = g_strdup("/usr/local/share/Choices");
83 dir_list[2] = g_strdup("/usr/share/Choices");
84 dir_list[3] = NULL;
87 #if 0
89 gchar **cdir = dir_list;
91 while (*cdir)
93 g_print("[ choices dir '%s' ]\n", *cdir);
94 cdir++;
97 g_print("[ saving is %s ]\n", saving_disabled ? "disabled"
98 : "enabled");
100 #endif
103 /* Returns an array of the directories in CHOICESPATH which contain
104 * a subdirectory called 'dir'.
106 * Lower-indexed results should override higher-indexed ones.
108 * Free the list using choices_free_list().
110 GPtrArray *choices_list_dirs(char *dir)
112 GPtrArray *list;
113 gchar **cdir = dir_list;
115 g_return_val_if_fail(dir_list != NULL, NULL);
117 list = g_ptr_array_new();
119 for (; *cdir; cdir++)
121 guchar *path;
123 path = g_strconcat(*cdir, "/", dir, NULL);
124 if (exists(path))
125 g_ptr_array_add(list, path);
126 else
127 g_free(path);
130 return list;
133 void choices_free_list(GPtrArray *list)
135 guint i;
137 g_return_if_fail(list != NULL);
139 for (i = 0; i < list->len; i++)
140 g_free(g_ptr_array_index(list, i));
142 g_ptr_array_free(list, TRUE);
145 /* Get the pathname of a choices file to load. Eg:
147 * choices_find_path_load("menus", "ROX-Filer")
148 * -> "/usr/local/share/Choices/ROX-Filer/menus".
150 * The return values may be NULL - use built-in defaults.
151 * g_free() the result.
153 guchar *choices_find_path_load(const char *leaf, const char *dir)
155 gchar **cdir = dir_list;
157 g_return_val_if_fail(dir_list != NULL, NULL);
159 for (; *cdir; cdir++)
161 gchar *path;
163 path = g_strconcat(*cdir, "/", dir, "/", leaf, NULL);
165 if (exists(path))
166 return path;
168 g_free(path);
171 return NULL;
174 /* Returns the pathname of a file to save to, or NULL if saving is
175 * disabled. If 'create' is TRUE then intermediate directories will
176 * be created (set this to FALSE if you just want to find out where
177 * a saved file would go without actually altering the filesystem).
179 * g_free() the result.
181 guchar *choices_find_path_save(const char *leaf, const char *dir,
182 gboolean create)
184 gchar *path, *retval;
186 g_return_val_if_fail(dir_list != NULL, NULL);
188 if (saving_disabled)
189 return NULL;
191 if (create && !exists(dir_list[0]))
193 if (mkdir(dir_list[0], 0777))
194 g_warning("mkdir(%s): %s\n", dir_list[0],
195 g_strerror(errno));
198 path = g_strconcat(dir_list[0], "/", dir, NULL);
199 if (create && !exists(path))
201 if (mkdir(path, 0777))
202 g_warning("mkdir(%s): %s\n", path, g_strerror(errno));
205 retval = g_strconcat(path, "/", leaf, NULL);
206 g_free(path);
208 return retval;
212 /****************************************************************
213 * INTERNAL FUNCTIONS *
214 ****************************************************************/
217 /* Returns TRUE if the object exists, FALSE if it doesn't */
218 static gboolean exists(char *path)
220 struct stat info;
222 return stat(path, &info) == 0;