~darkmuggle-deactivatedaccount/ubuntu/quantal/grub2/fix-872244

« back to all changes in this revision

Viewing changes to fs/affs.c

  • Committer: Bazaar Package Importer
  • Author(s): Colin Watson, Colin Watson, Evan Broder, Mario Limonciello
  • Date: 2010-11-24 13:59:55 UTC
  • mfrom: (1.17.6 upstream) (17.6.15 experimental)
  • Revision ID: james.westby@ubuntu.com-20101124135955-r6ii5sepayr7jt53
Tags: 1.99~20101124-1ubuntu1
[ Colin Watson ]
* Resynchronise with Debian experimental.  Remaining changes:
  - Adjust for default Ubuntu boot options ("quiet splash").
  - Default to hiding the menu; holding down Shift at boot will show it.
  - Set a monochromatic theme for Ubuntu.
  - Apply Ubuntu GRUB Legacy changes to legacy update-grub script: title,
    recovery mode, quiet option, tweak how memtest86+ is displayed, and
    use UUIDs where appropriate.
  - Fix backslash-escaping in merge_debconf_into_conf.
  - Remove "GNU/Linux" from default distributor string.
  - Add crashkernel= options if kdump and makedumpfile are available.
  - If other operating systems are installed, then automatically unhide
    the menu.  Otherwise, if GRUB_HIDDEN_TIMEOUT is 0, then use keystatus
    if available to check whether Shift is pressed.  If it is, show the
    menu, otherwise boot immediately.  If keystatus is not available, then
    fall back to a short delay interruptible with Escape.
  - Allow Shift to interrupt 'sleep --interruptible'.
  - Don't display introductory message about line editing unless we're
    actually offering a shell prompt.  Don't clear the screen just before
    booting if we never drew the menu in the first place.
  - Remove some verbose messages printed before reading the configuration
    file.
  - Suppress progress messages as the kernel and initrd load for
    non-recovery kernel menu entries.
  - Change prepare_grub_to_access_device to handle filesystems
    loop-mounted on file images.
  - Ignore devices loop-mounted from files in 10_linux.
  - Show the boot menu if the previous boot failed, that is if it failed
    to get to the end of one of the normal runlevels.
  - Don't generate /boot/grub/device.map during grub-install or
    grub-mkconfig by default.
  - Adjust upgrade version checks for Ubuntu.
  - Don't display "GRUB loading" unless Shift is held down.
  - Adjust versions of grub-doc and grub-legacy-doc conflicts to tolerate
    our backport of the grub-doc split.
  - Fix LVM/RAID probing in the absence of /boot/grub/device.map.
  - Look for .mo files in /usr/share/locale-langpack as well, in
    preference.
  - Make sure GRUB_TIMEOUT isn't quoted unnecessarily.
  - Probe all devices in 'grub-probe --target=drive' if
    /boot/grub/device.map is missing.
  - Build-depend on qemu-kvm rather than qemu-system for grub-pc tests.
  - Use qemu rather than qemu-system-i386.
  - Program vesafb on BIOS systems rather than efifb.
  - Add a grub-rescue-efi-amd64 package containing a rescue CD-ROM image
    for EFI-AMD64.
  - On Wubi, don't ask for an install device, but just update wubildr
    using the diverted grub-install.
  - When embedding the core image in a post-MBR gap, check for and avoid
    sectors matching any of a list of known signatures.
  - Disable video_bochs and video_cirrus on PC BIOS systems, as probing
    PCI space seems to break on some systems.
* Downgrade "ACPI shutdown failed" error to a debug message, since it can
  cause spurious test failures.

[ Evan Broder ]
* Enable lua from grub-extras.
* Incorporate the bitop library into lua.
* Add enum_pci function to grub module in lua.
* Switch back to gfxpayload=keep by default, unless the video hardware
  is known to not support it.

