"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/fsck.fat.c" between
dosfstools-4.1.tar.gz and dosfstools-4.2.tar.gz

About: dosfstools are utilities to create, check and label (MS-DOS) FAT filesystems.

fsck.fat.c  (dosfstools-4.1):fsck.fat.c  (dosfstools-4.2)
/* fsck.fat.c - User interface /* fsck.fat.c - User interface
Copyright (C) 1993 Werner Almesberger <werner.almesberger@lrc.di.epfl.ch> Copyright (C) 1993 Werner Almesberger <werner.almesberger@lrc.di.epfl.ch>
Copyright (C) 1998 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> Copyright (C) 1998 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
Copyright (C) 2008-2014 Daniel Baumann <mail@daniel-baumann.ch> Copyright (C) 2008-2014 Daniel Baumann <mail@daniel-baumann.ch>
Copyright (C) 2018-2021 Pali Rohár <pali.rohar@gmail.com>
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
skipping to change at line 33 skipping to change at line 34
/* FAT32, VFAT, Atari format support, and various fixes additions May 1998 /* FAT32, VFAT, Atari format support, and various fixes additions May 1998
* by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> */ * by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> */
#include "version.h" #include "version.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <errno.h>
#include <ctype.h>
#include <limits.h>
#include <unistd.h> #include <unistd.h>
#include <termios.h>
#include <getopt.h> #include <getopt.h>
#include "common.h" #include "common.h"
#include "fsck.fat.h" #include "fsck.fat.h"
#include "io.h" #include "io.h"
#include "boot.h" #include "boot.h"
#include "fat.h" #include "fat.h"
#include "file.h" #include "file.h"
#include "check.h" #include "check.h"
#include "charconv.h" #include "charconv.h"
int interactive = 0, rw = 0, list = 0, test = 0, verbose = 0, write_immed = 0; int rw = 0, list = 0, test = 0, verbose = 0;
int atari_format = 0, boot_only = 0; long fat_table = 0;
int no_spaces_in_sfns = 0;
int only_uppercase_label = 0;
int boot_only = 0;
unsigned n_files = 0; unsigned n_files = 0;
void *mem_queue = NULL; void *mem_queue = NULL;
static void usage(char *name) static struct termios original_termios;
static void restore_termios(void)
{ {
fprintf(stderr, "usage: %s [-aAbflrtvVwy] [-d path -d ...] " tcsetattr(0, TCSAFLUSH, &original_termios);
"[-u path -u ...]\n%15sdevice\n", name, "");
fprintf(stderr, " -a automatically repair the filesystem\n");
fprintf(stderr, " -A toggle Atari filesystem format\n");
fprintf(stderr, " -b make read-only boot sector check\n");
fprintf(stderr,
" -c N use DOS codepage N to decode short file names (default: %
d)\n",
DEFAULT_DOS_CODEPAGE);
fprintf(stderr, " -d path drop that file\n");
fprintf(stderr, " -f salvage unused chains to files\n");
fprintf(stderr, " -l list path names\n");
fprintf(stderr,
" -n no-op, check non-interactively without changing\n");
fprintf(stderr, " -p same as -a, for compat with other *fsck\n");
fprintf(stderr, " -r interactively repair the filesystem (default)\n"
);
fprintf(stderr, " -t test for bad clusters\n");
fprintf(stderr, " -u path try to undelete that (non-directory) file\n");
fprintf(stderr, " -v verbose mode\n");
fprintf(stderr, " -V perform a verification pass\n");
fprintf(stderr, " -w write changes to disk immediately\n");
fprintf(stderr, " -y same as -a, for compat with other *fsck\n");
exit(2);
} }
/* static void usage(char *name, int exitval)
* ++roman: On m68k, check if this is an Atari; if yes, turn on Atari variant
* of MS-DOS filesystem by default.
*/
static void check_atari(void)
{ {
#ifdef __mc68000__ fprintf(stderr, "Usage: %s [OPTIONS] DEVICE\n", name);
FILE *f; fprintf(stderr, "Check FAT filesystem on DEVICE for errors.\n");
char line[128], *p; fprintf(stderr, "\n");
fprintf(stderr, "Options:\n");
if (!(f = fopen("/proc/hardware", "r"))) { fprintf(stderr, " -a automatically repair the filesystem\n");
perror("/proc/hardware"); fprintf(stderr, " -A toggle Atari variant of the FAT filesyste
return; m\n");
} fprintf(stderr, " -b make read-only boot sector check\n");
fprintf(stderr, " -c N use DOS codepage N to decode short file n
while (fgets(line, sizeof(line), f)) { ames (default: %d)\n",
if (strncmp(line, "Model:", 6) == 0) { DEFAULT_DOS_CODEPAGE);
p = line + 6; fprintf(stderr, " -d PATH drop file with name PATH (can be given mu
p += strspn(p, " \t"); ltiple times)\n");
if (strncmp(p, "Atari ", 6) == 0) fprintf(stderr, " -f salvage unused chains to files\n");
atari_format = 1; fprintf(stderr, " -F NUM specify FAT table NUM used for filesystem
break; access\n");
} fprintf(stderr, " -l list path names\n");
} fprintf(stderr, " -n no-op, check non-interactively without ch
fclose(f); anging\n");
#endif fprintf(stderr, " -p same as -a, for compat with other *fsck\n
");
fprintf(stderr, " -r interactively repair the filesystem (defa
ult)\n");
fprintf(stderr, " -S disallow spaces in the middle of short fi
le names\n");
fprintf(stderr, " -t test for bad clusters\n");
fprintf(stderr, " -u PATH try to undelete (non-directory) file that
was named PATH (can be\n");
fprintf(stderr, " given multiple times)\n");
fprintf(stderr, " -U allow only uppercase characters in volume
and boot label\n");
fprintf(stderr, " -v verbose mode\n");
fprintf(stderr, " -V perform a verification pass\n");
fprintf(stderr, " --variant=TYPE handle variant TYPE of the filesystem\n")
;
fprintf(stderr, " -w write changes to disk immediately\n");
fprintf(stderr, " -y same as -a, for compat with other *fsck\n
");
fprintf(stderr, " --help print this message\n");
exit(exitval);
} }
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
DOS_FS fs; DOS_FS fs;
int salvage_files, verify, c; int salvage_files, verify, c;
uint32_t free_clusters = 0; uint32_t free_clusters = 0;
struct termios tio;
char *tmp;
long codepage;
enum {OPT_HELP=1000, OPT_VARIANT};
const struct option long_options[] = {
{"variant", required_argument, NULL, OPT_VARIANT},
{"help", no_argument, NULL, OPT_HELP},
{0,}
};
if (!tcgetattr(0, &original_termios)) {
tio = original_termios;
tio.c_lflag &= ~(ICANON | ECHO);
tcsetattr(0, TCSAFLUSH, &tio);
atexit(restore_termios);
}
memset(&fs, 0, sizeof(fs)); memset(&fs, 0, sizeof(fs));
salvage_files = verify = 0; salvage_files = verify = 0;
rw = interactive = 1; rw = interactive = 1;
check_atari(); check_atari();
while ((c = getopt(argc, argv, "Aac:d:bflnprtu:vVwy")) != -1) while ((c = getopt_long(argc, argv, "Aac:d:bfF:lnprStu:UvVwy",
long_options, NULL)) != -1)
switch (c) { switch (c) {
case 'A': /* toggle Atari format */ case 'A': /* toggle Atari format */
atari_format = !atari_format; atari_format = !atari_format;
break; break;
case 'a': case 'a':
case 'p': case 'p':
case 'y': case 'y':
rw = 1; rw = 1;
interactive = 0; interactive = 0;
salvage_files = 1; salvage_files = 1;
break; break;
case 'b': case 'b':
rw = 0; rw = 0;
interactive = 0; interactive = 0;
boot_only = 1; boot_only = 1;
break; break;
case 'c': case 'c':
set_dos_codepage(atoi(optarg)); errno = 0;
codepage = strtol(optarg, &tmp, 10);
if (!*optarg || isspace(*optarg) || *tmp || errno || codepage < 0 ||
codepage > INT_MAX) {
fprintf(stderr, "Invalid codepage : %s\n", optarg);
usage(argv[0], 2);
}
if (!set_dos_codepage(codepage))
usage(argv[0], 2);
break; break;
case 'd': case 'd':
file_add(optarg, fdt_drop); file_add(optarg, fdt_drop);
break; break;
case 'f': case 'f':
salvage_files = 1; salvage_files = 1;
break; break;
case 'F':
errno = 0;
fat_table = strtol(optarg, &tmp, 10);
if (!*optarg || isspace(*optarg) || *tmp || errno || fat_table < 0 ||
fat_table > 255) {
fprintf(stderr, "Invalid FAT table : %s\n", optarg);
usage(argv[0], 2);
}
break;
case 'l': case 'l':
list = 1; list = 1;
break; break;
case 'n': case 'n':
rw = 0; rw = 0;
interactive = 0; interactive = 0;
break; break;
case 'r': case 'r':
rw = 1; rw = 1;
interactive = 1; interactive = 1;
break; break;
case 'S':
no_spaces_in_sfns = 1;
break;
case 't': case 't':
test = 1; test = 1;
break; break;
case 'u': case 'u':
file_add(optarg, fdt_undelete); file_add(optarg, fdt_undelete);
break; break;
case 'U':
only_uppercase_label = 1;
break;
case 'v': case 'v':
verbose = 1; verbose = 1;
break; break;
case 'V': case 'V':
verify = 1; verify = 1;
break; break;
case OPT_VARIANT:
if (!strcasecmp(optarg, "standard")) {
atari_format = 0;
} else if (!strcasecmp(optarg, "atari")) {
atari_format = 1;
} else {
fprintf(stderr, "Unknown variant: %s\n", optarg);
usage(argv[0], 2);
}
break;
case 'w': case 'w':
write_immed = 1; write_immed = 1;
break; break;
case OPT_HELP:
usage(argv[0], 0);
break;
case '?':
usage(argv[0], 2);
break;
default: default:
usage(argv[0]); fprintf(stderr,
"Internal error: getopt_long() returned unexpected value %d\n
", c);
exit(3);
} }
set_dos_codepage(-1); /* set default codepage if none was given in comm if (!set_dos_codepage(-1)) /* set default codepage if none was given in comm
and line */ and line */
exit(2);
if ((test || write_immed) && !rw) { if ((test || write_immed) && !rw) {
fprintf(stderr, "-t and -w can not be used in read only mode\n"); fprintf(stderr, "-t and -w can not be used in read only mode\n");
exit(2); exit(2);
} }
if (optind != argc - 1) if (optind != argc - 1)
usage(argv[0]); usage(argv[0], 2);
printf("fsck.fat " VERSION " (" VERSION_DATE ")\n"); printf("fsck.fat " VERSION " (" VERSION_DATE ")\n");
fs_open(argv[optind], rw); fs_open(argv[optind], rw);
read_boot(&fs); read_boot(&fs);
if (boot_only) if (boot_only)
goto exit; goto exit;
if (verify) if (verify)
printf("Starting check/repair pass.\n"); printf("Starting check/repair pass.\n");
while (read_fat(&fs), scan_root(&fs)) while (read_fat(&fs, 2), scan_root(&fs))
qfree(&mem_queue); qfree(&mem_queue);
check_label(&fs);
if (test) if (test)
fix_bad(&fs); fix_bad(&fs);
if (salvage_files) if (salvage_files)
reclaim_file(&fs); reclaim_file(&fs);
else else
reclaim_free(&fs); reclaim_free(&fs);
if (!atari_format)
check_dirty_bits(&fs);
free_clusters = update_free(&fs); free_clusters = update_free(&fs);
file_unused(); file_unused();
qfree(&mem_queue); qfree(&mem_queue);
if (verify) { if (verify) {
n_files = 0; n_files = 0;
printf("Starting verification pass.\n"); printf("Starting verification pass.\n");
read_fat(&fs); read_fat(&fs, 2);
scan_root(&fs); scan_root(&fs);
check_label(&fs);
reclaim_free(&fs); reclaim_free(&fs);
if (!atari_format)
check_dirty_bits(&fs);
qfree(&mem_queue); qfree(&mem_queue);
} }
release_fat(&fs);
exit: exit:
if (fs_changed()) { if (!write_immed && fs_changed()) {
if (rw) { if (rw) {
printf("\n*** Filesystem was changed ***\n");
if (interactive) if (interactive)
rw = get_key("yn", "Perform changes ? (y/n)") == 'y'; printf("The changes have not yet been written, you can still choo
else se to leave the\n"
printf("Performing changes.\n"); "filesystem unmodified:\n");
rw = get_choice(1, "Writing changes.",
2,
1, "Write changes",
2, "Leave filesystem unchanged") == 1;
} else } else
printf("Leaving filesystem unchanged.\n"); printf("\nLeaving filesystem unchanged.\n");
} }
if (!boot_only) if (!boot_only)
printf("%s: %u files, %lu/%lu clusters\n", argv[optind], printf("%s: %u files, %lu/%lu clusters\n", argv[optind],
n_files, (unsigned long)fs.data_clusters - free_clusters, n_files, (unsigned long)fs.data_clusters - free_clusters,
(unsigned long)fs.data_clusters); (unsigned long)fs.data_clusters);
return fs_close(rw) ? 1 : 0; return fs_close(rw) ? 1 : 0;
} }
 End of changes. 30 change blocks. 
65 lines changed or deleted 142 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)