00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <u/libu.h>
00035 #include <sys/types.h>
00036 #include <sys/stat.h>
00037 #include <limits.h>
00038 #include <fcntl.h>
00039 #include <errno.h>
00040 #include <stdio.h>
00041 #include <stdlib.h>
00042 #include <string.h>
00043 #include <ctype.h>
00044 #include <unistd.h>
00045
00046 #ifndef HAVE_MKSTEMPS
00047
00048 static int _gettemp(char *, int *, int, int);
00049 static unsigned int __time_seed (void);
00050
00051 static const unsigned char padchar[] =
00052 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
00053
00054 int
00055 mkstemps(path, slen)
00056 char *path;
00057 int slen;
00058 {
00059 int fd;
00060
00061 return (_gettemp(path, &fd, 0, slen) ? fd : -1);
00062 }
00063
00064 static int
00065 _gettemp(path, doopen, domkdir, slen)
00066 char *path;
00067 int *doopen;
00068 int domkdir;
00069 int slen;
00070 {
00071 char *start, *trv, *suffp;
00072 char *pad;
00073 struct stat sbuf;
00074 int rval;
00075 int __rand;
00076
00077 srand(__time_seed());
00078
00079 if (doopen != NULL && domkdir) {
00080 errno = EINVAL;
00081 return (0);
00082 }
00083
00084 for (trv = path; *trv != '\0'; ++trv)
00085 ;
00086 trv -= slen;
00087 suffp = trv;
00088 --trv;
00089 if (trv < path) {
00090 errno = EINVAL;
00091 return (0);
00092 }
00093
00094
00095 while (trv >= path && *trv == 'X') {
00096 __rand = rand() % (sizeof(padchar) - 1);
00097 *trv-- = padchar[__rand];
00098 }
00099 start = trv + 1;
00100
00101
00102
00103
00104 if (doopen != NULL || domkdir) {
00105 for (; trv > path; --trv) {
00106 if (*trv == '/') {
00107 *trv = '\0';
00108 rval = stat(path, &sbuf);
00109 *trv = '/';
00110 if (rval != 0)
00111 return (0);
00112 if (!S_ISDIR(sbuf.st_mode)) {
00113 errno = ENOTDIR;
00114 return (0);
00115 }
00116 break;
00117 }
00118 }
00119 }
00120
00121 for (;;) {
00122 if (doopen) {
00123 if ((*doopen =
00124 open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0)
00125 return (1);
00126 if (errno != EEXIST)
00127 return (0);
00128 } else if (domkdir) {
00129 if (mkdir(path, 0700) == 0)
00130 return (1);
00131 if (errno != EEXIST)
00132 return (0);
00133 } else if (lstat(path, &sbuf))
00134 return (errno == ENOENT);
00135
00136
00137 for (trv = start;;) {
00138 if (*trv == '\0' || trv == suffp)
00139 return (0);
00140 pad = strchr((const char *) padchar, *trv);
00141 if (pad == NULL || *++pad == '\0')
00142 *trv++ = padchar[0];
00143 else {
00144 *trv++ = *pad;
00145 break;
00146 }
00147 }
00148 }
00149
00150 }
00151
00152 static unsigned int __time_seed (void)
00153 {
00154 time_t now;
00155 unsigned char *p;
00156 unsigned seed = 0;
00157 size_t i;
00158
00159 now = time(NULL);
00160 p = (unsigned char *) &now;
00161
00162 for (i = 0; i < sizeof now; i++)
00163 seed = seed * (UCHAR_MAX + 2U) + p[i];
00164
00165 return seed;
00166 }
00167
00168 #else
00169 int mkstemps (char *template, int suffixlen);
00170 #endif