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