]> git.sven.stormbind.net Git - sven/exfatprogs.git/blob - label/label.c
readd gitignore file
[sven/exfatprogs.git] / label / label.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *   Copyright (C) 2020 Namjae Jeon <linkinjeon@kernel.org>
4  */
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <unistd.h>
10 #include <getopt.h>
11 #include <errno.h>
12 #include <locale.h>
13
14 #include "exfat_ondisk.h"
15 #include "libexfat.h"
16
17 static void usage(void)
18 {
19         fprintf(stderr, "Usage: exfatlabel\n");
20         fprintf(stderr, "\t-i | --volume-serial                  Switch to volume serial mode\n");
21         fprintf(stderr, "\t-V | --version                        Show version\n");
22         fprintf(stderr, "\t-h | --help                           Show help\n");
23
24         exit(EXIT_FAILURE);
25 }
26
27 static struct option opts[] = {
28         {"volume-serial",       no_argument,            NULL,   'i' },
29         {"version",             no_argument,            NULL,   'V' },
30         {"help",                no_argument,            NULL,   'h' },
31         {"?",                   no_argument,            NULL,   '?' },
32         {NULL,                  0,                      NULL,    0  }
33 };
34
35 int main(int argc, char *argv[])
36 {
37         int c;
38         int ret = EXIT_FAILURE;
39         struct exfat_blk_dev bd;
40         struct exfat_user_input ui;
41         bool version_only = false;
42         off_t root_clu_off;
43         int serial_mode = 0;
44         int flags = 0;
45
46         init_user_input(&ui);
47
48         if (!setlocale(LC_CTYPE, ""))
49                 exfat_err("failed to init locale/codeset\n");
50
51         if (argc == 2)
52                 flags = EXFAT_GET_VOLUME_LABEL;
53         else if (argc == 3)
54                 flags = EXFAT_SET_VOLUME_LABEL;
55
56         opterr = 0;
57         while ((c = getopt_long(argc, argv, "iVh", opts, NULL)) != EOF)
58                 switch (c) {
59                 case 'i':
60                         serial_mode = true;
61                         if (argc == 3)
62                                 flags = EXFAT_GET_VOLUME_SERIAL;
63                         else if (argc == 4)
64                                 flags = EXFAT_SET_VOLUME_SERIAL;
65
66                         break;
67                 case 'V':
68                         version_only = true;
69                         break;
70                 case '?':
71                 case 'h':
72                 default:
73                         usage();
74         }
75
76         show_version();
77         if (version_only)
78                 exit(EXIT_FAILURE);
79
80         if (argc < 2)
81                 usage();
82
83         memset(ui.dev_name, 0, sizeof(ui.dev_name));
84         snprintf(ui.dev_name, sizeof(ui.dev_name), "%s", argv[serial_mode + 1]);
85
86         ret = exfat_get_blk_dev_info(&ui, &bd);
87         if (ret < 0)
88                 goto out;
89
90         if (serial_mode) {
91                 /* Mode to change or display volume serial */
92                 if (flags == EXFAT_GET_VOLUME_SERIAL) {
93                         ret = exfat_show_volume_serial(&bd, &ui);
94                 } else if (flags == EXFAT_SET_VOLUME_SERIAL) {
95                         ui.volume_serial = strtoul(argv[3], NULL, 0);
96                         ret = exfat_set_volume_serial(&bd, &ui);
97                 }
98         } else {
99                 /* Mode to change or display volume label */
100                 root_clu_off = exfat_get_root_entry_offset(&bd);
101                 if (root_clu_off < 0)
102                         goto close_fd_out;
103
104                 if (flags == EXFAT_GET_VOLUME_LABEL)
105                         ret = exfat_show_volume_label(&bd, root_clu_off);
106                 else if (flags == EXFAT_SET_VOLUME_LABEL)
107                         ret = exfat_set_volume_label(&bd, argv[2], root_clu_off);
108         }
109
110 close_fd_out:
111         close(bd.dev_fd);
112 out:
113         return ret;
114 }