/* recursively fix up permissions: used for R CMD INSTALL and build. NB: this overrides umask. */ SEXP dirchmod(SEXP dr) { if(!isString(dr) || length(dr) != 1) error(_("invalid '%s' argument"), "dir"); chmod_one(translateChar(STRING_ELT(dr, 0))); return R_NilValue; }
/* This is a .Call so manages R_alloc stack */ SEXP dirchmod(SEXP dr, SEXP gwsxp) { if(!isString(dr) || LENGTH(dr) != 1) error(_("invalid '%s' argument"), "dir"); chmod_one(translateChar(STRING_ELT(dr, 0)), asLogical(gwsxp)); return R_NilValue; }
static void chmod_one(const char *name, const int grpwrt) { DIR *dir; struct dirent *de; char p[PATH_MAX]; #ifdef Win32 struct _stati64 sb; #else struct stat sb; #endif #ifndef Win32 mode_t mask, dirmask; if (grpwrt) { mask = S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP; /* 0664 */ dirmask = mask | S_IXUSR | S_IXGRP | S_IXOTH; /* 0755 */ } else { mask = S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR; /* 0644 */ dirmask = mask | S_IXUSR | S_IXGRP | S_IXOTH; /* 0755 */ } #endif if (streql(name, ".") || streql(name, "..")) return; if (!R_FileExists(name)) return; #ifdef Win32 _stati64(name, &sb); chmod(name, _S_IWRITE); #else stat(name, &sb); chmod(name, (sb.st_mode | mask) & dirmask); #endif if ((sb.st_mode & S_IFDIR) > 0) { /* a directory */ #ifndef Win32 chmod(name, dirmask); #endif if ((dir = opendir(name)) != NULL) { while ((de = readdir(dir))) { if (streql(de->d_name, ".") || streql(de->d_name, "..")) continue; size_t n = strlen(name); if (name[n-1] == R_FileSep[0]) snprintf(p, PATH_MAX, "%s%s", name, de->d_name); else snprintf(p, PATH_MAX, "%s%s%s", name, R_FileSep, de->d_name); chmod_one(p, grpwrt); } closedir(dir); } else { /* we were unable to read a dir */ } } }