[ Mario Limonciello ]
* Built part_msdos and vfat into bootx64.efi (LP: #677758)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* affs.c - Amiga Fast FileSystem.  */
2
 
/*
3
 
 *  GRUB  --  GRand Unified Bootloader
4
 
 *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
5
 
 *
6
 
 *  GRUB is free software: you can redistribute it and/or modify
7
 
 *  it under the terms of the GNU General Public License as published by
8
 
 *  the Free Software Foundation, either version 3 of the License, or
9
 
 *  (at your option) any later version.
10
 
 *
11
 
 *  GRUB is distributed in the hope that it will be useful,
12
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
 *  GNU General Public License for more details.
15
 
 *
16
 
 *  You should have received a copy of the GNU General Public License
17
 
 *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
18
 
 */
19
 
 
20
 
#include <grub/err.h>
21
 
#include <grub/file.h>
22
 
#include <grub/mm.h>
23
 
#include <grub/misc.h>
24
 
#include <grub/disk.h>
25
 
#include <grub/dl.h>
26
 
#include <grub/types.h>
27
 
#include <grub/fshelp.h>
28
 
 
29
 
/* The affs bootblock.  */
30
 
struct grub_affs_bblock
31
 
{
32
 
  grub_uint8_t type[3];
33
 
  grub_uint8_t flags;
34
 
  grub_uint32_t checksum;
35
 
  grub_uint32_t rootblock;
36
 
} __attribute__ ((packed));
37
 
 
38
 
/* Set if the filesystem is a AFFS filesystem.  Otherwise this is an
39
 
   OFS filesystem.  */
40
 
#define GRUB_AFFS_FLAG_FFS      1
41
 
 
42
 
/* The affs rootblock.  */
43
 
struct grub_affs_rblock
44
 
{
45
 
  grub_uint8_t type[4];
46
 
  grub_uint8_t unused1[8];
47
 
  grub_uint32_t htsize;
48
 
  grub_uint32_t unused2;
49
 
  grub_uint32_t checksum;
50
 
  grub_uint32_t hashtable[1];
51
 
} __attribute__ ((packed));
52
 
 
53
 
/* The second part of a file header block.  */
54
 
struct grub_affs_file
55
 
{
56
 
  grub_uint8_t unused1[12];
57
 
  grub_uint32_t size;
58
 
  grub_uint8_t unused2[104];
59
 
  grub_uint8_t namelen;
60
 
  grub_uint8_t name[30];
61
 
  grub_uint8_t unused3[33];
62
 
  grub_uint32_t next;
63
 
  grub_uint32_t parent;
64
 
  grub_uint32_t extension;
65
 
  grub_int32_t type;
66
 
} __attribute__ ((packed));
67
 
 
68
 
/* The location of `struct grub_affs_file' relative to the end of a
69
 
   file header block.  */
70
 
#define GRUB_AFFS_FILE_LOCATION         200
71
 
 
72
 
/* The offset in both the rootblock and the file header block for the
73
 
   hashtable, symlink and block pointers (all synonyms).  */
74
 
#define GRUB_AFFS_HASHTABLE_OFFSET      24
75
 
#define GRUB_AFFS_BLOCKPTR_OFFSET       24
76
 
#define GRUB_AFFS_SYMLINK_OFFSET        24
77
 
 
78
 
#define GRUB_AFFS_SYMLINK_SIZE(blocksize) ((blocksize) - 225)
79
 
 
80
 
#define GRUB_AFFS_FILETYPE_DIR          -3
81
 
#define GRUB_AFFS_FILETYPE_REG          2
82
 
#define GRUB_AFFS_FILETYPE_SYMLINK      3
83
 
 
84
 
 
85
 
struct grub_fshelp_node
86
 
{
87
 
  struct grub_affs_data *data;
88
 
  int block;
89
 
  int size;
90
 
  int parent;
91
 
};
92
 
 
93
 
/* Information about a "mounted" affs filesystem.  */
94
 
struct grub_affs_data
95
 
{
96
 
  struct grub_affs_bblock bblock;
97
 
  struct grub_fshelp_node diropen;
98
 
  grub_disk_t disk;
99
 
 
100
 
  /* Blocksize in sectors.  */
101
 
  int blocksize;
102
 
 
103
 
  /* The number of entries in the hashtable.  */
104
 
  int htsize;
105
 
};
106
 
 
107
 
static grub_dl_t my_mod;
108
 
 
109
 
 
110
 
static grub_disk_addr_t
111
 
grub_affs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
112
 
{
113
 
  int links;
114
 
  grub_uint32_t pos;
115
 
  int block = node->block;
116
 
  struct grub_affs_file file;
117
 
  struct grub_affs_data *data = node->data;
118
 
  grub_uint32_t mod;
119
 
 
120
 
  /* Find the block that points to the fileblock we are looking up by
121
 
     following the chain until the right table is reached.  */
122
 
  for (links = grub_divmod64 (fileblock, data->htsize, &mod); links; links--)
123
 
    {
124
 
      grub_disk_read (data->disk, block + data->blocksize - 1,
125
 
                      data->blocksize * (GRUB_DISK_SECTOR_SIZE
126
 
                                         - GRUB_AFFS_FILE_LOCATION),
127
 
                      sizeof (file), &file);
128
 
      if (grub_errno)
129
 
        return 0;
130
 
 
131
 
      block = grub_be_to_cpu32 (file.extension);
132
 
    }
133
 
 
134
 
  /* Translate the fileblock to the block within the right table.  */
135
 
  fileblock = mod;
136
 
  grub_disk_read (data->disk, block,
137
 
                  GRUB_AFFS_BLOCKPTR_OFFSET
138
 
                  + (data->htsize - fileblock - 1) * sizeof (pos),
139
 
                  sizeof (pos), &pos);
140
 
  if (grub_errno)
141
 
    return 0;
142
 
 
143
 
  return grub_be_to_cpu32 (pos);
144
 
}
145
 
 
146
 
 
147
 
/* Read LEN bytes from the file described by DATA starting with byte
148
 
   POS.  Return the amount of read bytes in READ.  */
149
 
static grub_ssize_t
150
 
grub_affs_read_file (grub_fshelp_node_t node,
151
 
                     void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
152
 
                                        unsigned offset, unsigned length),
153
 
                     int pos, grub_size_t len, char *buf)
