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