/* fdisk.c -  fdisk program to modify partitions on disk.
 *
 * Copyright 2012 Ashwini Kumar <ak.ashwini@gmail.com>
 * Copyright 2013 Kyungwan Han <asura321@gmail.com>
 *
 * No Standard.

USE_FDISK(NEWTOY(fdisk, "C#<0H#<0S#<0b#<512ul", TOYFLAG_SBIN))

config FDISK
  bool "fdisk"
  default n
  help
    usage: fdisk [-lu] [-C CYLINDERS] [-H HEADS] [-S SECTORS] [-b SECTSZ] DISK

    Change partition table

    -u            Start and End are in sectors (instead of cylinders)
    -l            Show partition table for each DISK, then exit
    -b size       sector size (512, 1024, 2048 or 4096)
    -C CYLINDERS  Set number of cylinders/heads/sectors
    -H HEADS
    -S SECTORS
*/

#define FOR_fdisk
#include "toys.h"
#include <linux/hdreg.h>

GLOBALS(
  long sect_sz;
  long sectors;
  long heads;
  long cylinders;
)

#define EXTENDED        0x05                                                                      
#define WIN98_EXTENDED  0x0f
#define LINUX_NATIVE    0x83
#define LINUX_EXTENDED  0x85

#define SECTOR_SIZE 512
#define ONE_K       1024
#define PARTITION_MAX  60  //partition max is modifiable
#define IS_EXTENDED(i) ((i) == EXTENDED || (i) == WIN98_EXTENDED || (i) == LINUX_EXTENDED)
#define sector(s) ((s) & 0x3f)
#define cylinder(s, c) ((c) | (((s) & 0xc0) << 2))

typedef off_t sector_t;

struct partition {
  unsigned char boot_ind, head, sector, cyl, sys_ind, end_head,
                end_sector, end_cyl, start4[4], size4[4];
};

struct part_entry {
  struct partition *part;
  char *sec_buffer;
  sector_t  start_offset;
  int modified;
};

struct part_types {
  int id;
  char type[24];
} sys_types[] = {
  {0x00, "Empty"}, {0x01, "FAT12"}, {0x04, "FAT16 <32M"}, {0x05, "Extended"},
  {0x06, "FAT16"}, {0x07, "HPFS/NTFS"}, {0x0a, "OS/2 Boot Manager"},
  {0x0b, "Win95 FAT32"}, {0x0c, "Win95 FAT32 (LBA)"}, {0x0e, "Win95 FAT16 (LBA)"},
  {0x0f, "Win95 Ext'd (LBA)"}, {0x11, "Hidden FAT12"}, {0x12, "Compaq diagnostics"},
  {0x14, "Hidden FAT16 <32M"}, {0x16, "Hidden FAT16"}, {0x17, "Hidden HPFS/NTFS"},
  {0x1b, "Hidden Win95 FAT32"}, {0x1c, "Hidden W95 FAT32 (LBA)"}, {0x1e, "Hidden W95 FAT16 (LBA)"},
  {0x3c, "Part.Magic recovery"}, {0x41, "PPC PReP Boot"}, {0x42, "SFS"},
  {0x63, "GNU HURD or SysV"}, {0x80, "Old Minix"}, {0x81, "Minix / old Linux"},
  {0x82, "Linux swap"}, {0x83, "Linux"}, {0x84, "OS/2 hidden C: drive"},
  {0x85, "Linux extended"}, {0x86, "NTFS volume set"}, {0x87, "NTFS volume set"},
  {0x8e, "Linux LVM"}, {0x9f, "BSD/OS"}, {0xa0, "Thinkpad hibernation"},
  {0xa5, "FreeBSD"}, {0xa6, "OpenBSD"}, {0xa8, "Darwin UFS"}, {0xa9, "NetBSD"},
  {0xab, "Darwin boot"}, {0xb7, "BSDI fs"}, {0xb8, "BSDI swap"},
  {0xbe, "Solaris boot"}, {0xeb, "BeOS fs"}, {0xee, "EFI GPT"},
  {0xef, "EFI (FAT-12/16/32)"}, {0xf0, "Linux/PA-RISC boot"},
  {0xf2, "DOS secondary"}, {0xfd, "Linux raid autodetect"},
};

static int num_parts, disp_unit_cyl, dos_flag, dev_fd = 3;
static long g_cylinders, g_heads, g_sectors, g_sect_size;
static sector_t total_number_sectors, extended_offset;
static char MBRbuf[2048], *disk_device;
struct part_entry partitions[PARTITION_MAX];

static struct partition* part_offset(char *secbuf, int i)
{
  return (struct partition*)(secbuf + 0x1be + i*(sizeof(struct partition)));
}

static void set_levalue(unsigned char *cp, sector_t value )
{
  uint32_t val = SWAP_LE32(value);
  memcpy(cp, (void*)&val, 4);
}

static void set_hsc(struct partition *p, sector_t start, sector_t end)
{
  if (dos_flag && (start / (g_sectors * g_heads) > 1023))
    start = g_heads * g_sectors * ONE_K - 1;
  p->sector = (start % g_sectors) + 1;
  start /= g_sectors;
  p->head = start % g_heads;
  start /= g_heads;
  p->cyl = start & 0xFF;
  p->sector |= (start >> 2) & 0xc0;

  if (dos_flag && (end / (g_sectors * g_heads) > 1023))
    end = g_heads * g_sectors * ONE_K - 1;
  p->end_sector = (end % g_sectors) + 1;
  end /= g_sectors;
  p->end_head = end % g_heads;
  end /= g_heads;
  p->end_cyl = end & 0xFF;
  p->end_sector |= (end >> 2) & 0xc0;
}

static int chs_warn(void)
{
  if (g_heads && g_sectors && g_cylinders)
    return 0;

  printf("Unknown value(s) for:");
  if (!g_heads) printf(" heads");
  if (!g_sectors) printf(" sectors");
  if (!g_cylinders) printf(" cylinders");
  printf(". can set in the expert menu.\n");
  return 1;
}

static void list_types(void)
{
  int i, adjust = 0, size = ARRAY_LEN(sys_types);
 
  if(size % 2) adjust = 1;
  for (i = 0; i < (size - adjust); i+=2)
    xprintf("%2x %-22s\t\t%2x %-22.22s\n", sys_types[i].id, sys_types[i].type,
        sys_types[i+1].id, sys_types[i+1].type);
  if (adjust) xprintf("%2x %-22s\n",sys_types[size-1].id, sys_types[size-1].type);
  xputc('\n');
}

static void read_sec_sz()
{
  int arg;       
  if (ioctl(dev_fd, BLKSSZGET, &arg) == 0) g_sect_size = arg;
  if (toys.optflags & FLAG_b) {
    if (TT.sect_sz !=  512 && TT.sect_sz != 1024 && TT.sect_sz != 2048 &&
        TT.sect_sz != 4096)
    {
      help_exit("bad sector size");
    }
    g_sect_size = TT.sect_sz;
  }
}

