Use getopt for program parameters

Signed-off-by: Thomas Heijligen <src@posteo.de>
diff --git a/src/blockdev.c b/src/blockdev.c
index 443efcd..43c990c 100644
--- a/src/blockdev.c
+++ b/src/blockdev.c
@@ -1,5 +1,7 @@
 
 #include <stdio.h>
+#include <errno.h>
+#include <string.h>
 
 #include "blockdev.h"
 
@@ -11,10 +13,19 @@
 {
 	block_device = fopen(name, "rwb");
 	if (!block_device) {
+		fprintf(stderr, "devopen: %s.\n", strerror(errno));
 		return 0;
 	}
-	fseek(block_device, 0, SEEK_END);
+	int seek_res = 0;
+	seek_res |= fseek(block_device, 0, SEEK_END);
 	device_size = ftell(block_device);
+	seek_res |= fseek(block_device, 0, SEEK_SET);
+	if (seek_res || device_size == -1L || device_size % 512) {
+		fprintf(stderr, "devopen: Bad file %s.\n", name);
+		devclose();
+		return 0;
+	}
+
 	return 1;
 }
 
diff --git a/src/main.c b/src/main.c
index 5468842..d1939ee 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,24 +1,83 @@
 #include <stdio.h>
+#include <stdbool.h>
+#include <getopt.h>
 
 #include "blockdev.h"
 
+struct fsys_entry {
+	char *name;
+	int (*mount_func) (void);
+	int (*read_func) (char *buf, int len); // read from open file
+	int (*dir_func) (char *dirname); // open file
+	int (*close_func) (void);
+} fsys_table[] = {
+	{ "dummy", NULL, NULL, NULL, NULL},
+};
+
+static const size_t fsys_table_length = sizeof(fsys_table) / sizeof(struct fsys_entry);
+
+struct program_options {
+	char *devname;
+};
+
+static int get_options(int argc, char* argv[], struct program_options* opt);
+
 
 int main(int argc, char* argv[])
 {
-	if (argc != 2) {
-		fprintf(stderr, "Use %s /path/to/filesystem\n", argv[0]);
+	struct program_options opt;
+
+	if (get_options(argc, argv, &opt)) {
 		return -1;
 	}
 
-	if (devopen(argv[1], NULL) != 1) {
-		fprintf(stderr, "Faild to open %s\n", argv[1]);
+
+	if (devopen(opt.devname, NULL) != 1) {
 		return -1;
 	}
 
 	// TODO
 
-
 	devclose();
 	return 0;
 }
 
+
+
+static void fprint_help(FILE* to, char * pname)
+{
+	fprintf(to, "Usage: %s\n"
+		"  -d | --dev <path> \t File to use as block device\n"
+		, pname);
+}
+
+static int get_options(int argc, char* argv[], struct program_options *opt){
+	const struct option long_options[] = {
+		{"dev", required_argument, NULL, 'd'},
+		{NULL, 0, NULL, 0},
+	};
+
+	int c, option_index = 0;
+	while ((c = getopt_long(argc, argv, "d:", long_options, &option_index)) != -1) {
+		switch (c) {
+		case 'd':
+			opt->devname = optarg;
+			break;
+		default:
+			fprint_help(stderr, argv[0]);
+			return -1;
+		}
+	}
+
+	if (argc == 1) {
+		fprintf(stderr, "%s needs arguments.\n", argv[0]);
+		fprint_help(stderr, argv[0]);
+		return -1;
+	}
+
+	if (opt->devname == NULL) {
+		fprintf(stderr, "Argument \"--dev/-d\" missing.\n");
+		return -1;
+	}
+	return 0;
+}