You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
176 lines
3.8 KiB
176 lines
3.8 KiB
/* Copyright 1997,2000-2003,2007-2010 Alain Knaff. This file is
|
|
* part of mtools.
|
|
*
|
|
* Mtools is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* Mtools is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with Mtools. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "sysincludes.h"
|
|
#include "msdos.h"
|
|
#include "stream.h"
|
|
#include "file.h"
|
|
#include "mtoolsDirentry.h"
|
|
#include "file_name.h"
|
|
|
|
void initializeDirentry(direntry_t *entry, Stream_t *Dir)
|
|
{
|
|
memset(entry, 0, sizeof(direntry_t));
|
|
entry->entry = -1;
|
|
entry->Dir = Dir;
|
|
entry->beginSlot = 0;
|
|
entry->endSlot = 0;
|
|
}
|
|
|
|
int isNotFound(direntry_t *entry)
|
|
{
|
|
return entry->entry == -2;
|
|
}
|
|
|
|
direntry_t *getParent(direntry_t *entry)
|
|
{
|
|
return getDirentry(entry->Dir);
|
|
}
|
|
|
|
|
|
static size_t getPathLen(direntry_t *entry)
|
|
{
|
|
size_t length=0;
|
|
|
|
while(1) {
|
|
if(entry->entry == -3) /* rootDir */
|
|
return length + 3;
|
|
|
|
length += 1 + wcslen(entry->name);
|
|
entry = getDirentry(entry->Dir);
|
|
}
|
|
}
|
|
|
|
static char *sprintPwd(direntry_t *entry, char *ptr, size_t *len_available)
|
|
{
|
|
if(entry->entry == -3) {
|
|
*ptr++ = getDrive(entry->Dir);
|
|
*ptr++ = ':';
|
|
*ptr++ = '/';
|
|
(*len_available) -= 3;
|
|
} else {
|
|
size_t bytes_converted;
|
|
ptr = sprintPwd(getDirentry(entry->Dir), ptr, len_available);
|
|
if(ptr[-1] != '/') {
|
|
*ptr++ = '/';
|
|
(*len_available)--;
|
|
}
|
|
bytes_converted = wchar_to_native(entry->name, ptr,
|
|
MAX_VNAMELEN, *len_available);
|
|
ptr += bytes_converted;
|
|
(*len_available) -= bytes_converted;
|
|
}
|
|
return ptr;
|
|
}
|
|
|
|
|
|
#ifdef HAVE_WCHAR_H
|
|
#define NEED_ESCAPE L"\"$\\"
|
|
#else
|
|
#define NEED_ESCAPE "\"$\\"
|
|
#endif
|
|
|
|
static void _fprintPwd(FILE *f, direntry_t *entry, int recurs, int escape)
|
|
{
|
|
if(entry->entry == -3) {
|
|
putc(getDrive(entry->Dir), f);
|
|
putc(':', f);
|
|
if(!recurs)
|
|
putc('/', f);
|
|
} else {
|
|
_fprintPwd(f, getDirentry(entry->Dir), 1, escape);
|
|
if (escape && wcspbrk(entry->name, NEED_ESCAPE)) {
|
|
wchar_t *ptr;
|
|
putc('/', f);
|
|
for(ptr = entry->name; *ptr; ptr++) {
|
|
if (wcschr(NEED_ESCAPE, *ptr))
|
|
putc('\\', f);
|
|
putwc(*ptr, f);
|
|
}
|
|
} else {
|
|
char tmp[4*MAX_VNAMELEN+1];
|
|
WCHAR_TO_NATIVE(entry->name,tmp,MAX_VNAMELEN);
|
|
fprintf(f, "/%s", tmp);
|
|
}
|
|
}
|
|
}
|
|
|
|
void fprintPwd(FILE *f, direntry_t *entry, int escape)
|
|
{
|
|
if (escape)
|
|
putc('"', f);
|
|
_fprintPwd(f, entry, 0, escape);
|
|
if(escape)
|
|
putc('"', f);
|
|
}
|
|
|
|
static void _fprintShortPwd(FILE *f, direntry_t *entry, int recurs)
|
|
{
|
|
if(entry->entry == -3) {
|
|
putc(getDrive(entry->Dir), f);
|
|
putc(':', f);
|
|
if(!recurs)
|
|
putc('/', f);
|
|
} else {
|
|
int i,j;
|
|
_fprintShortPwd(f, getDirentry(entry->Dir), 1);
|
|
putc('/',f);
|
|
for(i=7; i>=0 && entry->dir.name[i] == ' ';i--);
|
|
for(j=0; j<=i; j++)
|
|
putc(entry->dir.name[j],f);
|
|
for(i=2; i>=0 && entry->dir.ext[i] == ' ';i--);
|
|
if(i > 0)
|
|
putc('.',f);
|
|
for(j=0; j<=i; j++)
|
|
putc(entry->dir.ext[j],f);
|
|
}
|
|
}
|
|
|
|
void fprintShortPwd(FILE *f, direntry_t *entry)
|
|
{
|
|
_fprintShortPwd(f, entry, 0);
|
|
}
|
|
|
|
char *getPwd(direntry_t *entry)
|
|
{
|
|
size_t size;
|
|
char *ret;
|
|
char *end;
|
|
size_t buf_size;
|
|
|
|
size = getPathLen(entry);
|
|
buf_size = size*4+1;
|
|
ret = malloc(buf_size);
|
|
if(!ret)
|
|
return 0;
|
|
end = sprintPwd(entry, ret, &buf_size);
|
|
*end = '\0';
|
|
return ret;
|
|
}
|
|
|
|
int isSubdirOf(Stream_t *inside, Stream_t *outside)
|
|
{
|
|
while(1) {
|
|
if(inside == outside) /* both are the same */
|
|
return 1;
|
|
if(getDirentry(inside)->entry == -3) /* root directory */
|
|
return 0;
|
|
/* look further up */
|
|
inside = getDirentry(inside)->Dir;
|
|
}
|
|
}
|