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 
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     /* append backslash if entry only consists of a drive specification */
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 /* OS_WIN32 */
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 /* OS_WIN32 */
00111   }
00112   GWEN_Buffer_AppendString(buf, entry);
00113 
00114   /* check for existence of the file/folder */
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   } /* if stat is ok */
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       /* create file */
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       /* create dir */
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   } /* if exists */
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   /* handle drive letters (only check for normal slashes here) */
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   /* Copied from http://svn.gnome.org/viewcvs/glib/trunk/glib/gutils.c */
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  /* !OS_WIN32 */
00379     }
00380 
00381   strncpy (buffer, tmp_dir, size);
00382   return 0;
00383 }
00384 
00385 
00386 
00387 
00388 

Generated on Wed Jul 9 13:12:27 2008 for gwenhywfar by  doxygen 1.5.6