static sector_t read_size()
{
  uint64_t sec64 = 0;
  unsigned long sectors = 0;
  if (ioctl(dev_fd, BLKGETSIZE64, &sec64) == 0) {
    sec64 = sec64 >> 9; //convert to 512 block size.
    if (sec64 != (uint32_t) sec64) {
      perror_msg("device has more than 2^32 sectors, can't use all of them");
      sec64 = (uint32_t) - 1L;
    }
    return sec64;
  }
  if (ioctl(dev_fd, BLKGETSIZE, &sectors) == 0)
    if (sizeof(long) > sizeof(sector_t) && sectors != (sector_t)sectors)
      sectors = (uint32_t) - 1L;
  return sectors;
}

static int validate_part_buff(char *buffer)
{
  if ((buffer[510] != 0x55) || (buffer[511] != 0xAA)) return 0;
  return 1;
}

static int is_partition_clear(struct partition* p)
{
  int i = 0;
  unsigned char res = 0;
  const char *ptr = (const char*)p;

  for (i = 0; i < sizeof(struct partition); i++) res |= (unsigned char)ptr[i];
  return (res == 0x00);
}

static uint32_t swap_le32toh(unsigned char *cp)
{
  uint32_t val;
  memcpy((void*)&val, cp, 4);
  return le32toh(val);
}

static int check_order(void)    
{                              
  sector_t first[num_parts], last_seen_val = 0;
  int i;
  struct part_entry *pe;       
  struct partition *px;

  for (i = 0; i < num_parts; i++) {
    if (i == 4) last_seen_val = 0;
    pe = &partitions[i];       
    px = pe->part;             
    if (px->sys_ind) {
      first[i] = swap_le32toh(px->start4) + pe->start_offset;
      if (last_seen_val > first[i]) return 1;
      last_seen_val = first[i];
    }
  }
  return 0;
}

static void read_geometry(struct hd_geometry *disk)
{
  struct hd_geometry geometry;

  if (ioctl(dev_fd, HDIO_GETGEO, &geometry)) return;
  disk->heads = geometry.heads;
  disk->sectors = geometry.sectors;
}

/* Read the extended boot record for the 
 * logical partion details.
 */
static void read_ebr(int idx)
{
  char *sec_buf = NULL;
  sector_t offset = 0, local_start_off = 0;
  struct partition *p, *q;

  q = p = partitions[idx].part;
  local_start_off = swap_le32toh(p->start4);

  if (!extended_offset) extended_offset = local_start_off;
  do {
    if (num_parts >= 60) {
      xprintf("Warning: deleting partitions after 60\n");
      memset(q, 0, sizeof(struct partition)); //clear_partition
      partitions[num_parts-1].modified = 1;
      break;
    }

    sec_buf = xzalloc(g_sect_size);
    partitions[num_parts].part = part_offset(sec_buf, 0);
    partitions[num_parts].sec_buffer = sec_buf;
    offset = swap_le32toh(q->start4);

    if (num_parts > 4) offset += local_start_off;
    partitions[num_parts].start_offset = offset;
    xlseek(dev_fd, (off_t)(offset * g_sect_size), SEEK_SET);

    if (g_sect_size != readall(dev_fd, sec_buf, g_sect_size)) {
      close(dev_fd);
      error_exit("Couldn't read sector zero\n");
    }
    num_parts++; //extended partions present.
    q = part_offset(sec_buf, 1);
  } while (!is_partition_clear(q) && IS_EXTENDED(q->sys_ind));
}

static void physical_HS(int* h, int *s)
{  
  struct partition *p;
  int i, end_h, end_s, e_hh = 0, e_ss = 0, ini = 1, dirty = 0;
  const unsigned char *bufp = (const unsigned char *)MBRbuf;

  if (!(validate_part_buff((char*)bufp))) return;

  for (i = 0; i < 4; i++) {
    p = part_offset((char*)bufp, i);
    if (p->sys_ind) {
      end_h = p->end_head + 1;
      end_s = (p->end_sector & 077);
      if (ini) {
        e_hh = end_h;
        e_ss = end_s;
        ini = 0;
      } else if (e_hh !=end_h || e_ss != end_s)
        dirty = 1;
    }
  }
  if (!dirty && !ini) {
    *h = e_hh;
    *s = e_ss;
  }
}

//Reset the primary partition table
static void reset_boot(int change)
{
  int i;
  for(i = 0; i < 4; i++) {
    struct part_entry *pe = &partitions[i];
    pe->part = part_offset(MBRbuf, i);
    pe->start_offset = 0;
    pe->sec_buffer = MBRbuf;
    pe->modified = change;
  }
}

static inline void write_table_flag(char *buf)
{
  buf[510] = 0x55;
  buf[511] = 0xaa;
}

/* free the buffers used for holding details of
 * extended logical partions
*/
static void free_bufs(void)
{
  int i = 4;
  for (; i < num_parts; i++) free(partitions[i].sec_buffer);
}

static void create_empty_doslabel(void)
{
  xprintf("Building a new DOS Disklabel. The changes will\n"
      "remain in memory only, until you write it.\n");

  num_parts = 4;
  extended_offset = 0;
  memset(&MBRbuf[510 - 4*16], 0, 4*16);
  write_table_flag(MBRbuf);
  partitions[0].modified = 1;
  reset_boot(1);
}

/* Read the Master Boot sector of the device for the 
 * partition table entries/details.
 * If any extended partition is found then read the EBR
 * for logical partition details
 */
static int read_mbr(char *device, int validate)
{
  int fd, sector_fac, i, h = 0, s = 0;
  struct hd_geometry disk;
  fd = open(device, O_RDWR);
  if(fd < 0) {
    perror_msg("can't open '%s'",device);
    return 1;
  }

  disk_device = strdup(device);
  if(fd != dev_fd) {
    if(dup2(fd, dev_fd) != dev_fd) perror_exit("Can't dup2");
    close(fd);
  }

  //read partition table - MBR
  if (SECTOR_SIZE != readall(dev_fd, MBRbuf, SECTOR_SIZE)) {
    close(dev_fd);
    perror_exit("Couldn't read sector zero\n");
  }
  if (validate && !validate_part_buff(MBRbuf)) {
    xprintf("Device contains neither a valid DOS "
        "partition table, nor Sun, SGI, OSF or GPT "
        "disklabel\n");
    create_empty_doslabel();
  }

  disk.heads = disk.sectors = 0;
  read_geometry(&disk); //CHS values
  total_number_sectors = read_size(); //Device size
  read_sec_sz();
  sector_fac = g_sect_size/SECTOR_SIZE; //512 is hardware sector size.
  physical_HS(&h, &s); //physical dimensions may be diferent from HDIO_GETGEO
  g_sectors = (toys.optflags & FLAG_S && TT.sectors)? TT.sectors :  s? s : disk.sectors?disk.sectors : 63;
  g_heads = (toys.optflags & FLAG_H && TT.heads)? TT.heads : h? h : disk.heads? disk.heads : 255;
  g_cylinders = total_number_sectors/(g_heads * g_sectors * sector_fac);

  if (!g_cylinders) g_cylinders = toys.optflags & FLAG_C? TT.cylinders : 0;
  if ((g_cylinders > ONE_K) && !(toys.optflags & (FLAG_l | FLAG_S)))
    xprintf("\nThe number of cylinders for this disk is set to %lu.\n"
        "There is nothing wrong with that, but this is larger than 1024,\n"
        "and could in certain setups cause problems.\n", g_cylinders);
  for (i = 0; i < num_parts; i++) {
    if (IS_EXTENDED(partitions[i].part->sys_ind)) {
      read_ebr(i);
      break;
    }
  }
  chs_warn();

  return 0;
}

