~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/openbios/fs/grubfs/fsys_ffs.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  GRUB  --  GRand Unified Bootloader
 
3
 *  Copyright (C) 2000, 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
/*
 
22
 * Elements of this file were originally from the FreeBSD "biosboot"
 
23
 * bootloader file "disk.c" dated 4/12/95.
 
24
 *
 
25
 * The license and header comments from that file are included here.
 
26
 */
 
27
 
 
28
/*
 
29
 * Mach Operating System
 
30
 * Copyright (c) 1992, 1991 Carnegie Mellon University
 
31
 * All Rights Reserved.
 
32
 *
 
33
 * Permission to use, copy, modify and distribute this software and its
 
34
 * documentation is hereby granted, provided that both the copyright
 
35
 * notice and this permission notice appear in all copies of the
 
36
 * software, derivative works or modified versions, and any portions
 
37
 * thereof, and that both notices appear in supporting documentation.
 
38
 *
 
39
 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
 
40
 * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
 
41
 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
 
42
 *
 
43
 * Carnegie Mellon requests users of this software to return to
 
44
 *
 
45
 *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
 
46
 *  School of Computer Science
 
47
 *  Carnegie Mellon University
 
48
 *  Pittsburgh PA 15213-3890
 
49
 *
 
50
 * any improvements or extensions that they make and grant Carnegie Mellon
 
51
 * the rights to redistribute these changes.
 
52
 *
 
53
 *      from: Mach, Revision 2.2  92/04/04  11:35:49  rpd
 
54
 *      $Id: fsys_ffs.c,v 1.10 2001/11/12 06:57:29 okuji Exp $
 
55
 */
 
56
 
 
57
#ifdef FSYS_FFS
 
58
 
 
59
#include "shared.h"
 
60
 
 
61
#include "filesys.h"
 
62
 
 
63
#include "defs.h"
 
64
#include "disk_inode.h"
 
65
#include "disk_inode_ffs.h"
 
66
#include "dir.h"
 
67
#include "fs.h"
 
68
 
 
69
/* used for filesystem map blocks */
 
70
static int mapblock;
 
71
static int mapblock_offset;
 
72
static int mapblock_bsize;
 
73
 
 
74
/* pointer to superblock */
 
75
#define SUPERBLOCK ((struct fs *) ( FSYS_BUF + 8192 ))
 
76
#define INODE ((struct icommon *) ( FSYS_BUF + 16384 ))
 
77
#define MAPBUF ( FSYS_BUF + 24576 )
 
78
#define MAPBUF_LEN 8192
 
79
 
 
80
 
 
81
int
 
82
ffs_mount (void)
 
83
{
 
84
  int retval = 1;
 
85
 
 
86
  if ((((current_drive & 0x80) || (current_slice != 0))
 
87
       && ! IS_PC_SLICE_TYPE_BSD_WITH_FS (current_slice, FS_BSDFFS))
 
88
      || part_length < (SBLOCK + (SBSIZE / DEV_BSIZE))
 
89
      || !devread (SBLOCK, 0, SBSIZE, (char *) SUPERBLOCK)
 
90
      || SUPERBLOCK->fs_magic != FS_MAGIC)
 
91
    retval = 0;
 
92
 
 
93
  mapblock = -1;
 
94
  mapblock_offset = -1;
 
95
 
 
96
  return retval;
 
97
}
 
98
 
 
99
static int
 
100
block_map (int file_block)
 
101
{
 
102
  int bnum, offset, bsize;
 
103
 
 
104
  if (file_block < NDADDR)
 
105
    return (INODE->i_db[file_block]);
 
106
 
 
107
  /* If the blockmap loaded does not include FILE_BLOCK,
 
108
     load a new blockmap.  */
 
109
  if ((bnum = fsbtodb (SUPERBLOCK, INODE->i_ib[0])) != mapblock
 
110
      || (mapblock_offset <= bnum && bnum <= mapblock_offset + mapblock_bsize))
 
111
    {
 
112
      if (MAPBUF_LEN < SUPERBLOCK->fs_bsize)
 
113
        {
 
114
          offset = ((file_block - NDADDR) % NINDIR (SUPERBLOCK));
 
115
          bsize = MAPBUF_LEN;
 
116
 
 
117
          if (offset + MAPBUF_LEN > SUPERBLOCK->fs_bsize)
 
118
            offset = (SUPERBLOCK->fs_bsize - MAPBUF_LEN) / sizeof (int);
 
119
        }
 
120
      else
 
121
        {
 
122
          bsize = SUPERBLOCK->fs_bsize;
 
123
          offset = 0;
 
124
        }
 
125
 
 
126
      if (! devread (bnum, offset * sizeof (int), bsize, (char *) MAPBUF))
 
127
        {
 
128
          mapblock = -1;
 
129
          mapblock_bsize = -1;
 
130
          mapblock_offset = -1;
 
131
          errnum = ERR_FSYS_CORRUPT;
 
132
          return -1;
 
133
        }
 
134
 
 
135
      mapblock = bnum;
 
136
      mapblock_bsize = bsize;
 
137
      mapblock_offset = offset;
 
138
    }
 
139
 
 
140
  return (((int *) MAPBUF)[((file_block - NDADDR) % NINDIR (SUPERBLOCK))
 
141
                          - mapblock_offset]);
 
142
}
 
143
 
 
144
 
 
145
int
 
146
ffs_read (char *buf, int len)
 
