unixfs.c

Go to the documentation of this file.
00001 /*
00002  * Winefile
00003  *
00004  * Copyright 2000, 2003, 2004, 2005, 2008 Martin Fuchs
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00019  */
00020 
00021 #include "winefile.h"
00022 
00023 
00024 #if !defined(_NO_EXTENSIONS) && defined(__WINE__)
00025 
00026 /* convert a time_t value to a FILETIME structure */
00027 static BOOL time_to_filetime(const time_t* t, FILETIME* ftime)
00028 {
00029     struct tm* tm = gmtime(t);
00030     SYSTEMTIME stime;
00031 
00032     if (!tm)
00033         return FALSE;
00034 
00035     stime.wYear = tm->tm_year+1900;
00036     stime.wMonth = tm->tm_mon+1;
00037     /* stime.wDayOfWeek */
00038     stime.wDay = tm->tm_mday;
00039     stime.wHour = tm->tm_hour;
00040     stime.wMinute = tm->tm_min;
00041     stime.wSecond = tm->tm_sec;
00042 
00043     return SystemTimeToFileTime(&stime, ftime);
00044 }
00045 
00046 /* read a directory entry using the UNIX API */
00047 void read_directory_unix(Entry* dir, LPCTSTR path)
00048 {
00049     Entry* first_entry = NULL;
00050     Entry* last = NULL;
00051     Entry* entry;
00052     DIR* pdir;
00053 
00054     int level = dir->level + 1;
00055 #ifdef UNICODE
00056     char cpath[MAX_PATH];
00057 
00058     WideCharToMultiByte(CP_UNIXCP, 0, path, -1, cpath, MAX_PATH, NULL, NULL);
00059 #else
00060     const char* cpath = path;
00061 #endif
00062 
00063     pdir = opendir(cpath);
00064 
00065     if (pdir) {
00066         struct stat st;
00067         struct dirent* ent;
00068         char buffer[MAX_PATH], *p;
00069         const char* s;
00070 
00071         for(p=buffer,s=cpath; *s; )
00072             *p++ = *s++;
00073 
00074         if (p==buffer || p[-1]!='/')
00075             *p++ = '/';
00076 
00077         while((ent=readdir(pdir))) {
00078             entry = alloc_entry();
00079 
00080             if (!first_entry)
00081                 first_entry = entry;
00082 
00083             if (last)
00084                 last->next = entry;
00085 
00086             entry->etype = ET_UNIX;
00087 
00088             strcpy(p, ent->d_name);
00089 #ifdef UNICODE
00090             MultiByteToWideChar(CP_UNIXCP, 0, p, -1, entry->data.cFileName, MAX_PATH);
00091 #else
00092             lstrcpy(entry->data.cFileName, p);
00093 #endif
00094 
00095             if (!stat(buffer, &st)) {
00096                 entry->data.dwFileAttributes = p[0]=='.'? FILE_ATTRIBUTE_HIDDEN: 0;
00097 
00098                 if (S_ISDIR(st.st_mode))
00099                     entry->data.dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
00100 
00101                 entry->data.nFileSizeLow = st.st_size & 0xFFFFFFFF;
00102                 entry->data.nFileSizeHigh = st.st_size >> 32;
00103 
00104                 memset(&entry->data.ftCreationTime, 0, sizeof(FILETIME));
00105                 time_to_filetime(&st.st_atime, &entry->data.ftLastAccessTime);
00106                 time_to_filetime(&st.st_mtime, &entry->data.ftLastWriteTime);
00107 
00108                 entry->bhfi.nFileIndexLow = ent->d_ino;
00109                 entry->bhfi.nFileIndexHigh = 0;
00110 
00111                 entry->bhfi.nNumberOfLinks = st.st_nlink;
00112 
00113                 entry->bhfi_valid = TRUE;
00114             } else {
00115                 entry->data.nFileSizeLow = 0;
00116                 entry->data.nFileSizeHigh = 0;
00117                 entry->bhfi_valid = FALSE;
00118             }
00119 
00120             entry->down = NULL;
00121             entry->up = dir;
00122             entry->expanded = FALSE;
00123             entry->scanned = FALSE;
00124             entry->level = level;
00125 
00126             last = entry;
00127         }
00128 
00129         if (last)
00130             last->next = NULL;
00131 
00132         closedir(pdir);
00133     }
00134 
00135     dir->down = first_entry;
00136     dir->scanned = TRUE;
00137 }
00138 
00139 /* search a UNIX directory entry by name */
00140 static Entry* find_entry_unix(Entry* dir, LPCTSTR name)
00141 {
00142     Entry* entry;
00143 
00144     for(entry=dir->down; entry; entry=entry->next) {
00145         LPCTSTR p = name;
00146         LPCTSTR q = entry->data.cFileName;
00147 
00148         do {
00149             if (!*p || *p=='/')
00150                 return entry;
00151         } while(*p++ == *q++);
00152     }
00153 
00154     return 0;
00155 }
00156 
00157 /* read a directory tree for the given path using the WIN32 Unix API */
00158 Entry* read_tree_unix(Root* root, LPCTSTR path, enum SORT_ORDER sortOrder, HWND hwnd)
00159 {
00160     TCHAR buffer[MAX_PATH];
00161     Entry* entry = &root->entry;
00162     LPCTSTR s = path;
00163     PTSTR d = buffer;
00164 
00165     HCURSOR old_cursor = SetCursor(LoadCursor(0, IDC_WAIT));
00166 
00167     entry->etype = ET_UNIX;
00168 
00169     while(entry) {
00170         while(*s && *s!='/')
00171             *d++ = *s++;
00172 
00173         while(*s == '/')
00174             s++;
00175 
00176         *d++ = '/';
00177         *d = '\0';
00178 
00179         read_directory(entry, buffer, sortOrder, hwnd);
00180 
00181         if (entry->down)
00182             entry->expanded = TRUE;
00183 
00184         if (!*s)
00185             break;
00186 
00187         entry = find_entry_unix(entry, s);
00188     }
00189 
00190     SetCursor(old_cursor);
00191 
00192     return entry;
00193 }
00194 
00195 #endif /* !defined(_NO_EXTENSIONS) && defined(__WINE__) */

Winefile Source Code Documentation
generated on 15.09.2008 by doxygen

Winefile Homepage