1/* Copyright 1997,2000-2003,2007-2009 Alain Knaff. 2 * This file is part of mtools. 3 * 4 * Mtools is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * Mtools is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with Mtools. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18#include "sysincludes.h" 19#include "msdos.h" 20#include "stream.h" 21#include "file.h" 22#include "mtoolsDirentry.h" 23#include "file_name.h" 24 25void initializeDirentry(direntry_t *entry, Stream_t *Dir) 26{ 27 entry->entry = -1; 28/* entry->parent = getDirentry(Dir);*/ 29 entry->Dir = Dir; 30 entry->beginSlot = 0; 31 entry->endSlot = 0; 32} 33 34int isNotFound(direntry_t *entry) 35{ 36 return entry->entry == -2; 37} 38 39direntry_t *getParent(direntry_t *entry) 40{ 41 return getDirentry(entry->Dir); 42} 43 44 45static int getPathLen(direntry_t *entry) 46{ 47 int length=0; 48 49 while(1) { 50 if(entry->entry == -3) /* rootDir */ 51 return length + 3; 52 53 length += 1 + wcslen(entry->name); 54 entry = getDirentry(entry->Dir); 55 } 56} 57 58static char *sprintPwd(direntry_t *entry, char *ptr) 59{ 60 if(entry->entry == -3) { 61 *ptr++ = getDrive(entry->Dir); 62 *ptr++ = ':'; 63 *ptr++ = '/'; 64 } else { 65 ptr = sprintPwd(getDirentry(entry->Dir), ptr); 66 if(ptr[-1] != '/') 67 *ptr++ = '/'; 68 ptr += wchar_to_native(entry->name, ptr, MAX_VNAMELEN); 69 } 70 return ptr; 71} 72 73 74#ifdef HAVE_WCHAR_H 75#define NEED_ESCAPE L"\"$\\" 76#else 77#define NEED_ESCAPE "\"$\\" 78#endif 79 80static void _fprintPwd(FILE *f, direntry_t *entry, int recurs, int escape) 81{ 82 if(entry->entry == -3) { 83 putc(getDrive(entry->Dir), f); 84 putc(':', f); 85 if(!recurs) 86 putc('/', f); 87 } else { 88 _fprintPwd(f, getDirentry(entry->Dir), 1, escape); 89 if (escape && wcspbrk(entry->name, NEED_ESCAPE)) { 90 wchar_t *ptr; 91 putc('/', f); 92 for(ptr = entry->name; *ptr; ptr++) { 93 if (wcschr(NEED_ESCAPE, *ptr)) 94 putc('\\', f); 95 putwc(*ptr, f); 96 } 97 } else { 98 char tmp[4*MAX_VNAMELEN+1]; 99 wchar_to_native(entry->name,tmp,MAX_VNAMELEN); 100 fprintf(f, "/%s", tmp); 101 } 102 } 103} 104 105void fprintPwd(FILE *f, direntry_t *entry, int escape) 106{ 107 if (escape) 108 putc('"', f); 109 _fprintPwd(f, entry, 0, escape); 110 if(escape) 111 putc('"', f); 112} 113 114char *getPwd(direntry_t *entry) 115{ 116 int size; 117 char *ret; 118 char *end; 119 120 size = getPathLen(entry); 121 ret = malloc(size+1); 122 if(!ret) 123 return 0; 124 end = sprintPwd(entry, ret); 125 *end = '\0'; 126 return ret; 127} 128 129int isSubdirOf(Stream_t *inside, Stream_t *outside) 130{ 131 while(1) { 132 if(inside == outside) /* both are the same */ 133 return 1; 134 if(getDirentry(inside)->entry == -3) /* root directory */ 135 return 0; 136 /* look further up */ 137 inside = getDirentry(inside)->Dir; 138 } 139} 140