154
 
{
155
 
  return grub_fshelp_read_file (node->data->disk, node, read_hook,
156
 
                                pos, len, buf, grub_affs_read_block,
157
 
                                node->size, 0);
158
 
}
159
 
 
160
 
 
161
 
static struct grub_affs_data *
162
 
grub_affs_mount (grub_disk_t disk)
163
 
{
164
 
  struct grub_affs_data *data;
165
 
  grub_uint32_t *rootblock = 0;
166
 
  struct grub_affs_rblock *rblock;
167
 
 
168
 
  int checksum = 0;
169
 
  int checksumr = 0;
170
 
  int blocksize = 0;
171
 
 
172
 
  data = grub_malloc (sizeof (struct grub_affs_data));
173
 
  if (!data)
174
 
    return 0;
175
 
 
176
 
  /* Read the bootblock.  */
177
 
  grub_disk_read (disk, 0, 0, sizeof (struct grub_affs_bblock),
178
 
                  &data->bblock);
179
 
  if (grub_errno)
180
 
    goto fail;
181
 
 
182
 
  /* Make sure this is an affs filesystem.  */
183
 
  if (grub_strncmp ((char *) (data->bblock.type), "DOS", 3))
184
 
    {
185
 
      grub_error (GRUB_ERR_BAD_FS, "not an AFFS filesystem");
186
 
      goto fail;
187
 
    }
188
 
 
189
 
  /* Test if the filesystem is a OFS filesystem.  */
190
 
  if (! (data->bblock.flags & GRUB_AFFS_FLAG_FFS))
191
 
    {
192
 
      grub_error (GRUB_ERR_BAD_FS, "OFS not yet supported");
193
 
      goto fail;
194
 
    }
195
 
 
196
 
  /* Read the bootblock.  */
197
 
  grub_disk_read (disk, 0, 0, sizeof (struct grub_affs_bblock),
198
 
                  &data->bblock);
199
 
  if (grub_errno)
200
 
    goto fail;
201
 
 
202
 
  /* No sane person uses more than 8KB for a block.  At least I hope
203
 
     for that person because in that case this won't work.  */
204
 
  rootblock = grub_malloc (GRUB_DISK_SECTOR_SIZE * 16);
205
 
  if (!rootblock)
206
 
    goto fail;
207
 
 
208
 
  rblock = (struct grub_affs_rblock *) rootblock;
209
 
 
210
 
  /* Read the rootblock.  */
211
 
  grub_disk_read (disk, (disk->total_sectors >> 1) + blocksize, 0,
212
 
                  GRUB_DISK_SECTOR_SIZE * 16, rootblock);
213
 
  if (grub_errno)
214
 
    goto fail;
215
 
 
216
 
  /* The filesystem blocksize is not stored anywhere in the filesystem
217
 
     itself.  One way to determine it is reading blocks for the
218
 
     rootblock until the checksum is correct.  */
219
 
  checksumr = grub_be_to_cpu32 (rblock->checksum);
220
 
  rblock->checksum = 0;
221
 
  for (blocksize = 0; blocksize < 8; blocksize++)
222
 
    {
223
 
      grub_uint32_t *currblock = rootblock + GRUB_DISK_SECTOR_SIZE * blocksize;
224
 
      unsigned int i;
225
 
 
226
 
      for (i = 0; i < GRUB_DISK_SECTOR_SIZE / sizeof (*currblock); i++)
227
 
        checksum += grub_be_to_cpu32 (currblock[i]);
228
 
 
229
 
      if (checksumr == -checksum)
230
 
        break;
231
 
    }
232
 
  if (-checksum != checksumr)
233
 
    {
234
 
      grub_error (GRUB_ERR_BAD_FS, "AFFS blocksize couldn't be determined");
235
 
      goto fail;
236
 
    }
237
 
  blocksize++;
238
 
 
239
 
  data->blocksize = blocksize;
240
 
  data->disk = disk;
241
 
  data->htsize = grub_be_to_cpu32 (rblock->htsize);
242
 
  data->diropen.data = data;
243
 
  data->diropen.block = (disk->total_sectors >> 1);
244
 
 
245
 
  grub_free (rootblock);
246
 
 
247
 
  return data;
248
 
 
249
 
 fail:
250
 
  if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
251
 
    grub_error (GRUB_ERR_BAD_FS, "not an AFFS filesystem");
252
 
 
253
 
  grub_free (data);
254
 
  grub_free (rootblock);
255
 
  return 0;
256
 
}
257
 
 
258
 
 
259
 
