Commit Graph

31 Commits

Author SHA1 Message Date
FRIGN 7b2465c101 Add maxdepth to recurse()
This also makes more sense.
2015-04-20 11:12:40 +01:00
FRIGN e14d9412f8 Properly handle recursion in recurse()
The restructuring of recurse() in the last few weeks actually broke
the recursion-flags in different tools.
As a long-term goal, the recursor should have a field "maxdepth"
which should be "1" for the non-Rflag-case. "0" stands for unlimited.
2015-04-20 11:12:40 +01:00
FRIGN 3111908b03 Refactor recurse() again
Okay, why yet another recurse()-refactor?
The last one added the recursor-struct, which simplified things
on the user-end, but there was still one thing that bugged me a lot:
Previously, all fn()'s were forced to (l)stat the paths themselves.
This does not work well when you try to keep up with H-, L- and P-
flags at the same time, as each utility-function would have to set
the right function-pointer for (l)stat every single time.

This is not desirable. Furthermore, recurse should be easy to use
and not involve trouble finding the right (l)stat-function to do it
right.
So, what we needed was a stat-argument for each fn(), so it is
directly accessible. This was impossible to do though when the
fn()'s are still directly called by the programs to "start" the
recurse.
Thus, the fundamental change is to make recurse() the function to
go, while designing the fn()'s in a way they can "live" with st
being NULL (we don't want a null-pointer-deref).

What you can see in this commit is the result of this work. Why
all this trouble instead of using nftw?
The special thing about recurse() is that you tell the function
when to recurse() in your fn(). You don't need special flags to
tell nftw() to skip the subtree, just to give an example.

The only single downside to this is that now, you are not allowed
to unconditionally call recurse() from your fn(). It has to be
a directory.
However, that is a cost I think is easily weighed up by the
advantages.

Another thing is the history: I added a procedure at the end of
the outmost recurse to free the history. This way we don't leak
memory.

A simple optimization on the side:

-		if (h->dev == st.st_dev && h->ino == st.st_ino)
+		if (h->ino == st.st_ino && h->dev == st.st_dev)

First compare the likely difference in inode-numbers instead of
checking the unlikely condition that the device-numbers are
different.
2015-03-19 01:08:19 +01:00
FRIGN 9fd4a745f8 Add history and config-struct to recurse
For loop detection, a history is mandatory. In the process of also
adding a flexible struct to recurse, the recurse-definition was moved
to fs.h.
The motivation behind the struct is to allow easy extensions to the
recurse-function without having to change the prototypes of all
functions in the process.
Adding flags is really simple as well now.

Using the recursor-struct, it's also easier to see which defaults
apply to a program (for instance, which type of follow, ...).

Another change was to add proper stat-lstat-usage in recurse. It
was wrong before.
2015-03-13 00:29:48 +01:00
FRIGN 01de5df8e6 Audit du(1) and refactor recurse()
While auditing du(1) I realized that there's no way the over 100 lines
of procedures in du() would pass the audit.
Instead, I decided to rewrite this section using recurse() from libutil.
However, the issue was that you'd need some kind of payload to count
the number of bytes in the subdirectories and use them in the higher
hierarchies.
The solution is to add a "void *data" data pointer to each recurse-
function-prototype, which we might also be able to use in other
recurse-applications.
recurse() itself had to be augmented with a recurse_samedev-flag, which
basically prevents recurse from leaving the current device.

Now, let's take a closer look at the audit:
1) Removing the now unnecessary util-functions push, pop, xrealpath,
   rename print() to printpath(), localize some global variables.
2) Only pass the block count to nblks instead of the entire stat-
   pointer.
3) Fix estrtonum to use the minimum of LLONG_MAX and SIZE_MAX.
4) Use idiomatic argv+argc-loop
5) Report proper exit-status.
2015-03-11 23:21:52 +01:00
FRIGN 286df29e7d Make already audited tools argv-centric instead of argc-centric
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.
2015-03-02 14:19:26 +01:00
FRIGN 6f715d8c6d Audit rm(1)
1) One small argc-style-matter
2) manpage cleanup
3) NOTE: The utility-functions will be evaluated separately.
2015-02-28 21:31:23 +01:00
sin 8d53fc9a79 rm: Remove -i from usage and manpage
We do not support it so do not lie to the user.
2015-02-19 14:54:12 +00:00
sin 8f068589fb Fix recurse() prototype and convert char to int flags 2015-02-16 16:23:12 +00:00
FRIGN 31572c8b0e Clean up #includes 2015-02-14 21:12:23 +01:00
FRIGN e60885699c Fix return values in rm(1) and mv(1)
by setting rm_status to 1 if removing 1 file in the list fails.
Extend this to mv_status in mv(1).
2015-01-30 12:45:54 +01:00
FRIGN 97ad252d5d Add mandoc-manpage for rm(1)
and mark it as finished in README.
2015-01-30 11:34:05 +01:00
FRIGN ec8246bbc6 Un-boolify sbase
It actually makes the binaries smaller, the code easier to read
(gems like "val == true", "val == false" are gone) and actually
predictable in the sense of that we actually know what we're
working with (one bitwise operator was quite adventurous and
should now be fixed).

This is also more consistent with the other suckless projects
around which don't use boolean types.
2014-11-14 10:54:20 +00:00
FRIGN eee98ed3a4 Fix coding style
It was about damn time. Consistency is very important in such a
big codebase.
2014-11-13 18:08:43 +00:00
sin 0c5b7b9155 Stop using EXIT_{SUCCESS,FAILURE} 2014-10-02 23:46:59 +01:00
sin 8eea7f74e9 A plain rm -f is valid and should not be considered an error 2014-07-04 14:55:45 +01:00
Hiltjo Posthuma 953ebf3573 code style
Signed-off-by: Hiltjo Posthuma <hiltjo@codemadness.org>
2014-06-01 18:02:30 +01:00
sin 7f6d5653c6 Add -R as a synonym to -r for rm(1)
Some scripts require this.
2013-12-12 13:15:47 +00:00
sin b5a511dacf Exit with EXIT_SUCCESS/EXIT_FAILURE instead of 0 and 1
Fixed for consistency purposes.
2013-10-07 16:44:22 +01:00
sin 428cd4fe84 None of these work without the proper # of arguments so print usage 2013-10-05 13:51:45 +01:00
stateless 7216a53a7e Remove unnecessary exit(1) in usage()
Signed-off-by: Christoph Lohmann <20h@r-36.net>
2013-06-19 19:58:19 +02:00
Christoph Lohmann 4d38f60685 Eliminating the getopt disgrace. 2013-06-14 20:20:47 +02:00
Connor Lane Smith 196e81c5fb rm: removing empty dirs is okay 2012-05-25 21:55:31 +01:00
William Haddon cec53d14b1 implement cp and mv and improve rm 2012-01-30 22:41:33 +00:00
Connor Lane Smith d90ced2047 consistent error check 2011-06-04 12:20:41 +01:00
Connor Lane Smith da757ff7d1 add chown 2011-05-25 00:24:33 +01:00
Connor Lane Smith f458397d5a no, getopt.h is gnu specific 2011-05-24 18:58:36 +01:00
pancake da547fb294 add missing #include <getopt.h>
do not override CC in config.mk
2011-05-24 14:34:26 +02:00
Connor Lane Smith 78fd8698cc fix rm -r 2011-05-24 13:04:56 +01:00
Connor Lane Smith be6e177f6e fix rm -f 2011-05-24 12:32:33 +01:00
Connor Lane Smith 8c76381e91 add rm, thanks rob 2011-05-24 01:52:28 +01:00