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