/* bsd.cc -- Functions for loading and manipulating legacy BSD disklabel
   data. */

/* By Rod Smith, initial coding August, 2009 */

/* This program is copyright (c) 2009 by Roderick W. Smith. It is distributed
  under the terms of the GNU GPL version 2, as detailed in the COPYING file. */

#define __STDC_LIMIT_MACROS
#ifndef __STDC_CONSTANT_MACROS
#define __STDC_CONSTANT_MACROS
#endif

#include <stdio.h>
//#include <unistd.h>
#include <stdlib.h>
#include <stdint.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <errno.h>
#include <iostream>
#include <string>
#include "support.h"
#include "bsd.h"

using namespace std;


BSDData::BSDData(void) {
   state = unknown;
   signature = UINT32_C(0);
   signature2 = UINT32_C(0);
   sectorSize = 512;
   numParts = 0;
   labelFirstLBA = 0;
   labelLastLBA = 0;
   labelStart = LABEL_OFFSET1; // assume raw disk format
   partitions = NULL;
} // default constructor

BSDData::~BSDData(void) {
   delete[] partitions;
} // destructor

// Read BSD disklabel data from the specified device filename. This function
// just opens the device file and then calls an overloaded function to do
// the bulk of the work. Returns 1 on success, 0 on failure.
int BSDData::ReadBSDData(const string & device, uint64_t startSector, uint64_t endSector) {
   int allOK = 1;
   DiskIO myDisk;

   if (device != "") {
      if (myDisk.OpenForRead(device)) {
         allOK = ReadBSDData(&myDisk, startSector, endSector);
      } else {
         allOK = 0;
      } // if/else

      myDisk.Close();
   } else {
      allOK = 0;
   } // if/else
   return allOK;
} // BSDData::ReadBSDData() (device filename version)

// Load the BSD disklabel data from an already-opened disk
// file, starting with the specified sector number.
int BSDData::ReadBSDData(DiskIO *theDisk, uint64_t startSector, uint64_t endSector) {
   int allOK = 1;
   int i, foundSig = 0, bigEnd = 0;
   int relative = 0; // assume absolute partition sector numbering
   uint8_t buffer[4096]; // I/O buffer
   uint32_t realSig;
   uint32_t* temp32;
   uint16_t* temp16;
   BSDRecord* tempRecords;
   int offset[NUM_OFFSETS] = { LABEL_OFFSET1, LABEL_OFFSET2 };

   labelFirstLBA = startSector;
   labelLastLBA = endSector;
   offset[1] = theDisk->GetBlockSize();

   // Read 4096 bytes (eight 512-byte sectors or equivalent)
   // into memory; we'll extract data from this buffer.
   // (Done to work around FreeBSD limitation on size of reads
   // from block devices.)
   allOK = theDisk->Seek(startSector);
   if (allOK) allOK = theDisk->Read(buffer, 4096);

   // Do some strangeness to support big-endian architectures...
   bigEnd = (IsLittleEndian() == 0);
   realSig = BSD_SIGNATURE;
   if (bigEnd && allOK)
      ReverseBytes(&realSig, 4);

   // Look for the signature at any of two locations.
   // Note that the signature is repeated at both the original
   // offset and 132 bytes later, so we need two checks....
   if (allOK) {
      i = 0;
      do {
         temp32 = (uint32_t*) &buffer[offset[i]];
         signature = *temp32;
         if (signature == realSig) { // found first, look for second
            temp32 = (uint32_t*) &buffer[offset[i] + 132];
            signature2 = *temp32;
            if (signature2 == realSig) {
               foundSig = 1;
               labelStart = offset[i];
            } // if found signature
         } // if/else
         i++;
      } while ((!foundSig) && (i < NUM_OFFSETS));
      allOK = foundSig;
   } // if

   // Load partition metadata from the buffer....
   if (allOK) {
      temp32 = (uint32_t*) &buffer[labelStart + 40];
      sectorSize = *temp32;
      temp16 = (uint16_t*) &buffer[labelStart + 138];
      numParts = *temp16;
   } // if

   // Make it big-endian-aware....
   if ((IsLittleEndian() == 0) && allOK)
      ReverseMetaBytes();

   // Check validity of the data and flag it appropriately....
   if (foundSig && (numParts <= MAX_BSD_PARTS) && allOK) {
      state = bsd;
   } else {
      state = bsd_invalid;
   } // if/else

   // If the state is good, go ahead and load the main partition data....
   if (state == bsd) {
      partitions = new struct BSDRecord[numParts * sizeof(struct BSDRecord)];
      if (partitions == NULL) {
         cerr << "Unable to allocate memory in BSDData::ReadBSDData()! Terminating!\n";
         exit(1);
      } // if
      for (i = 0; i < numParts; i++) {
         // Once again, we use the buffer, but index it using a BSDRecord
         // pointer (dangerous, but effective)....
         tempRecords = (BSDRecord*) &buffer[labelStart + 148];
         partitions[i].lengthLBA = tempRecords[i].lengthLBA;
         partitions[i].firstLBA = tempRecords[i].firstLBA;
         partitions[i].fsType = tempRecords[i].fsType;
         if (bigEnd) { // reverse data (fsType is a single byte)
            ReverseBytes(&partitions[i].lengthLBA, 4);
            ReverseBytes(&partitions[i].firstLBA, 4);
         } // if big-endian
         // Check for signs of relative sector numbering: A "0" first sector
         // number on a partition with a non-zero length -- but ONLY if the
         // length is less than the disk size, since NetBSD has a habit of
         // creating a disk-sized partition within a carrier MBR partition
         // that's too small to house it, and this throws off everything....
         if ((partitions[i].firstLBA == 0) && (partitions[i].lengthLBA > 0)
             && (partitions[i].lengthLBA < labelLastLBA))
            relative = 1;
      } // for
      // Some disklabels use sector numbers relative to the enclosing partition's
      // start, others use absolute sector numbers. If relative numbering was
      // detected above, apply a correction to all partition start sectors....
      if (relative) {
         for (i = 0; i < numParts; i++) {
            partitions[i].firstLBA += (uint32_t) startSector;
         } // for
      } // if
   } // if signatures OK
//   DisplayBSDData();
   return allOK;
} // BSDData::ReadBSDData(DiskIO* theDisk, uint64_t startSector)

// Reverse metadata's byte order; called only on big-endian systems
void BSDData::ReverseMetaBytes(void) {
   ReverseBytes(&signature, 4);
   ReverseBytes(&sectorSize, 4);
   ReverseBytes(&signature2, 4);
   ReverseBytes(&numParts, 2);
} // BSDData::ReverseMetaByteOrder()

// Display basic BSD partition data. Used for debugging.
void BSDData::DisplayBSDData(void) {
   int i;

   if (state == bsd) {
      cout << "BSD partitions:\n";
      for (i = 0; i < numParts; i++) {
         cout.width(4);
         cout << i + 1 << "\t";
         cout.width(13);
         cout << partitions[i].firstLBA << "\t";
         cout.width(15);
         cout << partitions[i].lengthLBA << " \t0x";
         cout.width(2);
         cout.fill('0');
         cout.setf(ios::uppercase);
         cout << hex << (int) partitions[i].fsType << "\n" << dec;
         cout.fill(' ');
      } // for
   } // if
} // BSDData::DisplayBSDData()

// Displays the BSD disklabel state. Called during program launch to inform
// the user about the partition table(s) status
int BSDData::ShowState(void) {
   int retval = 0;

   switch (state) {
      case bsd_invalid:
         cout << "  BSD: not present\n";
         break;
      case bsd:
         cout << "  BSD: present\n";
         retval = 1;
         break;
      default:
         cout << "\a  BSD: unknown -- bug!\n";
         break;
   } // switch
   return retval;
} // BSDData::ShowState()

// Weirdly, this function has stopped working when defined inline,
// but it's OK here....
int BSDData::IsDisklabel(void) {
   return (state == bsd);
} // BSDData::IsDiskLabel()

// Returns the BSD table's partition type code
uint8_t BSDData::GetType(int i) {
   uint8_t retval = 0; // 0 = "unused"

   if ((i < numParts) && (i >= 0) && (state == bsd) && (partitions != 0))
      retval = partitions[i].fsType;

   return(retval);
} // BSDData::GetType()

// Returns the number of the first sector of the specified partition
uint64_t BSDData::GetFirstSector(int i) {
   uint64_t retval = UINT64_C(0);

   if ((i < numParts) && (i >= 0) && (state == bsd) && (partitions != 0))
      retval = (uint64_t) partitions[i].firstLBA;

   return retval;
} // BSDData::GetFirstSector

// Returns the length (in sectors) of the specified partition
uint64_t BSDData::GetLength(int i) {
   uint64_t retval = UINT64_C(0);

   if ((i < numParts) && (i >= 0) && (state == bsd) && (partitions != 0))
      retval = (uint64_t) partitions[i].lengthLBA;

   return retval;
} // BSDData::GetLength()

// Returns the number of partitions defined in the current table
int BSDData::GetNumParts(void) {
   return numParts;
} // BSDData::GetNumParts()

// Returns the specified partition as a GPT partition. Used in BSD-to-GPT
// conversion process
GPTPart BSDData::AsGPT(int i) {
   GPTPart guid;                  // dump data in here, then return it
   uint64_t sectorOne, sectorEnd; // first & last sectors of partition
   int passItOn = 1;              // Set to 0 if partition is empty or invalid

   guid.BlankPartition();
   sectorOne = (uint64_t) partitions[i].firstLBA;
   sectorEnd = sectorOne + (uint64_t) partitions[i].lengthLBA;
   if (sectorEnd > 0) sectorEnd--;
   // Note on above: BSD partitions sometimes have a length of 0 and a start
   // sector of 0. With unsigned ints, the usual way (start + length - 1) to
   // find the end will result in a huge number, which will be confusing.
   // Thus, apply the "-1" part only if it's reasonable to do so.

   // Do a few sanity checks on the partition before we pass it on....
   // First, check that it falls within the bounds of its container
   // and that it starts before it ends....
   if ((sectorOne < labelFirstLBA) || (sectorEnd > labelLastLBA) || (sectorOne > sectorEnd))
      passItOn = 0;
   // Some disklabels include a pseudo-partition that's the size of the entire
   // disk or containing partition. Don't return it.
   if ((sectorOne <= labelFirstLBA) && (sectorEnd >= labelLastLBA) &&
       (GetType(i) == 0))
      passItOn = 0;
   // If the end point is 0, it's not a valid partition.
   if ((sectorEnd == 0) || (sectorEnd == labelFirstLBA))
      passItOn = 0;

   if (passItOn) {
      guid.SetFirstLBA(sectorOne);
      guid.SetLastLBA(sectorEnd);
      // Now set a random unique GUID for the partition....
      guid.RandomizeUniqueGUID();
      // ... zero out the attributes and name fields....
      guid.SetAttributes(UINT64_C(0));
      // Most BSD disklabel type codes seem to be archaic or rare.
      // They're also ambiguous; a FreeBSD filesystem is impossible
      // to distinguish from a NetBSD one. Thus, these code assignment
      // are going to be rough to begin with. For a list of meanings,
      // see http://fxr.watson.org/fxr/source/sys/dtype.h?v=DFBSD,
      // or Google it.
      switch (GetType(i)) {
         case 1: // BSD swap
            guid.SetType(0xa502); break;
         case 7: // BSD FFS
            guid.SetType(0xa503); break;
         case 8: case 11: // MS-DOS or HPFS
            guid.SetType(0x0700); break;
         case 9: // log-structured fs
            guid.SetType(0xa903); break;
         case 13: // bootstrap
            guid.SetType(0xa501); break;
         case 14: // vinum
            guid.SetType(0xa505); break;
         case 15: // RAID
            guid.SetType(0xa903); break;
         case 27: // FreeBSD ZFS
            guid.SetType(0xa504); break;
         default:
            guid.SetType(0xa503); break;
      } // switch
      // Set the partition name to the name of the type code....
      guid.SetName(guid.GetTypeName());
   } // if
   return guid;
} // BSDData::AsGPT()
