--- mktemp.c_ORIG Tue Jun 27 13:49:41 2000 +++ mktemp.c Tue Jun 27 14:07:16 2000 @@ -61,7 +61,20 @@ #include #include -static int _gettemp(); +char *_mktemp(char *); + +static int _gettemp(char *, int *, int, int); + +int +mkstemps(path, slen) + char *path; + int slen; +{ + int fd; + + return (_gettemp(path, &fd, 0, slen) ? fd : -1); +} + int mkstemp(path) @@ -69,72 +82,123 @@ { int fd; - return (_gettemp(path, &fd) ? fd : -1); + return (_gettemp(path, &fd, 0, 0) ? fd : -1); +} + + +char * +mkdtemp(path) + char *path; +{ + return(_gettemp(path, (int *)NULL, 1, 0) ? path : (char *)NULL); +} + +char * +_mktemp(path) + char *path; +{ + return(_gettemp(path, (int *)NULL, 0, 0) ? path : (char *)NULL); } char * mktemp(path) char *path; { - return(_gettemp(path, (int *)NULL) ? path : (char *)NULL); + return(_mktemp(path)); } + static int -_gettemp(path, doopen) +_gettemp(path, doopen, domkdir, slen) char *path; register int *doopen; + int domkdir; + int slen; { - register char *start, *trv; + register char *start, *trv, *suffp; struct stat sbuf; - u_int pid; + u_int pid, rval; + + if (doopen && domkdir) { + errno = EINVAL; + return(0); + } + for (trv = path; *trv; ++trv) + ; + trv -= slen; + suffp = trv; + --trv; + if (trv < path) { + c = pid + 'A'; + else + c = (pid - 26) + 'a'; + *trv-- = c; + } + start = trv + 1; /* * check the target directory; if you have six X's and it * doesn't exist this runs for a *very* long time. */ - for (start = trv + 1;; --trv) { + if (doopen || domkdir) { + for (;; --trv) { if (trv <= path) break; if (*trv == '/') { *trv = '\0'; - if (stat(path, &sbuf)) + rval = stat(path, &sbuf); + *trv = '/'; + if (rval != 0) return(0); if (!S_ISDIR(sbuf.st_mode)) { errno = ENOTDIR; return(0); } - *trv = '/'; break; } } + } for (;;) { if (doopen) { if ((*doopen = - open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0) + _open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0) return(1); if (errno != EEXIST) return(0); - } - else if (stat(path, &sbuf)) + } else if (domkdir) { + if (mkdir(path, 0700) == 0) + return(1); + if (errno != EEXIST) + return(0); + } else if (lstat(path, &sbuf)) return(errno == ENOENT ? 1 : 0); /* tricky little algorithm for backward compatibility */ for (trv = start;;) { - if (!*trv) + if (*trv == '\0' || trv == suffp) return(0); - if (*trv == 'z') + if (*trv == 'Z') *trv++ = 'a'; else { - if (isdigit(*trv)) + if (isdigit((unsigned char)*trv)) *trv = 'a'; + else if (*trv == 'z') /* inc from z to A */ + *trv = 'A'; else ++*trv; break;