00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include <stdio.h>
00030 #include <stdlib.h>
00031 #include <assert.h>
00032 #include <unistd.h>
00033 #include <string.h>
00034 #include <pwd.h>
00035 #include <sys/types.h>
00036 #include <sys/stat.h>
00037 #include <errno.h>
00038 #include "gis.h"
00039
00040
00041
00042
00043
00044
00045
00046 static char *
00047 _make_toplevel (void)
00048 {
00049 size_t len;
00050 int status;
00051 #ifdef __MINGW32__
00052 char *defaulthomedir = "c:";
00053 char *homedir = getenv ( "HOME" );
00054 #else
00055 uid_t me;
00056 struct passwd *my_passwd;
00057 #endif
00058 struct stat buf;
00059 char *path;
00060
00061 errno = 0;
00062
00063
00064 #ifdef __MINGW32__
00065 if ( NULL == homedir ) {
00066 homedir = defaulthomedir;
00067 }
00068
00069 len = strlen ( homedir ) + 8;
00070 if ( NULL == ( path = G_calloc ( 1, len ) ) ) {
00071 return NULL;
00072 }
00073 snprintf ( path, len, "%s%s", homedir, "/.grass" );
00074 #else
00075 me = getuid();
00076 my_passwd = getpwuid (me);
00077 if (my_passwd == NULL)
00078 return NULL;
00079
00080 len = strlen (my_passwd->pw_dir) + 8;
00081 if (NULL == (path = G_calloc (1, len)))
00082 return NULL;
00083
00084 snprintf (path, len, "%s%s", my_passwd->pw_dir, "/.grass");
00085 #endif
00086
00087 status = lstat (path, &buf);
00088
00089
00090 if (status != 0)
00091 {
00092 if (errno == ENOENT)
00093 {
00094 status = mkdir (path, S_IRWXU);
00095
00096 if (status != 0)
00097 {
00098 G_free (path);
00099 return NULL;
00100 }
00101
00102
00103 chmod (path, S_IRWXU);
00104
00105
00106 return path;
00107 }
00108
00109
00110 G_free (path);
00111 return NULL;
00112 }
00113
00114
00115
00116
00117 if (!S_ISDIR(buf.st_mode))
00118 {
00119 errno = ENOTDIR;
00120 G_free (path);
00121 return NULL;
00122 }
00123
00124
00125 if (!(
00126 (S_IRUSR & buf.st_mode) &&
00127 (S_IWUSR & buf.st_mode) &&
00128 (S_IXUSR & buf.st_mode)
00129 )
00130 )
00131 {
00132 errno = EACCES;
00133 G_free (path);
00134 return NULL;
00135 }
00136
00137
00138
00139
00140
00141
00142 return path;
00143 }
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157 static int
00158 _elem_count_split (char *elems)
00159 {
00160 int i;
00161 size_t len;
00162 char *begin, *end;
00163
00164
00165 assert (elems != NULL);
00166 assert ((len = strlen(elems)) > 0);
00167 assert (*elems != '/');
00168
00169 begin = elems;
00170 for (i = 0; begin != NULL && len > begin - elems; i++)
00171 {
00172
00173 if (*begin == '.')
00174 return 0;
00175 end = strchr (begin, '/');
00176
00177 if (end != NULL && end == begin)
00178 return 0;
00179
00180 begin = end;
00181 if (begin != NULL)
00182 {
00183 *begin = '\0';
00184 begin++;
00185 }
00186 }
00187
00188
00189 return i;
00190 }
00191
00192
00193
00194
00195
00196
00197
00198
00199 static char *
00200 _make_sublevels(char *elems)
00201 {
00202 int i, status;
00203 char *cp, *path, *top, *ptr;
00204 struct stat buf;
00205
00206
00207 if (NULL == (top = _make_toplevel()))
00208 return NULL;
00209
00210
00211 if (NULL == (cp = G_store (elems)))
00212 {
00213 G_free (top);
00214 return NULL;
00215 }
00216
00217
00218 if ((i = _elem_count_split (cp)) < 1)
00219 {
00220 G_free (cp);
00221 G_free (top);
00222 return NULL;
00223 }
00224
00225
00226 if ((path = G_calloc (1, strlen(top) + strlen(elems) + 2)) == NULL)
00227 {
00228 G_free (top);
00229 G_free (cp);
00230 return NULL;
00231 }
00232
00233
00234
00235
00236
00237
00238 for (; i > 0; i--)
00239 {
00240 sprintf (path, "%s/%s", top, cp);
00241 errno = 0;
00242 status = lstat (path, &buf);
00243 if (status != 0)
00244 {
00245
00246 status = mkdir (path, S_IRWXU);
00247 if (status != 0)
00248 {
00249
00250 G_free (top);
00251 G_free (cp);
00252 return NULL;
00253 }
00254
00255 chmod (path, S_IRWXU);
00256 }
00257 else
00258 {
00259
00260
00261 if (!S_ISDIR(buf.st_mode))
00262 {
00263 errno = ENOTDIR;
00264 G_free (path);
00265 return NULL;
00266 }
00267
00268
00269 if (!(
00270 (S_IRUSR & buf.st_mode) &&
00271 (S_IWUSR & buf.st_mode) &&
00272 (S_IXUSR & buf.st_mode)
00273 )
00274 )
00275 {
00276 errno = EACCES;
00277 G_free (path);
00278 return NULL;
00279 }
00280
00281
00282 }
00283
00284 ptr = strchr (cp, '\0');
00285 *ptr = '/';
00286 }
00287
00288
00289 G_free (top);
00290 G_free (cp);
00291
00292 return path;
00293 }
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303 char *
00304 G_rc_path (char *element, char *item)
00305 {
00306 size_t len;
00307 char *path, *ptr;
00308
00309 assert (!(element == NULL && item == NULL));
00310
00311
00312 if (element == NULL)
00313 {
00314 path = _make_toplevel();
00315 }
00316 else if (item == NULL)
00317 {
00318 return _make_sublevels (element);
00319 }
00320 else
00321 {
00322 path = _make_sublevels (element);
00323 }
00324
00325
00326 assert (*item != '.');
00327 assert (path != NULL);
00328 ptr = strchr (item, '/');
00329 assert (ptr == NULL);
00330 len = strlen(path) + strlen(item) + 2;
00331 if ((ptr = G_realloc (path, len)) == NULL)
00332 {
00333 G_free (path);
00334 return NULL;
00335 }
00336 path = ptr;
00337 ptr = strchr (path, '\0');
00338 sprintf (ptr, "/%s", item);
00339
00340 return path;
00341 }
00342
00343
00344
00345