Пример #1
0
  private void writeRoot(Mfs mfs) throws Exception {
    TivoDisk disk = mfs.getBootDisk();
    MfsHeader mfsHeader = (disk == null) ? null : disk.getMfsHeader();

    if (mfsHeader != null) {
      PartitionEntry pe = mfsHeader.getParent();
      //				Utils.printf( System.out, "Writing MFS header on %s: %s", disk.getName(), mfsHeader );
      Utils.write(Utils.seekBlock(disk, pe.getStartBlock()), mfsHeader);
      long roundedSize = Utils.roundDown(pe.getSizeBlocks(), MfsView.VOLUME_SIZE_ROUNDING);
      Utils.write(Utils.seekBlock(disk, pe.getStartBlock() + roundedSize - 1), mfsHeader);
    }
  }
Пример #2
0
  @Override
  public String toString() {
    StringBuffer sb = new StringBuffer(getClass().getSimpleName());
    sb.append(" {")
        .append(
            Utils.printf(
                "startBlockPrimary=%d\0"
                    + "startBlockBackup=%d\0"
                    + "first=%d\0"
                    + "last=%d\0"
                    + "size=%d\0"
                    + "free=%d\0"
                    + "length=%d\0"
                    + "min=%d\0"
                    + "logStamp=%d\0"
                    + "checksum=0x%08X (valid=%B)\0"
                    + "zero=%d\0"
                    + "num=%d\0"
                    + "type=%s\0"
                    + "next=%s\0"
                    + "extra=%d",
                descriptorStartBlock,
                backupStartBlock,
                dataStartBlocks,
                dataEndBlock,
                dataSize,
                freeDataBlocks,
                descriptorSize,
                min,
                logStamp,
                checksum,
                validCrc,
                zero,
                num,
                type,
                next,
                (extra == null) ? 0 : extra.length))
        .append("}\n")
        .append("Bitmaps: {");

    StringBuffer b = new StringBuffer();
    int num = 0;
    for (Bitmap bmp : bitmaps) b.append(Utils.printf("[%d]: %s", num++, bmp.toString()));

    sb.append(Utils.printf("ints=%s\0" + "bitmaps=%s", Arrays.asList(ints), b.toString()));

    return sb.toString();
  }
Пример #3
0
  private MfsAdd add(String[] args) {
    try {
      add(args[0], (args.length > 1) ? args[1] : null);
    } catch (Exception e) {
      Utils.printException(getClass().getSimpleName() + " exception: ", e);
      log.info(e, "");
    }

    return this;
  }
Пример #4
0
  private SizeSet calcSizes(long maxFreeBlocks, long chunkSize) throws Exception {
    long dataSize = chunkSize;
    SizeSet last = new SizeSet();

    log.debug("maxFreeBlocks=%d, chunkSize=%d", maxFreeBlocks, chunkSize);

    /*	Find optimal size set. Logic:
    		assume data size is 1 chunk - it will check for minimum
    			required space
    		calculate descriptor partition size to represent all data blocks
    		check if size set is valid - fits the free space (for first run it will not obviously)
    		if it is not valid - recalculate data size that is guaranteed to fit - i.e.
    				free space minus calculated descriptor partition size
    				note that after descriptor size is recalculated using this new (smaller)
    				data size, it can only be the same or smaller
    		if it is valid - check if it makes sense to continue -
    				stop if
    				1. data size is less or equal than previous known from valid
    					size set
    				2. unclaimed space (free - descriptor - data) is less than one data chunk
    		if continue - remember valid size set
    */
    while (true) {
      long descriptorSize =
          Zone64.calculateDescriptorSize(dataSize / chunkSize) / AppleDisk.BLOCK_SIZE;
      // account for backup as well and round up
      long descriptorPartitionSize =
          Utils.roundUp(descriptorSize * 2, MfsView.VOLUME_SIZE_ROUNDING);

      long unclaimedBlocks = maxFreeBlocks - (descriptorPartitionSize + dataSize);
      if (unclaimedBlocks < 0) { // combined size does not fit into free space
        if (dataSize <= chunkSize) {
          log.debug(
              "unclaimedBlocks=%d, descriptorSize=%d, descriptorPartitionSize=%d, dataSize=%d",
              unclaimedBlocks, descriptorSize, descriptorPartitionSize, dataSize);
          throw new Exception(
              "Free space is to small to accomodate necessary data - extension is impossible");
        }
      } else {
        // combined size fits - it is a valid size set
        if (last == null) last = new SizeSet();
        else {
          if (dataSize <= last.data) break;
        }
        last.partition = descriptorPartitionSize;
        last.data = dataSize;
        last.descriptor = descriptorSize;
        if (unclaimedBlocks < chunkSize) break;
      }

      dataSize = maxFreeBlocks - descriptorPartitionSize;
    }

    return last;
  }
