~ubuntu-branches/ubuntu/utopic/grub/utopic

« back to all changes in this revision

Viewing changes to stage2/fsys_vstafs.c

  • Committer: Bazaar Package Importer
  • Author(s): Jason Thomas
  • Date: 2002-02-04 15:35:01 UTC
  • Revision ID: james.westby@ubuntu.com-20020204153501-neulkag77r3a2m0v
Tags: upstream-0.91
ImportĀ upstreamĀ versionĀ 0.91

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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., 675 Mass Ave, Cambridge, MA 02139, USA.
 
18
 */
 
19
 
 
20
#ifdef FSYS_VSTAFS
 
21
 
 
22
#include "shared.h"
 
23
#include "filesys.h"
 
24
#include "vstafs.h"
 
25
 
 
26
 
 
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);
 
30
 
 
31
 
 
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)
 
35
 
 
36
#define ROOT_SECTOR     1
 
37
 
 
38
/*
 
39
 * In f_sector we store the sector number in which the information about
 
40
 * the found file is.
 
41
 */
 
42
extern int filepos;
 
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 *a;
 
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 0;
 
79
    }
 
80
  
 
81
  a = FILE_INFO->blocks;
 
82
  curr_ext = 0;
 
83
  devread (a[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 > (a[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 (a[curr_ext].a_start + current_blockpos, 0,
 
105
                   512, (char *) DIRECTORY_BUF);
 
106
        }
 
107
      else
 
108
        {
 
109
          /* errnum =ERR_FILE_NOT_FOUND; */
 
110
          return 0;
 
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
              putchar ('\n');
 
174
              return 1;
 
175
            }
 
176
          
 
177
          errnum = ERR_FILE_NOT_FOUND;
 
178
          return 0;
 
179
        }
 
180
    }
 
181
  while (*dirname && ! isspace (ch));
 
182
  
 
183
  return 1;
 
184
}
 
185
 
 
186
int 
 
187
vstafs_read (char *addr, int len)
 
188
{
 
189
  struct alloc *a;
 
190
  int size, ret = 0, offset, curr_len = 0;
 
191
  int curr_ext;
 
192
  char extent;
 
193
  int ext_size;
 
194
  char *curr_pos;
 
195
  
 
196
  get_file_info (f_sector);
 
197
  size = FILE_INFO->len-VSTAFS_START_DATA;
 
198
  a = FILE_INFO->blocks;
 
199
  
 
200
  if (filepos > 0)
 
201
    {
 
202
      if (filepos < a[0].a_len * 512 - VSTAFS_START_DATA)
 
203
        {
 
204
          offset = filepos + VSTAFS_START_DATA;
 
205
          extent = 0;
 
206
          curr_len = a[0].a_len * 512 - offset - filepos; 
 
207
        }
 
208
      else
 
209
        {
 
210
          ext_size = a[0].a_len * 512 - VSTAFS_START_DATA;
 
211
          offset = filepos - ext_size;
 
212
          extent = 1;
 
213
          do
 
214
            {
 
215
              curr_len -= ext_size;
 
216
              offset -= ext_size;
 
217
              ext_size = a[extent+1].a_len * 512;
 
218
            }
 
219
          while (extent < FILE_INFO->extents && offset>ext_size);
 
220
        }
 
221
    }
 
222
  else
 
223
    {
 
224
      offset = VSTAFS_START_DATA;
 
225
      extent = 0;
 
226
      curr_len = a[0].a_len * 512 - offset;
 
227
    }
 
228
  
 
229
  curr_pos = addr;
 
230
  if (curr_len > len)
 
231
    curr_len = len;
 
232
  
 
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++)
 
236
    {
 
237
      ret += curr_len;
 
238
      size -= curr_len;
 
239
      if (size < 0)
 
240
        {
 
241
          ret += size;
 
242
          curr_len += size;
 
243
        }
 
244
      
 
245
      devread (a[curr_ext].a_start,offset, curr_len, curr_pos);
 
246
      offset = 0;
 
247
    }
 
248
  
 
249
  return ret;
 
250
}
 
251
 
 
252
#endif /* FSYS_VSTAFS */