coan 4.2.4
|
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