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
00039 #ifdef HAVE_UNISTD_H
00040 # include <unistd.h>
00041 #endif
00042 #ifdef HAVE_SYS_STAT_H
00043 # include <sys/stat.h>
00044 #endif
00045 #include <sys/types.h>
00046 #ifdef HAVE_FCNTL_H
00047 # include <fcntl.h>
00048 #endif
00049 #include <string.h>
00050 #include <errno.h>
00051 #include <assert.h>
00052 #include <stdlib.h>
00053 #include <ctype.h>
00054
00055 #ifdef OS_WIN32
00056 # define DIRSEP "\\"
00057 #else
00058 # define DIRSEP "/"
00059 #endif
00060
00061
00062
00063 void *GWEN_Directory_HandlePathElement(const char *entry,
00064 void *data,
00065 unsigned int flags){
00066 char *p;
00067 struct stat st;
00068 int exists;
00069 int withDrive;
00070 GWEN_BUFFER *buf;
00071 GWEN_BUFFER *ebuf = 0;
00072 const char *origEntry;
00073
00074 withDrive=0;
00075 origEntry=entry;
00076
00077 #ifdef OS_WIN32
00078 if (entry && isalpha(*entry)) {
00079 int len;
00080
00081
00082 len=strlen(entry);
00083 if ( (len==2) && (entry[1] == ':') ) {
00084 ebuf=GWEN_Buffer_new(0, len+2, 0, 1);
00085 GWEN_Buffer_AppendString(ebuf, entry);
00086 GWEN_Buffer_AppendByte(ebuf, '\\');
00087 withDrive=1;
00088 entry=GWEN_Buffer_GetStart(ebuf);
00089 }
00090 }
00091 #endif
00092
00093 if (strcasecmp(entry, "..")==0) {
00094 DBG_ERROR(GWEN_LOGDOMAIN, "\"..\" detected");
00095 GWEN_Buffer_free(ebuf);
00096 return 0;
00097 }
00098
00099 buf=(GWEN_BUFFER*)data;
00100 if (GWEN_Buffer_GetUsedBytes(buf) && !withDrive) {
00101 char c;
00102
00103 c=GWEN_Buffer_GetStart(buf)[GWEN_Buffer_GetUsedBytes(buf)-1];
00104 #ifdef OS_WIN32
00105 if (c!='\\')
00106 GWEN_Buffer_AppendByte(buf, '\\');
00107 #else
00108 if (c!='/')
00109 GWEN_Buffer_AppendByte(buf, '/');
00110 #endif
00111 }
00112 GWEN_Buffer_AppendString(buf, entry);
00113
00114
00115 p=GWEN_Buffer_GetStart(buf);
00116 DBG_DEBUG(GWEN_LOGDOMAIN, "Checking path \"%s\"", p);
00117 if (stat(p, &st)) {
00118 exists=0;
00119 DBG_DEBUG(GWEN_LOGDOMAIN, "stat: %s (%s)", strerror(errno), p);
00120 if ((flags & GWEN_PATH_FLAGS_PATHMUSTEXIST) ||
00121 ((flags & GWEN_PATH_FLAGS_LAST) &&
00122 (flags & GWEN_PATH_FLAGS_NAMEMUSTEXIST))) {
00123 DBG_INFO(GWEN_LOGDOMAIN, "Path \"%s\" does not exist (it should)", p);
00124 GWEN_Buffer_free(ebuf);
00125 return 0;
00126 }
00127 }
00128 else {
00129 DBG_DEBUG(GWEN_LOGDOMAIN, "Checking for type");
00130 exists=1;
00131 if (flags & GWEN_PATH_FLAGS_VARIABLE) {
00132 if (!S_ISREG(st.st_mode)) {
00133 DBG_INFO(GWEN_LOGDOMAIN, "%s not a regular file", p);
00134 GWEN_Buffer_free(ebuf);
00135 return 0;
00136 }
00137 }
00138 else {
00139 if (!S_ISDIR(st.st_mode)) {
00140 DBG_INFO(GWEN_LOGDOMAIN, "%s not a direcory", p);
00141 GWEN_Buffer_free(ebuf);
00142 return 0;
00143 }
00144 }
00145 if ((flags & GWEN_PATH_FLAGS_PATHMUSTNOTEXIST) ||
00146 ((flags & GWEN_PATH_FLAGS_LAST) &&
00147 (flags & GWEN_PATH_FLAGS_NAMEMUSTNOTEXIST))) {
00148 DBG_INFO(GWEN_LOGDOMAIN, "Path \"%s\" exists (it should not)", p);
00149 GWEN_Buffer_free(ebuf);
00150 return 0;
00151 }
00152 }
00153
00154 if (!exists) {
00155 int isPublic;
00156
00157 DBG_DEBUG(GWEN_LOGDOMAIN, "Entry \"%s\" does not exist", p);
00158
00159 isPublic=(
00160 ((flags & GWEN_PATH_FLAGS_LAST) &&
00161 (flags & GWEN_DIR_FLAGS_PUBLIC_NAME)) ||
00162 (!(flags & GWEN_PATH_FLAGS_LAST) &&
00163 (flags & GWEN_DIR_FLAGS_PUBLIC_PATH))
00164 );
00165
00166 if (flags & GWEN_PATH_FLAGS_VARIABLE) {
00167
00168 int fd;
00169
00170 DBG_DEBUG(GWEN_LOGDOMAIN, "Creating file \"%s\"", p);
00171 if (isPublic)
00172 fd=open(p, O_RDWR | O_CREAT | O_TRUNC,
00173 S_IRUSR | S_IWUSR
00174 #ifdef S_IRGRP
00175 | S_IRGRP
00176 #endif
00177 #ifdef S_IROTH
00178 | S_IROTH
00179 #endif
00180 );
00181 else
00182 fd=open(p, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
00183 if (fd==-1) {
00184 DBG_ERROR(GWEN_LOGDOMAIN, "open: %s (%s)", strerror(errno), p);
00185 GWEN_Buffer_free(ebuf);
00186 return 0;
00187 }
00188 close(fd);
00189 DBG_DEBUG(GWEN_LOGDOMAIN, "Sucessfully created");
00190 }
00191 else {
00192
00193 DBG_DEBUG(GWEN_LOGDOMAIN, "Creating folder \"%s\"", p);
00194
00195 if (isPublic) {
00196 if (GWEN_Directory_CreatePublic(p)) {
00197 DBG_ERROR(GWEN_LOGDOMAIN, "Could not create directory \"%s\"", p);
00198 GWEN_Buffer_free(ebuf);
00199 return 0;
00200 }
00201 }
00202 else {
00203 if (GWEN_Directory_Create(p)) {
00204 DBG_ERROR(GWEN_LOGDOMAIN, "Could not create directory \"%s\"", p);
00205 GWEN_Buffer_free(ebuf);
00206 return 0;
00207 }
00208 }
00209 }
00210 }
00211 else {
00212 DBG_DEBUG(GWEN_LOGDOMAIN, "Entry \"%s\" exists", p);
00213 }
00214 DBG_DEBUG(GWEN_LOGDOMAIN, "Returning this: %s", p);
00215 GWEN_Buffer_free(ebuf);
00216 return buf;
00217 }
00218
00219
00220
00221 int GWEN_Directory_GetPath(const char *path,
00222 unsigned int flags) {
00223 GWEN_BUFFER *buf;
00224 void *p;
00225
00226 assert(path);
00227 buf=GWEN_Buffer_new(0, strlen(path)+10, 0, 1);
00228 p=GWEN_Path_Handle(path, buf,
00229 flags | GWEN_PATH_FLAGS_CHECKROOT,
00230 GWEN_Directory_HandlePathElement);
00231 if (!p) {
00232 DBG_INFO(GWEN_LOGDOMAIN, "Path so far: \"%s\"", GWEN_Buffer_GetStart(buf));
00233 GWEN_Buffer_free(buf);
00234 return -1;
00235 }
00236 GWEN_Buffer_free(buf);
00237 return 0;
00238 }
00239
00240
00241
00242 int GWEN_Directory_OsifyPath(const char *path, GWEN_BUFFER *pbuf,
00243 int transformDriveElement){
00244 int len;
00245 const char *p;
00246
00247 len=strlen(path);
00248 p=path;
00249
00250
00251 #ifdef OS_WIN32
00252 if (transformDriveElement) {
00253 if (*p=='/')
00254 if (isalpha(p[1]))
00255 if (p[2]=='/' || p[2]==0) {
00256 GWEN_Buffer_AppendByte(pbuf, p[0]);
00257 GWEN_Buffer_AppendByte(pbuf, ':');
00258 p+=2;
00259 }
00260 }
00261 #endif
00262
00263 while(*p) {
00264 if (*p=='/' || *p=='\\') {
00265 while (*p=='/' || *p=='\\')
00266 p++;
00267 #ifdef OS_WIN32
00268 GWEN_Buffer_AppendByte(pbuf, '\\');
00269 #else
00270 GWEN_Buffer_AppendByte(pbuf, '/');
00271 #endif
00272 }
00273 else {
00274 GWEN_Buffer_AppendByte(pbuf, *p);
00275 p++;
00276 }
00277 }
00278
00279 return 0;
00280 }
00281
00282
00283
00284 int GWEN_Directory_FindFileInPaths(const GWEN_STRINGLIST *paths,
00285 const char *filePath,
00286 GWEN_BUFFER *fbuf) {
00287 GWEN_STRINGLISTENTRY *se;
00288
00289 se=GWEN_StringList_FirstEntry(paths);
00290 while(se) {
00291 GWEN_BUFFER *tbuf;
00292 FILE *f;
00293
00294 tbuf=GWEN_Buffer_new(0, 256, 0, 1);
00295 GWEN_Buffer_AppendString(tbuf, GWEN_StringListEntry_Data(se));
00296 GWEN_Buffer_AppendString(tbuf, DIRSEP);
00297 GWEN_Buffer_AppendString(tbuf, filePath);
00298 DBG_DEBUG(GWEN_LOGDOMAIN, "Trying \"%s\"",
00299 GWEN_Buffer_GetStart(tbuf));
00300 f=fopen(GWEN_Buffer_GetStart(tbuf), "r");
00301 if (f) {
00302 fclose(f);
00303 DBG_DEBUG(GWEN_LOGDOMAIN,
00304 "File \"%s\" found in folder \"%s\"",
00305 filePath,
00306 GWEN_StringListEntry_Data(se));
00307 GWEN_Buffer_AppendBuffer(fbuf, tbuf);
00308 GWEN_Buffer_free(tbuf);
00309 return 0;
00310 }
00311 GWEN_Buffer_free(tbuf);
00312
00313 se=GWEN_StringListEntry_Next(se);
00314 }
00315
00316 DBG_INFO(GWEN_LOGDOMAIN, "File \"%s\" not found", filePath);
00317 return GWEN_ERROR_NOT_FOUND;
00318 }
00319
00320
00321
00322 int GWEN_Directory_FindPathForFile(const GWEN_STRINGLIST *paths,
00323 const char *filePath,
00324 GWEN_BUFFER *fbuf) {
00325 GWEN_STRINGLISTENTRY *se;
00326
00327 se=GWEN_StringList_FirstEntry(paths);
00328 while(se) {
00329 GWEN_BUFFER *tbuf;
00330 FILE *f;
00331
00332 tbuf=GWEN_Buffer_new(0, 256, 0, 1);
00333 GWEN_Buffer_AppendString(tbuf, GWEN_StringListEntry_Data(se));
00334 GWEN_Buffer_AppendString(tbuf, DIRSEP);
00335 GWEN_Buffer_AppendString(tbuf, filePath);
00336 DBG_DEBUG(GWEN_LOGDOMAIN, "Trying \"%s\"",
00337 GWEN_Buffer_GetStart(tbuf));
00338 f=fopen(GWEN_Buffer_GetStart(tbuf), "r");
00339 if (f) {
00340 fclose(f);
00341 DBG_INFO(GWEN_LOGDOMAIN,
00342 "File \"%s\" found in folder \"%s\"",
00343 filePath,
00344 GWEN_StringListEntry_Data(se));
00345 GWEN_Buffer_AppendString(fbuf, GWEN_StringListEntry_Data(se));
00346 GWEN_Buffer_free(tbuf);
00347 return 0;
00348 }
00349 GWEN_Buffer_free(tbuf);
00350
00351 se=GWEN_StringListEntry_Next(se);
00352 }
00353
00354 DBG_INFO(GWEN_LOGDOMAIN, "File \"%s\" not found", filePath);
00355 return GWEN_ERROR_NOT_FOUND;
00356 }
00357
00358
00359
00360 int GWEN_Directory_GetTmpDirectory(char *buffer, unsigned int size)
00361 {
00362 const char *tmp_dir;
00363 assert(buffer);
00364
00365
00366 tmp_dir = getenv ("TMPDIR");
00367 if (!tmp_dir)
00368 tmp_dir = getenv ("TMP");
00369 if (!tmp_dir)
00370 tmp_dir = getenv ("TEMP");
00371
00372 if (!tmp_dir)
00373 {
00374 #ifdef OS_WIN32
00375 tmp_dir = "C:\\";
00376 #else
00377 tmp_dir = "/tmp";
00378 #endif
00379 }
00380
00381 strncpy (buffer, tmp_dir, size);
00382 return 0;
00383 }
00384
00385
00386
00387
00388