mirror of
https://github.com/AltraMayor/f3.git
synced 2025-08-04 02:55:57 -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
|
f3brew: libutils.o libdevs.o f3brew.o
|
||||||
$(CC) -o $@ $^ -lm -ludev
|
$(CC) -o $@ $^ -lm -ludev
|
||||||
|
|
||||||
f3fix: f3fix.o
|
f3fix: utils.o f3fix.o
|
||||||
$(CC) -o $@ $^ -lparted
|
$(CC) -o $@ $^ -lparted
|
||||||
|
|
||||||
-include *.d
|
-include *.d
|
||||||
|
251
f3fix.c
251
f3fix.c
@ -1,24 +1,197 @@
|
|||||||
#include <error.h>
|
#include <stdbool.h>
|
||||||
#include <assert.h>
|
#include <argp.h>
|
||||||
#include <parted/parted.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.
|
/* TODO Modify f3probe to suggest using f3fix when the drive is fake.
|
||||||
* Wait until f3fix is stable to implement this.
|
* 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)
|
static void list_fs_types(void)
|
||||||
{
|
{
|
||||||
PedFileSystemType *fs_type;
|
PedFileSystemType *fs_type;
|
||||||
|
int i = 0;
|
||||||
|
printf("File system types:\n");
|
||||||
for (fs_type = ped_file_system_type_get_next(NULL); fs_type;
|
for (fs_type = ped_file_system_type_get_next(NULL); fs_type;
|
||||||
fs_type = ped_file_system_type_get_next(fs_type))
|
fs_type = ped_file_system_type_get_next(fs_type)) {
|
||||||
puts(fs_type->name);
|
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. */
|
/* 0 on failure, 1 otherwise. */
|
||||||
@ -67,37 +240,49 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Use example: sudo ./f3fix /dev/sdb msdos 2048 15010455 */
|
|
||||||
|
|
||||||
int main (int argc, char *argv[])
|
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;
|
PedDevice *dev;
|
||||||
PedDiskType *type;
|
int ret;
|
||||||
PedFileSystemType *fs_type;
|
|
||||||
PedSector start = atoi(argv[3]);
|
|
||||||
PedSector end = atoi(argv[4]);
|
|
||||||
int ret = 1;
|
|
||||||
|
|
||||||
if (argc != 5)
|
/* Read parameters. */
|
||||||
error(EXIT_FAILURE, 0, "wrong number of arguments");
|
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)
|
if (!dev)
|
||||||
goto out;
|
return 1;
|
||||||
|
|
||||||
type = ped_disk_type_get(argv[2]);
|
ret = !fix_disk(dev, args.disk_type, args.fs_type, args.boot,
|
||||||
if (!type)
|
args.first_sec, args.last_sec);
|
||||||
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:
|
|
||||||
ped_device_destroy(dev);
|
ped_device_destroy(dev);
|
||||||
out:
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user