gwenhywfar  4.7.0beta
directory_all.c
Go to the documentation of this file.
1 /***************************************************************************
2  $RCSfile$
3  -------------------
4  cvs : $Id$
5  begin : Sun Nov 23 2003
6  copyright : (C) 2003 by Martin Preuss
7  email : martin@libchipcard.de
8 
9  ***************************************************************************
10  * *
11  * This library is free software; you can redistribute it and/or *
12  * modify it under the terms of the GNU Lesser General Public *
13  * License as published by the Free Software Foundation; either *
14  * version 2.1 of the License, or (at your option) any later version. *
15  * *
16  * This library is distributed in the hope that it will be useful, *
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
19  * Lesser General Public License for more details. *
20  * *
21  * You should have received a copy of the GNU Lesser General Public *
22  * License along with this library; if not, write to the Free Software *
23  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
24  * MA 02111-1307 USA *
25  * *
26  ***************************************************************************/
27 
28 
29 #ifdef HAVE_CONFIG_H
30 # include <config.h>
31 #endif
32 
33 
34 #include <gwenhywfar/directory.h>
35 #include <gwenhywfar/debug.h>
36 #include <gwenhywfar/path.h>
37 #include <gwenhywfar/buffer.h>
38 #include <gwenhywfar/text.h>
39 
40 #ifdef HAVE_UNISTD_H
41 # include <unistd.h>
42 #endif
43 #ifdef HAVE_SYS_STAT_H
44 # include <sys/stat.h>
45 #endif
46 #include <sys/types.h>
47 #ifdef HAVE_FCNTL_H
48 # include <fcntl.h>
49 #endif
50 #include <string.h>
51 #include <errno.h>
52 #include <assert.h>
53 #include <stdlib.h>
54 #include <ctype.h>
55 
56 #ifdef OS_WIN32
57 # define DIRSEP "\\"
58 #else
59 # define DIRSEP "/"
60 #endif
61 
62 
63 
64 void *GWEN_Directory_HandlePathElement(const char *entry,
65  void *data,
66  unsigned int flags){
67  char *p;
68  struct stat st;
69  int exists;
70  int withDrive;
71  GWEN_BUFFER *buf;
72  GWEN_BUFFER *ebuf = 0;
73 
74  withDrive=0;
75 
76 #ifdef OS_WIN32
77  if (entry && isalpha(*entry)) {
78  int len;
79 
80  /* append backslash if entry only consists of a drive specification */
81  len=strlen(entry);
82  if ( (len==2) && (entry[1] == ':') ) {
83  ebuf=GWEN_Buffer_new(0, len+2, 0, 1);
84  GWEN_Buffer_AppendString(ebuf, entry);
85  GWEN_Buffer_AppendByte(ebuf, '\\');
86  withDrive=1;
87  entry=GWEN_Buffer_GetStart(ebuf);
88  }
89  }
90 #endif /* OS_WIN32 */
91 
92  if (strcasecmp(entry, "..")==0) {
93  DBG_ERROR(GWEN_LOGDOMAIN, "\"..\" detected");
94  GWEN_Buffer_free(ebuf);
95  return 0;
96  }
97 
98  buf=(GWEN_BUFFER*)data;
99  if (GWEN_Buffer_GetUsedBytes(buf) && !withDrive) {
100  char c;
101 
103 #ifdef OS_WIN32
104  if (c!='\\')
105  GWEN_Buffer_AppendByte(buf, '\\');
106 #else
107  if (c!='/')
108  GWEN_Buffer_AppendByte(buf, '/');
109 #endif /* OS_WIN32 */
110  }
111  GWEN_Buffer_AppendString(buf, entry);
112 
113  /* check for existence of the file/folder */
114  p=GWEN_Buffer_GetStart(buf);
115  DBG_DEBUG(GWEN_LOGDOMAIN, "Checking path \"%s\"", p);
116  if (stat(p, &st)) {
117  exists=0;
118  DBG_DEBUG(GWEN_LOGDOMAIN, "stat: %s (%s)", strerror(errno), p);
119  if ((flags & GWEN_PATH_FLAGS_PATHMUSTEXIST) ||
120  ((flags & GWEN_PATH_FLAGS_LAST) &&
121  (flags & GWEN_PATH_FLAGS_NAMEMUSTEXIST))) {
122  DBG_INFO(GWEN_LOGDOMAIN, "Path \"%s\" does not exist (it should)", p);
123  GWEN_Buffer_free(ebuf);
124  return 0;
125  }
126  }
127  else {
128  DBG_DEBUG(GWEN_LOGDOMAIN, "Checking for type");
129  exists=1;
130  if (flags & GWEN_PATH_FLAGS_VARIABLE) {
131  if (!S_ISREG(st.st_mode)) {
132  DBG_INFO(GWEN_LOGDOMAIN, "%s not a regular file", p);
133  GWEN_Buffer_free(ebuf);
134  return 0;
135  }
136  }
137  else {
138  if (!S_ISDIR(st.st_mode)) {
139  DBG_INFO(GWEN_LOGDOMAIN, "%s not a direcory", p);
140  GWEN_Buffer_free(ebuf);
141  return 0;
142  }
143  }
144  if ((flags & GWEN_PATH_FLAGS_PATHMUSTNOTEXIST) ||
145  ((flags & GWEN_PATH_FLAGS_LAST) &&
147  DBG_INFO(GWEN_LOGDOMAIN, "Path \"%s\" exists (it should not)", p);
148  GWEN_Buffer_free(ebuf);
149  return 0;
150  }
151  } /* if stat is ok */
152 
153  if (!exists) {
154  int isPublic;
155 
156  DBG_DEBUG(GWEN_LOGDOMAIN, "Entry \"%s\" does not exist", p);
157 
158  isPublic=(
159  ((flags & GWEN_PATH_FLAGS_LAST) &&
160  (flags & GWEN_DIR_FLAGS_PUBLIC_NAME)) ||
161  (!(flags & GWEN_PATH_FLAGS_LAST) &&
162  (flags & GWEN_DIR_FLAGS_PUBLIC_PATH))
163  );
164 
165  if (flags & GWEN_PATH_FLAGS_VARIABLE) {
166  /* create file */
167  int fd;
168 
169  DBG_DEBUG(GWEN_LOGDOMAIN, "Creating file \"%s\"", p);
170  if (isPublic)
171  fd=open(p, O_RDWR | O_CREAT | O_TRUNC,
172  S_IRUSR | S_IWUSR
173 #ifdef S_IRGRP
174  | S_IRGRP
175 #endif
176 #ifdef S_IROTH
177  | S_IROTH
178 #endif
179  );
180  else
181  fd=open(p, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
182  if (fd==-1) {
183  DBG_ERROR(GWEN_LOGDOMAIN, "open: %s (%s)", strerror(errno), p);
184  GWEN_Buffer_free(ebuf);
185  return 0;
186  }
187  close(fd);
188  DBG_DEBUG(GWEN_LOGDOMAIN, "Successfully created");
189  }
190  else {
191  /* create dir */
192  DBG_DEBUG(GWEN_LOGDOMAIN, "Creating folder \"%s\"", p);
193 
194  if (isPublic) {
196  DBG_ERROR(GWEN_LOGDOMAIN, "Could not create directory \"%s\"", p);
197  GWEN_Buffer_free(ebuf);
198  return 0;
199  }
200  }
201  else {
202  if (GWEN_Directory_Create(p)) {
203  DBG_ERROR(GWEN_LOGDOMAIN, "Could not create directory \"%s\"", p);
204  GWEN_Buffer_free(ebuf);
205  return 0;
206  }
207  }
208  }
209  } /* if exists */
210  else {
211  DBG_DEBUG(GWEN_LOGDOMAIN, "Entry \"%s\" exists", p);
212  }
213  DBG_DEBUG(GWEN_LOGDOMAIN, "Returning this: %s", p);
214  GWEN_Buffer_free(ebuf);
215  return buf;
216 }
217 
218 
219 
220 int GWEN_Directory_GetPath(const char *path,
221  unsigned int flags) {
222  GWEN_BUFFER *buf;
223  void *p;
224 
225  assert(path);
226  buf=GWEN_Buffer_new(0, strlen(path)+10, 0, 1);
227  p=GWEN_Path_Handle(path, buf,
230  if (!p) {
231  DBG_INFO(GWEN_LOGDOMAIN, "Path so far: \"%s\"", GWEN_Buffer_GetStart(buf));
232  GWEN_Buffer_free(buf);
233  return -1;
234  }
235  GWEN_Buffer_free(buf);
236  return 0;
237 }
238 
239 
240 
241 int GWEN_Directory_OsifyPath(const char *path, GWEN_BUFFER *pbuf,
242  int transformDriveElement){
243  const char *p;
244 
245  p=path;
246 
247  /* handle drive letters (only check for normal slashes here) */
248 #ifdef OS_WIN32
249  if (transformDriveElement) {
250  if (*p=='/')
251  if (isalpha(p[1]))
252  if (p[2]=='/' || p[2]==0) {
253  GWEN_Buffer_AppendByte(pbuf, p[0]);
254  GWEN_Buffer_AppendByte(pbuf, ':');
255  p+=2;
256  }
257  }
258 #endif
259 
260  while(*p) {
261  if (*p=='/' || *p=='\\') {
262  while (*p=='/' || *p=='\\')
263  p++;
264 #ifdef OS_WIN32
265  GWEN_Buffer_AppendByte(pbuf, '\\');
266 #else
267  GWEN_Buffer_AppendByte(pbuf, '/');
268 #endif
269  }
270  else {
271  GWEN_Buffer_AppendByte(pbuf, *p);
272  p++;
273  }
274  }
275 
276  return 0;
277 }
278 
279 
280 
282  const char *filePath,
283  GWEN_BUFFER *fbuf) {
285 
286  se=GWEN_StringList_FirstEntry(paths);
287  while(se) {
288  GWEN_BUFFER *tbuf;
289  FILE *f;
290 
291  tbuf=GWEN_Buffer_new(0, 256, 0, 1);
294  GWEN_Buffer_AppendString(tbuf, filePath);
295  DBG_DEBUG(GWEN_LOGDOMAIN, "Trying \"%s\"",
296  GWEN_Buffer_GetStart(tbuf));
297  f=fopen(GWEN_Buffer_GetStart(tbuf), "r");
298  if (f) {
299  fclose(f);
301  "File \"%s\" found in folder \"%s\"",
302  filePath,
304  GWEN_Buffer_AppendBuffer(fbuf, tbuf);
305  GWEN_Buffer_free(tbuf);
306  return 0;
307  }
308  GWEN_Buffer_free(tbuf);
309 
311  }
312 
313  DBG_INFO(GWEN_LOGDOMAIN, "File \"%s\" not found", filePath);
314  return GWEN_ERROR_NOT_FOUND;
315 }
316 
317 
318 
320  const char *filePath,
321  GWEN_BUFFER *fbuf) {
323 
324  se=GWEN_StringList_FirstEntry(paths);
325  while(se) {
326  GWEN_BUFFER *tbuf;
327  FILE *f;
328 
329  tbuf=GWEN_Buffer_new(0, 256, 0, 1);
332  GWEN_Buffer_AppendString(tbuf, filePath);
333  DBG_DEBUG(GWEN_LOGDOMAIN, "Trying \"%s\"",
334  GWEN_Buffer_GetStart(tbuf));
335  f=fopen(GWEN_Buffer_GetStart(tbuf), "r");
336  if (f) {
337  fclose(f);
339  "File \"%s\" found in folder \"%s\"",
340  filePath,
343  GWEN_Buffer_free(tbuf);
344  return 0;
345  }
346  GWEN_Buffer_free(tbuf);
347 
349  }
350 
351  DBG_INFO(GWEN_LOGDOMAIN, "File \"%s\" not found", filePath);
352  return GWEN_ERROR_NOT_FOUND;
353 }
354 
355 
356 
357 int GWEN_Directory_GetTmpDirectory(char *buffer, unsigned int size)
358 {
359  const char *tmp_dir;
360  assert(buffer);
361 
362  /* Copied from http://svn.gnome.org/viewcvs/glib/trunk/glib/gutils.c */
363  tmp_dir = getenv ("TMPDIR");
364  if (!tmp_dir)
365  tmp_dir = getenv ("TMP");
366  if (!tmp_dir)
367  tmp_dir = getenv ("TEMP");
368 
369  if (!tmp_dir)
370  {
371 #ifdef OS_WIN32
372  tmp_dir = "C:\\";
373 #else
374  tmp_dir = "/tmp";
375 #endif /* !OS_WIN32 */
376  }
377 
378  strncpy (buffer, tmp_dir, size);
379  return 0;
380 }
381 
382 
383 
384 int GWEN_Directory_GetAllEntries(const char *folder,
385  GWEN_STRINGLIST *sl,
386  const char *mask) {
387  GWEN_DIRECTORY *d;
388  int rv;
389  char buffer[256];
390 
391  d=GWEN_Directory_new();
392  rv=GWEN_Directory_Open(d, folder);
393  if (rv<0) {
394  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
396  return rv;
397  }
398 
399  while(0==GWEN_Directory_Read(d, buffer, sizeof(buffer))) {
400  if (strcmp(buffer, ".")!=0 &&
401  strcmp(buffer, "..")!=0 &&
402  (mask==NULL ||
403  GWEN_Text_ComparePattern(buffer+1, mask, 0)!=-1))
404  GWEN_StringList_AppendString(sl, buffer, 0, 1);
405  }
406 
409  return 0;
410 }
411 
412 
413 
415  GWEN_STRINGLIST *sl,
416  const char *mask) {
417  GWEN_DIRECTORY *d;
418  int rv;
419  char buffer[256];
420  GWEN_BUFFER *pbuf;
421  uint32_t pos;
422 
423  d=GWEN_Directory_new();
424  rv=GWEN_Directory_Open(d, folder);
425  if (rv<0) {
426  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
428  return rv;
429  }
430 
431  pbuf=GWEN_Buffer_new(0, 256, 0, 1);
432  GWEN_Buffer_AppendString(pbuf, folder);
434  pos=GWEN_Buffer_GetPos(pbuf);
435 
436  while(0==GWEN_Directory_Read(d, buffer+1, sizeof(buffer)-2)) {
437  if (strcmp(buffer, ".")!=0 &&
438  strcmp(buffer, "..")!=0 &&
439  (mask==NULL ||
440  GWEN_Text_ComparePattern(buffer+1, mask, 0)!=-1)) {
441  struct stat st;
442 
443  GWEN_Buffer_AppendString(pbuf, buffer+1);
444  if (stat(GWEN_Buffer_GetStart(pbuf), &st)==0) {
445  if (S_ISREG(st.st_mode))
446  buffer[0]='f';
447  else if (S_ISDIR(st.st_mode))
448  buffer[0]='d';
449  else
450  buffer[0]='?';
451  GWEN_StringList_AppendString(sl, buffer, 0, 1);
452  }
453  GWEN_Buffer_Crop(pbuf, 0, pos);
454  }
455  }
456 
459  return 0;
460 }
461 
462 
463 
464 
465 int GWEN_Directory_GetFileEntries(const char *folder, GWEN_STRINGLIST *sl,
466  const char *mask) {
467  GWEN_DIRECTORY *d;
468  int rv;
469  char buffer[256];
470  GWEN_BUFFER *pbuf;
471  uint32_t pos;
472 
473  d=GWEN_Directory_new();
474  rv=GWEN_Directory_Open(d, folder);
475  if (rv<0) {
476  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
478  return rv;
479  }
480 
481  pbuf=GWEN_Buffer_new(0, 256, 0, 1);
482  GWEN_Buffer_AppendString(pbuf, folder);
484  pos=GWEN_Buffer_GetPos(pbuf);
485 
486  while(0==GWEN_Directory_Read(d, buffer, sizeof(buffer))) {
487  if (strcmp(buffer, ".")!=0 &&
488  strcmp(buffer, "..")!=0 &&
489  (mask==NULL ||
490  GWEN_Text_ComparePattern(buffer+1, mask, 0)!=-1)) {
491  struct stat st;
492 
493  GWEN_Buffer_AppendString(pbuf, buffer);
494  if (stat(GWEN_Buffer_GetStart(pbuf), &st)==0) {
495  if (S_ISREG(st.st_mode))
496  GWEN_StringList_AppendString(sl, buffer, 0, 1);
497  }
498  GWEN_Buffer_Crop(pbuf, 0, pos);
499  }
500  }
501 
502  GWEN_Buffer_free(pbuf);
505  return 0;
506 }
507 
508 
509 
510 int GWEN_Directory_GetDirEntries(const char *folder, GWEN_STRINGLIST *sl,
511  const char *mask) {
512  GWEN_DIRECTORY *d;
513  int rv;
514  char buffer[256];
515  GWEN_BUFFER *pbuf;
516  uint32_t pos;
517 
518  d=GWEN_Directory_new();
519  rv=GWEN_Directory_Open(d, folder);
520  if (rv<0) {
521  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
523  return rv;
524  }
525 
526  pbuf=GWEN_Buffer_new(0, 256, 0, 1);
527  GWEN_Buffer_AppendString(pbuf, folder);
529  pos=GWEN_Buffer_GetPos(pbuf);
530 
531  while(0==GWEN_Directory_Read(d, buffer, sizeof(buffer))) {
532  if (strcmp(buffer, ".")!=0 &&
533  strcmp(buffer, "..")!=0 &&
534  (mask==NULL ||
535  GWEN_Text_ComparePattern(buffer+1, mask, 0)!=-1)) {
536  struct stat st;
537 
538  GWEN_Buffer_AppendString(pbuf, buffer);
539  if (stat(GWEN_Buffer_GetStart(pbuf), &st)==0) {
540  if (S_ISDIR(st.st_mode))
541  GWEN_StringList_AppendString(sl, buffer, 0, 1);
542  }
543  GWEN_Buffer_Crop(pbuf, 0, pos);
544  }
545  }
546 
549  return 0;
550 }
551 
552 
553 
555  GWEN_STRINGLIST *sl,
556  const char *mask) {
557  GWEN_DIRECTORY *d;
558  int rv;
559  char buffer[256];
560  GWEN_BUFFER *pbuf;
561  uint32_t pos;
562  GWEN_STRINGLIST *folderList;
563 
564  folderList=GWEN_StringList_new();
565 
566  d=GWEN_Directory_new();
567  rv=GWEN_Directory_Open(d, folder);
568  if (rv<0) {
569  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
571  GWEN_StringList_free(folderList);
572  return rv;
573  }
574 
575  pbuf=GWEN_Buffer_new(0, 256, 0, 1);
576  GWEN_Buffer_AppendString(pbuf, folder);
578  pos=GWEN_Buffer_GetPos(pbuf);
579 
580  while(0==GWEN_Directory_Read(d, buffer, sizeof(buffer)-2)) {
581  if (strcmp(buffer, ".")!=0 &&
582  strcmp(buffer, "..")!=0) {
583  struct stat st;
584 
585  GWEN_Buffer_AppendString(pbuf, buffer);
586  if (stat(GWEN_Buffer_GetStart(pbuf), &st)==0) {
587  if (S_ISDIR(st.st_mode))
588  /* add folders to the folder list */
589  GWEN_StringList_AppendString(folderList, GWEN_Buffer_GetStart(pbuf), 0, 1);
590  else {
591  if (mask==NULL || GWEN_Text_ComparePattern(buffer, mask, 0)!=-1)
593  }
594  }
595  GWEN_Buffer_Crop(pbuf, 0, pos);
596  }
597  }
598 
601 
602  if (GWEN_StringList_Count(folderList)) {
604 
605  se=GWEN_StringList_FirstEntry(folderList);
606  while(se) {
607  const char *s;
608 
610  if (s && *s)
613  }
614  }
615  GWEN_StringList_free(folderList);
616  GWEN_Buffer_free(pbuf);
617 
618  return 0;
619 }
620 
621 
622 
623 int GWEN_Directory_GetAbsoluteFolderPath(const char *folder, GWEN_BUFFER *tbuf) {
624  char savedPwd[300];
625  char dataPwd[300];
626 
627  /* get current working dir */
628  if (getcwd(savedPwd, sizeof(savedPwd)-1)==NULL) {
629  DBG_ERROR(GWEN_LOGDOMAIN, "getcwd(): %s", strerror(errno));
630  return GWEN_ERROR_IO;
631  }
632 
633  if (chdir(folder)) {
634  DBG_ERROR(GWEN_LOGDOMAIN, "chdir(%s): %s", folder, strerror(errno));
635  return GWEN_ERROR_IO;
636  }
637 
638  /* get new current working dir */
639  if (getcwd(dataPwd, sizeof(dataPwd)-1)==NULL) {
640  DBG_ERROR(GWEN_LOGDOMAIN, "getcwd(): %s", strerror(errno));
641  return GWEN_ERROR_IO;
642  }
643  dataPwd[sizeof(dataPwd)-1]=0;
644 
645  /* change back to previous pwd */
646  if (chdir(savedPwd)) {
647  DBG_ERROR(GWEN_LOGDOMAIN, "chdir(%s): %s", folder, strerror(errno));
648  return GWEN_ERROR_IO;
649  }
650 
651  GWEN_Buffer_AppendString(tbuf, dataPwd);
652  return 0;
653 }
654 
655 
656 
657 
658 
659