File: subdir.c

package info (click to toggle)
mtools 3.8-1
  • links: PTS
  • area: main
  • in suites: hamm
  • size: 1,116 kB
  • ctags: 1,306
  • sloc: ansic: 11,489; sh: 2,052; makefile: 223; sed: 8
file content (118 lines) | stat: -rw-r--r-- 2,251 bytes parent folder | download
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;
}