1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | #include "xmlrpc_config.h" |
36 | #include "mallocvar.h" |
37 | |
38 | #define _CRT_SECURE_NO_WARNINGS |
39 | |
40 | |
41 | |
42 | |
43 | #if !defined(_FILE_OFFSET_BITS64) |
44 | #define _FILE_OFFSET_BITS64 64 |
45 | #endif |
46 | |
47 | |
48 | |
49 | #if !defined(_LARGE_FILES) |
50 | #define _LARGE_FILES |
51 | #endif |
52 | |
53 | |
54 | #include <string.h> |
55 | |
56 | #if MSVCRT0 |
57 | #include <io.h> |
58 | typedef __int64 readwriterc_t; |
59 | #else |
60 | #include <unistd.h> |
61 | #include <fcntl.h> |
62 | #include <dirent.h> |
63 | #include <sys/stat.h> |
64 | typedef ssize_t readwriterc_t; |
65 | #endif |
66 | |
67 | #include "bool.h" |
68 | #include "xmlrpc-c/string_int.h" |
69 | #include "xmlrpc-c/abyss.h" |
70 | #include "file.h" |
71 | |
72 | bool const win32 = |
73 | #ifdef WIN32 |
74 | TRUE1; |
75 | #else |
76 | FALSE0; |
77 | #endif |
78 | |
79 | struct TFileFind { |
80 | #ifdef WIN32 |
81 | #if MSVCRT0 |
82 | intptr_t handle; |
83 | #else |
84 | HANDLE handle; |
85 | #endif |
86 | #else |
87 | char path[NAME_MAX255+1]; |
88 | DIR * handle; |
89 | #endif |
90 | }; |
91 | |
92 | |
93 | |
94 | |
95 | |
96 | |
97 | |
98 | static void |
99 | createFileImage(TFile ** const filePP, |
100 | const char * const name, |
101 | uint32_t const attrib, |
102 | bool const createFile, |
103 | bool * const succeededP) { |
104 | |
105 | TFile * fileP; |
106 | |
107 | MALLOCVAR(fileP)fileP = malloc(sizeof(*fileP)); |
108 | if (fileP == NULL((void*)0)) |
109 | *succeededP = FALSE0; |
110 | else { |
111 | int rc; |
112 | |
113 | if (createFile) |
114 | |
115 | rc = open(name, attrib | O_CREAT0100, S_IWRITE0200 | S_IREAD0400); |
116 | else |
117 | rc = open(name, attrib); |
118 | |
119 | if (rc < 0) |
120 | *succeededP = FALSE0; |
121 | else { |
122 | fileP->fd = rc; |
123 | *succeededP = TRUE1; |
124 | } |
125 | if (!*succeededP) |
126 | free(fileP); |
127 | } |
128 | *filePP = fileP; |
129 | } |
130 | |
131 | |
132 | |
133 | bool |
134 | FileOpen(TFile ** const filePP, |
135 | const char * const name, |
136 | uint32_t const attrib) { |
137 | |
138 | bool succeeded; |
139 | |
140 | createFileImage(filePP, name, attrib, FALSE0, &succeeded); |
141 | |
142 | return succeeded; |
143 | } |
144 | |
145 | |
146 | |
147 | bool |
148 | FileOpenCreate(TFile ** const filePP, |
149 | const char * const name, |
150 | uint32_t const attrib) { |
151 | |
152 | bool succeeded; |
153 | |
154 | createFileImage(filePP, name, attrib, TRUE1, &succeeded); |
155 | |
156 | return succeeded; |
157 | } |
158 | |
159 | |
160 | |
161 | bool |
162 | FileWrite(const TFile * const fileP, |
163 | const void * const buffer, |
164 | uint32_t const len) { |
165 | |
166 | readwriterc_t rc; |
167 | |
168 | rc = write(fileP->fd, buffer, len); |
169 | |
170 | return (rc > 0 && (uint32_t)rc == len); |
171 | } |
172 | |
173 | |
174 | |
175 | int32_t |
176 | FileRead(const TFile * const fileP, |
177 | void * const buffer, |
178 | uint32_t const len) { |
179 | |
180 | return read(fileP->fd, buffer, len); |
181 | } |
182 | |
183 | |
184 | |
185 | bool |
186 | FileSeek(const TFile * const fileP, |
187 | uint64_t const pos, |
188 | uint32_t const attrib) { |
189 | |
190 | int64_t rc; |
191 | #if MSVCRT0 |
192 | rc = _lseeki64(fileP->fd, pos, attrib); |
193 | #else |
194 | rc = lseek(fileP->fd, pos, attrib); |
195 | #endif |
196 | return (rc >= 0); |
197 | } |
198 | |
199 | |
200 | |
201 | uint64_t |
202 | FileSize(const TFile * const fileP) { |
203 | |
204 | #if MSVCRT0 |
205 | return (_filelength(fileP->fd)); |
206 | #else |
207 | struct stat fs; |
208 | |
209 | fstat(fileP->fd, &fs); |
210 | return (fs.st_size); |
211 | #endif |
212 | } |
213 | |
214 | |
215 | |
216 | bool |
217 | FileClose(TFile * const fileP) { |
218 | |
219 | int rc; |
220 | |
221 | rc = close(fileP->fd); |
222 | |
223 | if (rc >= 0) |
224 | free(fileP); |
225 | |
226 | return (rc >= 0); |
227 | } |
228 | |
229 | |
230 | |
231 | bool |
232 | FileStat(const char * const filename, |
233 | TFileStat * const filestat) { |
234 | |
235 | int rc; |
236 | |
237 | #if MSVCRT0 |
238 | rc = _stati64(filename,filestat); |
239 | #else |
240 | rc = stat(filename,filestat); |
241 | #endif |
242 | return (rc >= 0); |
243 | } |
244 | |
245 | |
246 | |
247 | static void |
248 | fileFindFirstWin(TFileFind * const filefindP ATTR_UNUSED__attribute__((__unused__)), |
249 | const char * const path, |
250 | TFileInfo * const fileinfo ATTR_UNUSED__attribute__((__unused__)), |
251 | bool * const retP ATTR_UNUSED__attribute__((__unused__))) { |
252 | const char * search; |
253 | |
254 | xmlrpc_asprintf(&search, "%s\\*", path); |
255 | |
256 | #if MSVCRT0 |
257 | filefindP->handle = _findfirsti64(search, fileinfo); |
258 | *retP = filefindP->handle != -1; |
259 | #else |
260 | #ifdef WIN32 |
261 | filefindP->handle = FindFirstFile(search, &fileinfo->data); |
262 | *retP = filefindP->handle != INVALID_HANDLE_VALUE; |
263 | if (*retP) { |
264 | LARGE_INTEGER li; |
265 | li.LowPart = fileinfo->data.nFileSizeLow; |
266 | li.HighPart = fileinfo->data.nFileSizeHigh; |
267 | strcpy( fileinfo->name, fileinfo->data.cFileName ); |
268 | fileinfo->attrib = fileinfo->data.dwFileAttributes; |
269 | fileinfo->size = li.QuadPart; |
270 | fileinfo->time_write = fileinfo->data.ftLastWriteTime.dwLowDateTime; |
271 | } |
272 | #endif |
273 | #endif |
274 | xmlrpc_strfree(search); |
275 | } |
276 | |
277 | |
278 | |
279 | static void |
280 | fileFindFirstPosix(TFileFind * const filefindP, |
281 | const char * const path, |
282 | TFileInfo * const fileinfo, |
283 | bool * const retP) { |
284 | |
285 | #if !MSVCRT0 |
286 | strncpy(filefindP->path, path, NAME_MAX)__builtin_strncpy (filefindP->path, path, 255); |
287 | filefindP->path[NAME_MAX255] = '\0'; |
288 | filefindP->handle = opendir(path); |
289 | if (filefindP->handle) |
290 | *retP = FileFindNext(filefindP, fileinfo); |
291 | else |
292 | *retP = FALSE0; |
293 | #endif |
294 | } |
295 | |
296 | |
297 | |
298 | bool |
299 | FileFindFirst(TFileFind ** const filefindPP, |
300 | const char * const path, |
301 | TFileInfo * const fileinfo) { |
302 | |
303 | bool succeeded; |
304 | |
305 | TFileFind * filefindP; |
306 | |
307 | MALLOCVAR(filefindP)filefindP = malloc(sizeof(*filefindP)); |
308 | |
309 | if (filefindP == NULL((void*)0)) |
310 | succeeded = FALSE0; |
311 | else { |
312 | if (win32) |
313 | fileFindFirstWin(filefindP, path, fileinfo, &succeeded); |
314 | else |
315 | fileFindFirstPosix(filefindP, path, fileinfo, &succeeded); |
316 | if (!succeeded) |
317 | free(filefindP); |
318 | } |
319 | *filefindPP = filefindP; |
320 | |
321 | return succeeded; |
322 | } |
323 | |
324 | |
325 | |
326 | static void |
327 | fileFindNextWin(TFileFind * const filefindP ATTR_UNUSED__attribute__((__unused__)), |
328 | TFileInfo * const fileinfo ATTR_UNUSED__attribute__((__unused__)), |
329 | bool * const retvalP ATTR_UNUSED__attribute__((__unused__))) { |
330 | |
331 | #if MSVCRT0 |
332 | *retvalP = _findnexti64(filefindP->handle, fileinfo) != -1; |
333 | #else |
334 | #ifdef WIN32 |
335 | bool found; |
336 | found = FindNextFile(filefindP->handle, &fileinfo->data); |
337 | if (found) { |
338 | LARGE_INTEGER li; |
339 | li.LowPart = fileinfo->data.nFileSizeLow; |
340 | li.HighPart = fileinfo->data.nFileSizeHigh; |
341 | strcpy(fileinfo->name, fileinfo->data.cFileName); |
342 | fileinfo->attrib = fileinfo->data.dwFileAttributes; |
343 | fileinfo->size = li.QuadPart; |
344 | fileinfo->time_write = fileinfo->data.ftLastWriteTime.dwLowDateTime; |
345 | } |
346 | *retvalP = found; |
347 | #endif |
348 | #endif |
349 | } |
350 | |
351 | |
352 | |
353 | static void |
354 | fileFindNextPosix(TFileFind * const filefindP, |
355 | TFileInfo * const fileinfoP, |
356 | bool * const retvalP) { |
357 | |
358 | #ifndef WIN32 |
359 | struct dirent * deP; |
360 | |
361 | deP = readdir(filefindP->handle); |
362 | if (deP) { |
| 3 | | Assuming 'deP' is non-null | |
|
| |
363 | char z[NAME_MAX255+1]; |
364 | struct stat fs; |
365 | |
366 | strcpy(fileinfoP->name, deP->d_name); |
367 | strcpy(z, filefindP->path); |
368 | strncat(z, "/",NAME_MAX)__builtin_strncat (z, "/", 255); |
369 | strncat(z, fileinfoP->name, NAME_MAX)__builtin_strncat (z, fileinfoP->name, 255); |
| 5 | | Within the expansion of the macro 'strncat':
|
a | Size argument is greater than the free space in the destination buffer |
|
370 | z[NAME_MAX255] = '\0'; |
371 | |
372 | stat(z, &fs); |
373 | |
374 | if (fs.st_mode & S_IFDIR0040000) |
375 | fileinfoP->attrib = A_SUBDIR1; |
376 | else |
377 | fileinfoP->attrib = 0; |
378 | |
379 | fileinfoP->size = fs.st_size; |
380 | fileinfoP->time_write = fs.st_mtimest_mtim.tv_sec; |
381 | |
382 | *retvalP = TRUE1; |
383 | } else |
384 | *retvalP = FALSE0; |
385 | #endif |
386 | } |
387 | |
388 | |
389 | |
390 | bool |
391 | FileFindNext(TFileFind * const filefindP, |
392 | TFileInfo * const fileinfo) { |
393 | |
394 | bool retval; |
395 | |
396 | if (win32) |
| |
397 | fileFindNextWin(filefindP, fileinfo, &retval); |
398 | else |
399 | fileFindNextPosix(filefindP, fileinfo, &retval); |
| 2 | | Calling 'fileFindNextPosix' | |
|
400 | |
401 | return retval; |
402 | } |
403 | |
404 | |
405 | |
406 | void |
407 | FileFindClose(TFileFind * const filefindP) { |
408 | #ifdef WIN32 |
409 | #if MSVCRT0 |
410 | _findclose(filefindP->handle); |
411 | #else |
412 | FindClose(filefindP->handle); |
413 | #endif |
414 | #else |
415 | closedir(filefindP->handle); |
416 | #endif |
417 | free(filefindP); |
418 | } |