static char *
260
 
grub_affs_read_symlink (grub_fshelp_node_t node)
261
 
{
262
 
  struct grub_affs_data *data = node->data;
263
 
  char *symlink;
264
 
 
265
 
  symlink = grub_malloc (GRUB_AFFS_SYMLINK_SIZE (data->blocksize));
266
 
  if (!symlink)
267
 
    return 0;
268
 
 
269
 
  grub_disk_read (data->disk, node->block, GRUB_AFFS_SYMLINK_OFFSET,
270
 
                  GRUB_AFFS_SYMLINK_SIZE (data->blocksize), symlink);
271
 
  if (grub_errno)
272
 
    {
273
 
      grub_free (symlink);
274
 
      return 0;
275
 
    }
276
 
  grub_dprintf ("affs", "Symlink: `%s'\n", symlink);
277
 
  return symlink;
278
 
}
279
 
 
280
 
 
281
 
static int
282
 
grub_affs_iterate_dir (grub_fshelp_node_t dir,
283
 
                       int NESTED_FUNC_ATTR
284
 
                       (*hook) (const char *filename,
285
 
                                enum grub_fshelp_filetype filetype,
286
 
                                grub_fshelp_node_t node))
287
 
{
288
 
  int i;
289
 
  struct grub_affs_file file;
290
 
  struct grub_fshelp_node *node = 0;
291
 
  struct grub_affs_data *data = dir->data;
292
 
  grub_uint32_t *hashtable;
293
 
 
294
 
  auto int NESTED_FUNC_ATTR grub_affs_create_node (const char *name, int block,
295
 
                                                   int size, int type);
296
 
 
297
 
  int NESTED_FUNC_ATTR grub_affs_create_node (const char *name, int block,
298
 
                                              int size, int type)
299
 
    {
300
 
      node = grub_malloc (sizeof (*node));
301
 
      if (!node)
302
 
        {
303
 
          grub_free (hashtable);
304
 
          return 1;
305
 
        }
306
 
 
307
 
      node->data = data;
308
 
      node->size = size;
309
 
      node->block = block;
310
 
      node->parent = grub_be_to_cpu32 (file.parent);
311
 
 
312
 
      if (hook (name, type, node))
313
 
        {
314
 
          grub_free (hashtable);
315
 
          return 1;
316
 
        }
317
 
      return 0;
318
 
    }
319
 
 
320
 
  hashtable = grub_malloc (data->htsize * sizeof (*hashtable));
321
 
  if (!hashtable)
322
 
    return 1;
323
 
 
324
 
  grub_disk_read (data->disk, dir->block, GRUB_AFFS_HASHTABLE_OFFSET,
325
 
                  data->htsize * sizeof (*hashtable), (char *) hashtable);
326
 
  if (grub_errno)
327
 
    goto fail;
328
 
 
329
 
  /* Create the directory entries for `.' and `..'.  */
330
 
  if (grub_affs_create_node (".", dir->block, dir->size, GRUB_FSHELP_DIR))
331
 
    return 1;
332
 
  if (grub_affs_create_node ("..", dir->parent ? dir->parent : dir->block,
333
 
                             dir->size, GRUB_FSHELP_DIR))
334
 
    return 1;
335
 
 
336
 
  for (i = 0; i < data->htsize; i++)
337
 
    {
338
 
      enum grub_fshelp_filetype type;
339
 
      grub_uint64_t next;
340
 
 
341
 
      if (!hashtable[i])
342
 
        continue;
343
 
 
344
 
      /* Every entry in the hashtable can be chained.  Read the entire
345
 
         chain.  */
346
 
      next = grub_be_to_cpu32 (hashtable[i]);
347
 
 
348
 
      while (next)
349
 
        {
350
 
          grub_disk_read (data->disk, next + data->blocksize - 1,
351
 
                          data->blocksize * GRUB_DISK_SECTOR_SIZE
352
 
                          - GRUB_AFFS_FILE_LOCATION,
353
 
                          sizeof (file), (char *) &file);
354
 
          if (grub_errno)
355
 
            goto fail;
356
 
 
357
 
          file.name[file.namelen] = '\0';
358
 
 
359
 
          if ((int) grub_be_to_cpu32 (file.type) == GRUB_AFFS_FILETYPE_DIR)
360
 
            type = GRUB_FSHELP_REG;
361
 
          else if (grub_be_to_cpu32 (file.type) == GRUB_AFFS_FILETYPE_REG)
362
 
            type = GRUB_FSHELP_DIR;
363
 
          else if (grub_be_to_cpu32 (file.type) == GRUB_AFFS_FILETYPE_SYMLINK)
364
 
            type = GRUB_FSHELP_SYMLINK;
365
 
          else
366
 
            type = GRUB_FSHELP_UNKNOWN;
367
 
 
368
 
          if (grub_affs_create_node ((char *) (file.name), next,
369
 
                                     grub_be_to_cpu32 (file.size), type))
370
 
            return 1;
371
 
 
372
 
          next = grub_be_to_cpu32 (file.next);
373
 
        }
374
 
    }
375
 
 
376
 
  grub_free (hashtable);
377
 
  return 0;
378
 
 
379
 
 fail:
380
 
  grub_free (node);
381
 
  grub_free (hashtable);
382
 
  return 0;
383
 
}
384
 
 
385
 
 
386
 
