directory_all.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  $RCSfile$
00003                              -------------------
00004     cvs         : $Id$
00005     begin       : Sun Nov 23 2003
00006     copyright   : (C) 2003 by Martin Preuss
00007     email       : martin@libchipcard.de
00008 
00009  ***************************************************************************
00010  *                                                                         *
00011  *   This library is free software; you can redistribute it and/or         *
00012  *   modify it under the terms of the GNU Lesser General Public            *
00013  *   License as published by the Free Software Foundation; either          *
00014  *   version 2.1 of the License, or (at your option) any later version.    *
00015  *                                                                         *
00016  *   This library is distributed in the hope that it will be useful,       *
00017  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00018  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00019  *   Lesser General Public License for more details.                       *
00020  *                                                                         *
00021  *   You should have received a copy of the GNU Lesser General Public      *
00022  *   License along with this library; if not, write to the Free Software   *
00023  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston,                 *
00024  *   MA  02111-1307  USA                                                   *
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     /* append backslash if entry only consists of a drive specification */
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 /* OS_WIN32 */
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 /* OS_WIN32 */
00112   }
00113   GWEN_Buffer_AppendString(buf, entry);
00114 
00115   /* check for existence of the file/folder */
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   } /* if stat is ok */
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       /* create file */
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       /* create dir */
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   } /* if exists */
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   /* handle drive letters (only check for normal slashes here) */
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   /* Copied from http://svn.gnome.org/viewcvs/glib/trunk/glib/gutils.c */
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  /* !OS_WIN32 */
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 
Generated on Mon Jul 5 22:52:47 2010 for gwenhywfar by  doxygen 1.6.3