147
{
 
148
  int logno, off, size, map, ret = 0;
 
149
 
 
150
  while (len && !errnum)
 
151
    {
 
152
      off = blkoff (SUPERBLOCK, filepos);
 
153
      logno = lblkno (SUPERBLOCK, filepos);
 
154
      size = blksize (SUPERBLOCK, INODE, logno);
 
155
 
 
156
      if ((map = block_map (logno)) < 0)
 
157
        break;
 
158
 
 
159
      size -= off;
 
160
 
 
161
      if (size > len)
 
162
        size = len;
 
163
 
 
164
      disk_read_func = disk_read_hook;
 
165
 
 
166
      devread (fsbtodb (SUPERBLOCK, map), off, size, buf);
 
167
 
 
168
      disk_read_func = NULL;
 
169
 
 
170
      buf += size;
 
171
      len -= size;
 
172
      filepos += size;
 
173
      ret += size;
 
174
    }
 
175
 
 
176
  if (errnum)
 
177
    ret = 0;
 
178
 
 
179
  return ret;
 
180
}
 
181
 
 
182
 
 
183
int
 
184
ffs_dir (char *dirname)
 
185
{
 
186
  char *rest, ch;
 
187
  int block, off, loc, map, ino = ROOTINO;
 
188
  struct direct *dp;
 
189
 
 
190
/* main loop to find destination inode */
 
191
loop:
 
192
 
 
193
  /* load current inode (defaults to the root inode) */
 
194
 
 
195
        if (!devread (fsbtodb (SUPERBLOCK, itod (SUPERBLOCK, ino)),
 
196
                                                                ino % (SUPERBLOCK->fs_inopb) * sizeof (struct dinode),
 
197
                                                                sizeof (struct dinode), (char *) INODE))
 
198
                        return 0;                       /* XXX what return value? */
 
199
 
 
200
  /* if we have a real file (and we're not just printing possibilities),
 
201
     then this is where we want to exit */
 
202
 
 
203
  if (!*dirname || isspace (*dirname))
 
204
    {
 
205
      if ((INODE->i_mode & IFMT) != IFREG)
 
206
        {
 
207
          errnum = ERR_BAD_FILETYPE;
 
208
          return 0;
 
209
        }
 
210
 
 
211
      filemax = INODE->i_size;
 
212
 
 
213
      /* incomplete implementation requires this! */
 
214
      fsmax = (NDADDR + NINDIR (SUPERBLOCK)) * SUPERBLOCK->fs_bsize;
 
215
      return 1;
 
216
    }
 
217
 
 
218
  /* continue with file/directory name interpretation */
 
219
 
 
220
  while (*dirname == '/')
 
221
    dirname++;
 
222
 
 
223
  if (!(INODE->i_size) || ((INODE->i_mode & IFMT) != IFDIR))
 
224
    {
 
225
      errnum = ERR_BAD_FILETYPE;
 
226
      return 0;
 
227
    }
 
228
 
 
229
  for (rest = dirname; (ch = *rest) && !isspace (ch) && ch != '/'; rest++);
 
230
 
 
231
  *rest = 0;
 
232
  loc = 0;
 
233
 
 
234
  /* loop for reading a the entries in a directory */
 
235
 
 
236
  do
 
237
    {
 
238
      if (loc >= INODE->i_size)
 
239
        {
 
240
#if 0
 
241
          putchar ('\n');
 
242
#endif
 
243
 
 
244
          if (print_possibilities < 0)
 
245
            return 1;
 
246
 
 
247
          errnum = ERR_FILE_NOT_FOUND;
 
248
          *rest = ch;
 
249
          return 0;
 
250
        }
 
251
 
 
252
      if (!(off = blkoff (SUPERBLOCK, loc)))
 
253
        {
 
254
          block = lblkno (SUPERBLOCK, loc);
 
255
 
 
256
          if ((map = block_map (block)) < 0
 
257
              || !devread (fsbtodb (SUPERBLOCK, map), 0,
 
258
                           blksize (SUPERBLOCK, INODE, block),
 
259
                           (char *) FSYS_BUF))
 
260
            {
 
261
              errnum = ERR_FSYS_CORRUPT;
 
262
              *rest = ch;
 
263
              return 0;
 
264
            }
 
265
        }
 
266
 
 
267
      dp = (struct direct *) (FSYS_BUF + off);
 
268
      loc += dp->d_reclen;
 
269
 
 
270
#ifndef STAGE1_5
 
271
      if (dp->d_ino && print_possibilities && ch != '/'
 
272
          && (!*dirname || substring (dirname, dp->d_name) <= 0))
 
273
        {
 
274
          if (print_possibilities > 0)
 
275
            print_possibilities = -print_possibilities;
 
276
 
 
277
          print_a_completion (dp->d_name);
 
278
        }
 
279
#endif /* STAGE1_5 */
 
280
    }
 
281
  while (!dp->d_ino || (substring (dirname, dp->d_name) != 0
 
282
                        || (print_possibilities && ch != '/')));
 
283
 
 
284
  /* only get here if we have a matching directory entry */
 
285
 
 
286
  ino = dp->d_ino;
 
287
  *(dirname = rest) = ch;
 
288
 
 
289
  /* go back to main loop at top of function */
 
290
  goto loop;
 
291
}
 
292
 
 
293
int
 
294
ffs_embed (int *start_sector, int needed_sectors)
 
295
{
 
296
  /* XXX: I don't know if this is really correct. Someone who is
 
297
     familiar with BSD should check for this.  */
 
298
  if (needed_sectors > 14)
 
299
    return 0;
 
300
 
 
301
  *start_sector = 1;
 
302
#if 1
 
303
  /* FIXME: Disable the embedding in FFS until someone checks if
 
304
     the code above is correct.  */
 
305
  return 0;
 
306
#else
 
307
  return 1;
 
308
#endif
 
309
}
 
310
 
 
311
#endif /* FSYS_FFS */