static char* get_type(int sys_ind)
{
  int i, size = ARRAY_LEN(sys_types);
  for (i = 0; i < size; i++)
    if (sys_ind == sys_types[i].id)
      return sys_types[i].type;
  return "Unknown";
}

static void consistency_check(const struct partition *p, int partition)
{        
  unsigned physbc, physbh, physbs, physec, physeh, physes;
  unsigned lbc, lbh, lbs, lec, leh, les;
  sector_t start, end;

  if (!g_heads || !g_sectors || (partition >= 4)) return;
  // physical beginning c, h, s 
  physbc = cylinder(p->sector,p->cyl);
  physbh = p->head;
  physbs = sector(p->sector);
  // physical ending c, h, s 
  physec = cylinder(p->end_sector, p->end_cyl);
  physeh = p->end_head;
  physes = sector(p->end_sector);
  // logical begin and end CHS values 
  start = swap_le32toh((unsigned char*)(p->start4));
  end = start + swap_le32toh((unsigned char*)(p->size4)) -1;

  lbc = start/(g_sectors * g_heads);
  lbh = (start/g_sectors) % g_heads;
  lbs = (start % g_sectors) + 1;

  lec = end/(g_sectors * g_heads);
  leh = (end/g_sectors) % g_heads;
  les = (end % g_sectors) + 1;

  //Logical and Physical diff 
  if (g_cylinders <= ONE_K && (physbc != lbc || physbh != lbh || physbs != lbs)) {
    xprintf("Partition %u has different physical/logical beginings (Non-Linux?): \n", partition+1);
    xprintf("phys = (%u %u %u) ",physbc, physbh, physbs);
    xprintf("logical = (%u %u %u)\n", lbc, lbh, lbs);
  }
  if (g_cylinders <= ONE_K && (physec != lec || physeh != leh || physes != les)) {
    xprintf("Partition %u has different physical/logical endings: \n", partition+1);
    xprintf("phys = (%u %u %u) ",physec, physeh, physes);
    xprintf("logical = (%u %u %u)\n", lec, leh, les);
  }
  // Ending on cylinder boundary? 
  if (physeh != (g_heads - 1) || physes != g_sectors)
    xprintf("Partition %u does not end on cylinder boundary\n", partition + 1);
}

// List the partition details
static void list_partitions(int validate)
{
  struct partition *p;
  uint32_t start_cyl, end_cyl, start_sec, end_sec, blocks, secs;
  char boot, lastchar = '\0', *dev = disk_device;
  int i = 0, len = strlen(disk_device), odds = 0;

  if (validate && !validate_part_buff(MBRbuf)) {
    close(dev_fd);
    toys.exitval = 1;
    xprintf("Device %s: doesn't contain a valid partition table\n", disk_device);
    return;
  }
  if (isdigit(dev[len - 1])) lastchar = 'p';

  xprintf("%*s Boot      Start         End      Blocks  Id System\n", len+1, "Device");
  for (i = 0; i < num_parts; i++) {
    p = partitions[i].part;
    if (is_partition_clear(p)) continue;

    boot = ((p->boot_ind == 0x80)?'*':(!p->boot_ind)?' ':'?');
    start_sec = swap_le32toh(p->start4) + partitions[i].start_offset;
    secs = swap_le32toh(p->size4);

    if ((start_sec + secs) == 0) end_sec = 0;
    else end_sec = start_sec + secs -1;
    start_cyl = start_sec/(g_heads * g_sectors) + 1;
    end_cyl = end_sec/(g_heads * g_sectors) + 1;
    blocks = secs;
    if (g_sect_size < ONE_K) {
      blocks /= (ONE_K/g_sect_size);
      odds = secs %(ONE_K/g_sect_size);
    } else if (g_sect_size > ONE_K) blocks *= (g_sect_size/ONE_K);

    if (lastchar) xprintf("%s%c%d",dev, lastchar, i+1);
    else xprintf("%s%d",dev, i+1);

    xprintf("   %c %11u %11u %11u%c %2x %s\n",
        boot,
        disp_unit_cyl == 0? start_sec: start_cyl,
        disp_unit_cyl == 0? end_sec: end_cyl,
        blocks,odds?'+':' ', p->sys_ind, get_type(p->sys_ind));

    consistency_check(p, i);
  }
  if (check_order()) xprintf("\nPartition table entries are not in disk order");
}

//Print device details
static void print_mbr(int validate)
{
  unsigned long long bytes = ((unsigned long long)total_number_sectors << 9);
  long mbytes = bytes/1000000;

  if (mbytes < 10000) xprintf("Disk %s: %lu MB, %llu bytes\n", disk_device, mbytes, bytes);
  else xprintf("Disk %s: %lu.%lu GB, %llu bytes\n", disk_device, mbytes/1000, (mbytes/100)%10, bytes);
  xprintf("%ld heads, %ld sectors/track, %ld cylinders", g_heads, g_sectors, g_cylinders);
  if (!disp_unit_cyl) {
    xprintf(", total %lld sectors\n", total_number_sectors/(g_sect_size/SECTOR_SIZE));
    xprintf("Units = sectors of 1 * %ld = %ld bytes\n",g_sect_size, g_sect_size);
  } else xprintf("\nUnits = cylinders of %ld * %ld = %ld bytes\n\n",
      g_heads * g_sectors, g_sect_size, g_heads * g_sectors * g_sect_size);
  list_partitions(validate);
  xputc('\n');
}

static void init_members(void)
{
  int i = 0;
  num_parts = 4; //max of primaries in a part table
  disp_unit_cyl = dos_flag = 1;
  extended_offset = 0;
  g_sect_size = SECTOR_SIZE;
  for (i = 0; i < num_parts; i++) {
    partitions[i].part = part_offset(MBRbuf, i);
    partitions[i].sec_buffer = MBRbuf;
    partitions[i].modified = 0;
    partitions[i].start_offset = 0;
  }
}

