coan 4.2.4
fs_nix.c
Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2004, 2006 Symbian Software Ltd.                        *
00003  *   All rights reserved.                                                  *
00004  *   Copyright (C) 2007-2011 Mike Kinghan, imk@strudl.org                  *
00005  *   All rights reserved.                                                  *
00006  *                                                                         *
00007  *   Redistribution and use in source and binary forms, with or without    *
00008  *   modification, are permitted provided that the following conditions    *
00009  *   are met:                                                              *
00010  *                                                                         *
00011  *   Redistributions of source code must retain the above copyright        *
00012  *   notice, this list of conditions and the following disclaimer.         *
00013  *                                                                         *
00014  *   Redistributions in binary form must reproduce the above copyright     *
00015  *   notice, this list of conditions and the following disclaimer in the   *
00016  *   documentation and/or other materials provided with the distribution.  *
00017  *                                                                         *
00018  *   Neither the name of Symbian Software Ltd. nor the names of its        *
00019  *   contributors may be used to endorse or promote products derived from  *
00020  *   this software without specific prior written permission.              *
00021  *                                                                         *
00022  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   *
00023  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     *
00024  *   LIMITED TO, THE IMPLIED WARRANTIES OF  MERCHANTABILITY AND FITNESS    *
00025  *   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE        *
00026  *   COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,   *
00027  *   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,  *
00028  *   BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS *
00029  *   OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED    *
00030  *   AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,*
00031  *   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF *
00032  *   THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH  *
00033  *   DAMAGE.                                                               *
00034  *                                                                         *
00035  **************************************************************************/
00036 
00042 #include "platform.h"
00043 
00044 #ifdef NIX
00045 
00046 #include <sys/stat.h>
00047 #include <sys/types.h>
00048 #include <dirent.h>
00049 #include "filesys.h"
00050 #include "report.h"
00051 
00052 
00055 
00057 typedef struct fs_dir_nix {
00059     struct fs_dir_nix * parent;
00061     heap_str dirname;
00063     char *dirname_end;
00065     DIR * dir;
00067     struct dirent entry;
00068 } fs_dir_nix_t;
00069 
00073 heap_str
00074 fs_real_path(char const *relname, size_t *namelen)
00075 {
00076     char buf[PATH_MAX];
00077     if (realpath(relname,buf)) {
00078         char *full_path;
00079         size_t len = strlen(buf);
00080         if (namelen) {
00081             *namelen = len;
00082         }
00083         full_path = zallocate(len + 1);
00084         strcpy(full_path,buf);
00085         return full_path;
00086     }
00087     return NULL;
00088 }
00089 
00090 fs_obj_type_t
00091 fs_obj_type(char const *name)
00092 {
00093     fs_obj_type_t type = FS_OBJ_NONE;
00094     struct stat obj_info;
00095     int res = lstat(name,&obj_info);
00096     if (!res) {
00097         if (S_ISLNK(obj_info.st_mode)) {
00098             type |= FS_OBJ_SLINK;
00099         }
00100         res = stat(name,&obj_info);
00101         if (!res) {
00102             if (S_ISREG(obj_info.st_mode)) {
00103                 type |= FS_OBJ_FILE;
00104             } else if (S_ISDIR(obj_info.st_mode)) {
00105                 type |= FS_OBJ_DIR;
00106             }
00107         }
00108     }
00109     return type;
00110 }
00111 
00112 fs_dir_t
00113 fs_open_dir(char const *dirname, fs_dir_t const parent)
00114 {
00115     fs_dir_nix_t * dir = NULL;
00116     DIR * dir_handle = opendir(dirname);
00117     if (dir_handle ) {
00118         size_t namelen;
00119         heap_str fullname = fs_real_path(dirname,&namelen);
00120         if (fullname) {
00121             dir = zallocate(sizeof(fs_dir_nix_t));
00122             dir->parent = (fs_dir_nix_t *)parent;
00123             dir->dir = dir_handle;
00124             dir->dirname = fullname;
00125             dir->dirname_end = dir->dirname + namelen;
00126         }
00127     }
00128     return dir;
00129 }
00130 
00131 
00132 void
00133 fs_close_dir(fs_dir_t dir)
00134 {
00135     fs_dir_nix_t * nix_dir = dir;
00136     assert(dir);
00137     if (nix_dir->dir) {
00138         closedir(nix_dir->dir);
00139         free(nix_dir->dirname);
00140         free(nix_dir);
00141     }
00142 }
00143 
00144 char const *
00145 fs_read_dir(fs_dir_t dir, char const **fullname)
00146 {
00147     char *filename = NULL;
00148     fs_dir_nix_t * nix_dir = dir;
00149     struct dirent * entry;
00150     int res = readdir_r(nix_dir->dir,&nix_dir->entry,&entry);
00151     if (res) {
00152         bail(GRIPE_CANT_READ_DIR,"Read error on directory \"%s\"",
00153              nix_dir->dirname);
00154     }
00155     if (entry) {
00156         filename = nix_dir->entry.d_name;
00157         if (filename[0] == '.' &&
00158                 ((filename[1] == '.' && filename[2] == '\0') || filename[1] == '\0')) {
00159             return fs_read_dir(dir,fullname);
00160         }
00161         if (fullname) {
00162             size_t len = nix_dir->dirname_end - nix_dir->dirname;
00163             size_t available = strlen(nix_dir->dirname_end) ;
00164             size_t needed = strlen(filename) + 1;
00165             if (available < needed) {
00166                 nix_dir->dirname = reallocate(nix_dir->dirname,len + needed + 1);
00167                 nix_dir->dirname_end = nix_dir->dirname + len;
00168             }
00169             *nix_dir->dirname_end = PATH_DELIM;
00170             strcpy(nix_dir->dirname_end + 1,filename);
00171             filename = nix_dir->dirname_end + 1;
00172             *fullname = nix_dir->dirname;
00173         }
00174     } else {
00175         *nix_dir->dirname_end = '\0';
00176     }
00177     return filename;
00178 }
00179 
00180 char const *
00181 fs_cur_dir_entry(fs_dir_t dir, char const **entry)
00182 {
00183     fs_dir_nix_t * nix_dir = dir;
00184     assert(dir);
00185     if (entry) {
00186         *entry = nix_dir->dirname_end;
00187     }
00188     return nix_dir->dirname;
00189 }
00190 
00191 fs_dir_t
00192 fs_get_parent(fs_dir_t dir)
00193 {
00194     fs_dir_nix_t * nix_dir;
00195     assert(dir);
00196     nix_dir = dir;
00197     return nix_dir->parent;
00198 }
00199 
00200 #endif
00201 
00202 /* EOF*/
00203 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines