1 /*
   2     asfs.c -- parted asfs filesystem support
   3     Copyright (C) 1998-2000, 2007 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 3 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, see <http://www.gnu.org/licenses/>.
  17 */
  18 
  19 #include <config.h>
  20 
  21 #include <parted/parted.h>
  22 #include <parted/debug.h>
  23 #include <parted/endian.h>
  24 
  25 #include "amiga.h"
  26 #include "asfs.h"
  27 
  28 #if ENABLE_NLS
  29 #  include <libintl.h>
  30 #  define _(String) dgettext (PACKAGE, String)
  31 #else
  32 #  define _(String) (String)
  33 #endif /* ENABLE_NLS */
  34 
  35 static int
  36 _asfs_probe_root (PedGeometry *geom, uint32_t *block, int blocksize, PedSector root) {
  37         int i, sum;
  38         PedSector start, end;
  39 
  40         if (PED_BE32_TO_CPU (block[0]) != 0x53465300) return 0;
  41         for (i = 0, sum = 1; i < 128*blocksize; i++) sum += PED_BE32_TO_CPU (block[i]);
  42         if (sum != 0) return 0;
  43         if (PED_BE32_TO_CPU (block[2]) * blocksize + geom->start != root) {
  44                 return 0;
  45         }
  46         start = ((((PedSector) PED_BE32_TO_CPU (block[8])) << 32)
  47                 + (PedSector) PED_BE32_TO_CPU (block[9])) / 512;
  48         end = (((((PedSector) PED_BE32_TO_CPU (block[10])) << 32)
  49                 + (PedSector) PED_BE32_TO_CPU (block[11])) / 512) - 1;
  50         if (start != geom->start || end != geom->end) return 0;
  51         return 1;
  52 }
  53 
  54 static PedGeometry*
  55 _asfs_probe (PedGeometry* geom)
  56 {
  57         uint32_t *block;
  58         struct PartitionBlock * part;
  59         int blocksize = 1, reserved = 1, prealloc = 1;
  60         PedSector root;
  61         int found = 0;
  62 
  63         PED_ASSERT (geom != NULL, return NULL);
  64         PED_ASSERT (geom->dev != NULL, return NULL);
  65 
  66         /* Finds the blocksize, prealloc and reserved values of the partition block */
  67         if (!(part = ped_malloc (PED_SECTOR_SIZE_DEFAULT*blocksize))) {
  68                 ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
  69                         _("%s : Failed to allocate partition block\n"), __func__);
  70                 goto error_part;
  71         }
  72         if (amiga_find_part(geom, part) != NULL) {
  73                 prealloc = PED_BE32_TO_CPU (part->de_PreAlloc) == 0 ?
  74                         1 : PED_BE32_TO_CPU (part->de_PreAlloc);
  75                 reserved = PED_BE32_TO_CPU (part->de_Reserved) == 0 ?
  76                         1 : PED_BE32_TO_CPU (part->de_Reserved);
  77                 blocksize = PED_BE32_TO_CPU (part->de_SizeBlock)
  78                         * PED_BE32_TO_CPU (part->de_SectorPerBlock) / 128;
  79         }
  80         ped_free (part);
  81 
  82         /* Test boot block */
  83         if (!(block = ped_malloc (PED_SECTOR_SIZE_DEFAULT*blocksize))) {
  84                 ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
  85                         _("%s : Failed to allocate block\n"), __func__);
  86                 goto error_block;
  87         }
  88         root = geom->start;
  89         if (!ped_device_read (geom->dev, block, root, blocksize)) {
  90                 ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
  91                         _("%s : Couldn't read root block %llu\n"), __func__, root);
  92                 goto error;
  93         }
  94         if (PED_BE32_TO_CPU (block[0]) != 0x53465300) {
  95                 goto error;
  96         }
  97 
  98         /* Find and test the root blocks */
  99         if (_asfs_probe_root(geom, block, blocksize, root)) {
 100                 found++;
 101         }
 102         root = geom->end - blocksize - (geom->length % blocksize) + 1;
 103         if (!ped_device_read (geom->dev, block, root, 1)) {
 104                 ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
 105                         _("%s : Couldn't read root block %llu\n"), __func__, root);
 106                 goto error;
 107         }
 108         if (_asfs_probe_root(geom, block, blocksize, root)) {
 109                 found++;
 110         }
 111         if (found != 0) {
 112                 ped_free (block);
 113                 return ped_geometry_duplicate (geom);
 114         }
 115 
 116 error:
 117         ped_free (block);
 118 error_block:
 119 error_part:
 120         return NULL;
 121 }
 122 
 123 static PedFileSystemOps _asfs_ops = {
 124         .probe =                _asfs_probe,
 125         .clobber =      NULL,
 126         .open =         NULL,
 127         .create =         NULL,
 128         .close =                NULL,
 129         .check =          NULL,
 130         .resize =               NULL,
 131         .copy =           NULL,
 132         .get_create_constraint =        NULL,
 133         .get_copy_constraint =  NULL,
 134         .get_resize_constraint =        NULL
 135 };
 136 
 137 PedFileSystemType _asfs_type = {
 138        .next =           NULL,
 139        .ops =            &_asfs_ops,
 140        .name =           "asfs",
 141        .block_sizes =      ((int[2]){512, 0})
 142 };