1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
|
#include "sysincludes.h"
#include "msdos.h"
#include "mtools.h"
#include "vfat.h"
#include "file.h"
#include "buffer.h"
/*
* Find the directory and load a new dir_chain[]. A null directory
* is OK. Returns a 1 on error.
*/
static void bufferize(Stream_t **Dir)
{
Stream_t *BDir;
#if 1
if(!*Dir)
return;
BDir = buf_init(*Dir, 16384, MDIR_SIZE, MDIR_SIZE);
if(!BDir){
FREE(Dir);
*Dir = NULL;
} else
*Dir = BDir;
#endif
}
Stream_t *descend(Stream_t *Dir, char *path, int barf,char *outname, int lock)
{
/* this function makes its own copy of the Next pointers */
int entry;
struct directory dir;
Stream_t *SubDir;
int ret;
if(path[0] == '\0' || !strcmp(path, "."))
/* don't waste timing scanning through the directory if
* we look for dot anyways */
return COPY(Dir);
entry = 0;
ret = vfat_lookup(Dir, &dir, &entry, 0, path,
ACCEPT_DIR | SINGLE | DO_OPEN | (barf ? 0 : NO_MSG),
outname, 0, 0);
if(ret == 0){
SubDir = open_file(Dir, &dir);
if(lock)
LockFile(SubDir);
bufferize(&SubDir);
return SubDir;
}
/*
* If path is '..', but it wasn't found, then you must be
* at root.
*/
if (!strcmp(path, "..")){
SubDir = open_root(Dir);
bufferize(&SubDir);
if(lock)
LockFile(SubDir);
return SubDir;
}
if (barf)
fprintf(stderr, "Path component \"%s\" is not a directory\n",
path);
return NULL;
}
/*
* Descends the directory tree. Returns 1 on error. Attempts to optimize by
* remembering the last path it parsed
*/
Stream_t *subdir(Stream_t *Fs, char *pathname, int lock)
{
/* this function makes its own copy of the Next pointers */
char *s, *tmp, tbuf[MAX_PATH], *path, terminator;
Stream_t *Dir, *NewDir;
/* FIXME: path caching */
strcpy(tbuf, pathname);
/* start at root */
Dir = open_root(Fs);
bufferize(&Dir);
if (!Dir){
FREE(&Fs);
return Dir;
}
/* separate the parts */
tmp = &tbuf[1];
for (s = tmp; ; ++s) {
if (*s == '/' || *s == '\0') {
path = tmp;
terminator = *s;
*s = '\0';
if (s != tmp && strcmp(path,".") && path[0]){
NewDir = descend(Dir, path, 1, 0, lock);
FREE(&Dir);
if(!NewDir)
return NewDir;
Dir = NewDir;
}
if (!terminator)
break;
tmp = s + 1;
}
}
return Dir;
}
|