static int read_input(char *mesg, char *outp)
{
  char *p;
  int size = 0;
  do {
    xprintf("%s", mesg);
    p = fgets(toybuf, 80, stdin);
  
    if (!p || !(size = strlen(p))) exit(0);
    if (p[size-1] == '\n') p[--size] = '\0';
  } while (!size);

  while (*p != '\0' && *p <= ' ') p++;
  if (outp) memcpy(outp, p, strlen(p) + 1); //1 for nul
  return *p;
}

static int read_hex(char *mesg)
{
  int val;
  char input[80], *endp;
  while (1) {
    read_input(mesg, input);
    if ((*input | 0x20) == 'l') {
      list_types();
      memset(input, 0, 80);
      continue;
    }
    val = strtoul(input, &endp, 16);
    if (endp && *endp) continue;
    if (val <= 0xff) return val;
  }
}

/* Delete an exiting partition,
 * if its primary, then just clear the partition details
 * if extended, then clear the partition details, also for logical
 * if only logical, then move the later partitions backwards 1 step
 */
void delete_partition(int i)
{
  int sys_id, looper = 0;
  struct partition *p, *q, *ext_p, *ext_q;
  sector_t new_start;
  struct part_entry *pe = &partitions[i];
  
  if (chs_warn()) return;
  p = pe->part;
  sys_id = p->sys_ind;
  if (!sys_id) xprintf("Partition %u is empty\n", i+1);

  if (i < 4 && !IS_EXTENDED(sys_id)) {
    memset(p, 0, sizeof(struct partition)); //clear_partition
    pe->modified = 1;
  } else if (i < 4 && IS_EXTENDED(sys_id)) {
    memset(p, 0, sizeof(struct partition)); //clear_partition
    pe->modified = 1;
    for (looper = 4; looper < num_parts; looper++) {
      pe = &partitions[looper];
      p = pe->part; 
      if (is_partition_clear(p)) break;
      else {
        memset(p, 0, sizeof(struct partition)); //clear_partition
        pe->modified = 1;
        free(pe->sec_buffer);
      }
    }
    extended_offset = 0;
    num_parts = 4;
  } else {
    //only logical is delete, need to move the rest of them backwards
    if (i == 4) { //move partiton# 6 to 5.
      partitions[i].modified = 1;
      if (num_parts > i+1) {
        q = partitions[i + 1].part;
        *p = *q; //copy the part table
        ext_p = part_offset(partitions[i].sec_buffer, 1);
        ext_q = part_offset(partitions[i + 1].sec_buffer, 1);
        *ext_p = *ext_q; //copy the extended info pointer
        // change the start of the 4th partiton. 
        new_start = partitions[i + 1].start_offset + swap_le32toh(q->start4) - extended_offset;
        new_start = SWAP_LE32(new_start);
        memcpy(p->start4, (void *)&new_start, 4);
      } else {
        memset(partitions[i].part, 0, sizeof(struct partition));
        return; //only logical
      }
    } else if (i > 4) {
      ext_p = part_offset(partitions[i-1].sec_buffer, 1);
      ext_q = part_offset(partitions[i].sec_buffer, 1);
      memcpy((void*)ext_p, (void *)ext_q, sizeof(struct partition));
      partitions[i-1].modified = 1;
    }
    if (i == 4) looper = i+2;
    else if (i > 4) looper = i+1;
    for (; looper < num_parts; looper++)
      partitions[looper-1] = partitions[looper];
    num_parts--;
  }
}

static int ask_partition(int num_parts)
{
  int val;
  while (1) {
    do {
      xprintf("Partition (%u - %u):", 1, num_parts);
      fgets(toybuf, 80, stdin);
    } while (!isdigit(*toybuf));
    val = atoi(toybuf);
    if (val > 0 && val <= num_parts) return val;
    else xprintf("Invalid number entered\n");
  }
}

static void toggle_active_flag(int i)
{
  struct partition *p = partitions[i].part;
  if (is_partition_clear(p)) xprintf("Partition %u is empty\n", i+1);
  
  if (IS_EXTENDED(p->sys_ind) && !p->boot_ind)
    xprintf("WARNING: Partition %u is an extended partition\n", i + 1);
  p->boot_ind = p->boot_ind == 0x80?0 : 0x80;
  partitions[i].modified = 1;
}

//Write the partition details from Buffer to Disk.
void write_table(void)
{
  int i =0;
  struct part_entry *pe;
  sector_t offset;

  for (i = 0; i < 4; i++)
    if (partitions[i].modified) partitions[3].modified = 1;

  for (i = 3; i < num_parts; i++) {
    pe = &partitions[i];
    write_table_flag(pe->sec_buffer);
    offset = pe->start_offset;
    if (pe->modified == 1) {
      xlseek(dev_fd, offset * g_sect_size, SEEK_SET);
      xwrite(dev_fd, pe->sec_buffer, g_sect_size);
    }
  }
  xprintf("The partition table has been altered.\n");
  xprintf("Calling ioctl() to re-read partition table\n");
  sync();
  for (i = 4; i < num_parts; i++) free(partitions[i].sec_buffer);
  if(ioctl(dev_fd, BLKRRPART, NULL) < 0)
    perror_exit("WARNING: rereading partition table failed, kernel still uses old table");

}

/* try to find a partition for deletion, if only
 * one, then select the same, else ask from USER
 */
static int get_non_free_partition(int max)
{       
  int num = -1, i = 0;

  for (i = 0; i < max; i++) {
    if (!is_partition_clear(partitions[i].part)) {
      if (num >= 0)
        return ask_partition(num_parts)-1;
      num = i;
    }
  }
  (num >= 0) ? xprintf("Selected partition %d\n",num+1):
    xprintf("No partition is defined yet!\n");
  return num;
}

/* a try at autodetecting an empty partition table entry,
 * if multiple options then get USER's choce.
 */
static int get_free_partition(int max)
{
  int num = -1, i = 0;

  for (i = 0; i < max; i++) {
    if (is_partition_clear(partitions[i].part)) {
      if (num >= 0)
        return ask_partition(4)-1;
      num = i;
    }
  }
  (num >= 0) ? xprintf("Selected partition %d\n",num+1):
    xprintf("All primary partitions have been defined already!\n");
  return num;
}

