/* sectsz - A utility for finding the sector size of a disk.
          - William Favorite
          - Version 1.0.0

   Usage: sectsz /dev/sda1

   Note: This must be run with root priveledges.
*/     
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/fs.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
  int d;
  int e;
  size_t sz;
  size_t scnt;

  unsigned long long totalsz;

  char MULT[] = "BKMGTP";
  int m = 0;

  if(argc != 2)
  {
    fprintf(stderr, "Incorrect number of arguments.\n");
    return(1);
  }

  fprintf(stderr, "Opening %s...", argv[1]);
  if(-1 == (d = open(argv[1], O_NONBLOCK)))
    {
      e = errno;
      fprintf(stderr, "Failed.\n");
      fprintf(stderr, "%s.\n", strerror(e));
      return(1);
    }
  fprintf(stderr, "Done.\n");

  fprintf(stderr, "Calling ioctl() on device...");
  /* An alternate call would be HDIO_GET_IDENTITY for more info */
  if(0 != ioctl(d, BLKSSZGET, &sz))
    {
      e = errno;
      fprintf(stderr, "Failed.\n");
      fprintf(stderr, "%s.\n", strerror(e));
      close(d);
      return(1);
    }
  fprintf(stderr, "Done.\n");

  fprintf(stderr, "Got size of: %lu\n", (unsigned long)sz); 


  fprintf(stderr, "Calling ioctl() on device...");
  /* An alternate call would be HDIO_GET_IDENTITY for more info */
  if(0 != ioctl(d, BLKGETSIZE, &scnt))
    {
      e = errno;
      fprintf(stderr, "Failed.\n");
      fprintf(stderr, "%s.\n", strerror(e));
      close(d);
      return(1);
    }
  fprintf(stderr, "Done.\n");

  fprintf(stderr, "Got sector count of: %lu\n", (unsigned long)scnt); 

  totalsz = (unsigned long long)scnt * (unsigned long long)sz;

  /* totalsz is the size of the disk in bytes. */

  /* Change (roll down) the factor of the size. */
  while(totalsz > 10000)
  {
    totalsz = totalsz / (unsigned long long)1024;
    m++;
  }

  fprintf(stderr, "Size of disk is: %llu %c\n", (unsigned long long)totalsz, MULT[m]); 

  fprintf(stderr, "Close()ing the device...");
  close(d);
  fprintf(stderr, "Done.\nExiting.\n");

  return(0);
}