|
|
1.1 root 1: /*
2: * GRUB -- GRand Unified Bootloader
3: * Copyright (C) 2001 Free Software Foundation, Inc.
4: *
5: * This program is free software; you can redistribute it and/or modify
6: * it under the terms of the GNU General Public License as published by
7: * the Free Software Foundation; either version 2 of the License, or
8: * (at your option) any later version.
9: *
10: * This program is distributed in the hope that it will be useful,
11: * but WITHOUT ANY WARRANTY; without even the implied warranty of
12: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13: * GNU General Public License for more details.
14: *
15: * You should have received a copy of the GNU General Public License
16: * along with this program; if not, write to the Free Software
17: * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
18: * MA 02110-1301, USA.
19: */
20:
21: #ifdef FSYS_VSTAFS
22:
23: #include "shared.h"
24: #include "filesys.h"
25: #include "vstafs.h"
26:
27:
28: static void get_file_info (int sector);
29: static struct dir_entry *vstafs_readdir (long sector);
30: static struct dir_entry *vstafs_nextdir (void);
31:
32:
33: #define FIRST_SECTOR ((struct first_sector *) FSYS_BUF)
34: #define FILE_INFO ((struct fs_file *) (long) FIRST_SECTOR + 8192)
35: #define DIRECTORY_BUF ((struct dir_entry *) (long) FILE_INFO + 512)
36:
37: #define ROOT_SECTOR 1
38:
39: /*
40: * In f_sector we store the sector number in which the information about
41: * the found file is.
42: */
43: static int f_sector;
44:
45: int
46: vstafs_mount (void)
47: {
48: int retval = 1;
49:
50: if( (((current_drive & 0x80) || (current_slice != 0))
51: && current_slice != PC_SLICE_TYPE_VSTAFS)
52: || ! devread (0, 0, BLOCK_SIZE, (char *) FSYS_BUF)
53: || FIRST_SECTOR->fs_magic != 0xDEADFACE)
54: retval = 0;
55:
56: return retval;
57: }
58:
59: static void
60: get_file_info (int sector)
61: {
62: devread (sector, 0, BLOCK_SIZE, (char *) FILE_INFO);
63: }
64:
65: static int curr_ext, current_direntry, current_blockpos;
66: static struct alloc *a1;
67:
68: static struct dir_entry *
69: vstafs_readdir (long sector)
70: {
71: /*
72: * Get some information from the current directory
73: */
74: get_file_info (sector);
75: if (FILE_INFO->type != 2)
76: {
77: errnum = ERR_FILE_NOT_FOUND;
78: return NULL;
79: }
80:
81: a1 = FILE_INFO->blocks;
82: curr_ext = 0;
83: devread (a1[curr_ext].a_start, 0, 512, (char *) DIRECTORY_BUF);
84: current_direntry = 11;
85: current_blockpos = 0;
86:
87: return &DIRECTORY_BUF[10];
88: }
89:
90: static struct dir_entry *
91: vstafs_nextdir (void)
92: {
93: if (current_direntry > 15)
94: {
95: current_direntry = 0;
96: if (++current_blockpos > (a1[curr_ext].a_len - 1))
97: {
98: current_blockpos = 0;
99: curr_ext++;
100: }
101:
102: if (curr_ext < FILE_INFO->extents)
103: {
104: devread (a1[curr_ext].a_start + current_blockpos, 0,
105: 512, (char *) DIRECTORY_BUF);
106: }
107: else
108: {
109: /* errnum =ERR_FILE_NOT_FOUND; */
110: return NULL;
111: }
112: }
113:
114: return &DIRECTORY_BUF[current_direntry++];
115: }
116:
117: int
118: vstafs_dir (char *dirname)
119: {
120: char *fn, ch;
121: struct dir_entry *d;
122: /* int l, i, s; */
123:
124: /*
125: * Read in the entries of the current directory.
126: */
127: f_sector = ROOT_SECTOR;
128: do
129: {
130: if (! (d = vstafs_readdir (f_sector)))
131: {
132: return 0;
133: }
134:
135: /*
136: * Find the file in the path
137: */
138: while (*dirname == '/') dirname++;
139: fn = dirname;
140: while ((ch = *fn) && ch != '/' && ! isspace (ch)) fn++;
141: *fn = 0;
142:
143: do
144: {
145: if (d->name[0] == 0 || d->name[0] & 0x80)
146: continue;
147:
148: #ifndef STAGE1_5
149: if (print_possibilities && ch != '/'
150: && (! *dirname || strcmp (dirname, d->name) <= 0))
151: {
152: if (print_possibilities > 0)
153: print_possibilities = -print_possibilities;
154:
155: printf (" %s", d->name);
156: }
157: #endif
158: if (! grub_strcmp (dirname, d->name))
159: {
160: f_sector = d->start;
161: get_file_info (f_sector);
162: filemax = FILE_INFO->len;
163: break;
164: }
165: }
166: while ((d =vstafs_nextdir ()));
167:
168: *(dirname = fn) = ch;
169: if (! d)
170: {
171: if (print_possibilities < 0)
172: {
173: #ifndef STAGE1_5
174: putchar ('\n');
175: #endif
176: return 1;
177: }
178:
179: errnum = ERR_FILE_NOT_FOUND;
180: return 0;
181: }
182: }
183: while (*dirname && ! isspace (ch));
184:
185: return 1;
186: }
187:
188: int
189: vstafs_read (char *addr, int len)
190: {
191: struct alloc *a2;
192: int size, ret = 0, offset, curr_len = 0;
193: int curr_ext2;
194: char extent;
195: int ext_size;
196: char *curr_pos;
197:
198: get_file_info (f_sector);
199: size = FILE_INFO->len-VSTAFS_START_DATA;
200: a2 = FILE_INFO->blocks;
201:
202: if (filepos > 0)
203: {
204: if (filepos < a2[0].a_len * 512 - VSTAFS_START_DATA)
205: {
206: offset = filepos + VSTAFS_START_DATA;
207: extent = 0;
208: curr_len = a2[0].a_len * 512 - offset - filepos;
209: }
210: else
211: {
212: ext_size = a2[0].a_len * 512 - VSTAFS_START_DATA;
213: offset = filepos - ext_size;
214: extent = 1;
215: do
216: {
217: curr_len -= ext_size;
218: offset -= ext_size;
219: ext_size = a2[extent+1].a_len * 512;
220: }
221: while (extent < FILE_INFO->extents && offset>ext_size);
222: }
223: }
224: else
225: {
226: offset = VSTAFS_START_DATA;
227: extent = 0;
228: curr_len = a2[0].a_len * 512 - offset;
229: }
230:
231: curr_pos = addr;
232: if (curr_len > len)
233: curr_len = len;
234:
235: for (curr_ext2=extent;
236: curr_ext2 < FILE_INFO->extents;
237: curr_len = a2[curr_ext].a_len * 512, curr_pos += curr_len, curr_ext2++)
238: {
239: ret += curr_len;
240: size -= curr_len;
241: if (size < 0)
242: {
243: ret += size;
244: curr_len += size;
245: }
246:
247: devread (a2[curr_ext2].a_start,offset, curr_len, curr_pos);
248: offset = 0;
249: }
250:
251: return ret;
252: }
253:
254: #endif /* FSYS_VSTAFS */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.