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., 675 Mass Ave, Cambridge, MA 02139, USA.
27 static void get_file_info (int sector
);
28 static struct dir_entry
*vstafs_readdir (long sector
);
29 static struct dir_entry
*vstafs_nextdir (void);
32 #define FIRST_SECTOR ((struct first_sector *) FSYS_BUF)
33 #define FILE_INFO ((struct fs_file *) (int) FIRST_SECTOR + 8192)
34 #define DIRECTORY_BUF ((struct dir_entry *) (int) FILE_INFO + 512)
39 * 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
*a
;
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 a
= FILE_INFO
->blocks
;
83 devread (a
[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
> (a
[curr_ext
].a_len
- 1))
102 if (curr_ext
< FILE_INFO
->extents
)
104 devread (a
[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)
177 errnum
= ERR_FILE_NOT_FOUND
;
181 while (*dirname
&& ! isspace (ch
));
187 vstafs_read (char *addr
, int len
)
190 int size
, ret
= 0, offset
, curr_len
= 0;
196 get_file_info (f_sector
);
197 size
= FILE_INFO
->len
-VSTAFS_START_DATA
;
198 a
= FILE_INFO
->blocks
;
202 if (filepos
< a
[0].a_len
* 512 - VSTAFS_START_DATA
)
204 offset
= filepos
+ VSTAFS_START_DATA
;
206 curr_len
= a
[0].a_len
* 512 - offset
- filepos
;
210 ext_size
= a
[0].a_len
* 512 - VSTAFS_START_DATA
;
211 offset
= filepos
- ext_size
;
215 curr_len
-= ext_size
;
217 ext_size
= a
[extent
+1].a_len
* 512;
219 while (extent
< FILE_INFO
->extents
&& offset
>ext_size
);
224 offset
= VSTAFS_START_DATA
;
226 curr_len
= a
[0].a_len
* 512 - offset
;
233 for (curr_ext
=extent
;
234 curr_ext
< FILE_INFO
->extents
;
235 curr_len
= a
[curr_ext
].a_len
* 512, curr_pos
+= curr_len
, curr_ext
++)
245 devread (a
[curr_ext
].a_start
,offset
, curr_len
, curr_pos
);
252 #endif /* FSYS_VSTAFS */