• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*  Copyright 1997,2000-2003,2007-2010 Alain Knaff.  This file is
2  *  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 
initializeDirentry(direntry_t * entry,Stream_t * Dir)25 void initializeDirentry(direntry_t *entry, Stream_t *Dir)
26 {
27 	memset(entry, 0, sizeof(direntry_t));
28 	entry->entry = -1;
29 	entry->Dir = Dir;
30 	entry->beginSlot = 0;
31 	entry->endSlot = 0;
32 }
33 
isNotFound(direntry_t * entry)34 int isNotFound(direntry_t *entry)
35 {
36 	return entry->entry == -2;
37 }
38 
getParent(direntry_t * entry)39 direntry_t *getParent(direntry_t *entry)
40 {
41 	return getDirentry(entry->Dir);
42 }
43 
44 
getPathLen(direntry_t * entry)45 static size_t getPathLen(direntry_t *entry)
46 {
47 	size_t 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 
sprintPwd(direntry_t * entry,char * ptr,size_t * len_available)58 static char *sprintPwd(direntry_t *entry, char *ptr, size_t *len_available)
59 {
60 	if(entry->entry == -3) {
61 		*ptr++ = getDrive(entry->Dir);
62 		*ptr++ = ':';
63 		*ptr++ = '/';
64 		(*len_available) -= 3;
65 	} else {
66 		size_t bytes_converted;
67 		ptr = sprintPwd(getDirentry(entry->Dir), ptr, len_available);
68 		if(ptr[-1] != '/') {
69 			*ptr++ = '/';
70 			(*len_available)--;
71 		}
72 		bytes_converted = wchar_to_native(entry->name, ptr,
73 						  MAX_VNAMELEN, *len_available);
74 		ptr += bytes_converted;
75 		(*len_available) -= bytes_converted;
76 	}
77 	return ptr;
78 }
79 
80 
81 #ifdef HAVE_WCHAR_H
82 #define NEED_ESCAPE L"\"$\\"
83 #else
84 #define NEED_ESCAPE "\"$\\"
85 #endif
86 
_fprintPwd(FILE * f,direntry_t * entry,int recurs,int escape)87 static void _fprintPwd(FILE *f, direntry_t *entry, int recurs, int escape)
88 {
89 	if(entry->entry == -3) {
90 		putc(getDrive(entry->Dir), f);
91 		putc(':', f);
92 		if(!recurs)
93 			putc('/', f);
94 	} else {
95 		_fprintPwd(f, getDirentry(entry->Dir), 1, escape);
96 		if (escape && wcspbrk(entry->name, NEED_ESCAPE)) {
97 			wchar_t *ptr;
98 			putc('/', f);
99 			for(ptr = entry->name; *ptr; ptr++) {
100 				if (wcschr(NEED_ESCAPE, *ptr))
101 					putc('\\', f);
102 				putwc(*ptr, f);
103 			}
104 		} else {
105 			char tmp[4*MAX_VNAMELEN+1];
106 			WCHAR_TO_NATIVE(entry->name,tmp,MAX_VNAMELEN);
107 			fprintf(f, "/%s", tmp);
108 		}
109 	}
110 }
111 
fprintPwd(FILE * f,direntry_t * entry,int escape)112 void fprintPwd(FILE *f, direntry_t *entry, int escape)
113 {
114 	if (escape)
115 		putc('"', f);
116 	_fprintPwd(f, entry, 0, escape);
117 	if(escape)
118 		putc('"', f);
119 }
120 
_fprintShortPwd(FILE * f,direntry_t * entry,int recurs)121 static void _fprintShortPwd(FILE *f, direntry_t *entry, int recurs)
122 {
123 	if(entry->entry == -3) {
124 		putc(getDrive(entry->Dir), f);
125 		putc(':', f);
126 		if(!recurs)
127 			putc('/', f);
128 	} else {
129 		int i,j;
130 		_fprintShortPwd(f, getDirentry(entry->Dir), 1);
131 		putc('/',f);
132 		for(i=7; i>=0 && entry->dir.name[i] == ' ';i--);
133 		for(j=0; j<=i; j++)
134 			putc(entry->dir.name[j],f);
135 		for(i=2; i>=0 && entry->dir.ext[i] == ' ';i--);
136 		if(i > 0)
137 			putc('.',f);
138 		for(j=0; j<=i; j++)
139 			putc(entry->dir.ext[j],f);
140 	}
141 }
142 
fprintShortPwd(FILE * f,direntry_t * entry)143 void fprintShortPwd(FILE *f, direntry_t *entry)
144 {
145 	_fprintShortPwd(f, entry, 0);
146 }
147 
getPwd(direntry_t * entry)148 char *getPwd(direntry_t *entry)
149 {
150 	size_t size;
151 	char *ret;
152 	char *end;
153 	size_t buf_size;
154 
155 	size = getPathLen(entry);
156 	buf_size = size*4+1;
157 	ret = malloc(buf_size);
158 	if(!ret)
159 		return 0;
160 	end = sprintPwd(entry, ret, &buf_size);
161 	*end = '\0';
162 	return ret;
163 }
164 
isSubdirOf(Stream_t * inside,Stream_t * outside)165 int isSubdirOf(Stream_t *inside, Stream_t *outside)
166 {
167 	while(1) {
168 		if(inside == outside) /* both are the same */
169 			return 1;
170 		if(getDirentry(inside)->entry == -3) /* root directory */
171 			return 0;
172 		/* look further up */
173 		inside = getDirentry(inside)->Dir;
174 	}
175 }
176