blob: 3d79dc9eef470e1f1665b4453b8bbca052ab3820 [file] [log] [blame]
/* 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;
}
}