]> git.ipfire.org Git - thirdparty/cups.git/blame - cups/dir.c
Load cups into easysw/current.
[thirdparty/cups.git] / cups / dir.c
CommitLineData
ef416fc2 1/*
f7faf1f5 2 * "$Id$"
ef416fc2 3 *
4 * Public directory routines for the Common UNIX Printing System (CUPS).
5 *
6 * This set of APIs abstracts enumeration of directory entries.
7 *
bc44d920 8 * Copyright 2007 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
34#include "dir.h"
35#include "string.h"
36#include "debug.h"
37#include <stdlib.h>
38#include <errno.h>
39
40
41/*
42 * Windows implementation...
43 */
44
45#ifdef WIN32
46# include <windows.h>
47
48/*
49 * Types and structures...
50 */
51
52struct _cups_dir_s /**** Directory data structure ****/
53{
54 char directory[1024]; /* Directory filename */
55 HANDLE dir; /* Directory handle */
56 cups_dentry_t entry; /* Directory entry */
57};
58
59
60/*
61 * '_cups_dir_time()' - Convert a FILETIME value to a UNIX time value.
62 */
63
64time_t /* O - UNIX time */
65_cups_dir_time(FILETIME ft) /* I - File time */
66{
67 ULONGLONG val; /* File time in 0.1 usecs */
68
69
70 /*
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
73 * between them...
74 */
75
76 val = ft.dwLowDateTime + (ft.dwHighDateTime << 32);
77 return ((time_t)(val / 10000000 - 11644732800));
78}
79
80
81/*
82 * 'cupsDirClose()' - Close a directory.
83 */
84
85void
86cupsDirClose(cups_dir_t *dp) /* I - Directory */
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.
112 */
113
114cups_dir_t * /* O - Directory */
115cupsDirOpen(const char *directory) /* I - Directory name */
116{
117 cups_dir_t *dp; /* Directory */
118
119
120 /*
121 * Range check input...
122 */
123
124 if (!directory)
125 return (NULL);
126
127 /*
128 * Allocate memory for the directory structure...
129 */
130
131 dp = (cups_dir_t *)calloc(1, sizeof(cups_dir_t));
132 if (!dp)
133 return (NULL);
134
135 /*
136 * Copy the directory name for later use...
137 */
138
139 dp->dir = INVALID_HANDLE_VALUE;
140
141 strlcpy(dp->directory, directory, sizeof(dp->directory));
142
143 /*
144 * Return the new directory structure...
145 */
146
147 return (dp);
148}
149
150
151/*
152 * 'cupsDirRead()' - Read the next directory entry.
153 */
154
155cups_dentry_t * /* O - Directory entry */
156cupsDirRead(cups_dir_t *dp) /* I - Directory */
157{
158 WIN32_FIND_DATA entry; /* Directory entry data */
159
160
161 /*
162 * Range check input...
163 */
164
165 if (!dp)
166 return (NULL);
167
168 /*
169 * See if we have already started finding files...
170 */
171
172 if (dp->dir == INVALID_HANDLE_VALUE)
173 {
174 /*
175 * No, find the first file...
176 */
177
178 dp->dir = FindFirstFile(dp->directory, &entry);
179 if (dp->dir == INVALID_HANDLE_VALUE)
180 return (NULL);
181 }
182 else if (!FindNextFile(dp->dir, &entry))
183 return (NULL);
184
185 /*
186 * Copy the name over and convert the file information...
187 */
188
189 strlcpy(dp->entry.filename, entry.cFileName, sizeof(dp->entry.filename));
190
191 if (entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
192 dp->entry.fileinfo.st_mode = 0755 | S_IFDIR;
193 else
194 dp->entry.fileinfo.st_mode = 0644;
195
196 dp->entry.fileinfo.st_atime = _cups_dir_time(entry.ftLastAccessTime);
197 dp->entry.fileinfo.st_ctime = _cups_dir_time(entry.ftCreationTime);
198 dp->entry.fileinfo.st_mtime = _cups_dir_time(entry.ftLastWriteTime);
199 dp->entry.fileinfo.st_size = entry.nFileSizeLow + (entry.nFileSizeHigh << 32);
200
201 /*
202 * Return the entry...
203 */
204
205 return (&(dp->entry));
206}
207
208
209/*
210 * 'cupsDirRewind()' - Rewind to the start of the directory.
211 */
212
213void
214cupsDirRewind(cups_dir_t *dp) /* I - Directory */
215{
216 /*
217 * Range check input...
218 */
219
220 if (!dp)
221 return;
222
223 /*
224 * Close an open directory handle...
225 */
226
227 if (dp->dir != INVALID_HANDLE_VALUE)
228 {
229 FindClose(dp->dir);
230 dp->dir = INVALID_HANDLE_VALUE;
231 }
232}
233
234
235#else
236
237/*
238 * POSIX implementation...
239 */
240
241# include <sys/types.h>
242# include <dirent.h>
243
244
245/*
246 * Types and structures...
247 */
248
249struct _cups_dir_s /**** Directory data structure ****/
250{
251 char directory[1024]; /* Directory filename */
252 DIR *dir; /* Directory file */
253 cups_dentry_t entry; /* Directory entry */
254};
255
256
257/*
258 * 'cupsDirClose()' - Close a directory.
259 */
260
261void
262cupsDirClose(cups_dir_t *dp) /* I - Directory */
263{
264 DEBUG_printf(("cupsDirClose(dp=%p)\n", dp));
265
266 /*
267 * Range check input...
268 */
269
270 if (!dp)
271 return;
272
273 /*
274 * Close the directory and free memory...
275 */
276
277 closedir(dp->dir);
278 free(dp);
279}
280
281
282/*
283 * 'cupsDirOpen()' - Open a directory.
284 */
285
286cups_dir_t * /* O - Directory */
287cupsDirOpen(const char *directory) /* I - Directory name */
288{
289 cups_dir_t *dp; /* Directory */
290
291
292 DEBUG_printf(("cupsDirOpen(directory=\"%s\")\n", directory));
293
294 /*
295 * Range check input...
296 */
297
298 if (!directory)
299 return (NULL);
300
301 /*
302 * Allocate memory for the directory structure...
303 */
304
305 dp = (cups_dir_t *)calloc(1, sizeof(cups_dir_t));
306 if (!dp)
307 return (NULL);
308
309 /*
310 * Open the directory...
311 */
312
313 dp->dir = opendir(directory);
314 if (!dp->dir)
315 {
316 free(dp);
317 return (NULL);
318 }
319
320 /*
321 * Copy the directory name for later use...
322 */
323
324 strlcpy(dp->directory, directory, sizeof(dp->directory));
325
326 /*
327 * Return the new directory structure...
328 */
329
330 return (dp);
331}
332
333
334/*
335 * 'cupsDirRead()' - Read the next directory entry.
336 */
337
338cups_dentry_t * /* O - Directory entry */
339cupsDirRead(cups_dir_t *dp) /* I - Directory */
340{
ef416fc2 341 struct dirent *entry; /* Pointer to entry */
342 char filename[1024]; /* Full filename */
2abf387c 343# ifdef HAVE_PTHREAD_H
344 char buffer[sizeof(struct dirent) + 1024];
345 /* Directory entry buffer */
346# endif /* HAVE_PTHREAD_H */
ef416fc2 347
348
349 DEBUG_printf(("cupsDirRead(dp=%p)\n", dp));
350
351 /*
352 * Range check input...
353 */
354
355 if (!dp)
356 return (NULL);
357
358 /*
359 * Try reading an entry that is not "." or ".."...
360 */
361
07725fee 362 for (;;)
ef416fc2 363 {
2abf387c 364# ifdef HAVE_PTHREAD_H
365 /*
366 * Read the next entry using the reentrant version of readdir...
367 */
368
ef416fc2 369 if (readdir_r(dp->dir, (struct dirent *)buffer, &entry))
370 {
371 DEBUG_printf((" readdir_r() failed - %s\n", strerror(errno)));
372 return (NULL);
373 }
374
375 if (!entry)
376 {
377 DEBUG_puts(" readdir_r() returned a NULL pointer!");
378 return (NULL);
379 }
380
381 DEBUG_printf((" readdir_r() returned \"%s\"...\n", entry->d_name));
ef416fc2 382
2abf387c 383# else
384 /*
385 * Read the next entry using the original version of readdir...
386 */
387
388 if ((entry = readdir(dp->dir)) == NULL)
389 {
390 DEBUG_puts(" readdir() returned a NULL pointer!");
391 return (NULL);
392 }
393
394 DEBUG_printf((" readdir() returned \"%s\"...\n", entry->d_name));
395
396# endif /* HAVE_PTHREAD_H */
397
398 /*
399 * Skip "." and ".."...
400 */
401
07725fee 402 if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, ".."))
403 continue;
ef416fc2 404
07725fee 405 /*
406 * Copy the name over and get the file information...
407 */
ef416fc2 408
07725fee 409 strlcpy(dp->entry.filename, entry->d_name, sizeof(dp->entry.filename));
ef416fc2 410
07725fee 411 snprintf(filename, sizeof(filename), "%s/%s", dp->directory, entry->d_name);
ef416fc2 412
07725fee 413 if (stat(filename, &(dp->entry.fileinfo)))
414 {
415 DEBUG_printf((" stat() failed for \"%s\" - %s...\n", filename,
416 strerror(errno)));
417 continue;
418 }
419
420 /*
421 * Return the entry...
422 */
423
424 return (&(dp->entry));
425 }
ef416fc2 426}
427
428
429/*
430 * 'cupsDirRewind()' - Rewind to the start of the directory.
431 */
432
433void
434cupsDirRewind(cups_dir_t *dp) /* I - Directory */
435{
436 DEBUG_printf(("cupsDirRewind(dp=%p)\n", dp));
437
438 /*
439 * Range check input...
440 */
441
442 if (!dp)
443 return;
444
445 /*
446 * Rewind the directory...
447 */
448
449 rewinddir(dp->dir);
450}
451
452
453#endif /* WIN32 */
454
455/*
f7faf1f5 456 * End of "$Id$".
ef416fc2 457 */