//taking user input for partition start/end sectors/cyinders
static uint32_t ask_value(char *mesg, sector_t left, sector_t right, sector_t defalt)
{ 
  char *str = toybuf;
  uint32_t val;
  int use_default = 1;

  while (1) {
    use_default = 1;
    do {
      xprintf("%s",mesg);
      fgets(str, 80, stdin);
    } while (!isdigit(*str) && (*str != '\n')
        && (*str != '-') && (*str != '+') && (!isblank(*str)));
    while (isblank(*str)) str++; //remove leading white spaces
    if (*str == '+' || *str == '-') {
      int minus = (*str == '-');
      int absolute = 0;

      val = atoi(str + 1);
      while (isdigit(*++str)) use_default = 0;

      switch (*str) {
        case 'c':
        case 'C':
          if (!disp_unit_cyl) val *= g_heads * g_sectors;
          break;
        case 'K':
          absolute = ONE_K;
          break;
        case 'k':
          absolute = 1000;
          break;
        case 'm':
        case 'M':
          absolute = 1000000;
          break;
        case 'g':
        case 'G':
          absolute = 1000000000;
          break;
        default:
          break;
      }
      if (absolute) {
        unsigned long long bytes = (unsigned long long) val * absolute;
        unsigned long unit = (disp_unit_cyl && (g_heads * g_sectors))? g_heads * g_sectors : 1;

        unit = unit * g_sect_size;
        bytes += unit/2; // rounding
        bytes /= unit;
        val = bytes;
      }
      if (minus)
        val = -val;
      val += left;
    } else {
      val = atoi(str);
      while (isdigit(*str)) {
        str++;
        use_default = 0;
      }
    }
    if(use_default) {
      val = defalt;
      xprintf("Using default value %lld\n", defalt);
    }
    if (val >= left && val <= right) return val;
    else xprintf("Value out of range\n");
  }
}

//validating if the start given falls in a limit or not
static int validate(int start_index, sector_t* begin,sector_t* end, sector_t start
    , int asked)
{
  int i, valid = 0;
  for (i = start_index; i < num_parts; i++) {
    if (start >= begin[i] && start <= end[i]) {
      if (asked) xprintf("Sector %lld is already allocated\n",start);
      valid = 0;
      break;
    } else valid = 1;
  }
  return valid;
}

//get the start sector/cylinder of a new partition
static sector_t ask_start_sector(int idx, sector_t* begin, sector_t* end, int ext_idx)
{
  sector_t start, limit, temp = 0, start_cyl, limit_cyl, offset = 1;
  char mesg[256];
  int i, asked = 0, valid = 0, start_index = 0;

  if (dos_flag) offset = g_sectors;
  start = offset;
  if (disp_unit_cyl) limit = (sector_t)g_sectors * g_heads * g_cylinders - 1;
  else limit = total_number_sectors - 1;

  if (disp_unit_cyl) //make the begin of every partition to cylnder boundary 
    for (i = 0; i < num_parts; i++)
      begin[i] = (begin[i]/(g_heads* g_sectors)) * (g_heads* g_sectors);

  if (idx >= 4) {
    if (!begin[ext_idx] && extended_offset) begin[ext_idx] = extended_offset;
    start = begin[ext_idx] + offset;
    limit = end[ext_idx];
    start_index = 4;
  }
  do {
    if (asked) valid = validate(start_index, begin, end, start, asked);
    if (valid) break;

    do {
      for (i = start_index; i < num_parts; i++) 
        if (start >= begin[i] && start <= end[i])
          start = end[i] + 1 + ((idx >= 4)? offset : 0);
    } while (!validate(start_index, begin, end, start, 0));

    start_cyl = start/(g_sectors * g_heads) + 1;
    limit_cyl = limit/(g_sectors * g_heads) + 1;

    if (start > limit) break;
    sprintf(mesg, "First %s (%lld - %lld, default %lld): ", disp_unit_cyl? "cylinder" : "sector",
        (long long int)(disp_unit_cyl? start_cyl : start), 
        (long long int)(disp_unit_cyl? limit_cyl : limit),
        (long long int)(disp_unit_cyl? start_cyl : start));
    temp = ask_value(mesg, disp_unit_cyl? start_cyl : start, 
        disp_unit_cyl? limit_cyl : limit, disp_unit_cyl? start_cyl : start);
    asked = 1;

    if (disp_unit_cyl) {
      // point to the cylinder start sector
      temp = (temp-1) * g_heads * g_sectors;
      if (temp < start) //the boundary is falling in the already used sectors.
        temp = start;
    }
    start = temp;
  } while (asked && !valid);
  return start;
}

//get the end sector/cylinder of a new partition
static sector_t ask_end_sector(int idx, sector_t* begin, sector_t* end, int ext_idx, sector_t start_sec)
{
  sector_t limit, temp = 0, start_cyl, limit_cyl, start = start_sec;
  char mesg[256];
  int i;

  if (disp_unit_cyl) limit = (sector_t)g_sectors * g_heads * g_cylinders - 1;
  else limit = total_number_sectors - 1;

  if (disp_unit_cyl) //make the begin of every partition to cylnder boundary
    for (i = 0; i < num_parts; i++)
      begin[i] = (begin[i]/(g_heads* g_sectors)) * (g_heads* g_sectors);

  if (idx >= 4) limit = end[ext_idx];

  for (i = 0; i < num_parts; i++) {
    struct part_entry *pe = &partitions[i];
    if (start < pe->start_offset && limit >= pe->start_offset) limit = pe->start_offset - 1;
    if (start < begin[i] && limit >= begin[i]) limit = begin[i] - 1;
  }

  start_cyl = start/(g_sectors * g_heads) + 1;
  limit_cyl = limit/(g_sectors * g_heads) + 1;
  if (limit < start) { //the boundary is falling in the already used sectors.
    xprintf("No Free sectors available\n");
    return 0;
  }
  sprintf(mesg, "Last %s or +size or +sizeM or +sizeK (%lld - %lld, default %lld): ",
      disp_unit_cyl? "cylinder" : "sector",
      (long long int)(disp_unit_cyl? start_cyl : start), 
      (long long int)(disp_unit_cyl? limit_cyl : limit),
      (long long int)(disp_unit_cyl? limit_cyl : limit));
  temp = ask_value(mesg, disp_unit_cyl? start_cyl : start, 
      disp_unit_cyl? limit_cyl : limit, disp_unit_cyl? limit_cyl : limit);

  if (disp_unit_cyl) { // point to the cylinder start sector
    temp = temp * g_heads * g_sectors - 1;
    if (temp > limit) temp = limit;
  }
  if (temp < start) { //the boundary is falling in the already used sectors.
    xprintf("No Free sectors available\n");
    return 0;
  }
  return temp;
}

