1) no need to include sys/stat.h
2) remove the enum which just added a layer too thick on this simple
program
3) argc-style, other style
4) weprintf instead of enprintf, then save the error-message of
execvp before and return the proper status.
5) write consistent "not reached" comment.
col is used to display troff documents in ttys, removing the reverse
line feeds generated by .2C in ms. This implementation keeps the limit
of 256 lines of 800 characteres of the original implementation.
The HLP-changes to sbase have been a great addition of functionality,
but they kind of "polluted" the enmasse() and recurse() prototypes.
As this will come in handy in the future, knowing at which "depth"
you are inside a recursing function is an important functionality.
Instead of having a special HLP-flag passed to enmasse, each sub-
function needs to provide it on its own and can calculate results
based on the current depth (for instance, 'H' implies 'P' at
depth > 0).
A special case is recurse(), because it actually depends on the
follow-type. A new flag "recurse_follow" brings consistency into
what used to be spread across different naming conventions (fflag,
HLP_flag, ...).
This also fixes numerous bugs with the behaviour of HLP in the
tools using it.
1) Refactor the manpage, which has been a bloody mess, documenting
fantasy-flags (-d for example) and add a STANDARDS section
2) fix usage()
3) sort ARG-block
4) Check return-value of stat() separately, so a lack of permissions
doesn't tell the user "the directory doesn't exist", which could
be a bit confusing.
5) Add empty line before return.
1) Fix usage()
2) Group local variables
3) Idiomatic argv-loop
4) BUGFIX: When the m-flag is specified, POSIX clearly says:
"Set the file permission bits of the newly-created FIFO to the specified mode
value."
This means, that if mkfifo() fails for some reason, it should not try to
chmod() the given path (which has been fixed with the "else if")
A simple testcase is:
$ touch testfile; mkfifo -m 000 testfile;
GNU mkfifo(1): ls -l testfile
-rw-r--r-- 1 testfile
sbase mkfifo(1): ls -l testfile
---------- 1 testfile
5) Add blank line before return
1) val is sufficient as "int" (read the standard)
2) BUGFIX: If getpriority fails, it returns -1 and sets errno.
Previously, it would correctly catch the errno but not take
care of the fact that by then val has been decremented by 1.
Only change val if the getpriority-call has been successful.
3) Add LIMIT()-macro from st to increase readability.
4) setpriority returns < 0 on failure
5) Remove bikeshedding-comment. Read the standard if you wonder.
6) return-value trick from env(1)
1) style fix (don't arrange local variables)
2) BUGFIX: Previously, if ret was turned 1 for some folder, it
would disable the p-flag for every following folders, which
is not desired.
Instead, the "else if" makes sure that the p-flag-section is
only entered when the initial rmdir succeeds.
3) BUGFIX: Previously, the program would cancel with eprintf if
it failed to remove one folder in the parent-pathname.
This is not desired, as we have other folders pending.
Instead, print a warning for the current failing parent-folder,
set ret to 1 and break off the loop at this point.
This allows to finish the other pending folders without issues.
1) Update usage as already done in the manpage
2) group and sort local variable declarations
3) Be pedantic about the number of options. Don't just ignore it
if argc > 1.
1) Shorten synopsis and reflect this in the manual
2) Use argv0 in usage()
3) Decrement argc in argv-loop for consistency
4) Make it clearer which error-code results from which errno in enprintf
5) Use idiomatic for-loop also for environ. Don't increment these pointers
in the loop itself!
This has already been suggested by Evan Gates <evan.gates@gmail.com>
and he's totally right about it.
So, what's the problem?
I wrote a testing program asshole.c with
int
main(void)
{
execl("/path/to/sbase/echo", "echo", "test");
return 0;
}
and checked the results with glibc and musl. Note that the
sentinel NULL is missing from the end of the argument list.
glibc calculates an argc of 5, musl 4 (instead of 2) and thus
mess up things anyway.
The powerful arg.h also focuses on argv instead of argc as well,
but ignoring argc completely is also the wrong way to go.
Instead, a more idiomatic approach is to check *argv only and
decrement argc on the go.
While at it, I rewrote yes(1) in an argv-centric way as well.
All audited tools have been "fixed" and each following audited
tool will receive the same treatment.
1) Fix usage ... spacing
2) use *argv instead of argv[0] in the idiomatic for-loop
3) Stop the naïve usage of "/dev/fd/0" and use plain stdin
instead (This also makes error-messages more consistent).
4) Add newline before return
5) Remove comma in manpage
Now that -c behaves correctly, the tools are pretty much done.
Only the manpages were not clear enough what happens when you
specify the c-flag.
This is fixed now.
Previously, it was not possible to use
sha1sum test.c | sha1sum -c
because the program would not differenciate between an empty
argument and a non-specified argument.
Moreover, why not allow this?
sha1sum -c hashlist1 hashlist2
Digging deeper I found that using function pointers and a
modification in the crypt-backend might simplify the program
a lot by passing the argument-list to both cryptmain and
cryptcheck.
Allowing more than one list-file to be specified is also
consistent with what the other implementations support,
so we not only have simpler code, we also do not silently
break if there's a script around passing multiple files to
check.
1) be stricter which number of arguments is accepted (1 or 2)
2) basename already returns a pointer to "." is argv[0] is ""
3) No need to check for *p != '/', because basename() only returns
a string beginning with '/' which has length 1, so if strlen(p)
== 1, the only way for suffix to be "evaluated" is for off to
be > 0, being equal to suffix being "", but "" != "/".
4) don't calculate strlen twice for each string. Store it in a
ssize_t and check if it's > 0.
Okay, so why another section?
The finished-section applies to general feature-completeness and
manual status. It somehow is not an indicator for general code-
clarity, so the audited-column reflects a thorough audit of the
underlying code and optimization.
Take a look at the upcoming basename(1)-patch for an example on
how this goes.
rule to make sbase-box and setup symlinks for $BIN and /bin/[
some (maybe) interesting info:
$ make LDFLAGS="-s -static" CFLAGS="-Os" PREFIX=/ DESTDIR=`pwd`/static-normal install
$ make LDFLAGS="-s -static" CFLAGS="-Os" PREFIX=/ DESTDIR=`pwd`/static-box sbase-box-install
$ du -sk static-normal/ static-box
2728 static-normal/
572 static-box