55 static void handle_label(
bool change,
bool reset,
const char *device,
char *newlabel)
61 char label[12] = { 0 };
67 len = mbstowcs(NULL, newlabel, 0);
68 if (len != (
size_t)-1 && len > 11) {
70 "fatlabel: labels can be no longer than 11 characters\n");
76 "fatlabel: error when processing label\n");
80 for (i = strlen(label); i < 11; ++i)
87 "fatlabel: warning - lowercase labels might not work properly on some systems\n");
91 "fatlabel: labels with characters below 0x20 are not allowed\n");
96 "fatlabel: labels with characters *?.,;:/\\|+=<>[]\" are not allowed\n");
101 "fatlabel: labels can't be empty or white space only\n");
106 "fatlabel: labels can't start with a space character\n");
114 if (!change && !reset) {
120 if (de.
name[0] == 0x05)
144 static void handle_volid(
bool change,
bool reset,
const char *device,
const char *newserial)
148 long long conversion;
153 conversion = strtoll(newserial, &tmp, 16);
155 if (!*newserial || isspace(*newserial) || *tmp || conversion < 0) {
156 fprintf(stderr,
"fatlabel: volume ID must be a hexadecimal number\n");
159 if (conversion > UINT32_MAX) {
160 fprintf(stderr,
"fatlabel: given volume ID does not fit in 32 bit\n");
164 fprintf(stderr,
"fatlabel: parsing volume ID failed (%s)\n", strerror(errno));
176 if (!change && !reset) {
177 printf(
"%08x\n", fs.
serial);
187 FILE *f =
error ? stderr : stdout;
188 int status =
error ? 1 : 0;
190 fprintf(f,
"Usage: fatlabel [OPTIONS] DEVICE [NEW]\n");
194 fprintf(f,
"Change the FAT filesystem label or serial on DEVICE to NEW or display the\n");
195 fprintf(f,
"existing label or serial if NEW is not given.\n");
197 fprintf(f,
"Options:\n");
198 fprintf(f,
" -i, --volume-id Work on serial number instead of label\n");
199 fprintf(f,
" -r, --reset Remove label or generate new serial number\n");
200 fprintf(f,
" -c N, --codepage=N use DOS codepage N to encode/decode label (default: %d)\n",
DEFAULT_DOS_CODEPAGE);
201 fprintf(f,
" -V, --version Show version number and terminate\n");
202 fprintf(f,
" -h, --help Print this message and terminate\n");
207 int main(
int argc,
char *argv[])
209 const struct option long_options[] = {
210 {
"volume-id", no_argument, NULL,
'i'},
211 {
"reset", no_argument, NULL,
'r'},
212 {
"codepage", required_argument, NULL,
'c'},
213 {
"version", no_argument, NULL,
'V'},
214 {
"help", no_argument, NULL,
'h'},
219 bool volid_mode =
false;
228 while ((c = getopt_long(argc, argv,
"irc:Vh", long_options, NULL)) != -1) {
240 codepage = strtol(optarg, &tmp, 10);
241 if (!*optarg || isspace(*optarg) || *tmp || errno || codepage < 0 || codepage > INT_MAX) {
242 fprintf(stderr,
"Invalid codepage : %s\n", optarg);
250 printf(
"fatlabel " VERSION
" (" VERSION_DATE
")\n");
264 "Internal error: getopt_long() returned unexpected value %d\n", c);
272 if (optind == argc - 2) {
274 }
else if (optind == argc - 1) {
283 if (change && reset) {
284 fprintf(stderr,
"fatlabel: giving new value with --reset not allowed\n");
288 device = argv[optind++];
void write_label(DOS_FS *fs, char *label)
const char * pretty_label(const char *label)
off_t find_volume_de(DOS_FS *fs, DIR_ENT *de)
void remove_label(DOS_FS *fs)
void read_boot(DOS_FS *fs)
void write_serial(DOS_FS *fs, uint32_t serial)
int local_string_to_dos_string(char *out, char *in, unsigned int out_size)
int set_dos_codepage(int codepage)
#define DEFAULT_DOS_CODEPAGE
int validate_volume_label(char *doslabel)
uint32_t generate_volume_id(void)
void release_fat(DOS_FS *fs)
void read_fat(DOS_FS *fs, int mode)
static void handle_volid(bool change, bool reset, const char *device, const char *newserial)
int main(int argc, char *argv[])
static void usage(int error, int usage_only)
static void handle_label(bool change, bool reset, const char *device, char *newlabel)
void fs_open(const char *path, int rw)