]> git.ipfire.org Git - thirdparty/cups.git/blame - cups/dir.c
Import experimental work-in-progress HTTP/2 branch
[thirdparty/cups.git] / cups / dir.c
CommitLineData
ef416fc2 1/*
354aadbe 2 * "$Id: dir.c 10996 2013-05-29 11:51:34Z msweet $"
ef416fc2 3 *
71e16022 4 * Directory routines for CUPS.
ef416fc2 5 *
6 * This set of APIs abstracts enumeration of directory entries.
7 *
f3c17241 8 * Copyright 2007-2012 by Apple Inc.
ef416fc2 9 * Copyright 1997-2005 by Easy Software Products, all rights reserved.
10 *
11 * These coded instructions, statements, and computer programs are the
bc44d920 12 * property of Apple Inc. and are protected by Federal copyright
13 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
14 * which should have been included with this file. If this file is
15 * file is missing or damaged, see the license at "http://www.cups.org/".
ef416fc2 16 *
17 * Contents:
18 *
19 * _cups_dir_time() - Convert a FILETIME value to a UNIX time value.
20 * cupsDirClose() - Close a directory.
21 * cupsDirOpen() - Open a directory.
22 * cupsDirRead() - Read the next directory entry.
23 * cupsDirRewind() - Rewind to the start of the directory.
24 * cupsDirClose() - Close a directory.
25 * cupsDirOpen() - Open a directory.
26 * cupsDirRead() - Read the next directory entry.
27 * cupsDirRewind() - Rewind to the start of the directory.
28 */
29
30/*
31 * Include necessary headers...
32 */
33
71e16022
MS
34#include "string-private.h"
35#include "debug-private.h"
ef416fc2 36#include "dir.h"
ef416fc2 37
38
39/*
40 * Windows implementation...
41 */
42
43#ifdef WIN32
44# include <windows.h>
45
46/*
47 * Types and structures...
48 */
49
50struct _cups_dir_s /**** Directory data structure ****/
51{
52 char directory[1024]; /* Directory filename */
53 HANDLE dir; /* Directory handle */
54 cups_dentry_t entry; /* Directory entry */
55};
56
57
58/*
59 * '_cups_dir_time()' - Convert a FILETIME value to a UNIX time value.
60 */
61
62time_t /* O - UNIX time */
63_cups_dir_time(FILETIME ft) /* I - File time */
64{
65 ULONGLONG val; /* File time in 0.1 usecs */
66
67
68 /*
69 * Convert file time (1/10 microseconds since Jan 1, 1601) to UNIX
70 * time (seconds since Jan 1, 1970). There are 11,644,732,800 seconds
71 * between them...
72 */
73
536bc2c6 74 val = ft.dwLowDateTime + ((ULONGLONG)ft.dwHighDateTime << 32);
ef416fc2 75 return ((time_t)(val / 10000000 - 11644732800));
76}
77
78
79/*
80 * 'cupsDirClose()' - Close a directory.
5a738aea 81 *
f3c17241 82 * @since CUPS 1.2/OS X 10.5@
ef416fc2 83 */
84
85void
5a738aea 86cupsDirClose(cups_dir_t *dp) /* I - Directory pointer */
ef416fc2 87{
88 /*
89 * Range check input...
90 */
91
92 if (!dp)
93 return;
94
95 /*
96 * Close an open directory handle...
97 */
98
99 if (dp->dir != INVALID_HANDLE_VALUE)
100 FindClose(dp->dir);
101
102 /*
103 * Free memory used...
104 */
105
106 free(dp);
107}
108
109
110/*
111 * 'cupsDirOpen()' - Open a directory.
5a738aea 112 *
f3c17241 113 * @since CUPS 1.2/OS X 10.5@
ef416fc2 114 */
115
5a738aea 116cups_dir_t * /* O - Directory pointer or @code NULL@ if the directory could not be opened. */
ef416fc2 117cupsDirOpen(const char *directory) /* I - Directory name */
118{
119 cups_dir_t *dp; /* Directory */
120
121
122 /*
123 * Range check input...
124 */
125
126 if (!directory)
127 return (NULL);
128
129 /*
130 * Allocate memory for the directory structure...
131 */
132
133 dp = (cups_dir_t *)calloc(1, sizeof(cups_dir_t));
134 if (!dp)
135 return (NULL);
136
137 /*
138 * Copy the directory name for later use...
139 */
140
141 dp->dir = INVALID_HANDLE_VALUE;
142
143 strlcpy(dp->directory, directory, sizeof(dp->directory));
144
145 /*
146 * Return the new directory structure...
147 */
148
149 return (dp);
150}
151
152
153/*
154 * 'cupsDirRead()' - Read the next directory entry.
5a738aea 155 *
f3c17241 156 * @since CUPS 1.2/OS X 10.5@
ef416fc2 157 */
158
5a738aea
MS
159cups_dentry_t * /* O - Directory entry or @code NULL@ if there are no more */
160cupsDirRead(cups_dir_t *dp) /* I - Directory pointer */
ef416fc2 161{
162 WIN32_FIND_DATA entry; /* Directory entry data */
163
164
165 /*
166 * Range check input...
167 */
168
169 if (!dp)
170 return (NULL);
171
172 /*
173 * See if we have already started finding files...
174 */
175
176 if (dp->dir == INVALID_HANDLE_VALUE)
177 {
178 /*
179 * No, find the first file...
180 */
181
182 dp->dir = FindFirstFile(dp->directory, &entry);
183 if (dp->dir == INVALID_HANDLE_VALUE)
184 return (NULL);
185 }
186 else if (!FindNextFile(dp->dir, &entry))
187 return (NULL);
188
189 /*
190 * Copy the name over and convert the file information...
191 */
192
193 strlcpy(dp->entry.filename, entry.cFileName, sizeof(dp->entry.filename));
194
195 if (entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
196 dp->entry.fileinfo.st_mode = 0755 | S_IFDIR;
197 else
198 dp->entry.fileinfo.st_mode = 0644;
199
200 dp->entry.fileinfo.st_atime = _cups_dir_time(entry.ftLastAccessTime);
201 dp->entry.fileinfo.st_ctime = _cups_dir_time(entry.ftCreationTime);
202 dp->entry.fileinfo.st_mtime = _cups_dir_time(entry.ftLastWriteTime);
7cf5915e 203 dp->entry.fileinfo.st_size = entry.nFileSizeLow + ((unsigned long long)entry.nFileSizeHigh << 32);
ef416fc2 204
205 /*
206 * Return the entry...
207 */
208
209 return (&(dp->entry));
210}
211
212
213/*
214 * 'cupsDirRewind()' - Rewind to the start of the directory.
5a738aea 215 *
f3c17241 216 * @since CUPS 1.2/OS X 10.5@
ef416fc2 217 */
218
219void
5a738aea 220cupsDirRewind(cups_dir_t *dp) /* I - Directory pointer */
ef416fc2 221{
222 /*
223 * Range check input...
224 */
225
226 if (!dp)
227 return;
228
229 /*
230 * Close an open directory handle...
231 */
232
233 if (dp->dir != INVALID_HANDLE_VALUE)
234 {
235 FindClose(dp->dir);
236 dp->dir = INVALID_HANDLE_VALUE;
237 }
238}
239
240
241#else
242
243/*
244 * POSIX implementation...
245 */
246
247# include <sys/types.h>
248# include <dirent.h>
249
250
251/*
252 * Types and structures...
253 */
254
255struct _cups_dir_s /**** Directory data structure ****/
256{
257 char directory[1024]; /* Directory filename */
258 DIR *dir; /* Directory file */
259 cups_dentry_t entry; /* Directory entry */
260};
261
262
263/*
264 * 'cupsDirClose()' - Close a directory.
5a738aea 265 *
f3c17241 266 * @since CUPS 1.2/OS X 10.5@
ef416fc2 267 */
268
269void
5a738aea 270cupsDirClose(cups_dir_t *dp) /* I - Directory pointer */
ef416fc2 271{
e07d4801 272 DEBUG_printf(("cupsDirClose(dp=%p)", dp));
ef416fc2 273
274 /*
275 * Range check input...
276 */
277
278 if (!dp)
279 return;
280
281 /*
282 * Close the directory and free memory...
283 */
284
285 closedir(dp->dir);
286 free(dp);
287}
288
289
290/*
291 * 'cupsDirOpen()' - Open a directory.
5a738aea 292 *
f3c17241 293 * @since CUPS 1.2/OS X 10.5@
ef416fc2 294 */
295
5a738aea 296cups_dir_t * /* O - Directory pointer or @code NULL@ if the directory could not be opened. */
ef416fc2 297cupsDirOpen(const char *directory) /* I - Directory name */
298{
299 cups_dir_t *dp; /* Directory */
300
301
e07d4801 302 DEBUG_printf(("cupsDirOpen(directory=\"%s\")", directory));
ef416fc2 303
304 /*
305 * Range check input...
306 */
307
308 if (!directory)
309 return (NULL);
310
311 /*
312 * Allocate memory for the directory structure...
313 */
314
315 dp = (cups_dir_t *)calloc(1, sizeof(cups_dir_t));
316 if (!dp)
317 return (NULL);
318
319 /*
320 * Open the directory...
321 */
322
323 dp->dir = opendir(directory);
324 if (!dp->dir)
325 {
326 free(dp);
327 return (NULL);
328 }
329
330 /*
331 * Copy the directory name for later use...
332 */
333
334 strlcpy(dp->directory, directory, sizeof(dp->directory));
335
336 /*
337 * Return the new directory structure...
338 */
339
340 return (dp);
341}
342
343
344/*
345 * 'cupsDirRead()' - Read the next directory entry.
5a738aea 346 *
f3c17241 347 * @since CUPS 1.2/OS X 10.5@
ef416fc2 348 */
349
5a738aea
MS
350cups_dentry_t * /* O - Directory entry or @code NULL@ when there are no more */
351cupsDirRead(cups_dir_t *dp) /* I - Directory pointer */
ef416fc2 352{
ef416fc2 353 struct dirent *entry; /* Pointer to entry */
354 char filename[1024]; /* Full filename */
2abf387c 355# ifdef HAVE_PTHREAD_H
356 char buffer[sizeof(struct dirent) + 1024];
357 /* Directory entry buffer */
358# endif /* HAVE_PTHREAD_H */
ef416fc2 359
360
e07d4801 361 DEBUG_printf(("2cupsDirRead(dp=%p)", dp));
ef416fc2 362
363 /*
364 * Range check input...
365 */
366
367 if (!dp)
368 return (NULL);
369
370 /*
371 * Try reading an entry that is not "." or ".."...
372 */
373
07725fee 374 for (;;)
ef416fc2 375 {
2abf387c 376# ifdef HAVE_PTHREAD_H
377 /*
378 * Read the next entry using the reentrant version of readdir...
379 */
380
ef416fc2 381 if (readdir_r(dp->dir, (struct dirent *)buffer, &entry))
382 {
e07d4801 383 DEBUG_printf(("3cupsDirRead: readdir_r() failed - %s\n", strerror(errno)));
ef416fc2 384 return (NULL);
385 }
386
387 if (!entry)
388 {
e07d4801 389 DEBUG_puts("3cupsDirRead: readdir_r() returned a NULL pointer!");
ef416fc2 390 return (NULL);
391 }
392
e07d4801
MS
393 DEBUG_printf(("4cupsDirRead: readdir_r() returned \"%s\"...",
394 entry->d_name));
ef416fc2 395
2abf387c 396# else
397 /*
398 * Read the next entry using the original version of readdir...
399 */
400
401 if ((entry = readdir(dp->dir)) == NULL)
402 {
e07d4801 403 DEBUG_puts("3cupsDirRead: readdir() returned a NULL pointer!");
2abf387c 404 return (NULL);
405 }
406
e07d4801 407 DEBUG_printf(("4cupsDirRead: readdir() returned \"%s\"...", entry->d_name));
2abf387c 408
409# endif /* HAVE_PTHREAD_H */
410
411 /*
412 * Skip "." and ".."...
413 */
414
07725fee 415 if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, ".."))
416 continue;
ef416fc2 417
07725fee 418 /*
419 * Copy the name over and get the file information...
420 */
ef416fc2 421
07725fee 422 strlcpy(dp->entry.filename, entry->d_name, sizeof(dp->entry.filename));
ef416fc2 423
07725fee 424 snprintf(filename, sizeof(filename), "%s/%s", dp->directory, entry->d_name);
ef416fc2 425
07725fee 426 if (stat(filename, &(dp->entry.fileinfo)))
427 {
e07d4801 428 DEBUG_printf(("3cupsDirRead: stat() failed for \"%s\" - %s...", filename,
07725fee 429 strerror(errno)));
430 continue;
431 }
432
433 /*
434 * Return the entry...
435 */
436
437 return (&(dp->entry));
438 }
ef416fc2 439}
440
441
442/*
443 * 'cupsDirRewind()' - Rewind to the start of the directory.
5a738aea 444 *
f3c17241 445 * @since CUPS 1.2/OS X 10.5@
ef416fc2 446 */
447
448void
5a738aea 449cupsDirRewind(cups_dir_t *dp) /* I - Directory pointer */
ef416fc2 450{
e07d4801 451 DEBUG_printf(("cupsDirRewind(dp=%p)", dp));
ef416fc2 452
453 /*
454 * Range check input...
455 */
456
457 if (!dp)
458 return;
459
460 /*
461 * Rewind the directory...
462 */
463
464 rewinddir(dp->dir);
465}
466
467
468#endif /* WIN32 */
469
470/*
354aadbe 471 * End of "$Id: dir.c 10996 2013-05-29 11:51:34Z msweet $".
ef416fc2 472 */