// add a new partition to the partition table
static int add_partition(int idx, int sys_id)
{
  int i, ext_idx = -1;
  sector_t start, end, begin_sec[num_parts], end_sec[num_parts];
  struct part_entry *pe = &partitions[idx];
  struct partition *p = pe->part;

  if (p && !is_partition_clear(p)) {
    xprintf("Partition %u is already defined, delete it to re-add\n", idx+1);
    return 0;
  }
  for (i = 0; i < num_parts; i++) {
    pe = &partitions[i];
    p = pe->part;
    if (is_partition_clear(p)) {
      begin_sec[i] = 0xffffffff;
      end_sec[i] = 0;
    } else {
      begin_sec[i] = swap_le32toh(p->start4) + pe->start_offset;
      end_sec[i] = begin_sec[i] + swap_le32toh(p->size4) - 1;
    }
    if (IS_EXTENDED(p->sys_ind)) ext_idx = i;
  }
  start = ask_start_sector(idx, begin_sec, end_sec, ext_idx);
  end = ask_end_sector(idx, begin_sec, end_sec, ext_idx, start);
  if (!end) return 0;
  //Populate partition table entry  - 16 bytes
  pe = &partitions[idx];
  p = pe->part;

  if (idx > 4) {
    if (dos_flag) pe->start_offset = start - (sector_t)g_sectors;
    else pe->start_offset = start - 1;
    if (pe->start_offset == extended_offset) pe->start_offset++;
    if (!dos_flag) start++;
  }
 
  set_levalue(p->start4, start - pe->start_offset);
  set_levalue(p->size4, end - start + 1);
  set_hsc(p, start, end);
  p->boot_ind = 0;
  p->sys_ind = sys_id;
  pe->modified = 1;

  if (idx > 4) {
    p = partitions[idx-1].part + 1; //extended pointer for logical partitions
    set_levalue(p->start4, pe->start_offset - extended_offset);
    set_levalue(p->size4, end - start + 1 + (dos_flag? g_sectors: 1));
    set_hsc(p, pe->start_offset, end);
    p->boot_ind = 0;  
    p->sys_ind = EXTENDED;
    partitions[idx-1].modified = 1;   
  }
  if (IS_EXTENDED(sys_id)) {
    pe = &partitions[4];
    pe->modified = 1; 
    pe->sec_buffer = xzalloc(g_sect_size);
    pe->part = part_offset(pe->sec_buffer, 0);
    pe->start_offset = extended_offset = start;
    num_parts = 5;
  }
  return 1;
}

static void add_logical_partition(void)
{
  struct part_entry *pe;
  if (num_parts > 5 || !is_partition_clear(partitions[4].part)) {
    pe = &partitions[num_parts];
    pe->modified = 1;
    pe->sec_buffer = xzalloc(g_sect_size);
    pe->part = part_offset(pe->sec_buffer, 0);
    pe->start_offset = 0;
    num_parts++;
    if (!add_partition(num_parts - 1, LINUX_NATIVE)) {
      num_parts--;
      free(pe->sec_buffer);
    }
  } 
  else add_partition(num_parts -1, LINUX_NATIVE);
}

/* Add a new partiton to the partition table.
 * MAX partitions limit is taken to be 60, can be changed
 */
static void add_new_partition(void)
{
  int choice, idx, i, free_part = 0;
  char *msg = NULL;
  
  if (chs_warn()) return;
  for (i = 0; i < 4; i++) if(is_partition_clear(partitions[i].part)) free_part++;

  if (!free_part && num_parts >= 60) {
    xprintf("The maximum number of partitions has been created\n");
    return;       
  }
  if (!free_part) {
    if (extended_offset) add_logical_partition();
    else xprintf("You must delete some partition and add "
          "an extended partition first\n");
    return;
  }

  msg = xmprintf("  %s\n  p  primary partition(1-4)\n",
          extended_offset? "l  logical (5 or over)" : "e  extended");

  choice = 0x20 | read_input(msg, NULL);
  free(msg);
  if (choice == 'p') {
    idx = get_free_partition(4);
    if (idx >= 0) add_partition(idx, LINUX_NATIVE);
    return;
  }
  if (choice =='l' && extended_offset) {
    add_logical_partition();
    return;
  }
  if (choice == 'e' && !extended_offset) {
    idx = get_free_partition(4);   
    if (idx >= 0) add_partition(idx, EXTENDED);
    return;
  }
}

static void change_systype(void )
{
  int i, sys_id;
  struct partition *p;
  struct part_entry *pe;

  i = ask_partition(num_parts);
  pe = &partitions[i-1];
  p = pe->part;
  if (is_partition_clear(p)) {
    xprintf("Partition %d doesn't exist yet!\n", i);
    return;
  }
  sys_id = read_hex("Hex code (L to list codes): ");
  if ((IS_EXTENDED(p->sys_ind) && !IS_EXTENDED(sys_id)) ||
      (!IS_EXTENDED(p->sys_ind) && IS_EXTENDED(sys_id))) {
    xprintf("you can't change a  partition to an extended or vice-versa\n");
    return;
  }

  xprintf("Changed system type of partition %u to %0x (%s)\n",i, sys_id, get_type(sys_id));
  p->sys_ind = sys_id;
  pe->modified = 1;
}

static void check(int n, unsigned h, unsigned s, unsigned c, sector_t start)
{   
  sector_t total, real_s, real_c;

  real_s = sector(s) - 1;
  real_c = cylinder(s, c);
  total = (real_c * g_sectors + real_s) * g_heads + h;
  if (!total) xprintf("Partition %u contains sector 0\n", n);
  if (h >= g_heads)
    xprintf("Partition %u: head %u greater than maximum %lu\n", n, h + 1, g_heads);
  if (real_s >= g_sectors)
    xprintf("Partition %u: sector %u greater than maximum %lu\n", n, s, g_sectors);
  if (real_c >= g_cylinders)
    xprintf("Partition %u: cylinder %lld greater than maximum %lu\n", n, real_c + 1, g_cylinders);
  if (g_cylinders <= ONE_K && start != total)
    xprintf("Partition %u: previous sectors %lld disagrees with total %lld\n", n, start, total);
}

static void verify_table(void)
{
  int i, j, ext_idx = -1;
  sector_t begin_sec[num_parts], end_sec[num_parts], total = 1;
  struct part_entry *pe;
  struct partition *p;

  for (i = 0; i < num_parts; i++) {
    pe = &partitions[i];
    p = pe->part;
    if (is_partition_clear(p) || IS_EXTENDED(p->sys_ind)) {
      begin_sec[i] = 0xffffffff;
      end_sec[i] = 0;
    } else {
      begin_sec[i] = swap_le32toh(p->start4) + pe->start_offset;
      end_sec[i] = begin_sec[i] + swap_le32toh(p->size4) - 1;
    }
    if (IS_EXTENDED(p->sys_ind)) ext_idx = i;
  }
  for (i = 0; i < num_parts; i++) {
    pe = &partitions[i];
    p = pe->part;
    if (p->sys_ind && !IS_EXTENDED(p->sys_ind)) {
      consistency_check(p, i);
      if ((swap_le32toh(p->start4) + pe->start_offset) < begin_sec[i])
        xprintf("Warning: bad start-of-data in partition %u\n", i + 1);
      check(i + 1, p->end_head, p->end_sector, p->end_cyl, end_sec[i]);
      total += end_sec[i] + 1 - begin_sec[i];
      for (j = 0; j < i; j++) {
        if ((begin_sec[i] >= begin_sec[j] && begin_sec[i] <= end_sec[j])
            || ((end_sec[i] <= end_sec[j] && end_sec[i] >= begin_sec[j]))) {
          xprintf("Warning: partition %u overlaps partition %u\n", j + 1, i + 1);
          total += begin_sec[i] >= begin_sec[j] ? begin_sec[i] : begin_sec[j];
          total -= end_sec[i] <= end_sec[j] ? end_sec[i] : end_sec[j];
        }
      }
    }
  }  
  if (extended_offset) {
    struct part_entry *pex = &partitions[ext_idx];
    sector_t e_last = swap_le32toh(pex->part->start4) +
      swap_le32toh(pex->part->size4) - 1;

    for (i = 4; i < num_parts; i++) {
      total++;
      p = partitions[i].part;
      if (!p->sys_ind) {
        if (i != 4 || i + 1 < num_parts)
          xprintf("Warning: partition %u is empty\n", i + 1);
      } else if (begin_sec[i] < extended_offset || end_sec[i] > e_last)
        xprintf("Logical partition %u not entirely in partition %u\n", i + 1, ext_idx + 1);
    }
  }
  if (total > g_heads * g_sectors * g_cylinders)
    xprintf("Total allocated sectors %lld greater than the maximum "
        "%lu\n", total, g_heads * g_sectors * g_cylinders);
  else {
    total = g_heads * g_sectors * g_cylinders - total;
    if (total) xprintf("%lld unallocated sectors\n", total);
  }
}

