1 /*
   2     affs.c -- parted support for affs file systems
   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 "affs.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 _affs_probe_root (uint32_t *block, int blocksize) {
  37         int i;
  38         uint32_t sum;
  39 
  40         if (PED_BE32_TO_CPU (block[0]) != 2) return 0;
  41         if (PED_BE32_TO_CPU (block[128*blocksize-1]) != 1) return 0;
  42         for (i = 0, sum = 0; i < 128*blocksize; i++)
  43                 sum += PED_BE32_TO_CPU (block[i]);
  44         if (sum) return 0;
  45         return 1;
  46 }
  47 
  48 static PedGeometry*
  49 _generic_affs_probe (PedGeometry* geom, uint32_t kind)
  50 {
  51         uint32_t *block;
  52         PedSector root, len, pos;
  53         struct PartitionBlock * part;
  54         int blocksize = 1, reserved = 2, prealloc = 0;
  55 
  56         PED_ASSERT (geom != NULL, return NULL);
  57         PED_ASSERT (geom->dev != NULL, return NULL);
  58 
  59         /* Finds the blocksize, prealloc and reserved values of the partition block */
  60         if (!(part = ped_malloc (PED_SECTOR_SIZE_DEFAULT*blocksize))) {
  61                 ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
  62                         _("%s : Failed to allocate partition block\n"), __func__);
  63                 goto error_part;
  64         }
  65         if (amiga_find_part(geom, part) != NULL) {
  66                 prealloc = PED_BE32_TO_CPU (part->de_PreAlloc);
  67                 reserved = PED_BE32_TO_CPU (part->de_Reserved);
  68                 reserved = reserved == 0 ? 1 : reserved;
  69                 blocksize = PED_BE32_TO_CPU (part->de_SizeBlock)
  70                         * PED_BE32_TO_CPU (part->de_SectorPerBlock) / 128;
  71         }
  72         ped_free (part);
  73 
  74         /* Test boot block */
  75         if (!(block = ped_malloc (PED_SECTOR_SIZE_DEFAULT*blocksize))) {
  76                 ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
  77                         _("%s : Failed to allocate block\n"), __func__);
  78                 goto error_block;
  79         }
  80         if (!ped_device_read (geom->dev, block, geom->start, blocksize)) {
  81                 ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
  82                         _("%s : Couldn't read boot block %llu\n"), __func__, geom->start);
  83                 goto error;
  84         }
  85         if (PED_BE32_TO_CPU (block[0]) != kind) {
  86                 goto error;
  87         }
  88 
  89         /* Find and test the root block */
  90         len = geom->length / blocksize - reserved;
  91         pos = (len - 1) / 2;
  92         root = geom->start + (pos + reserved) * blocksize;
  93         printf ("Pralloc = %d, Reserved = %d, blocksize = %d, root block at %llu\n",
  94                 prealloc, reserved, blocksize, root);
  95 
  96         if (!ped_device_read (geom->dev, block, root, blocksize)) {
  97                 ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
  98                         _("%s : Couldn't read root block %llu\n"), __func__, root);
  99                 goto error;
 100         }
 101         if (_affs_probe_root(block, blocksize) == 1) {
 102                 ped_free (block);
 103                 return ped_geometry_duplicate (geom);
 104         }
 105 
 106 error:
 107         ped_free (block);
 108 error_block:
 109 error_part:
 110         return NULL;
 111 }
 112 static PedGeometry*
 113 _affs0_probe (PedGeometry* geom) {
 114         return _generic_affs_probe (geom, 0x444f5300);
 115 }
 116 static PedGeometry*
 117 _affs1_probe (PedGeometry* geom) {
 118         return _generic_affs_probe (geom, 0x444f5301);
 119 }
 120 static PedGeometry*
 121 _affs2_probe (PedGeometry* geom) {
 122         return _generic_affs_probe (geom, 0x444f5302);
 123 }
 124 static PedGeometry*
 125 _affs3_probe (PedGeometry* geom) {
 126         return _generic_affs_probe (geom, 0x444f5303);
 127 }
 128 static PedGeometry*
 129 _affs4_probe (PedGeometry* geom) {
 130         return _generic_affs_probe (geom, 0x444f5304);
 131 }
 132 static PedGeometry*
 133 _affs5_probe (PedGeometry* geom) {
 134         return _generic_affs_probe (geom, 0x444f5305);
 135 }
 136 static PedGeometry*
 137 _affs6_probe (PedGeometry* geom) {
 138         return _generic_affs_probe (geom, 0x444f5306);
 139 }
 140 static PedGeometry*
 141 _affs7_probe (PedGeometry* geom) {
 142         return _generic_affs_probe (geom, 0x444f5307);
 143 }
 144 static PedGeometry*
 145 _amufs_probe (PedGeometry* geom) {
 146         return _generic_affs_probe (geom, 0x6d754653);
 147 }
 148 static PedGeometry*
 149 _amufs0_probe (PedGeometry* geom) {
 150         return _generic_affs_probe (geom, 0x6d754600);
 151 }
 152 static PedGeometry*
 153 _amufs1_probe (PedGeometry* geom) {
 154         return _generic_affs_probe (geom, 0x6d754601);
 155 }
 156 static PedGeometry*
 157 _amufs2_probe (PedGeometry* geom) {
 158         return _generic_affs_probe (geom, 0x6d754602);
 159 }
 160 static PedGeometry*
 161 _amufs3_probe (PedGeometry* geom) {
 162         return _generic_affs_probe (geom, 0x6d754603);
 163 }
 164 static PedGeometry*
 165 _amufs4_probe (PedGeometry* geom) {
 166         return _generic_affs_probe (geom, 0x6d754604);
 167 }
 168 static PedGeometry*
 169 _amufs5_probe (PedGeometry* geom) {
 170         return _generic_affs_probe (geom, 0x6d754605);
 171 }
 172 
 173 static PedFileSystemOps _affs0_ops = {
 174         .probe =                _affs0_probe,
 175         .clobber =      NULL,
 176         .open =         NULL,
 177         .create =         NULL,
 178         .close =                NULL,
 179         .check =          NULL,
 180         .resize =               NULL,
 181         .copy =           NULL,
 182         .get_create_constraint =        NULL,
 183         .get_copy_constraint =  NULL,
 184         .get_resize_constraint =        NULL
 185 };
 186 static PedFileSystemOps _affs1_ops = {
 187         .probe =                _affs1_probe,
 188         .clobber =      NULL,
 189         .open =         NULL,
 190         .create =         NULL,
 191         .close =                NULL,
 192         .check =          NULL,
 193         .resize =               NULL,
 194         .copy =           NULL,
 195         .get_create_constraint =        NULL,
 196         .get_copy_constraint =  NULL,
 197         .get_resize_constraint =        NULL
 198 };
 199 static PedFileSystemOps _affs2_ops = {
 200         .probe =                _affs2_probe,
 201         .clobber =      NULL,
 202         .open =         NULL,
 203         .create =         NULL,
 204         .close =                NULL,
 205         .check =          NULL,
 206         .resize =               NULL,
 207         .copy =           NULL,
 208         .get_create_constraint =        NULL,
 209         .get_copy_constraint =  NULL,
 210         .get_resize_constraint =        NULL
 211 };
 212 static PedFileSystemOps _affs3_ops = {
 213         .probe =                _affs3_probe,
 214         .clobber =      NULL,
 215         .open =         NULL,
 216         .create =         NULL,
 217         .close =                NULL,
 218         .check =          NULL,
 219         .resize =               NULL,
 220         .copy =           NULL,
 221         .get_create_constraint =        NULL,
 222         .get_copy_constraint =  NULL,
 223         .get_resize_constraint =        NULL
 224 };
 225 static PedFileSystemOps _affs4_ops = {
 226         .probe =                _affs4_probe,
 227         .clobber =      NULL,
 228         .open =         NULL,
 229         .create =         NULL,
 230         .close =                NULL,
 231         .check =          NULL,
 232         .resize =               NULL,
 233         .copy =           NULL,
 234         .get_create_constraint =        NULL,
 235         .get_copy_constraint =  NULL,
 236         .get_resize_constraint =        NULL
 237 };
 238 static PedFileSystemOps _affs5_ops = {
 239         .probe =                _affs5_probe,
 240         .clobber =      NULL,
 241         .open =         NULL,
 242         .create =         NULL,
 243         .close =                NULL,
 244         .check =          NULL,
 245         .resize =               NULL,
 246         .copy =           NULL,
 247         .get_create_constraint =        NULL,
 248         .get_copy_constraint =  NULL,
 249         .get_resize_constraint =        NULL
 250 };
 251 static PedFileSystemOps _affs6_ops = {
 252         .probe =                _affs6_probe,
 253         .clobber =      NULL,
 254         .open =         NULL,
 255         .create =         NULL,
 256         .close =                NULL,
 257         .check =          NULL,
 258         .resize =               NULL,
 259         .copy =           NULL,
 260         .get_create_constraint =        NULL,
 261         .get_copy_constraint =  NULL,
 262         .get_resize_constraint =        NULL
 263 };
 264 static PedFileSystemOps _affs7_ops = {
 265         .probe =                _affs7_probe,
 266         .clobber =      NULL,
 267         .open =         NULL,
 268         .create =         NULL,
 269         .close =                NULL,
 270         .check =          NULL,
 271         .resize =               NULL,
 272         .copy =           NULL,
 273         .get_create_constraint =        NULL,
 274         .get_copy_constraint =  NULL,
 275         .get_resize_constraint =        NULL
 276 };
 277 static PedFileSystemOps _amufs_ops = {
 278         .probe =                _amufs_probe,
 279         .clobber =      NULL,
 280         .open =         NULL,
 281         .create =         NULL,
 282         .close =                NULL,
 283         .check =          NULL,
 284         .resize =               NULL,
 285         .copy =           NULL,
 286         .get_create_constraint =        NULL,
 287         .get_copy_constraint =  NULL,
 288         .get_resize_constraint =        NULL
 289 };
 290 static PedFileSystemOps _amufs0_ops = {
 291         .probe =                _amufs0_probe,
 292         .clobber =      NULL,
 293         .open =         NULL,
 294         .create =         NULL,
 295         .close =                NULL,
 296         .check =          NULL,
 297         .resize =               NULL,
 298         .copy =           NULL,
 299         .get_create_constraint =        NULL,
 300         .get_copy_constraint =  NULL,
 301         .get_resize_constraint =        NULL
 302 };
 303 static PedFileSystemOps _amufs1_ops = {
 304         .probe =                _amufs1_probe,
 305         .clobber =      NULL,
 306         .open =         NULL,
 307         .create =         NULL,
 308         .close =                NULL,
 309         .check =          NULL,
 310         .resize =               NULL,
 311         .copy =           NULL,
 312         .get_create_constraint =        NULL,
 313         .get_copy_constraint =  NULL,
 314         .get_resize_constraint =        NULL
 315 };
 316 static PedFileSystemOps _amufs2_ops = {
 317         .probe =                _amufs2_probe,
 318         .clobber =      NULL,
 319         .open =         NULL,
 320         .create =         NULL,
 321         .close =                NULL,
 322         .check =          NULL,
 323         .resize =               NULL,
 324         .copy =           NULL,
 325         .get_create_constraint =        NULL,
 326         .get_copy_constraint =  NULL,
 327         .get_resize_constraint =        NULL
 328 };
 329 static PedFileSystemOps _amufs3_ops = {
 330         .probe =                _amufs3_probe,
 331         .clobber =      NULL,
 332         .open =         NULL,
 333         .create =         NULL,
 334         .close =                NULL,
 335         .check =          NULL,
 336         .resize =               NULL,
 337         .copy =           NULL,
 338         .get_create_constraint =        NULL,
 339         .get_copy_constraint =  NULL,
 340         .get_resize_constraint =        NULL
 341 };
 342 static PedFileSystemOps _amufs4_ops = {
 343         .probe =                _amufs4_probe,
 344         .clobber =      NULL,
 345         .open =         NULL,
 346         .create =         NULL,
 347         .close =                NULL,
 348         .check =          NULL,
 349         .resize =               NULL,
 350         .copy =           NULL,
 351         .get_create_constraint =        NULL,
 352         .get_copy_constraint =  NULL,
 353         .get_resize_constraint =        NULL
 354 };
 355 static PedFileSystemOps _amufs5_ops = {
 356         .probe =                _amufs5_probe,
 357         .clobber =      NULL,
 358         .open =         NULL,
 359         .create =         NULL,
 360         .close =                NULL,
 361         .check =          NULL,
 362         .resize =               NULL,
 363         .copy =           NULL,
 364         .get_create_constraint =        NULL,
 365         .get_copy_constraint =  NULL,
 366         .get_resize_constraint =        NULL
 367 };
 368 
 369 #define AFFS_BLOCK_SIZES        ((int[5]){512, 1024, 2048, 4096, 0})
 370 #define AMUFS_BLOCK_SIZES       ((int[2]){512, 0})
 371 
 372 
 373 PedFileSystemType _affs0_type = {
 374        .next =           NULL,
 375        .ops =            &_affs0_ops,
 376        .name =           "affs0",
 377        .block_sizes =      AFFS_BLOCK_SIZES
 378 };
 379 PedFileSystemType _affs1_type = {
 380        .next =           NULL,
 381        .ops =            &_affs1_ops,
 382        .name =           "affs1",
 383        .block_sizes =      AFFS_BLOCK_SIZES
 384 };
 385 PedFileSystemType _affs2_type = {
 386        .next =           NULL,
 387        .ops =            &_affs2_ops,
 388        .name =           "affs2",
 389        .block_sizes =      AFFS_BLOCK_SIZES
 390 };
 391 PedFileSystemType _affs3_type = {
 392        .next =           NULL,
 393        .ops =            &_affs3_ops,
 394        .name =           "affs3",
 395        .block_sizes =      AFFS_BLOCK_SIZES
 396 };
 397 PedFileSystemType _affs4_type = {
 398        .next =           NULL,
 399        .ops =            &_affs4_ops,
 400        .name =           "affs4",
 401        .block_sizes =      AFFS_BLOCK_SIZES
 402 };
 403 PedFileSystemType _affs5_type = {
 404        .next =           NULL,
 405        .ops =            &_affs5_ops,
 406        .name =           "affs5",
 407        .block_sizes =      AFFS_BLOCK_SIZES
 408 };
 409 PedFileSystemType _affs6_type = {
 410        .next =           NULL,
 411        .ops =            &_affs6_ops,
 412        .name =           "affs6",
 413        .block_sizes =      AFFS_BLOCK_SIZES
 414 };
 415 PedFileSystemType _affs7_type = {
 416        .next =           NULL,
 417        .ops =            &_affs7_ops,
 418        .name =           "affs7",
 419        .block_sizes =      AFFS_BLOCK_SIZES
 420 };
 421 PedFileSystemType _amufs_type = {
 422        .next =           NULL,
 423        .ops =            &_amufs_ops,
 424        .name =           "amufs",
 425        .block_sizes =      AMUFS_BLOCK_SIZES
 426 };
 427 PedFileSystemType _amufs0_type = {
 428        .next =           NULL,
 429        .ops =            &_amufs0_ops,
 430        .name =           "amufs0",
 431        .block_sizes =      AMUFS_BLOCK_SIZES
 432 };
 433 PedFileSystemType _amufs1_type = {
 434        .next =           NULL,
 435        .ops =            &_amufs1_ops,
 436        .name =           "amufs1",
 437        .block_sizes =      AMUFS_BLOCK_SIZES
 438 };
 439 PedFileSystemType _amufs2_type = {
 440        .next =           NULL,
 441        .ops =            &_amufs2_ops,
 442        .name =           "amufs2",
 443        .block_sizes =      AMUFS_BLOCK_SIZES
 444 };
 445 PedFileSystemType _amufs3_type = {
 446        .next =           NULL,
 447        .ops =            &_amufs3_ops,
 448        .name =           "amufs3",
 449        .block_sizes =      AMUFS_BLOCK_SIZES
 450 };
 451 PedFileSystemType _amufs4_type = {
 452        .next =           NULL,
 453        .ops =            &_amufs4_ops,
 454        .name =           "amufs4",
 455        .block_sizes =      AMUFS_BLOCK_SIZES
 456 };
 457 PedFileSystemType _amufs5_type = {
 458        .next =           NULL,
 459        .ops =            &_amufs5_ops,
 460        .name =           "amufs5",
 461        .block_sizes =      AMUFS_BLOCK_SIZES
 462 };