the way nvmutil is designed, setWord() is only ever called
under non-error conditions. however, if one part is valid but
the other one isn't, and a command is run that touches both parts,
errno is non-zero write writeGbeFile is called
in situations where one part is valid, but the other isn't, AND the
writes to gbe (in memory) results in a non-change, writeGbeFile is
not called; in this situation, errno is not being reset, despite
non-error condition
this patch fixed the bug, resulting in zero status upon exit under
such conditions
the current code writes part 1 first, and part 0 next,
on the disk, due to the way the swap works.
with this change, swap still swaps the two parts of the file,
on disk, but writes the new file sequentially.
this change might speed up i/o on the file system, on HDDs.
on SSDs, this change likely makes no difference at all.
On many Lenovo GbE regions (in factory firmware), part 0 is
invalid but part 1 is valid.
This change means part 1 is checked first. If part 1 is valid,
part 0 won't be checked at all (due to how most C compilers
optimise).
Most people are just going to extract the factory GbE file,
modify it and re-insert it into the ROM image, so this causes
a nice speedup.
don't constantly open/close the file: /dev/urandom
only read 12 bytes at a time
because of this change, the readFromFile() function now only
handles gbe files
don't do xor swap. we know gbe2 is always 4KB higher than
gbe in memory, so we can just set gbe2 to the value of gbe,
and OR the size in bytes of 4KB into gbe2
this is only a marginal speed boost, negligible even, but it's
done for the lulz
similar to the last change by concept. we now write
individual 4KB blocks per part 0 and 1, at the end
of nvmutil, based on pointer values gbe and gbe2
instead of running memcpy, simply overwrite the pointer
this results in less I/O, thus more speed
instead of XOR-swapping every byte, have pointers to the
two parts and *XOR swap the pointers*. at the end of the
program execution, when writing, pwrite the two parts into
the same file
*This condition will probably never be met, but it is theoretically
possible that the code could still fail at this point. Catch all errors,
and exit, ruthlessly.
The code was only checking whether all of the bytes were read,
but there are other errors that can be caught via errno.
Enforce strict errno handling, when generating random
numbers for command `setmac`.
previously, it was always initialised, but now it's only
initialised if '?' is used on a mac address character in
command `setmac`
this is done by simply moving mac address character
randomisation to a separate function
If one of the checksums was valid, but the other was not,
errno would be set to E_CANCELED, but then the buffer would
be modified anyway; this is acceptable behaviour, and errno
would later be reset writing the GBE file, which is done
only on the condition that the buffer was modified, but
it's also a good idea to reset it here just in case.
This is not a bugfix, and no behavioural changes will be
observed by the user, but this may *prevent* a bug in the
future, so let's pre-fix that bug now.
in any C program, main() should not contain detailed logic.
ideally, the main() function should only be a skeleton, showing
the overall logic flow of the program. split writing gbe files
into a separate function, to satisfy this criteria.