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