static void move_begning(int idx)
{
  sector_t start, num, new_start, end;
  char mesg[256];
  struct part_entry *pe = &partitions[idx];
  struct partition *p = pe->part;

  if (chs_warn()) return;
  start = swap_le32toh(p->start4) + pe->start_offset;
  num = swap_le32toh(p->size4);
  end = start + num -1;

  if (!num || IS_EXTENDED(p->sys_ind)) {
    xprintf("Partition %u doesn't have data area\n", idx+1);
    return;
  }
  sprintf(mesg, "New begining of data (0 - %lld, default %lld): ", 
      (long long int)(end), (long long int)(start));
  new_start = ask_value(mesg, 0, end, start);
  if (new_start != start) {
    set_levalue(p->start4, new_start - pe->start_offset);
    set_levalue(p->size4, end - new_start +1);
    if ((read_input("Recalculate C/H/S (Y/n): ", NULL) | 0x20) == 'y')
      set_hsc(p, new_start, end);
    pe->modified = 1;
  }
}

static void print_raw_sectors()
{
  int i, j;
  struct part_entry *pe;

  xprintf("Device: %s\n", disk_device);
  for (i = 3; i < num_parts; i++) {
    pe = &partitions[i];
    for (j = 0; j < g_sect_size; j++) {
      if (!(j % 16)) xprintf("\n0x%03X: ",j);
      xprintf("%02X ",pe->sec_buffer[j]);
    }
    xputc('\n');
  }
}

static void print_partitions_list(int ext)
{
  int i;                                                                                    
  struct part_entry *pe;
  struct partition *p;

  xprintf("Disk %s: %lu heads, %lu sectors, %lu cylinders\n\n", disk_device, g_heads, g_sectors, g_cylinders);
  xprintf("Nr AF  Hd Sec  Cyl  Hd Sec  Cyl      Start       Size ID\n");

  for (i = 0; i < num_parts; i++) {
    pe = &partitions[i];
    p = pe->part;
    if (p) {
      if (ext && (i >= 4)) p = pe->part + 1;
      if(ext && i < 4 && !IS_EXTENDED(p->sys_ind)) continue;

      xprintf("%2u %02x%4u%4u%5u%4u%4u%5u%11u%11u %02x\n",
          i+1, p->boot_ind, p->head,
          sector(p->sector), cylinder(p->sector, p->cyl),
          p->end_head,           
          sector(p->end_sector), cylinder(p->end_sector, p->end_cyl),
          swap_le32toh(p->start4),
          swap_le32toh(p->size4),
          p->sys_ind);
      if (p->sys_ind) consistency_check(p, i);
    }
  }
}

//fix the partition table order to ascending
static void fix_order(void)
{
  sector_t first[num_parts], min;
  int i, j, oj, ojj, sj, sjj;
  struct part_entry *pe;
  struct partition *px, *py, temp, *pj, *pjj, tmp;

  for (i = 0; i < num_parts; i++) {
    pe = &partitions[i];
    px = pe->part;
    if (is_partition_clear(px)) first[i] = 0xffffffff;
    else first[i] = swap_le32toh(px->start4) + pe->start_offset;
  }
  
  if (!check_order()) {
    xprintf("Ordering is already correct\n\n");
    return;
  }
  for (i = 0; i < 4; i++) {
    for (j = 0; j < 3; j++) {
      if (first[j] > first[j+1]) {
        py = partitions[j+1].part;
        px = partitions[j].part;
        memcpy(&temp, py, sizeof(struct partition));
        memcpy(py, px, sizeof(struct partition));
        memcpy(px, &temp, sizeof(struct partition));
        min = first[j+1];
        first[j+1] = first[j];
        first[j] = min;
        partitions[j].modified = 1;
      }
    }
  }
  for (i = 5; i < num_parts; i++) {
    for (j = 5; j < num_parts - 1; j++) {
      oj = partitions[j].start_offset;
      ojj = partitions[j+1].start_offset;
      if (oj > ojj) {
        partitions[j].start_offset = ojj;
        partitions[j+1].start_offset = oj;
        pj = partitions[j].part;
        set_levalue(pj->start4, swap_le32toh(pj->start4)+oj-ojj);
        pjj = partitions[j+1].part;
        set_levalue(pjj->start4, swap_le32toh(pjj->start4)+ojj-oj);
        set_levalue((partitions[j-1].part+1)->start4, ojj-extended_offset);
        set_levalue((partitions[j].part+1)->start4, oj-extended_offset);
      }
    }
  }
  for (i = 4; i < num_parts; i++) {
    for (j = 4; j < num_parts - 1; j++) {
      pj = partitions[j].part;
      pjj = partitions[j+1].part;
      sj = swap_le32toh(pj->start4);
      sjj = swap_le32toh(pjj->start4);
      oj = partitions[j].start_offset;
      ojj = partitions[j+1].start_offset;
      if (oj+sj > ojj+sjj) {
        tmp = *pj;
        *pj = *pjj;
        *pjj = tmp;
        set_levalue(pj->start4, ojj+sjj-oj);
        set_levalue(pjj->start4, oj+sj-ojj);
      }  
    }    
  }
  // If anything changed 
  for (j = 4; j < num_parts; j++) partitions[j].modified = 1;
  xprintf("Done!\n");
}

static void print_menu(void)
{
  xprintf("a\ttoggle a bootable flag\n"
  "b\tedit bsd disklabel\n"
  "c\ttoggle the dos compatibility flag\n"
  "d\tdelete a partition\n"
  "l\tlist known partition types\n"
  "n\tadd a new partition\n"
  "o\tcreate a new empty DOS partition table\n"
  "p\tprint the partition table\n"
  "q\tquit without saving changes\n"
  "s\tcreate a new empty Sun disklabel\n"
  "t\tchange a partition's system id\n"
  "u\tchange display/entry units\n"
  "v\tverify the partition table\n"
  "w\twrite table to disk and exit\n"
  "x\textra functionality (experts only)\n");
}

