00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifdef HAVE_CONFIG_H
00030 # include <config.h>
00031 #endif
00032
00033
00034 #include <gwenhywfar/directory.h>
00035 #include <gwenhywfar/debug.h>
00036 #include <gwenhywfar/path.h>
00037 #include <gwenhywfar/buffer.h>
00038 #include <gwenhywfar/text.h>
00039
00040 #ifdef HAVE_UNISTD_H
00041 # include <unistd.h>
00042 #endif
00043 #ifdef HAVE_SYS_STAT_H
00044 # include <sys/stat.h>
00045 #endif
00046 #include <sys/types.h>
00047 #ifdef HAVE_FCNTL_H
00048 # include <fcntl.h>
00049 #endif
00050 #include <string.h>
00051 #include <errno.h>
00052 #include <assert.h>
00053 #include <stdlib.h>
00054 #include <ctype.h>
00055
00056 #ifdef OS_WIN32
00057 # define DIRSEP "\\"
00058 #else
00059 # define DIRSEP "/"
00060 #endif
00061
00062
00063
00064 void *GWEN_Directory_HandlePathElement(const char *entry,
00065 void *data,
00066 unsigned int flags){
00067 char *p;
00068 struct stat st;
00069 int exists;
00070 int withDrive;
00071 GWEN_BUFFER *buf;
00072 GWEN_BUFFER *ebuf = 0;
00073 const char *origEntry;
00074
00075 withDrive=0;
00076 origEntry=entry;
00077
00078 #ifdef OS_WIN32
00079 if (entry && isalpha(*entry)) {
00080 int len;
00081
00082
00083 len=strlen(entry);
00084 if ( (len==2) && (entry[1] == ':') ) {
00085 ebuf=GWEN_Buffer_new(0, len+2, 0, 1);
00086 GWEN_Buffer_AppendString(ebuf, entry);
00087 GWEN_Buffer_AppendByte(ebuf, '\\');
00088 withDrive=1;
00089 entry=GWEN_Buffer_GetStart(ebuf);
00090 }
00091 }
00092 #endif
00093
00094 if (strcasecmp(entry, "..")==0) {
00095 DBG_ERROR(GWEN_LOGDOMAIN, "\"..\" detected");
00096 GWEN_Buffer_free(ebuf);
00097 return 0;
00098 }
00099
00100 buf=(GWEN_BUFFER*)data;
00101 if (GWEN_Buffer_GetUsedBytes(buf) && !withDrive) {
00102 char c;
00103
00104 c=GWEN_Buffer_GetStart(buf)[GWEN_Buffer_GetUsedBytes(buf)-1];
00105 #ifdef OS_WIN32
00106 if (c!='\\')
00107 GWEN_Buffer_AppendByte(buf, '\\');
00108 #else
00109 if (c!='/')
00110 GWEN_Buffer_AppendByte(buf, '/');
00111 #endif
00112 }
00113 GWEN_Buffer_AppendString(buf, entry);
00114
00115
00116 p=GWEN_Buffer_GetStart(buf);
00117 DBG_DEBUG(GWEN_LOGDOMAIN, "Checking path \"%s\"", p);
00118 if (stat(p, &st)) {
00119 exists=0;
00120 DBG_DEBUG(GWEN_LOGDOMAIN, "stat: %s (%s)", strerror(errno), p);
00121 if ((flags & GWEN_PATH_FLAGS_PATHMUSTEXIST) ||
00122 ((flags & GWEN_PATH_FLAGS_LAST) &&
00123 (flags & GWEN_PATH_FLAGS_NAMEMUSTEXIST))) {
00124 DBG_INFO(GWEN_LOGDOMAIN, "Path \"%s\" does not exist (it should)", p);
00125 GWEN_Buffer_free(ebuf);
00126 return 0;
00127 }
00128 }
00129 else {
00130 DBG_DEBUG(GWEN_LOGDOMAIN, "Checking for type");
00131 exists=1;
00132 if (flags & GWEN_PATH_FLAGS_VARIABLE) {
00133 if (!S_ISREG(st.st_mode)) {
00134 DBG_INFO(GWEN_LOGDOMAIN, "%s not a regular file", p);
00135 GWEN_Buffer_free(ebuf);
00136 return 0;
00137 }
00138 }
00139 else {
00140 if (!S_ISDIR(st.st_mode)) {
00141 DBG_INFO(GWEN_LOGDOMAIN, "%s not a direcory", p);
00142 GWEN_Buffer_free(ebuf);
00143 return 0;
00144 }
00145 }
00146 if ((flags & GWEN_PATH_FLAGS_PATHMUSTNOTEXIST) ||
00147 ((flags & GWEN_PATH_FLAGS_LAST) &&
00148 (flags & GWEN_PATH_FLAGS_NAMEMUSTNOTEXIST))) {
00149 DBG_INFO(GWEN_LOGDOMAIN, "Path \"%s\" exists (it should not)", p);
00150 GWEN_Buffer_free(ebuf);
00151 return 0;
00152 }
00153 }
00154
00155 if (!exists) {
00156 int isPublic;
00157
00158 DBG_DEBUG(GWEN_LOGDOMAIN, "Entry \"%s\" does not exist", p);
00159
00160 isPublic=(
00161 ((flags & GWEN_PATH_FLAGS_LAST) &&
00162 (flags & GWEN_DIR_FLAGS_PUBLIC_NAME)) ||
00163 (!(flags & GWEN_PATH_FLAGS_LAST) &&
00164 (flags & GWEN_DIR_FLAGS_PUBLIC_PATH))
00165 );
00166
00167 if (flags & GWEN_PATH_FLAGS_VARIABLE) {
00168
00169 int fd;
00170
00171 DBG_DEBUG(GWEN_LOGDOMAIN, "Creating file \"%s\"", p);
00172 if (isPublic)
00173 fd=open(p, O_RDWR | O_CREAT | O_TRUNC,
00174 S_IRUSR | S_IWUSR
00175 #ifdef S_IRGRP
00176 | S_IRGRP
00177 #endif
00178 #ifdef S_IROTH
00179 | S_IROTH
00180 #endif
00181 );
00182 else
00183 fd=open(p, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
00184 if (fd==-1) {
00185 DBG_ERROR(GWEN_LOGDOMAIN, "open: %s (%s)", strerror(errno), p);
00186 GWEN_Buffer_free(ebuf);
00187 return 0;
00188 }
00189 close(fd);
00190 DBG_DEBUG(GWEN_LOGDOMAIN, "Sucessfully created");
00191 }
00192 else {
00193
00194 DBG_DEBUG(GWEN_LOGDOMAIN, "Creating folder \"%s\"", p);
00195
00196 if (isPublic) {
00197 if (GWEN_Directory_CreatePublic(p)) {
00198 DBG_ERROR(GWEN_LOGDOMAIN, "Could not create directory \"%s\"", p);
00199 GWEN_Buffer_free(ebuf);
00200 return 0;
00201 }
00202 }
00203 else {
00204 if (GWEN_Directory_Create(p)) {
00205 DBG_ERROR(GWEN_LOGDOMAIN, "Could not create directory \"%s\"", p);
00206 GWEN_Buffer_free(ebuf);
00207 return 0;
00208 }
00209 }
00210 }
00211 }
00212 else {
00213 DBG_DEBUG(GWEN_LOGDOMAIN, "Entry \"%s\" exists", p);
00214 }
00215 DBG_DEBUG(GWEN_LOGDOMAIN, "Returning this: %s", p);
00216 GWEN_Buffer_free(ebuf);
00217 return buf;
00218 }
00219
00220
00221
00222 int GWEN_Directory_GetPath(const char *path,
00223 unsigned int flags) {
00224 GWEN_BUFFER *buf;
00225 void *p;
00226
00227 assert(path);
00228 buf=GWEN_Buffer_new(0, strlen(path)+10, 0, 1);
00229 p=GWEN_Path_Handle(path, buf,
00230 flags | GWEN_PATH_FLAGS_CHECKROOT,
00231 GWEN_Directory_HandlePathElement);
00232 if (!p) {
00233 DBG_INFO(GWEN_LOGDOMAIN, "Path so far: \"%s\"", GWEN_Buffer_GetStart(buf));
00234 GWEN_Buffer_free(buf);
00235 return -1;
00236 }
00237 GWEN_Buffer_free(buf);
00238 return 0;
00239 }
00240
00241
00242
00243 int GWEN_Directory_OsifyPath(const char *path, GWEN_BUFFER *pbuf,
00244 int transformDriveElement){
00245 int len;
00246 const char *p;
00247
00248 len=strlen(path);
00249 p=path;
00250
00251
00252 #ifdef OS_WIN32
00253 if (transformDriveElement) {
00254 if (*p=='/')
00255 if (isalpha(p[1]))
00256 if (p[2]=='/' || p[2]==0) {
00257 GWEN_Buffer_AppendByte(pbuf, p[0]);
00258 GWEN_Buffer_AppendByte(pbuf, ':');
00259 p+=2;
00260 }
00261 }
00262 #endif
00263
00264 while(*p) {
00265 if (*p=='/' || *p=='\\') {
00266 while (*p=='/' || *p=='\\')
00267 p++;
00268 #ifdef OS_WIN32
00269 GWEN_Buffer_AppendByte(pbuf, '\\');
00270 #else
00271 GWEN_Buffer_AppendByte(pbuf, '/');
00272 #endif
00273 }
00274 else {
00275 GWEN_Buffer_AppendByte(pbuf, *p);
00276 p++;
00277 }
00278 }
00279
00280 return 0;
00281 }
00282
00283
00284
00285 int GWEN_Directory_FindFileInPaths(const GWEN_STRINGLIST *paths,
00286 const char *filePath,
00287 GWEN_BUFFER *fbuf) {
00288 GWEN_STRINGLISTENTRY *se;
00289
00290 se=GWEN_StringList_FirstEntry(paths);
00291 while(se) {
00292 GWEN_BUFFER *tbuf;
00293 FILE *f;
00294
00295 tbuf=GWEN_Buffer_new(0, 256, 0, 1);
00296 GWEN_Buffer_AppendString(tbuf, GWEN_StringListEntry_Data(se));
00297 GWEN_Buffer_AppendString(tbuf, DIRSEP);
00298 GWEN_Buffer_AppendString(tbuf, filePath);
00299 DBG_DEBUG(GWEN_LOGDOMAIN, "Trying \"%s\"",
00300 GWEN_Buffer_GetStart(tbuf));
00301 f=fopen(GWEN_Buffer_GetStart(tbuf), "r");
00302 if (f) {
00303 fclose(f);
00304 DBG_DEBUG(GWEN_LOGDOMAIN,
00305 "File \"%s\" found in folder \"%s\"",
00306 filePath,
00307 GWEN_StringListEntry_Data(se));
00308 GWEN_Buffer_AppendBuffer(fbuf, tbuf);
00309 GWEN_Buffer_free(tbuf);
00310 return 0;
00311 }
00312 GWEN_Buffer_free(tbuf);
00313
00314 se=GWEN_StringListEntry_Next(se);
00315 }
00316
00317 DBG_INFO(GWEN_LOGDOMAIN, "File \"%s\" not found", filePath);
00318 return GWEN_ERROR_NOT_FOUND;
00319 }
00320
00321
00322
00323 int GWEN_Directory_FindPathForFile(const GWEN_STRINGLIST *paths,
00324 const char *filePath,
00325 GWEN_BUFFER *fbuf) {
00326 GWEN_STRINGLISTENTRY *se;
00327
00328 se=GWEN_StringList_FirstEntry(paths);
00329 while(se) {
00330 GWEN_BUFFER *tbuf;
00331 FILE *f;
00332
00333 tbuf=GWEN_Buffer_new(0, 256, 0, 1);
00334 GWEN_Buffer_AppendString(tbuf, GWEN_StringListEntry_Data(se));
00335 GWEN_Buffer_AppendString(tbuf, DIRSEP);
00336 GWEN_Buffer_AppendString(tbuf, filePath);
00337 DBG_DEBUG(GWEN_LOGDOMAIN, "Trying \"%s\"",
00338 GWEN_Buffer_GetStart(tbuf));
00339 f=fopen(GWEN_Buffer_GetStart(tbuf), "r");
00340 if (f) {
00341 fclose(f);
00342 DBG_INFO(GWEN_LOGDOMAIN,
00343 "File \"%s\" found in folder \"%s\"",
00344 filePath,
00345 GWEN_StringListEntry_Data(se));
00346 GWEN_Buffer_AppendString(fbuf, GWEN_StringListEntry_Data(se));
00347 GWEN_Buffer_free(tbuf);
00348 return 0;
00349 }
00350 GWEN_Buffer_free(tbuf);
00351
00352 se=GWEN_StringListEntry_Next(se);
00353 }
00354
00355 DBG_INFO(GWEN_LOGDOMAIN, "File \"%s\" not found", filePath);
00356 return GWEN_ERROR_NOT_FOUND;
00357 }
00358
00359
00360
00361 int GWEN_Directory_GetTmpDirectory(char *buffer, unsigned int size)
00362 {
00363 const char *tmp_dir;
00364 assert(buffer);
00365
00366
00367 tmp_dir = getenv ("TMPDIR");
00368 if (!tmp_dir)
00369 tmp_dir = getenv ("TMP");
00370 if (!tmp_dir)
00371 tmp_dir = getenv ("TEMP");
00372
00373 if (!tmp_dir)
00374 {
00375 #ifdef OS_WIN32
00376 tmp_dir = "C:\\";
00377 #else
00378 tmp_dir = "/tmp";
00379 #endif
00380 }
00381
00382 strncpy (buffer, tmp_dir, size);
00383 return 0;
00384 }
00385
00386
00387
00388 int GWEN_Directory_GetAllEntries(char *folder, GWEN_STRINGLIST *sl,
00389 const char *mask) {
00390 GWEN_DIRECTORY *d;
00391 int rv;
00392 char buffer[256];
00393
00394 d=GWEN_Directory_new();
00395 rv=GWEN_Directory_Open(d, folder);
00396 if (rv<0) {
00397 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00398 GWEN_Directory_free(d);
00399 return rv;
00400 }
00401
00402 while(0==GWEN_Directory_Read(d, buffer, sizeof(buffer))) {
00403 if (strcmp(buffer, ".")!=0 &&
00404 strcmp(buffer, "..")!=0 &&
00405 (mask==NULL ||
00406 GWEN_Text_ComparePattern(buffer+1, mask, 0)!=-1))
00407 GWEN_StringList_AppendString(sl, buffer, 0, 1);
00408 }
00409
00410 GWEN_Directory_Close(d);
00411 GWEN_Directory_free(d);
00412 return 0;
00413 }
00414
00415
00416
00417 int GWEN_Directory_GetFileEntriesWithType(char *folder, GWEN_STRINGLIST *sl,
00418 const char *mask) {
00419 GWEN_DIRECTORY *d;
00420 int rv;
00421 char buffer[256];
00422 GWEN_BUFFER *pbuf;
00423 uint32_t pos;
00424
00425 d=GWEN_Directory_new();
00426 rv=GWEN_Directory_Open(d, folder);
00427 if (rv<0) {
00428 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00429 GWEN_Directory_free(d);
00430 return rv;
00431 }
00432
00433 pbuf=GWEN_Buffer_new(0, 256, 0, 1);
00434 GWEN_Buffer_AppendString(pbuf, folder);
00435 GWEN_Buffer_AppendString(pbuf, GWEN_DIR_SEPARATOR_S);
00436 pos=GWEN_Buffer_GetPos(pbuf);
00437
00438 while(0==GWEN_Directory_Read(d, buffer+1, sizeof(buffer)-1)) {
00439 if (strcmp(buffer, ".")!=0 &&
00440 strcmp(buffer, "..")!=0 &&
00441 (mask==NULL ||
00442 GWEN_Text_ComparePattern(buffer+1, mask, 0)!=-1)) {
00443 struct stat st;
00444
00445 GWEN_Buffer_AppendString(pbuf, buffer);
00446 if (stat(GWEN_Buffer_GetStart(pbuf), &st)==0) {
00447 if (S_ISREG(st.st_mode))
00448 buffer[0]='f';
00449 else if (S_ISDIR(st.st_mode))
00450 buffer[0]='d';
00451 else
00452 buffer[0]='?';
00453 GWEN_StringList_AppendString(sl, buffer, 0, 1);
00454 }
00455 GWEN_Buffer_Crop(pbuf, 0, pos);
00456 }
00457 }
00458
00459 GWEN_Directory_Close(d);
00460 GWEN_Directory_free(d);
00461 return 0;
00462 }
00463
00464
00465
00466
00467 int GWEN_Directory_GetFileEntries(char *folder, GWEN_STRINGLIST *sl,
00468 const char *mask) {
00469 GWEN_DIRECTORY *d;
00470 int rv;
00471 char buffer[256];
00472 GWEN_BUFFER *pbuf;
00473 uint32_t pos;
00474
00475 d=GWEN_Directory_new();
00476 rv=GWEN_Directory_Open(d, folder);
00477 if (rv<0) {
00478 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00479 GWEN_Directory_free(d);
00480 return rv;
00481 }
00482
00483 pbuf=GWEN_Buffer_new(0, 256, 0, 1);
00484 GWEN_Buffer_AppendString(pbuf, folder);
00485 GWEN_Buffer_AppendString(pbuf, GWEN_DIR_SEPARATOR_S);
00486 pos=GWEN_Buffer_GetPos(pbuf);
00487
00488 while(0==GWEN_Directory_Read(d, buffer, sizeof(buffer))) {
00489 if (strcmp(buffer, ".")!=0 &&
00490 strcmp(buffer, "..")!=0 &&
00491 (mask==NULL ||
00492 GWEN_Text_ComparePattern(buffer+1, mask, 0)!=-1)) {
00493 struct stat st;
00494
00495 GWEN_Buffer_AppendString(pbuf, buffer);
00496 if (stat(GWEN_Buffer_GetStart(pbuf), &st)==0) {
00497 if (S_ISREG(st.st_mode))
00498 GWEN_StringList_AppendString(sl, buffer, 0, 1);
00499 }
00500 GWEN_Buffer_Crop(pbuf, 0, pos);
00501 }
00502 }
00503
00504 GWEN_Directory_Close(d);
00505 GWEN_Directory_free(d);
00506 return 0;
00507 }
00508
00509
00510
00511 int GWEN_Directory_GetDirEntries(char *folder, GWEN_STRINGLIST *sl,
00512 const char *mask) {
00513 GWEN_DIRECTORY *d;
00514 int rv;
00515 char buffer[256];
00516 GWEN_BUFFER *pbuf;
00517 uint32_t pos;
00518
00519 d=GWEN_Directory_new();
00520 rv=GWEN_Directory_Open(d, folder);
00521 if (rv<0) {
00522 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00523 GWEN_Directory_free(d);
00524 return rv;
00525 }
00526
00527 pbuf=GWEN_Buffer_new(0, 256, 0, 1);
00528 GWEN_Buffer_AppendString(pbuf, folder);
00529 GWEN_Buffer_AppendString(pbuf, GWEN_DIR_SEPARATOR_S);
00530 pos=GWEN_Buffer_GetPos(pbuf);
00531
00532 while(0==GWEN_Directory_Read(d, buffer, sizeof(buffer))) {
00533 if (strcmp(buffer, ".")!=0 &&
00534 strcmp(buffer, "..")!=0 &&
00535 (mask==NULL ||
00536 GWEN_Text_ComparePattern(buffer+1, mask, 0)!=-1)) {
00537 struct stat st;
00538
00539 GWEN_Buffer_AppendString(pbuf, buffer);
00540 if (stat(GWEN_Buffer_GetStart(pbuf), &st)==0) {
00541 if (S_ISDIR(st.st_mode))
00542 GWEN_StringList_AppendString(sl, buffer, 0, 1);
00543 }
00544 GWEN_Buffer_Crop(pbuf, 0, pos);
00545 }
00546 }
00547
00548 GWEN_Directory_Close(d);
00549 GWEN_Directory_free(d);
00550 return 0;
00551 }
00552
00553
00554
00555
00556