/* Open a file named NAME and initialize FILE.  */
387
 
static grub_err_t
388
 
grub_affs_open (struct grub_file *file, const char *name)
389
 
{
390
 
  struct grub_affs_data *data;
391
 
  struct grub_fshelp_node *fdiro = 0;
392
 
 
393
 
  grub_dl_ref (my_mod);
394
 
 
395
 
  data = grub_affs_mount (file->device->disk);
396
 
  if (!data)
397
 
    goto fail;
398
 
 
399
 
  grub_fshelp_find_file (name, &data->diropen, &fdiro, grub_affs_iterate_dir,
400
 
                         grub_affs_read_symlink, GRUB_FSHELP_REG);
401
 
  if (grub_errno)
402
 
    goto fail;
403
 
 
404
 
  file->size = fdiro->size;
405
 
  data->diropen = *fdiro;
406
 
  grub_free (fdiro);
407
 
 
408
 
  file->data = data;
409
 
  file->offset = 0;
410
 
 
411
 
  return 0;
412
 
 
413
 
 fail:
414
 
  if (data && fdiro != &data->diropen)
415
 
    grub_free (fdiro);
416
 
  grub_free (data);
417
 
 
418
 
  grub_dl_unref (my_mod);
419
 
 
420
 
  return grub_errno;
421
 
}
422
 
 
423
 
 
424
 
static grub_err_t
425
 
grub_affs_close (grub_file_t file)
426
 
{
427
 
  grub_free (file->data);
428
 
 
429
 
  grub_dl_unref (my_mod);
430
 
 
431
 
  return GRUB_ERR_NONE;
432
 
}
433
 
 
434
 
 
435
 