Пример #5
0
 @Override
 public String toString() {
   StringBuffer sb = new StringBuffer(getClass().getSimpleName());
   sb.append(" {")
       .append(
           Utils.printf(
               "fsid=%d\0" + "length=%d\0" + "type=%s\0" + "name='%s'",
               getFsid(), getLength(), getType(), getName()))
       .append('}');
   return sb.toString();
 }
Пример #6
0
 public InodeEntry readData(DataInput in) throws Exception {
   if (length != null) {
     byte[] buf = new byte[getReadSize()];
     in.readFully(buf);
     name = new String(buf);
     int i = name.indexOf('\0');
     if (i >= 0) name = name.substring(0, i);
   } else {
     fsid = Utils.getUnsigned(in.readInt());
     length = in.readUnsignedByte();
     type = InodeType.fromInt(in.readUnsignedByte());
   }
   return this;
 }
Пример #7
0
  public void add(String bootDisk, String externalDisk) throws Exception {
    log.debug("bootDisk='%s', externalDisk='%s'", bootDisk, externalDisk);

    Mfs mfs = new Mfs(true, bootDisk);
    AppleDisk target = null;

    if (externalDisk == null) target = findLargestFreeSpace(mfs);
    else target = createNewDisk(mfs, externalDisk);

    target = add(mfs, target);
    writeChanges(mfs, target);

    if (externalDisk != null)
      Utils.log(
          "Added disk external disk '%s'. It will be named in Tivo as device '%s'\n",
          externalDisk, target.getName());
  }
Пример #8
0
  private void writeZone(Mfs mfs, Zone z) throws Exception {
    MfsView v = mfs.getMfs();
    PhysicalAddress a;

    //		Utils.printf( System.out, "Writing zone: %s", z.toString() );

    a = Utils.getValidPhysicalAddress(v, z.getDescriptorStartBlock());
    Utils.write(Utils.seekBlock(a), z);

    a = Utils.getValidPhysicalAddress(v, z.getBackupStartBlock());
    Utils.write(Utils.seekBlock(a), z);
  }
Пример #9
0
  //	@Override me
  public DataOutput write(DataOutput out) throws Exception {
    int total = (this instanceof Zone64) ? Zone64.SIZE : Zone32.SIZE;

    for (int i = 0; i < num; i++) {
      out.writeInt(ints[i]);
      total += Utils.SIZEOF_INT;
    }
    for (int i = 0; i < num; i++) {
      bitmaps[i].write(out);
      total += bitmaps[i].getReadAheadSize() + bitmaps[i].getReadSize();
    }

    if (extra != null) out.write(extra);
    else {
      int extraSize = (int) Utils.blocksToBytes(getDescriptorSize()) - total;
      while (extraSize-- > 0) out.writeByte(0xAA);
    }

    return out;
  }
Пример #10
0
  //	@Override me
  public Zone readData(DataInput in) throws Exception {
    int total = 0;
    ints = new Integer[(int) num];
    bitmaps = new Bitmap[(int) num];

    for (int i = 0; i < num; i++) ints[i] = in.readInt();
    total += num * (Integer.SIZE / 8);
    for (int i = 0; i < num; i++) {
      bitmaps[i] = Utils.read(in, Bitmap.class);
      total += bitmaps[i].getReadAheadSize() + bitmaps[i].getReadSize();
    }

    int extraSize = getReadSize() - total - ((this instanceof Zone64) ? Zone64.SIZE : Zone32.SIZE);
    if (extraSize > 0) {
      extra = new byte[extraSize];
      in.readFully(extra);
    }

    return this;
  }
Пример #11
0
  private Zone addZone(Mfs mfs, long logicalStartBlock, SizeSet sizes, long chunkSize)
      throws Exception {
    if ((mfs == null) || (mfs.getMfs() == null))
      throw new Exception("No MFS - MFS has not been initialized");

    List<Zone> zones = mfs.getZones();

    if ((zones == null) || zones.isEmpty())
      throw new Exception("No Zones - MFS has not been initialized");

    Zone lastZone = zones.get(zones.size() - 1);
    int baseFsPointer =
        lastZone.getInts()[0]
            - (int) lastZone.getNum() * Utils.SIZEOF_INT
            + (int) Utils.blocksToBytes(lastZone.getDescriptorSize() + 1)
            + 160;
    Zone64 z =
        new Zone64(
            logicalStartBlock, // descriptor start
            logicalStartBlock + sizes.partition, // data start
            sizes.data, // data size
            chunkSize,
            baseFsPointer);
    z.setType(ZoneType.MEDIA);

    ZoneHeader lastNext = lastZone.getNext();
    /*	just put the next pointer indicating the end into the
    	new zone and fill the previous next with pointers to the new zone
    */
    z.setNext(lastNext);
    lastZone.setNext(z.getHeader());

    mfs.addZone(z);

    return z;
  }