]>
git.ipfire.org Git - thirdparty/cups.git/blob - cups/dir.c
4 * Directory routines for CUPS.
6 * This set of APIs abstracts enumeration of directory entries.
8 * Copyright 2007-2012 by Apple Inc.
9 * Copyright 1997-2005 by Easy Software Products, all rights reserved.
11 * These coded instructions, statements, and computer programs are the
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/".
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.
31 * Include necessary headers...
34 #include "string-private.h"
35 #include "debug-private.h"
40 * Windows implementation...
47 * Types and structures...
50 struct _cups_dir_s
/**** Directory data structure ****/
52 char directory
[1024]; /* Directory filename */
53 HANDLE dir
; /* Directory handle */
54 cups_dentry_t entry
; /* Directory entry */
59 * '_cups_dir_time()' - Convert a FILETIME value to a UNIX time value.
62 time_t /* O - UNIX time */
63 _cups_dir_time(FILETIME ft
) /* I - File time */
65 ULONGLONG val
; /* File time in 0.1 usecs */
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
74 val
= ft
.dwLowDateTime
+ ((ULONGLONG
)ft
.dwHighDateTime
<< 32);
75 return ((time_t)(val
/ 10000000 - 11644732800));
80 * 'cupsDirClose()' - Close a directory.
82 * @since CUPS 1.2/OS X 10.5@
86 cupsDirClose(cups_dir_t
*dp
) /* I - Directory pointer */
89 * Range check input...
96 * Close an open directory handle...
99 if (dp
->dir
!= INVALID_HANDLE_VALUE
)
103 * Free memory used...
111 * 'cupsDirOpen()' - Open a directory.
113 * @since CUPS 1.2/OS X 10.5@
116 cups_dir_t
* /* O - Directory pointer or @code NULL@ if the directory could not be opened. */
117 cupsDirOpen(const char *directory
) /* I - Directory name */
119 cups_dir_t
*dp
; /* Directory */
123 * Range check input...
130 * Allocate memory for the directory structure...
133 dp
= (cups_dir_t
*)calloc(1, sizeof(cups_dir_t
));
138 * Copy the directory name for later use...
141 dp
->dir
= INVALID_HANDLE_VALUE
;
143 strlcpy(dp
->directory
, directory
, sizeof(dp
->directory
));
146 * Return the new directory structure...
154 * 'cupsDirRead()' - Read the next directory entry.
156 * @since CUPS 1.2/OS X 10.5@
159 cups_dentry_t
* /* O - Directory entry or @code NULL@ if there are no more */
160 cupsDirRead(cups_dir_t
*dp
) /* I - Directory pointer */
162 WIN32_FIND_DATA entry
; /* Directory entry data */
166 * Range check input...
173 * See if we have already started finding files...
176 if (dp
->dir
== INVALID_HANDLE_VALUE
)
179 * No, find the first file...
182 dp
->dir
= FindFirstFile(dp
->directory
, &entry
);
183 if (dp
->dir
== INVALID_HANDLE_VALUE
)
186 else if (!FindNextFile(dp
->dir
, &entry
))
190 * Copy the name over and convert the file information...
193 strlcpy(dp
->entry
.filename
, entry
.cFileName
, sizeof(dp
->entry
.filename
));
195 if (entry
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
196 dp
->entry
.fileinfo
.st_mode
= 0755 | S_IFDIR
;
198 dp
->entry
.fileinfo
.st_mode
= 0644;
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
);
203 dp
->entry
.fileinfo
.st_size
= entry
.nFileSizeLow
+ ((unsigned long long)entry
.nFileSizeHigh
<< 32);
206 * Return the entry...
209 return (&(dp
->entry
));
214 * 'cupsDirRewind()' - Rewind to the start of the directory.
216 * @since CUPS 1.2/OS X 10.5@
220 cupsDirRewind(cups_dir_t
*dp
) /* I - Directory pointer */
223 * Range check input...
230 * Close an open directory handle...
233 if (dp
->dir
!= INVALID_HANDLE_VALUE
)
236 dp
->dir
= INVALID_HANDLE_VALUE
;
244 * POSIX implementation...
247 # include <sys/types.h>
252 * Types and structures...
255 struct _cups_dir_s
/**** Directory data structure ****/
257 char directory
[1024]; /* Directory filename */
258 DIR *dir
; /* Directory file */
259 cups_dentry_t entry
; /* Directory entry */
264 * 'cupsDirClose()' - Close a directory.
266 * @since CUPS 1.2/OS X 10.5@
270 cupsDirClose(cups_dir_t
*dp
) /* I - Directory pointer */
272 DEBUG_printf(("cupsDirClose(dp=%p)", dp
));
275 * Range check input...
282 * Close the directory and free memory...
291 * 'cupsDirOpen()' - Open a directory.
293 * @since CUPS 1.2/OS X 10.5@
296 cups_dir_t
* /* O - Directory pointer or @code NULL@ if the directory could not be opened. */
297 cupsDirOpen(const char *directory
) /* I - Directory name */
299 cups_dir_t
*dp
; /* Directory */
302 DEBUG_printf(("cupsDirOpen(directory=\"%s\")", directory
));
305 * Range check input...
312 * Allocate memory for the directory structure...
315 dp
= (cups_dir_t
*)calloc(1, sizeof(cups_dir_t
));
320 * Open the directory...
323 dp
->dir
= opendir(directory
);
331 * Copy the directory name for later use...
334 strlcpy(dp
->directory
, directory
, sizeof(dp
->directory
));
337 * Return the new directory structure...
345 * 'cupsDirRead()' - Read the next directory entry.
347 * @since CUPS 1.2/OS X 10.5@
350 cups_dentry_t
* /* O - Directory entry or @code NULL@ when there are no more */
351 cupsDirRead(cups_dir_t
*dp
) /* I - Directory pointer */
353 struct dirent
*entry
; /* Pointer to entry */
354 char filename
[1024]; /* Full filename */
355 # ifdef HAVE_PTHREAD_H
356 char buffer
[sizeof(struct dirent
) + 1024];
357 /* Directory entry buffer */
358 # endif /* HAVE_PTHREAD_H */
361 DEBUG_printf(("2cupsDirRead(dp=%p)", dp
));
364 * Range check input...
371 * Try reading an entry that is not "." or ".."...
376 # ifdef HAVE_PTHREAD_H
378 * Read the next entry using the reentrant version of readdir...
381 if (readdir_r(dp
->dir
, (struct dirent
*)buffer
, &entry
))
383 DEBUG_printf(("3cupsDirRead: readdir_r() failed - %s\n", strerror(errno
)));
389 DEBUG_puts("3cupsDirRead: readdir_r() returned a NULL pointer!");
393 DEBUG_printf(("4cupsDirRead: readdir_r() returned \"%s\"...",
398 * Read the next entry using the original version of readdir...
401 if ((entry
= readdir(dp
->dir
)) == NULL
)
403 DEBUG_puts("3cupsDirRead: readdir() returned a NULL pointer!");
407 DEBUG_printf(("4cupsDirRead: readdir() returned \"%s\"...", entry
->d_name
));
409 # endif /* HAVE_PTHREAD_H */
412 * Skip "." and ".."...
415 if (!strcmp(entry
->d_name
, ".") || !strcmp(entry
->d_name
, ".."))
419 * Copy the name over and get the file information...
422 strlcpy(dp
->entry
.filename
, entry
->d_name
, sizeof(dp
->entry
.filename
));
424 snprintf(filename
, sizeof(filename
), "%s/%s", dp
->directory
, entry
->d_name
);
426 if (stat(filename
, &(dp
->entry
.fileinfo
)))
428 DEBUG_printf(("3cupsDirRead: stat() failed for \"%s\" - %s...", filename
,
434 * Return the entry...
437 return (&(dp
->entry
));
443 * 'cupsDirRewind()' - Rewind to the start of the directory.
445 * @since CUPS 1.2/OS X 10.5@
449 cupsDirRewind(cups_dir_t
*dp
) /* I - Directory pointer */
451 DEBUG_printf(("cupsDirRewind(dp=%p)", dp
));
454 * Range check input...
461 * Rewind the directory...