/* Read LEN bytes data from FILE into BUF.  */
436
 
static grub_ssize_t
437
 
grub_affs_read (grub_file_t file, char *buf, grub_size_t len)
438
 
{
439
 
  struct grub_affs_data *data =
440
 
    (struct grub_affs_data *) file->data;
441
 
 
442
 
  int size = grub_affs_read_file (&data->diropen, file->read_hook,
443
 
                              file->offset, len, buf);
444
 
 
445
 
  return size;
446
 
}
447
 
 
448
 
 
449
 
static grub_err_t
450
 
grub_affs_dir (grub_device_t device, const char *path,
451
 
               int (*hook) (const char *filename,
452
 
                            const struct grub_dirhook_info *info))
453
 
{
454
 
  struct grub_affs_data *data = 0;
455
 
  struct grub_fshelp_node *fdiro = 0;
456
 
 
457
 
  auto int NESTED_FUNC_ATTR iterate (const char *filename,
458
 
                                     enum grub_fshelp_filetype filetype,
459
 
                                     grub_fshelp_node_t node);
460
 
 
461
 
  int NESTED_FUNC_ATTR iterate (const char *filename,
462
 
                                enum grub_fshelp_filetype filetype,
463
 
                                grub_fshelp_node_t node)
464
 
    {
465
 
      struct grub_dirhook_info info;
466
 
      grub_memset (&info, 0, sizeof (info));
467
 
      info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
468
 
      grub_free (node);
469
 
      return hook (filename, &info);
470
 
    }
471
 
 
472
 
  grub_dl_ref (my_mod);
473
 
 
474
 
  data = grub_affs_mount (device->disk);
475
 
  if (!data)
476
 
    goto fail;
477
 
 
478
 
  grub_fshelp_find_file (path, &data->diropen, &fdiro, grub_affs_iterate_dir,
479
 
                         grub_affs_read_symlink, GRUB_FSHELP_DIR);
480
 
  if (grub_errno)
481
 
    goto fail;
482
 
 
483
 
  grub_affs_iterate_dir (fdiro, iterate);
484
 
 
485
 
 fail:
486
 
  if (data && fdiro != &data->diropen)
487
 
    grub_free (fdiro);
488
 
  grub_free (data);
489
 
 
490
 
  grub_dl_unref (my_mod);
491
 
 
492
 
  return grub_errno;
493
 
}
494
 
 
495
 
 
496
 
static grub_err_t
497
 
grub_affs_label (grub_device_t device, char **label)
498
 
{
499
 
  struct grub_affs_data *data;
500
 
  struct grub_affs_file file;
501
 
  grub_disk_t disk = device->disk;
502
 
 
503
 
  grub_dl_ref (my_mod);
504
 
 
505
 
  data = grub_affs_mount (disk);
506
 
  if (data)
507
 
    {
508
 
      /* The rootblock maps quite well on a file header block, it's
509
 
         something we can use here.  */
510
 
      grub_disk_read (data->disk, disk->total_sectors >> 1,
511
 
                      data->blocksize * (GRUB_DISK_SECTOR_SIZE
512
 
                                         - GRUB_AFFS_FILE_LOCATION),
513
 
                      sizeof (file), &file);
514
 
      if (grub_errno)
515
 
        return 0;
516
 
 
517
 
      *label = grub_strndup ((char *) (file.name), file.namelen);
518
 
    }
519
 
  else
520
 
    *label = 0;
521
 
 
522
 
  grub_dl_unref (my_mod);
523
 
 
524
 
  grub_free (data);
525
 
 
526
 
  return grub_errno;
527
 
}
528
 
 
529
 
 
530
 
static struct grub_fs grub_affs_fs =
531
 
  {
532
 
    .name = "affs",
533
 
    .dir = grub_affs_dir,
534
 
    .open = grub_affs_open,
535
 
    .read = grub_affs_read,
536
 
    .close = grub_affs_close,
537
 
    .label = grub_affs_label,
538
 
    .next = 0
539
 
  };
540
 
 
541
 
GRUB_MOD_INIT(affs)
542
 
{
543
 
  grub_fs_register (&grub_affs_fs);
544
 
  my_mod = mod;
545
 
}
546
 
 
547
 
GRUB_MOD_FINI(affs)
548
 
{
549
 
  grub_fs_unregister (&grub_affs_fs);
550
 
}