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 #ifdef OS_WIN
00047 #include <windows.h>
00048 #define _mkdir(dir, perm) CreateDirectory(dir, NULL)
00049 #else
00050 #define _mkdir(dir, perm) mkdir(dir, perm)
00051 #endif
00052
00053 #ifndef HAVE_MKSTEMPS
00054
00055 static int _gettemp(char *, int *, int, int);
00056 static unsigned int __time_seed (void);
00057
00058 static const unsigned char padchar[] =
00059 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
00060
00061 int
00062 mkstemps(path, slen)
00063 char *path;
00064 int slen;
00065 {
00066 int fd;
00067
00068 return (_gettemp(path, &fd, 0, slen) ? fd : -1);
00069 }
00070
00071 static int
00072 _gettemp(path, doopen, domkdir, slen)
00073 char *path;
00074 int *doopen;
00075 int domkdir;
00076 int slen;
00077 {
00078 char *start, *trv, *suffp;
00079 char *pad;
00080 struct stat sbuf;
00081 int rval;
00082 int __rand;
00083
00084 srand(__time_seed());
00085
00086 if (doopen != NULL && domkdir) {
00087 errno = EINVAL;
00088 return (0);
00089 }
00090
00091 for (trv = path; *trv != '\0'; ++trv)
00092 ;
00093 trv -= slen;
00094 suffp = trv;
00095 --trv;
00096 if (trv < path) {
00097 errno = EINVAL;
00098 return (0);
00099 }
00100
00101
00102 while (trv >= path && *trv == 'X') {
00103 __rand = rand() % (sizeof(padchar) - 1);
00104 *trv-- = padchar[__rand];
00105 }
00106 start = trv + 1;
00107
00108
00109
00110
00111 if (doopen != NULL || domkdir) {
00112 for (; trv > path; --trv) {
00113 if (*trv == '/') {
00114 *trv = '\0';
00115 rval = stat(path, &sbuf);
00116 *trv = '/';
00117 if (rval != 0)
00118 return (0);
00119 if (!S_ISDIR(sbuf.st_mode)) {
00120 errno = ENOTDIR;
00121 return (0);
00122 }
00123 break;
00124 }
00125 }
00126 }
00127
00128 for (;;) {
00129 if (doopen) {
00130 if ((*doopen =
00131 open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0)
00132 return (1);
00133 if (errno != EEXIST)
00134 return (0);
00135 } else if (domkdir) {
00136 if (_mkdir(path, 0700) == 0)
00137 return (1);
00138 if (errno != EEXIST)
00139 return (0);
00140 } else if (lstat(path, &sbuf))
00141 return (errno == ENOENT);
00142
00143
00144 for (trv = start;;) {
00145 if (*trv == '\0' || trv == suffp)
00146 return (0);
00147 pad = strchr((const char *) padchar, *trv);
00148 if (pad == NULL || *++pad == '\0')
00149 *trv++ = padchar[0];
00150 else {
00151 *trv++ = *pad;
00152 break;
00153 }
00154 }
00155 }
00156
00157 }
00158
00159 static unsigned int __time_seed (void)
00160 {
00161 time_t now;
00162 unsigned char *p;
00163 unsigned seed = 0;
00164 size_t i;
00165
00166 now = time(NULL);
00167 p = (unsigned char *) &now;
00168
00169 for (i = 0; i < sizeof now; i++)
00170 seed = seed * (UCHAR_MAX + 2U) + p[i];
00171
00172 return seed;
00173 }
00174
00175 #else
00176 int mkstemps (char *template, int suffixlen);
00177 #endif