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