static void print_xmenu(void)
{
  xprintf("b\tmove beginning of data in a partition\n"
  "c\tchange number of cylinders\n"
  "d\tprint the raw data in the partition table\n"
  "e\tlist extended partitions\n"
  "f\tfix partition order\n"  
  "h\tchange number of heads\n"
  "p\tprint the partition table\n"
  "q\tquit without saving changes\n"
  "r\treturn to main menu\n"
  "s\tchange number of sectors/track\n"
  "v\tverify the partition table\n"
  "w\twrite table to disk and exit\n");
}

static void expert_menu(void)
{
  int choice, idx;
  sector_t value;
  char mesg[256];

  while (1) {
    xputc('\n');
    char *msg = "Expert Command ('m' for help): ";
    choice = 0x20 | read_input(msg, NULL);
    switch (choice) {
      case 'b': //move data begining in partition
        idx = ask_partition(num_parts);
        move_begning(idx - 1);
        break;
      case 'c': //change cylinders
          sprintf(mesg, "Number of cylinders (1 - 1048576, default %lu): ", g_cylinders);
          value = ask_value(mesg, 1, 1048576, g_cylinders);
          g_cylinders = TT.cylinders = value;
          toys.optflags |= FLAG_C;
          if(g_cylinders > ONE_K)
            xprintf("\nThe number of cylinders for this disk is set to %lu.\n"
                "There is nothing wrong with that, but this is larger than 1024,\n"
                "and could in certain setups cause problems.\n", g_cylinders);
        break;
      case 'd': //print raw data in part tables
        print_raw_sectors();
        break;
      case 'e': //list extended partitions
        print_partitions_list(1);
        break;
      case 'f': //fix part order
        fix_order();
        break;
      case 'h': //change number of heads
          sprintf(mesg, "Number of heads (1 - 256, default %lu): ", g_heads);
          value = ask_value(mesg, 1, 256, g_heads);
          g_heads = TT.heads = value;
          toys.optflags |= FLAG_H;
        break;
      case 'p': //print partition table
        print_partitions_list(0);
        break;
      case 'q':
        free_bufs();
        close(dev_fd);
        xputc('\n');
        exit(0);
        break;
      case 'r':
        return;
        break;
      case 's': //change sector/track
          sprintf(mesg, "Number of sectors (1 - 63, default %lu): ", g_sectors);
          value = ask_value(mesg, 1, 63, g_sectors);
          g_sectors = TT.sectors = value;
          toys.optflags |= FLAG_H;
        break;
      case 'v':
        verify_table();
        break;
      case 'w':
        write_table();
        toys.exitval = 0;
        exit(0);
        break;
      case 'm':
        print_xmenu();
        break;
      default:
        xprintf("Unknown command '%c'\n",choice);
        print_xmenu();
        break;
    }
  } //while(1)
}

static int disk_proper(const char *device)
{
  unsigned length;
  int fd = open(device, O_RDONLY);

  if (fd != -1) {
    struct hd_geometry dev_geo;
    dev_geo.heads = 0;
    dev_geo.sectors = 0;
    int err = ioctl(fd, HDIO_GETGEO, &dev_geo);
    close(fd);
    if (!err) return (dev_geo.start == 0);
  }
  length = strlen(device);
  if (length != 0 && isdigit(device[length - 1])) return 0;
  return 1;
}

static void reset_entries()
{
  int i;

  memset(MBRbuf, 0, sizeof(MBRbuf));
  for (i = 4; i < num_parts; i++)
    memset(&partitions[i], 0, sizeof(struct part_entry));
}

//this will keep dev_fd = 3 always alive
static void move_fd()
{
  int fd = xopen("/dev/null", O_RDONLY);
  if(fd != dev_fd) {
    if(dup2(fd, dev_fd) != dev_fd) perror_exit("Can't dup2");
    close(fd);
  }
}

/* Read proc/partitions and then print the details
 * for partitions on each device
 */
static void read_and_print_parts()
{
  unsigned int ma, mi, sz;
  char *name = toybuf, *buffer = toybuf + ONE_K, *device = toybuf + 2048;
  FILE* fp = xfopen("/proc/partitions", "r");

  while (fgets(buffer, ONE_K, fp)) {
    reset_entries();
    num_parts = 4;
    memset(name, 0, sizeof(name));
    if (sscanf(buffer, " %u %u %u %[^\n ]", &ma, &mi, &sz, name) != 4)
      continue;
      
    sprintf(device,"/dev/%s",name);
    if (disk_proper(device)) {
      if (read_mbr(device, 0)) continue;
      print_mbr(1);
      move_fd();
    }
  }
  fclose(fp);
}

void fdisk_main(void)
{
  int choice, p;

  init_members();
  move_fd();
  if (TT.heads >= 256) TT.heads = 0;
  if (TT.sectors >= 64) TT.sectors = 0;
  if (toys.optflags & FLAG_u) disp_unit_cyl = 0;
  if (toys.optflags & FLAG_l) {
    if (!toys.optc) read_and_print_parts();
    else {
      while(*toys.optargs){
        if (read_mbr(*toys.optargs, 0)) {
          toys.optargs++;
          continue;
        }
        print_mbr(1);
        move_fd();
        toys.optargs++;
      }
    }
    toys.exitval = 0;
    return;
  } else {
    if (toys.optc != 1) help_exit(stdout);
    if (read_mbr(toys.optargs[0], 1)) return;
    while (1) {
      xputc('\n');
      char *msg = "Command ('m' for help): ";
      choice = 0x20 | read_input(msg, NULL);
      switch (choice) {
        case 'a':
          p = ask_partition(num_parts);
          toggle_active_flag(p - 1); //partition table index start from 0.
          break;
        case 'b':
          break;
        case 'c':
          dos_flag = !dos_flag;
          xprintf("Dos compatible flag is %s\n", dos_flag?"Set" : "Not set");
          break;
        case 'd':
          p = get_non_free_partition(num_parts); //4 was here
          if(p >= 0) delete_partition(p);
          break;
        case 'l':
          list_types();
          break;
        case 'n': //add new partition
          add_new_partition();
          break;
        case 'o':
          create_empty_doslabel();
          break;
        case 'p':
          print_mbr(0);
          break;
        case 'q':
          free_bufs();
          close(dev_fd);
          xputc('\n');
          exit(0);
          break;
        case 's':
          break;
        case 't':
          change_systype();
          break;
        case 'u':
          disp_unit_cyl = !disp_unit_cyl;
          xprintf("Changing Display/Entry units to %s\n",disp_unit_cyl?"cylinders" : "sectors");
          break;
        case 'v':
          verify_table();
          break;
        case 'w':
          write_table();
          toys.exitval = 0;
          return;
          break;
        case 'x':
          expert_menu();
          break;
        case 'm':
          print_menu();
          break;
        default:
          xprintf("%c: Unknown command\n",choice);
          break;
      }
    } //while(1)
  }
}
