unixfs.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright 2003, 2004 Martin Fuchs
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2.1 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Lesser General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Lesser General Public
00015  * License along with this library; if not, write to the Free Software
00016  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017  */
00018 
00019 
00020  //
00021  // Explorer clone
00022  //
00023  // unixfs.cpp
00024  //
00025  // Martin Fuchs, 23.07.2003
00026  //
00027 
00028 
00029 #ifdef __WINE__
00030 
00031 #include <precomp.h>
00032 
00033 //#include "unixfs.h"
00034 
00035  // for UnixDirectory::read_directory()
00036 #include <dirent.h>
00037 #include <sys/stat.h>
00038 #include <time.h>
00039 
00040 
00041 void UnixDirectory::read_directory()
00042 {
00043     Entry* first_entry = NULL;
00044     Entry* last = NULL;
00045     Entry* entry;
00046 
00047     int level = _level + 1;
00048 
00049     LPCTSTR path = (LPCTSTR)_path;
00050     DIR* pdir = opendir(path);
00051 
00052     if (pdir) {
00053         struct stat st;
00054         struct dirent* ent;
00055         TCHAR buffer[MAX_PATH], *p;
00056 
00057         for(p=buffer; *path; )
00058             *p++ = *path++;
00059 
00060         if (p==buffer || p[-1]!='/')
00061             *p++ = '/';
00062 
00063         while((ent=readdir(pdir))) {
00064             int statres = stat(buffer, &st);
00065 
00066             if (!statres && S_ISDIR(st.st_mode))
00067                 entry = new UnixDirectory(this, buffer);
00068             else
00069                 entry = new UnixEntry(this);
00070 
00071             if (!first_entry)
00072                 first_entry = entry;
00073 
00074             if (last)
00075                 last->_next = entry;
00076 
00077             lstrcpy(entry->_data.cFileName, ent->d_name);
00078             entry->_data.dwFileAttributes = ent->d_name[0]=='.'? FILE_ATTRIBUTE_HIDDEN: 0;
00079 
00080             strcpy(p, ent->d_name);
00081 
00082             if (!statres) {
00083                 if (S_ISDIR(st.st_mode))
00084                     entry->_data.dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
00085 
00086                 entry->_data.nFileSizeLow = st.st_size & 0xFFFFFFFF;
00087                 entry->_data.nFileSizeHigh = st.st_size >> 32;
00088 
00089                 memset(&entry->_data.ftCreationTime, 0, sizeof(FILETIME));
00090                 time_to_filetime(&st.st_atime, &entry->_data.ftLastAccessTime);
00091                 time_to_filetime(&st.st_mtime, &entry->_data.ftLastWriteTime);
00092 
00093                 entry->_bhfi.nFileIndexLow = ent->d_ino;
00094                 entry->_bhfi.nFileIndexHigh = 0;
00095 
00096                 entry->_bhfi.nNumberOfLinks = st.st_nlink;
00097 
00098                 entry->_bhfi_valid = TRUE;
00099             } else {
00100                 entry->_data.nFileSizeLow = 0;
00101                 entry->_data.nFileSizeHigh = 0;
00102                 entry->_bhfi_valid = FALSE;
00103             }
00104 
00105             entry->_up = this;
00106             entry->_expanded = FALSE;
00107             entry->_scanned = FALSE;
00108             entry->_level = level;
00109 
00110             last = entry;
00111         }
00112 
00113         last->_next = NULL;
00114 
00115         closedir(pdir);
00116     }
00117 
00118     _down = first_entry;
00119     _scanned = true;
00120 }
00121 
00122 
00123 const void* UnixDirectory::get_next_path_component(const void* p)
00124 {
00125     LPCTSTR s = (LPCTSTR) p;
00126 
00127     while(*s && *s!=TEXT('/'))
00128         ++s;
00129 
00130     while(*s == TEXT('/'))
00131         ++s;
00132 
00133     if (!*s)
00134         return NULL;
00135 
00136     return s;
00137 }
00138 
00139 
00140 Entry* UnixDirectory::find_entry(const void* p)
00141 {
00142     LPCTSTR name = (LPCTSTR)p;
00143 
00144     for(Entry*entry=_down; entry; entry=entry->_next) {
00145         LPCTSTR p = name;
00146         LPCTSTR q = entry->_data.cFileName;
00147 
00148         do {
00149             if (!*p || *p==TEXT('/'))
00150                 return entry;
00151         } while(*p++ == *q++);
00152     }
00153 
00154     return NULL;
00155 }
00156 
00157 
00158  // get full path of specified directory entry
00159 bool UnixEntry::get_path(PTSTR path, size_t path_count) const
00160 {
00161     int level = 0;
00162     size_t len = 0;
00163 
00164     if (!path || path_count==0)
00165         return false;
00166 
00167     if ( path_count > 1 )
00168     {
00169         for(const Entry* entry=this; entry; level++) {
00170             LPCTSTR name = entry->_data.cFileName;
00171             size_t l = 0;
00172 
00173             for(LPCTSTR s=name; *s && *s!=TEXT('/'); s++)
00174                 ++l;
00175 
00176             if (entry->_up) {
00177                 if (l > 0) {
00178                     if ( len+l+1 >= path_count )
00179                     {
00180                         /* compare to 2 here because of terminator plus the '\\' we prepend */
00181                         if ( l + 2 > path_count )
00182                             len = 0;
00183                         else
00184                             len = path_count - l - 2;
00185                     }
00186                     memmove(path+l+1, path, len*sizeof(TCHAR));
00187                     /* compare to 2 here because of terminator plus the '\\' we prepend */
00188                     if ( l+2 >= path_count )
00189                         l = path_count - 2;
00190                     memcpy(path+1, name, l*sizeof(TCHAR));
00191                     len += l+1;
00192 
00193                     path[0] = TEXT('/');
00194                 }
00195 
00196                 entry = entry->_up;
00197             } else {
00198                 if ( len+l >= path_count )
00199                 {
00200                     if ( l + 1 > path_count )
00201                         len = 0;
00202                     else
00203                         len = path_count - l - 1;
00204                 }
00205                 memmove(path+l, path, len*sizeof(TCHAR));
00206                 if ( l+1 >= path_count )
00207                     l = path_count - 1;
00208                 memcpy(path, name, l*sizeof(TCHAR));
00209                 len += l;
00210                 break;
00211             }
00212         }
00213 
00214         if ( !level && (len+1 < path_count) )
00215             path[len++] = TEXT('/');
00216     }
00217 
00218     path[len] = TEXT('\0');
00219 
00220     return true;
00221 }
00222 
00223 #endif // __WINE__

ROS Explorer Source Code Documentation
generated on 02.01.2013 by doxygen

ROS Explorer Homepage