]>
git.ipfire.org Git - thirdparty/cups.git/blob - cups/dir.c
2 * "$Id: dir.c 7279 2008-01-31 01:50:44Z mike $"
4 * Public directory routines for the Common UNIX Printing System (CUPS).
6 * This set of APIs abstracts enumeration of directory entries.
8 * Copyright 2007-2008 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...
42 * Windows implementation...
49 * Types and structures...
52 struct _cups_dir_s
/**** Directory data structure ****/
54 char directory
[1024]; /* Directory filename */
55 HANDLE dir
; /* Directory handle */
56 cups_dentry_t entry
; /* Directory entry */
61 * '_cups_dir_time()' - Convert a FILETIME value to a UNIX time value.
64 time_t /* O - UNIX time */
65 _cups_dir_time(FILETIME ft
) /* I - File time */
67 ULONGLONG val
; /* File time in 0.1 usecs */
71 * Convert file time (1/10 microseconds since Jan 1, 1601) to UNIX
72 * time (seconds since Jan 1, 1970). There are 11,644,732,800 seconds
76 val
= ft
.dwLowDateTime
+ (ft
.dwHighDateTime
<< 32);
77 return ((time_t)(val
/ 10000000 - 11644732800));
82 * 'cupsDirClose()' - Close a directory.
88 cupsDirClose(cups_dir_t
*dp
) /* I - Directory pointer */
91 * Range check input...
98 * Close an open directory handle...
101 if (dp
->dir
!= INVALID_HANDLE_VALUE
)
105 * Free memory used...
113 * 'cupsDirOpen()' - Open a directory.
118 cups_dir_t
* /* O - Directory pointer or @code NULL@ if the directory could not be opened. */
119 cupsDirOpen(const char *directory
) /* I - Directory name */
121 cups_dir_t
*dp
; /* Directory */
125 * Range check input...
132 * Allocate memory for the directory structure...
135 dp
= (cups_dir_t
*)calloc(1, sizeof(cups_dir_t
));
140 * Copy the directory name for later use...
143 dp
->dir
= INVALID_HANDLE_VALUE
;
145 strlcpy(dp
->directory
, directory
, sizeof(dp
->directory
));
148 * Return the new directory structure...
156 * 'cupsDirRead()' - Read the next directory entry.
161 cups_dentry_t
* /* O - Directory entry or @code NULL@ if there are no more */
162 cupsDirRead(cups_dir_t
*dp
) /* I - Directory pointer */
164 WIN32_FIND_DATA entry
; /* Directory entry data */
168 * Range check input...
175 * See if we have already started finding files...
178 if (dp
->dir
== INVALID_HANDLE_VALUE
)
181 * No, find the first file...
184 dp
->dir
= FindFirstFile(dp
->directory
, &entry
);
185 if (dp
->dir
== INVALID_HANDLE_VALUE
)
188 else if (!FindNextFile(dp
->dir
, &entry
))
192 * Copy the name over and convert the file information...
195 strlcpy(dp
->entry
.filename
, entry
.cFileName
, sizeof(dp
->entry
.filename
));
197 if (entry
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
198 dp
->entry
.fileinfo
.st_mode
= 0755 | S_IFDIR
;
200 dp
->entry
.fileinfo
.st_mode
= 0644;
202 dp
->entry
.fileinfo
.st_atime
= _cups_dir_time(entry
.ftLastAccessTime
);
203 dp
->entry
.fileinfo
.st_ctime
= _cups_dir_time(entry
.ftCreationTime
);
204 dp
->entry
.fileinfo
.st_mtime
= _cups_dir_time(entry
.ftLastWriteTime
);
205 dp
->entry
.fileinfo
.st_size
= entry
.nFileSizeLow
+ (entry
.nFileSizeHigh
<< 32);
208 * Return the entry...
211 return (&(dp
->entry
));
216 * 'cupsDirRewind()' - Rewind to the start of the directory.
222 cupsDirRewind(cups_dir_t
*dp
) /* I - Directory pointer */
225 * Range check input...
232 * Close an open directory handle...
235 if (dp
->dir
!= INVALID_HANDLE_VALUE
)
238 dp
->dir
= INVALID_HANDLE_VALUE
;
246 * POSIX implementation...
249 # include <sys/types.h>
254 * Types and structures...
257 struct _cups_dir_s
/**** Directory data structure ****/
259 char directory
[1024]; /* Directory filename */
260 DIR *dir
; /* Directory file */
261 cups_dentry_t entry
; /* Directory entry */
266 * 'cupsDirClose()' - Close a directory.
272 cupsDirClose(cups_dir_t
*dp
) /* I - Directory pointer */
274 DEBUG_printf(("cupsDirClose(dp=%p)\n", dp
));
277 * Range check input...
284 * Close the directory and free memory...
293 * 'cupsDirOpen()' - Open a directory.
298 cups_dir_t
* /* O - Directory pointer or @code NULL@ if the directory could not be opened. */
299 cupsDirOpen(const char *directory
) /* I - Directory name */
301 cups_dir_t
*dp
; /* Directory */
304 DEBUG_printf(("cupsDirOpen(directory=\"%s\")\n", directory
));
307 * Range check input...
314 * Allocate memory for the directory structure...
317 dp
= (cups_dir_t
*)calloc(1, sizeof(cups_dir_t
));
322 * Open the directory...
325 dp
->dir
= opendir(directory
);
333 * Copy the directory name for later use...
336 strlcpy(dp
->directory
, directory
, sizeof(dp
->directory
));
339 * Return the new directory structure...
347 * 'cupsDirRead()' - Read the next directory entry.
352 cups_dentry_t
* /* O - Directory entry or @code NULL@ when there are no more */
353 cupsDirRead(cups_dir_t
*dp
) /* I - Directory pointer */
355 struct dirent
*entry
; /* Pointer to entry */
356 char filename
[1024]; /* Full filename */
357 # ifdef HAVE_PTHREAD_H
358 char buffer
[sizeof(struct dirent
) + 1024];
359 /* Directory entry buffer */
360 # endif /* HAVE_PTHREAD_H */
363 DEBUG_printf(("cupsDirRead(dp=%p)\n", dp
));
366 * Range check input...
373 * Try reading an entry that is not "." or ".."...
378 # ifdef HAVE_PTHREAD_H
380 * Read the next entry using the reentrant version of readdir...
383 if (readdir_r(dp
->dir
, (struct dirent
*)buffer
, &entry
))
385 DEBUG_printf((" readdir_r() failed - %s\n", strerror(errno
)));
391 DEBUG_puts(" readdir_r() returned a NULL pointer!");
395 DEBUG_printf((" readdir_r() returned \"%s\"...\n", entry
->d_name
));
399 * Read the next entry using the original version of readdir...
402 if ((entry
= readdir(dp
->dir
)) == NULL
)
404 DEBUG_puts(" readdir() returned a NULL pointer!");
408 DEBUG_printf((" readdir() returned \"%s\"...\n", entry
->d_name
));
410 # endif /* HAVE_PTHREAD_H */
413 * Skip "." and ".."...
416 if (!strcmp(entry
->d_name
, ".") || !strcmp(entry
->d_name
, ".."))
420 * Copy the name over and get the file information...
423 strlcpy(dp
->entry
.filename
, entry
->d_name
, sizeof(dp
->entry
.filename
));
425 snprintf(filename
, sizeof(filename
), "%s/%s", dp
->directory
, entry
->d_name
);
427 if (stat(filename
, &(dp
->entry
.fileinfo
)))
429 DEBUG_printf((" stat() failed for \"%s\" - %s...\n", filename
,
435 * Return the entry...
438 return (&(dp
->entry
));
444 * 'cupsDirRewind()' - Rewind to the start of the directory.
450 cupsDirRewind(cups_dir_t
*dp
) /* I - Directory pointer */
452 DEBUG_printf(("cupsDirRewind(dp=%p)\n", dp
));
455 * Range check input...
462 * Rewind the directory...
472 * End of "$Id: dir.c 7279 2008-01-31 01:50:44Z mike $".