mirror of
https://github.com/AltraMayor/f3.git
synced 2025-08-03 18:46:00 -04:00
f3fix: add proper support to parameters
This commit is contained in:
parent
5df999a767
commit
3f02ab9ac6
2
Makefile
2
Makefile
@ -19,7 +19,7 @@ f3probe: libutils.o libdevs.o libprobe.o utils.o f3probe.o
|
||||
f3brew: libutils.o libdevs.o f3brew.o
|
||||
$(CC) -o $@ $^ -lm -ludev
|
||||
|
||||
f3fix: f3fix.o
|
||||
f3fix: utils.o f3fix.o
|
||||
$(CC) -o $@ $^ -lparted
|
||||
|
||||
-include *.d
|
||||
|
251
f3fix.c
251
f3fix.c
@ -1,24 +1,197 @@
|
||||
#include <error.h>
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <argp.h>
|
||||
#include <parted/parted.h>
|
||||
|
||||
#include "version.h"
|
||||
|
||||
/* XXX Refactor utils library since f3probe barely uses it. */
|
||||
#include "utils.h"
|
||||
|
||||
/* TODO Modify f3probe to suggest using f3fix when the drive is fake.
|
||||
* Wait until f3fix is stable to implement this.
|
||||
*/
|
||||
|
||||
/* TODO Add parameters. */
|
||||
/* Argp's global variables. */
|
||||
const char *argp_program_version = "F3 Fix " F3_STR_VERSION;
|
||||
|
||||
/* TODO List types of the partition table. */
|
||||
/* Arguments. */
|
||||
static char adoc[] = "<DISK_DEV>";
|
||||
|
||||
static char doc[] = "F3 Fix -- edit the partition table of "
|
||||
"a fake flash drive to have a single partition that fully covers "
|
||||
"the real capacity of the drive";
|
||||
|
||||
static struct argp_option options[] = {
|
||||
{"disk-type", 'd', "TYPE", 0,
|
||||
"Disk type of the partition table", 2},
|
||||
{"fs-type", 'f', "TYPE", 0,
|
||||
"Type of the file system of the partition", 0},
|
||||
{"boot", 'b', NULL, 0,
|
||||
"Mark the partition for boot", 0},
|
||||
{"no-boot", 'n', NULL, 0,
|
||||
"Do not mark the partition for boot", 0},
|
||||
{"first-sec", 'a', "SEC-NUM", 0,
|
||||
"Sector where the partition starts", 0},
|
||||
{"last-sec", 'l', "SEC-NUM", 0,
|
||||
"Sector where the partition ends", 0},
|
||||
{"list-disk-types", 'k', NULL, 0,
|
||||
"List all supported disk types", 3},
|
||||
{"list-fs-types", 's', NULL, 0,
|
||||
"List all supported types of file systems", 0},
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
struct args {
|
||||
bool list_disk_types;
|
||||
bool list_fs_types;
|
||||
|
||||
bool boot;
|
||||
|
||||
/* 29 free bytes. */
|
||||
|
||||
const char *dev_filename;
|
||||
PedDiskType *disk_type;
|
||||
PedFileSystemType *fs_type;
|
||||
PedSector first_sec;
|
||||
PedSector last_sec;
|
||||
};
|
||||
|
||||
static long long arg_to_long_long(const struct argp_state *state,
|
||||
const char *arg)
|
||||
{
|
||||
char *end;
|
||||
long long ll = strtoll(arg, &end, 0);
|
||||
if (!arg)
|
||||
argp_error(state, "An integer must be provided");
|
||||
if (!*arg || *end)
|
||||
argp_error(state, "`%s' is not an integer", arg);
|
||||
return ll;
|
||||
}
|
||||
|
||||
static error_t parse_opt(int key, char *arg, struct argp_state *state)
|
||||
{
|
||||
struct args *args = state->input;
|
||||
long long ll;
|
||||
|
||||
switch (key) {
|
||||
case 'd':
|
||||
args->disk_type = ped_disk_type_get(arg);
|
||||
if (!args->disk_type)
|
||||
argp_error(state,
|
||||
"Disk type `%s' is not supported; use --list-disk-types to see the supported types");
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
args->fs_type = ped_file_system_type_get(arg);
|
||||
if (!args->fs_type)
|
||||
argp_error(state,
|
||||
"File system type `%s' is not supported; use --list-fs-types to see the supported types");
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
args->boot = true;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
args->boot = false;
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
ll = arg_to_long_long(state, arg);
|
||||
if (ll < 0)
|
||||
argp_error(state,
|
||||
"First sector must be greater or equal to 0");
|
||||
args->first_sec = ll;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
ll = arg_to_long_long(state, arg);
|
||||
if (ll < 0)
|
||||
argp_error(state,
|
||||
"Last sector must be greater or equal to 0");
|
||||
args->last_sec = ll;
|
||||
break;
|
||||
|
||||
case 'k':
|
||||
args->list_disk_types = true;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
args->list_fs_types = true;
|
||||
break;
|
||||
|
||||
case ARGP_KEY_INIT:
|
||||
args->dev_filename = NULL;
|
||||
args->last_sec = -1;
|
||||
break;
|
||||
|
||||
case ARGP_KEY_ARG:
|
||||
if (args->dev_filename)
|
||||
argp_error(state,
|
||||
"Wrong number of arguments; only one is allowed");
|
||||
args->dev_filename = arg;
|
||||
break;
|
||||
|
||||
case ARGP_KEY_END:
|
||||
if (args->list_disk_types || args->list_fs_types)
|
||||
break;
|
||||
|
||||
if (!args->dev_filename)
|
||||
argp_error(state,
|
||||
"The disk device was not specified");
|
||||
|
||||
if (args->last_sec < 0)
|
||||
argp_error(state,
|
||||
"Option --last-sec is required");
|
||||
if (args->first_sec > args->last_sec)
|
||||
argp_error(state,
|
||||
"Option --fist_sec must be less or equal to option --last_sec");
|
||||
break;
|
||||
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct argp argp = {options, parse_opt, adoc, doc, NULL, NULL, NULL};
|
||||
|
||||
static void list_disk_types(void)
|
||||
{
|
||||
PedDiskType *type;
|
||||
int i = 0;
|
||||
printf("Disk types:\n");
|
||||
for (type = ped_disk_type_get_next(NULL); type;
|
||||
type = ped_disk_type_get_next(type)) {
|
||||
printf("%s\t", type->name);
|
||||
i++;
|
||||
if (i == 5) {
|
||||
printf("\n");
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
if (i > 0)
|
||||
printf("\n");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/* TODO List types of file systems (function below).
|
||||
* One still needs a calling option to list the types.
|
||||
*/
|
||||
static void list_fs_types(void)
|
||||
{
|
||||
PedFileSystemType *fs_type;
|
||||
int i = 0;
|
||||
printf("File system types:\n");
|
||||
for (fs_type = ped_file_system_type_get_next(NULL); fs_type;
|
||||
fs_type = ped_file_system_type_get_next(fs_type))
|
||||
puts(fs_type->name);
|
||||
fs_type = ped_file_system_type_get_next(fs_type)) {
|
||||
printf("%s\t", fs_type->name);
|
||||
i++;
|
||||
if (i == 5) {
|
||||
printf("\n");
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
if (i > 0)
|
||||
printf("\n");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/* 0 on failure, 1 otherwise. */
|
||||
@ -67,37 +240,49 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Use example: sudo ./f3fix /dev/sdb msdos 2048 15010455 */
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
struct args args = {
|
||||
/* Defaults. */
|
||||
.list_disk_types = false,
|
||||
.list_fs_types = false,
|
||||
|
||||
.boot = true,
|
||||
|
||||
.disk_type = ped_disk_type_get("msdos"),
|
||||
.fs_type = ped_file_system_type_get("fat32"),
|
||||
.first_sec = 2048, /* Skip first 1MB. */
|
||||
};
|
||||
|
||||
PedDevice *dev;
|
||||
PedDiskType *type;
|
||||
PedFileSystemType *fs_type;
|
||||
PedSector start = atoi(argv[3]);
|
||||
PedSector end = atoi(argv[4]);
|
||||
int ret = 1;
|
||||
int ret;
|
||||
|
||||
if (argc != 5)
|
||||
error(EXIT_FAILURE, 0, "wrong number of arguments");
|
||||
/* Read parameters. */
|
||||
argp_parse(&argp, argc, argv, 0, NULL, &args);
|
||||
print_header(stdout, "fix");
|
||||
|
||||
dev = ped_device_get(argv[1]);
|
||||
if (args.list_disk_types)
|
||||
list_disk_types();
|
||||
|
||||
if (args.list_fs_types)
|
||||
list_fs_types();
|
||||
|
||||
if (args.list_disk_types || args.list_fs_types) {
|
||||
/* If the user has asked for the types,
|
||||
* so she doesn't want to fix the drive yet.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* XXX If @dev is a partition, refer the user to
|
||||
* the disk of this partition.
|
||||
*/
|
||||
dev = ped_device_get(args.dev_filename);
|
||||
if (!dev)
|
||||
goto out;
|
||||
return 1;
|
||||
|
||||
type = ped_disk_type_get(argv[2]);
|
||||
if (!type)
|
||||
goto device;
|
||||
|
||||
fs_type = ped_file_system_type_get("fat32");
|
||||
if (!fs_type)
|
||||
goto device;
|
||||
|
||||
ret = !fix_disk(dev, type, fs_type, true, start, end);
|
||||
|
||||
device:
|
||||
ret = !fix_disk(dev, args.disk_type, args.fs_type, args.boot,
|
||||
args.first_sec, args.last_sec);
|
||||
ped_device_destroy(dev);
|
||||
out:
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user