This source file includes following definitions.
- utfile_mkstemps
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #include <ctype.h>
20 #include <signal.h>
21 #include <errno.h>
22 #include <fcntl.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #if defined(__sunos) && defined(SYSV)
27 # include <sys/param.h>
28 #endif
29 #include <sys/stat.h>
30 #include <sys/types.h>
31 #include <time.h>
32 #include <sys/time.h>
33 #include <unistd.h>
34
35 #define MAX_MKSTEMPS_TRIES 10000
36
37 #if defined(__MINGW64__) || defined(__MINGW32__)
38 # include "bsd_random.h"
39 # define random bsd_random
40 # define srandom bsd_srandom
41 #endif
42
43 #undef FREE
44 #ifdef TESTING
45 # define FREE(p) free(p)
46 #else
47 # define FREE(p) do \
48 { \
49 free((p)); \
50 (p) = NULL; \
51 } while(0)
52 #endif
53
54 static char valid_file_name_chars[]
55 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
56
57
58
59
60
61
62 int
63 utfile_mkstemps(char *request_pattern, int suffix_length)
64 {
65 long pattern_length;
66 int st1ret;
67 char *mask_pointer;
68 struct timespec st1;
69
70 char *pattern = strdup(request_pattern);
71 if (!pattern)
72 {
73 fprintf (stderr, "\rFATAL: Out of memory! Aborting at %s[%s:%d]\r\n",
74 __func__, __FILE__, __LINE__);
75 #if defined(USE_BACKTRACE)
76 # ifdef SIGUSR2
77 (void)raise(SIGUSR2);
78
79 # endif
80 #endif
81 abort();
82 }
83
84 pattern_length = (long) strlen(pattern);
85
86 #ifdef USE_MONOTONIC
87 st1ret = clock_gettime(CLOCK_MONOTONIC, &st1);
88 #else
89 st1ret = clock_gettime(CLOCK_REALTIME, &st1);
90 #endif
91 if (st1ret != 0)
92 {
93 fprintf (stderr, "\rFATAL: clock_gettime failure! Aborting at %s[%s:%d]\r\n",
94 __func__, __FILE__, __LINE__);
95 #if defined(USE_BACKTRACE)
96 # ifdef SIGUSR2
97 (void)raise(SIGUSR2);
98
99 # endif
100 #endif
101 abort();
102 }
103
104 srandom((unsigned int)(getpid() ^ (long)((1LL + (long long)st1.tv_nsec) * (1LL + (long long)st1.tv_sec))));
105
106 if (( (long) pattern_length - 6 ) < (long) suffix_length)
107 {
108 FREE(pattern);
109 return ( -1 );
110 }
111
112 long mask_offset = (long) pattern_length - ( 6 + (long) suffix_length );
113
114 if (strncmp(&pattern[mask_offset], "XXXXXX", 6))
115 {
116 FREE(pattern);
117 return ( -1 );
118 }
119
120 mask_pointer = &pattern[mask_offset];
121
122 long valid_char_count = (long) strlen(valid_file_name_chars);
123
124 if (valid_char_count < 1)
125 {
126 FREE(pattern);
127 return ( -1 );
128 }
129
130 for (int count = 0; count < MAX_MKSTEMPS_TRIES; count++)
131 {
132 for (int mask_index = 0; mask_index < 6; mask_index++)
133 {
134 mask_pointer[mask_index]
135 = valid_file_name_chars[random() % valid_char_count];
136 }
137
138 int fd = open(pattern, O_CREAT | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR);
139
140 if (fd >= 0)
141 {
142 FREE(pattern);
143 return ( fd );
144 }
145
146
147
148
149
150
151 if (( errno != EEXIST ) && ( errno != EISDIR ))
152 {
153 break;
154 }
155 }
156
157
158
159
160
161
162 FREE(pattern);
163 return ( -1 );
164 }