The blkbuf array in check_blocks is not needed. It is always given as an
argument to do_check. Keep the buffer there for easier access and
reduced visibility in code.
Signed-off-by: Samanta Navarro <ferivoz@riseup.net>
If the root cluster is bad, then mkfs.fat creates a filesystem which
fsck.fat considers to be broken and cannot fix.
Find the next free FAT cluster for root instead during creation.
Signed-off-by: Samanta Navarro <ferivoz@riseup.net>
If bad cluster markers have been added to FAT, then FAT32 filesystems
contain the wrong amount of free clusters. This ultimately means that
newly created filesystems are repaired when calling fsck.fat.
Signed-off-by: Samanta Navarro <ferivoz@riseup.net>
All other variables which have multiple words in their name use
a separator. Do so for variable "badblocks" as well.
Signed-off-by: Samanta Navarro <ferivoz@riseup.net>
According to signal(2) manual page the system call is only portable when
setting a signal's disposition to SIG_DFL or SIG_IGN.
Using sigaction(2) allows specific definition of flags, which in this
case will always instruct system calls to restart when SIGALRM is
received. This should be the default on Linux with signal(2) anyway.
This reduces the signal handler to set only a single variable.
Signed-off-by: Samanta Navarro <ferivoz@riseup.net>
The signal handler used during bad block detection calls the
signal-unsafe function printf. This could get in conflict with a printf
for an error condition in do_check.
Just set a sig_atomic_t variable to indicate that current status should
be displayed and leave the signal handler again.
The main loop checks the flag and prints the status when needed.
Signed-off-by: Samanta Navarro <ferivoz@riseup.net>
If a file has to be generated, then alloc_rootdir_entry tries to create
a unique name by using a counter curr_num for name generation and
looking for duplicates. If no duplicate is found, the counter curr_num
is not incremented, which means that the next file uses the same name
again. It is only incremented after the previously created file is
detected, just to repeat the loop again.
The improvement is simple: Increment the counter after creating the
filename. This has also the benefit that the check and use of
curr_num are closer to each other within the source code.
Signed-off-by: Samanta Navarro <ferivoz@riseup.net>
If a badblocks file contains the same block number multiple times,
then the status message of mkfs.fat shows the wrong amount of bad
blocks.
Proof of Concept:
```
echo -e "30\n30\n30" > badblocks
dd if=/dev/zero of=poc.iso bs=512 count=100
mkfs.fat -l badblocks poc.iso
```
Output is `3 bad blocks`.
With this commit it is `1 bad block`.
Signed-off-by: Samanta Navarro <ferivoz@riseup.net>
A signed integer overflow could occur with huge badblocks file because
we store the current line number in lineno. The unsigned data type
should be large enough for any sane badblocks file, otherwise it still
overflows but does not lead to C language issues.
Signed-off-by: Samanta Navarro <ferivoz@riseup.net>
Fixes a compiler error that can occur when building with clang:
error: variable 'change' is used uninitialized whenever 'if' condition is false [-Werror,-Wsometimes-uninitialized]
Previously, this variable was initialized on all code paths except for
one that called `usage(1, 1)`. In practice that should have been safe
as `usage` should cause the program to exit. But to make this
obviously safe, initialize `change` to false when it is declared.
"less then" should be "less than" instead. I have looked for more
occurrences of then/than typos but did not find any.
Signed-off-by: Samanta Navarro <ferivoz@riseup.net>
Use last given codepage argument instead of first to comply with
other command line arguments.
Proof of Concept:
1. Prepare a filesystem with label ° in codepage 1252
```
$ dd if=/dev/zero of=poc.iso bs=512 count=100
$ mkfs.fat -c 1252 -n "°" poc.iso
```
2. Query the label
```
$ fatlabel -c 1252 poc.iso
$ fatlabel -c 850 -c 1252 poc.iso
```
The output should be identical.
Signed-off-by: Samanta Navarro <ferivoz@riseup.net>
char may be either signed or unsigned and if it is signed the "< 0x20"
comparison will reject any values >= 0x80 even though these are valid
characters in a label.
Cast to an unsigned type to ensure the full range of valid characters
are accepted.
File with size 4294967295 (2^32-1) is stored in cluster chain of size
4294967296 (2^32). This cluster chain length cannot be represented in
32-bit integer so explicitly cast calculation to 64-bit (long long)
integer.
Before this change all files with size of 4294967295 bytes were auto
truncated to zero size because cluster chain size overflowed to zero.
This change fixes it and valid files are not automatically truncated.
Fixes: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1001845
Function isspace() takes int as an argument and expects either unsigned
char (values 0-255) or EOF (-1). So explicitly cast not-specified char type
variables to unsigned char types.
Function isspace() takes int as an argument and expects either unsigned
char (values 0-255) or EOF (-1). So explicitly cast not-specified char type
variables to unsigned char types.
Function isspace() takes int as an argument and expects either unsigned
char (values 0-255) or EOF (-1). So explicitly cast not-specified char type
variables to unsigned char types.
The invariant flag is superseded by SOURCE_DATE_EPOCH and the existing
volume-id (-i) flag. Start by removing --invariant from the help text.
Later versions may print a warning, and finally remove the flag
completely.
Signed-off-by: Bjørn Forsman <bjorn.forsman@gmail.com>
Instead of the special --invariant flag, use SOURCE_DATE_EPOCH (and the
volume-id option) for reproducible build. (Plan for eventual removal of
the --invariant flag.)
Use "export SOURCE_DATE_EPOCH=1426325213; command" instead of the
simpler "SOURCE_DATE_EPOCH=1426325213 command". Both forms work in bash,
but apparently only the "export" version works in dash. Run in a
subshell to not leak SOURCE_DATE_EPOCH.
Signed-off-by: Bjørn Forsman <bjorn.forsman@gmail.com>
Implement the SOURCE_DATE_EPOCH specification[1] for reproducible
builds. If SOURCE_DATE_EPOCH is set, use it as timestamp instead of the
current time.
[1] https://reproducible-builds.org/specs/source-date-epoch/
Signed-off-by: Bjørn Forsman <bjorn.forsman@gmail.com>
Maximal head value in MBR CHS is 255. But due to bug in MS-DOS which cause
system crash when head value in MBR CHS is 255, it is common to use only
maximal head value 254.
Head value in MBR CHS is zero indexed. So number of disk heads (stored in
FAT boot sector) is maximal head value in MBR CHS + 1.
So fix upper limit for number of heads to 255 which can be still
represented in MBR CHS without MS-DOS crash.