X-Git-Url: https://git.sven.stormbind.net/?p=sven%2Fexfatprogs.git;a=blobdiff_plain;f=label%2Flabel.c;fp=label%2Flabel.c;h=fd77a549b06e3344854e2cca02ac43ff9b8e140a;hp=0000000000000000000000000000000000000000;hb=a4f2404c58ad9a1134d98838617019286a680bef;hpb=3f2b844a9a4c1c01c6e7c7971c716d725e5460b2;ds=sidebyside

diff --git a/label/label.c b/label/label.c
new file mode 100644
index 0000000..fd77a54
--- /dev/null
+++ b/label/label.c
@@ -0,0 +1,114 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ *   Copyright (C) 2020 Namjae Jeon <linkinjeon@kernel.org>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <errno.h>
+#include <locale.h>
+
+#include "exfat_ondisk.h"
+#include "libexfat.h"
+
+static void usage(void)
+{
+	fprintf(stderr, "Usage: exfatlabel\n");
+	fprintf(stderr, "\t-i | --volume-serial                  Switch to volume serial mode\n");
+	fprintf(stderr, "\t-V | --version                        Show version\n");
+	fprintf(stderr, "\t-h | --help                           Show help\n");
+
+	exit(EXIT_FAILURE);
+}
+
+static struct option opts[] = {
+	{"volume-serial",	no_argument,		NULL,	'i' },
+	{"version",		no_argument,		NULL,	'V' },
+	{"help",		no_argument,		NULL,	'h' },
+	{"?",			no_argument,		NULL,	'?' },
+	{NULL,			0,			NULL,	 0  }
+};
+
+int main(int argc, char *argv[])
+{
+	int c;
+	int ret = EXIT_FAILURE;
+	struct exfat_blk_dev bd;
+	struct exfat_user_input ui;
+	bool version_only = false;
+	off_t root_clu_off;
+	int serial_mode = 0;
+	int flags = 0;
+
+	init_user_input(&ui);
+
+	if (!setlocale(LC_CTYPE, ""))
+		exfat_err("failed to init locale/codeset\n");
+
+	if (argc == 2)
+		flags = EXFAT_GET_VOLUME_LABEL;
+	else if (argc == 3)
+		flags = EXFAT_SET_VOLUME_LABEL;
+
+	opterr = 0;
+	while ((c = getopt_long(argc, argv, "iVh", opts, NULL)) != EOF)
+		switch (c) {
+		case 'i':
+			serial_mode = true;
+			if (argc == 3)
+				flags = EXFAT_GET_VOLUME_SERIAL;
+			else if (argc == 4)
+				flags = EXFAT_SET_VOLUME_SERIAL;
+
+			break;
+		case 'V':
+			version_only = true;
+			break;
+		case '?':
+		case 'h':
+		default:
+			usage();
+	}
+
+	show_version();
+	if (version_only)
+		exit(EXIT_FAILURE);
+
+	if (argc < 2)
+		usage();
+
+	memset(ui.dev_name, 0, sizeof(ui.dev_name));
+	snprintf(ui.dev_name, sizeof(ui.dev_name), "%s", argv[serial_mode + 1]);
+
+	ret = exfat_get_blk_dev_info(&ui, &bd);
+	if (ret < 0)
+		goto out;
+
+	if (serial_mode) {
+		/* Mode to change or display volume serial */
+		if (flags == EXFAT_GET_VOLUME_SERIAL) {
+			ret = exfat_show_volume_serial(&bd, &ui);
+		} else if (flags == EXFAT_SET_VOLUME_SERIAL) {
+			ui.volume_serial = strtoul(argv[3], NULL, 0);
+			ret = exfat_set_volume_serial(&bd, &ui);
+		}
+	} else {
+		/* Mode to change or display volume label */
+		root_clu_off = exfat_get_root_entry_offset(&bd);
+		if (root_clu_off < 0)
+			goto close_fd_out;
+
+		if (flags == EXFAT_GET_VOLUME_LABEL)
+			ret = exfat_show_volume_label(&bd, root_clu_off);
+		else if (flags == EXFAT_SET_VOLUME_LABEL)
+			ret = exfat_set_volume_label(&bd, argv[2], root_clu_off);
+	}
+
+close_fd_out:
+	close(bd.dev_fd);
+out:
+	return ret;
+}