static char *_get_make_sock_path(void) { char *path, *user, *lock; const char *prefix = "/tmp/grass6"; int len, status; struct stat theStat; user = G_whoami(); /* Don't G_free () return value ever! */ if (user == NULL) return NULL; else if (user[0] == '?') { /* why's it do that? */ return NULL; } if ((lock = getenv("GIS_LOCK")) == NULL) G_fatal_error(_("Unable to get GIS_LOCK environment variable value")); len = strlen(prefix) + strlen(user) + strlen(lock) + 3; path = G_malloc(len); sprintf(path, "%s-%s-%s", prefix, user, lock); if ((status = G_lstat(path, &theStat)) != 0) { status = G_mkdir(path); } else { if (!S_ISDIR(theStat.st_mode)) { status = -1; /* not a directory ?? */ } else { status = chmod(path, S_IRWXU); /* fails if we don't own it */ } } if (status) { /* something's wrong if non-zero */ G_free(path); path = NULL; } return path; }
/************************************************************************** * _make_toplevel(): make user's toplevel config directory if it doesn't * already exist. Adjust perms to 1700. Returns the toplevel directory * path [caller must G_free ()] on success, or NULL on failure *************************************************************************/ #ifndef __MINGW32__ /* TODO */ static char *_make_toplevel(void) { size_t len; int status; #ifdef __MINGW32__ char *defaulthomedir = "c:"; char *homedir = getenv("HOME"); #else uid_t me; struct passwd *my_passwd; #endif struct stat buf; char *path; errno = 0; /* Query whatever database to get user's home dir */ #ifdef __MINGW32__ if (NULL == homedir) { homedir = defaulthomedir; } len = strlen(homedir) + 8; /* + "/.grass\0" */ if (NULL == (path = G_calloc(1, len))) { return NULL; } sprintf(path, "%s%s", homedir, "/.grass"); #else me = getuid(); my_passwd = getpwuid(me); if (my_passwd == NULL) return NULL; len = strlen(my_passwd->pw_dir) + 8; /* + "/.grass\0" */ if (NULL == (path = G_calloc(1, len))) return NULL; sprintf(path, "%s%s", my_passwd->pw_dir, "/.grass"); #endif status = G_lstat(path, &buf); /* If errno == ENOENT, the directory doesn't exist */ if (status != 0) { if (errno == ENOENT) { status = G_mkdir(path); if (status != 0) { /* mkdir failed */ G_free(path); return NULL; } /* override umask settings, if possible */ chmod(path, S_IRWXU); /* otherwise mkdir succeeded, we're done here */ return path; } /* other errors should not be defined ??? give up */ G_free(path); return NULL; } /* implicit else */ /* Examine the stat "buf" */ /* It better be a directory */ if (!S_ISDIR(buf.st_mode)) { /* File, link, something else */ errno = ENOTDIR; /* element is not a directory, but should be */ G_free(path); return NULL; } /* No read/write/execute ??? */ if (!((S_IRUSR & buf.st_mode) && (S_IWUSR & buf.st_mode) && (S_IXUSR & buf.st_mode) ) ) { errno = EACCES; /* Permissions error */ G_free(path); return NULL; } /* We'll assume that if the user grants greater permissions * than we would, that they know what they're doing * -- so we're done here... */ return path; }
/************************************************************************** * _make_sublevels(): creates subelements as necessary from the passed * "elems" string. It returns the full path if successful or NULL * if it fails. "elems" must not be NULL, zero length, or have any * elements that begin with a '.' or any occurrences of '//'. *************************************************************************/ static char *_make_sublevels(const char *elems) { int i, status; char *cp, *path, *top, *ptr; struct stat buf; /* Get top level path */ if (NULL == (top = _make_toplevel())) return NULL; /* Make a copy of elems */ if (NULL == (cp = G_store(elems))) { G_free(top); return NULL; } /* Do element count, sanity checking and "splitting" */ if ((i = _elem_count_split(cp)) < 1) { G_free(cp); G_free(top); return NULL; } /* Allocate our path to be large enough */ if ((path = G_calloc(1, strlen(top) + strlen(elems) + 2)) == NULL) { G_free(top); G_free(cp); return NULL; } /* Now loop along adding directories if they don't exist * make sure the thing is a directory as well. * If there was a trailing '/' in the original "elem", it doesn't * make it into the returned path. */ for (; i > 0; i--) { sprintf(path, "%s/%s", top, cp); errno = 0; status = G_lstat(path, &buf); if (status != 0) { /* the element doesn't exist */ status = G_mkdir(path); if (status != 0) { /* Some kind of problem... */ G_free(top); G_free(cp); return NULL; } /* override umask settings, if possible */ chmod(path, S_IRWXU); } else { /* Examine the stat "buf" */ /* It better be a directory */ if (!S_ISDIR(buf.st_mode)) { /* File, link, something else */ errno = ENOTDIR; /* element is not a directory, but should be */ G_free(path); return NULL; } /* No read/write/execute ??? */ if (!((S_IRUSR & buf.st_mode) && (S_IWUSR & buf.st_mode) && (S_IXUSR & buf.st_mode) ) ) { errno = EACCES; /* Permissions error */ G_free(path); return NULL; } /* okay continue ... */ } ptr = strchr(cp, '\0'); *ptr = '/'; } /* All done, free memory */ G_free(top); G_free(cp); return path; }
int G_recursive_copy(const char *src, const char *dst) { DIR *dirp; struct stat sb; if (G_lstat(src, &sb) < 0) return 1; /* src is a file */ if (!S_ISDIR(sb.st_mode)) { char buf[4096]; int fd, fd2; size_t len, len2; if (G_lstat(dst, &sb) == 0 && S_ISDIR(sb.st_mode)) { char path[GPATH_MAX]; const char *p = strrchr(src, '/'); /* src => dst/src */ sprintf(path, "%s/%s", dst, (p ? p + 1 : src)); return G_recursive_copy(src, path); } /* src => dst */ if ((fd = open(src, O_RDONLY)) < 0) return 1; if ((fd2 = open(dst, O_CREAT | O_TRUNC | O_WRONLY, sb.st_mode & 0777)) < 0) { close(fd); return 1; } while ((len = read(fd, buf, sizeof(buf))) > 0) { while (len && (len2 = write(fd2, buf, len)) >= 0) len -= len2; } close(fd); close(fd2); return 0; } /* src is a directory */ if (G_lstat(dst, &sb) < 0) { if (G_mkdir(dst)) return 1; } else /* if dst already exists and it's a file, try to remove it */ if (!S_ISDIR(sb.st_mode)) { if (remove(dst) < 0 || G_mkdir(dst) < 0) return 1; } dirp = opendir(src); if (!dirp) return 1; for (;;) { char path[GPATH_MAX], path2[GPATH_MAX]; struct dirent *dp = readdir(dirp); if (!dp) break; /* do not copy hidden files */ if (dp->d_name[0] == '.') continue; sprintf(path, "%s/%s", src, dp->d_name); sprintf(path2, "%s/%s", dst, dp->d_name); if (G_recursive_copy(path, path2) != 0) return 1; } closedir(dirp); return 0; }