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