2 * GRUB -- GRand Unified Bootloader
3 * Copyright (C) 2001 Free Software Foundation, Inc.
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.
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.
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,
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);
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)
40 * In f_sector we store the sector number in which the information about
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)
60 get_file_info (int sector)
62 devread (sector, 0, BLOCK_SIZE, (char *) FILE_INFO);
65 static int curr_ext, current_direntry, current_blockpos;
66 static struct alloc *a1;
68 static struct dir_entry *
69 vstafs_readdir (long sector)
72 * Get some information from the current directory
74 get_file_info (sector);
75 if (FILE_INFO->type != 2)
77 errnum = ERR_FILE_NOT_FOUND;
81 a1 = FILE_INFO->blocks;
83 devread (a1[curr_ext].a_start, 0, 512, (char *) DIRECTORY_BUF);
84 current_direntry = 11;
87 return &DIRECTORY_BUF[10];
90 static struct dir_entry *
93 if (current_direntry > 15)
96 if (++current_blockpos > (a1[curr_ext].a_len - 1))
102 if (curr_ext < FILE_INFO->extents)
104 devread (a1[curr_ext].a_start + current_blockpos, 0,
105 512, (char *) DIRECTORY_BUF);
109 /* errnum =ERR_FILE_NOT_FOUND; */
114 return &DIRECTORY_BUF[current_direntry++];
118 vstafs_dir (char *dirname)
125 * Read in the entries of the current directory.
127 f_sector = ROOT_SECTOR;
130 if (! (d = vstafs_readdir (f_sector)))
136 * Find the file in the path
138 while (*dirname == '/') dirname++;
140 while ((ch = *fn) && ch != '/' && ! isspace (ch)) fn++;
145 if (d->name[0] == 0 || d->name[0] & 0x80)
149 if (print_possibilities && ch != '/'
150 && (! *dirname || strcmp (dirname, d->name) <= 0))
152 if (print_possibilities > 0)
153 print_possibilities = -print_possibilities;
155 printf (" %s", d->name);
158 if (! grub_strcmp (dirname, d->name))
161 get_file_info (f_sector);
162 filemax = FILE_INFO->len;
166 while ((d =vstafs_nextdir ()));
168 *(dirname = fn) = ch;
171 if (print_possibilities < 0)
179 errnum = ERR_FILE_NOT_FOUND;
183 while (*dirname && ! isspace (ch));
189 vstafs_read (char *addr, int len)
192 int size, ret = 0, offset, curr_len = 0;
198 get_file_info (f_sector);
199 size = FILE_INFO->len-VSTAFS_START_DATA;
200 a2 = FILE_INFO->blocks;
204 if (filepos < a2[0].a_len * 512 - VSTAFS_START_DATA)
206 offset = filepos + VSTAFS_START_DATA;
208 curr_len = a2[0].a_len * 512 - offset - filepos;
212 ext_size = a2[0].a_len * 512 - VSTAFS_START_DATA;
213 offset = filepos - ext_size;
217 curr_len -= ext_size;
219 ext_size = a2[extent+1].a_len * 512;
221 while (extent < FILE_INFO->extents && offset>ext_size);
226 offset = VSTAFS_START_DATA;
228 curr_len = a2[0].a_len * 512 - offset;
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++)
247 devread (a2[curr_ext2].a_start,offset, curr_len, curr_pos);
254 #endif /* FSYS_VSTAFS */