/*
 *  diskinfo -- ディスクのジオメトリ情報を取得
 *
 *  revision history
 *	0.0: Sep.  6, 2002 by Dai ISHIJIMA (とりあえずバージョン)
 *	0.0: Oct. 21, 2002
 *
 *  参考文献:
 *	fdisk(8) のソース (/usr/src/sbin/i386/fdisk/fdisk.c)
 */

#include <sys/disklabel.h>
#include <fcntl.h>
#include <unistd.h>


#define SHOW_CYLS 1
#define SHOW_HEAD 2
#define SHOW_SECS 4

#define shift --argc; ++argv

#define DFLT_DISK "/dev/rad0"
#define EOS '\0'

#ifndef BUFSIZ
#define BUFSIZ 512
#endif


/* 数値を文字列に変換 */
char *num2str(int d, char *s)
{
    int p;
    int q;
    int ch;

    p = 0;
    do {
	s[p] = '0' + (d % 10);
	++p;
	d /= 10;
    } while (d > 0);
    s[p] = EOS;
    for (q = 0; q < p / 2; q++) {
	ch = s[q];
	s[q] = s[p - q - 1];
	s[p - q - 1] = ch;
    }
    return(s);
}


/* 文字列出力 */
int myputs(int fd, char *s)
{
    return(write(fd, s, strlen(s)));
}


int main(int argc, char *argv[])
{
    char *disk;
    char s[BUFSIZ];
    struct disklabel disklabel;
    int show;
    int fd;

    show = 0;
    shift;
    while ((argc > 0) && (argv[0][0] == '-')) {
	if (argv[0][1] == 'c') {
	    show |= SHOW_CYLS;
	}
	else if (argv[0][1] == 'h') {
	    show |= SHOW_HEAD;
	}
	else if (argv[0][1] == 's') {
	    show |= SHOW_SECS;
	}
	else {
	    myputs(STDERR_FILENO, "Usage: diskinfo [-c|-h|-s] [device]\n");
	    exit(1);
	}
	shift;
    }
    if (show == 0) {
	show = SHOW_CYLS | SHOW_HEAD | SHOW_SECS;
    }
    if (argc > 0) {
	disk = *argv;
    }
    else {
	disk = DFLT_DISK;
    }
    if ((fd = open(disk, O_RDONLY)) < 0) {
	/* fprintf(stderr, "diskinfo: unable to open disk %s\n", disk); */
	myputs(STDERR_FILENO, "diskinfo: unable to open disk ");
	myputs(STDERR_FILENO, disk);
	myputs(STDERR_FILENO, "\n");
	exit(1);
    }
    if (ioctl(fd, DIOCGDINFO, &disklabel) == -1) {
	/* fprintf(stderr, "can't get disk parameters\n"); */
	myputs(STDERR_FILENO, "diskinfo: can't get disk parameters\n");
    }
    /* printf("cyls %d, heads %d, secs %d\n",
	   disklabel.d_ncylinders,
	   disklabel.d_ntracks,
	   disklabel.d_nsectors);
    */
    if (show & SHOW_CYLS) {
	num2str(disklabel.d_ncylinders, s);
	myputs(STDOUT_FILENO, s);
	myputs(STDOUT_FILENO, "\n");
    }
    if (show & SHOW_HEAD) {
	num2str(disklabel.d_ntracks, s);
	myputs(STDOUT_FILENO, s);
	myputs(STDOUT_FILENO, "\n");
    }
    if (show & SHOW_SECS) {
	num2str(disklabel.d_nsectors, s);
	myputs(STDOUT_FILENO, s);
	myputs(STDOUT_FILENO, "\n");
    }
    exit(0);
}


/* Local Variables: */
/* compile-command:"cc -static -Wall -o diskinfo diskinfo.c" */
/* End: */
