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 */ } } }
char * R_tmpnam(const char * prefix, const char * tempdir) { char tm[PATH_MAX], tmp1[PATH_MAX], *res; unsigned int n, done = 0; if(!prefix) prefix = ""; /* NULL */ strcpy(tmp1, tempdir); for (n = 0; n < 100; n++) { /* try a random number at the end */ sprintf(tm, "%s/%s%x", tmp1, prefix, rand()); if(!R_FileExists(tm)) { done = 1; break; } } if(!done) error(_("cannot find unused tempfile name")); res = (char *) malloc((strlen(tm)+1) * sizeof(char)); strcpy(res, tm); return res; }
/* NB for use with multicore: parent and all children share the same session directory and run in parallel. So as from 2.14.1, we make sure getpic() is part of the process. */ char * R_tmpnam2(const char *prefix, const char *tempdir, const char *fileext) { char tm[PATH_MAX], *res; unsigned int n, done = 0, pid = getpid(); #ifdef Win32 char filesep[] = "\\"; #else char filesep[] = "/"; #endif if(!prefix) prefix = ""; /* NULL */ if(!fileext) fileext = ""; /* " */ #if RAND_MAX > 16777215 #define RAND_WIDTH 8 #else #define RAND_WIDTH 12 #endif if(strlen(tempdir) + 1 + strlen(prefix) + RAND_WIDTH + strlen(fileext) >= PATH_MAX) error(_("temporary name too long")); for (n = 0; n < 100; n++) { /* try a random number at the end. Need at least 6 hex digits */ #if RAND_MAX > 16777215 snprintf(tm, PATH_MAX, "%s%s%s%x%x%s", tempdir, filesep, prefix, pid, rand(), fileext); #else snprintf(tm, PATH_MAX, "%s%s%s%x%x%x%s", tempdir, filesep, prefix, pid, rand(), rand(), fileext); #endif if(!R_FileExists(tm)) { done = 1; break; } } if(!done) error(_("cannot find unused tempfile name")); res = (char *) malloc((strlen(tm)+1) * sizeof(char)); if(!res) error(_("allocation failed in R_tmpnam2")); strcpy(res, tm); return res; }