/* mkhdimage.c, for the Linux DOS emulator
 *
 * cheesy program to create an hdimage header
 *
 */

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#ifdef __linux__
#include <getopt.h>
#endif
#include <errno.h>
#include <string.h>

#include "disks.h"


static void usage(void)
{
  fprintf(stderr, "mkhdimage [-h <heads>] [-s <sectors>] [-c|-t <cylinders>] [-f <outfile>]\n");
}

int main(int argc, char **argv)
{
  int c;
  int ret = 0;
  int fdout = STDOUT_FILENO;
  struct image_header hdr = {
    .sig = "DOSEMU",
    .cylinders = 40,
    .heads = 4,
    .sectors = 17,
    .header_end = sizeof(hdr),
    .dexeflags = 0,
  };

  while ((c = getopt(argc, argv, "h:s:t:c:s:f:")) != EOF) {
    switch (c) {
    case 'h':
      hdr.heads = atoi(optarg);
      break;
    case 's':
      hdr.sectors = atoi(optarg);
      break;
    case 'c':  /* cylinders */
    case 't':  /* tracks */
      hdr.cylinders = atoi(optarg);
      break;
    case 'f':
      fdout = open(optarg, O_CREAT|O_WRONLY|O_TRUNC, 0644);
      if(fdout < 0) {
        fprintf(stderr, "Could not open file '%s' for writing\n", optarg);
        return 1;
      }
      break;
    default:
      fprintf(stderr, "Unknown option '%c'\n", c);
      usage();
      return 1;
    }
  }

  ret = write(fdout, &hdr, sizeof(hdr));
  if (ret != sizeof(hdr)) {
    fprintf(stderr, "Failed to write header\n");
    return 1;
  }

  if(fdout != STDOUT_FILENO) {
    /* Write hole */
    ret = lseek(fdout, (hdr.cylinders * hdr.heads * hdr.sectors * 512) - 1, SEEK_CUR);
    if (ret == -1) {
      fprintf(stderr, "Failed to lseek\n");
      return 2;
    }
    ret = write(fdout, "", 1);
    if (ret != 1) {
      fprintf(stderr, "Failed to write disk blocks\n");
      return 2;
    }
    close(fdout);
  }

  return 0;
}
