Commit Graph

125 Commits

Author SHA1 Message Date
Michael Forney
edbcc223ea libutil/recurse: Use a single path buffer, and directory fd
This way, we don't use PATH_MAX bytes on the stack per path component,
and don't have to keep copying the complete path around.
2020-03-05 00:45:53 -08:00
Michael Forney
039b54aa51 Use *at functions with appropriate flags instead of lstat/lchown 2020-03-05 00:45:53 -08:00
Michael Forney
f3d05ffd0a chmod: Implement X perm symbol
Instead of clearing the format bits before calling parsemode, leave
them in so we can differentiate between directories and other files,
then clear the format bits in the result.
2020-01-06 13:47:26 -08:00
Michael Forney
d4634f6740 libutil/getlines: Use reallocarray 2019-12-31 13:39:08 -08:00
Michael Forney
60895834f0 libutil/recurse: Use while-loop instead of for-loop with only condition 2019-12-28 22:38:17 -08:00
Michael Forney
f4b9b966cf cp: Default to -P when -R is specified
POSIX only specifies the -H, -L, and -P options for use with -R, and
the default is left to the implementation. Without -R, symlinks must
be followed.

Most implementations use -P as the default with -R, which makes sense
to me as default behavior (the source and destination trees are the same).

Since we use the same code for -R and without it, and we allow -H, -L,
and -P without -R, set the default based on the presence of -R. Without
it, use -L as before, as required by POSIX, and with it, use -P to match
the behavior of other implementations.
2019-12-21 21:26:19 -08:00
Michael Forney
45b9b26cae libutil/recurse: Remove some unnecessary parentheses 2019-11-02 14:03:10 -07:00
Michael Forney
c5c8c7ff86 libutil/mode: Remove unnecessary octal-to-mode conversion
The values of the file mode macros are specified explicitly by POSIX,
so we can just use the octal value directly.
2019-11-01 19:07:10 -07:00
Michael Forney
3fec3e2f4c libutil: Add enreallocarray 2019-04-16 17:41:39 -07:00
David Phillips
69b9c2444b libutil/recurse: only opendir if recursing
Previous behaviour was to call opendir regardless of if we are actually going
to be recursing into the directory. Additionally, some utilities that use
DIRFIRST benefit from running the function pointed to by fn before the call
to opendir. One such example is `chmod [-R] 777 dir` on a directory with mode
000, where it will be expected for chmod to first give itself rwx before
optionally listing the directory to traverse it.
2017-10-01 09:34:47 -07:00
Michael Forney
51e432cc44 cp: Only call chmod with -p or -a
Previously, when the destination file was created with fopen, we needed
to use fchmod to set its permissions.

Now that we pass in the mode to creat, we already get the desired
behavior of creating the file with the same mode as the source file
modified by the user's file creation mask.

This fixes the issue where a directory or special file created with
mkdir/mknod does not end up with the appropriate mode with -p or -a
(since it may have been narrowed by the umask).

This also allows us to clear the SUID and SGID bits from the mode if the
chown fails, as specified by POSIX.
2017-07-14 07:50:50 +02:00
Michael Forney
3276fbea1c concat: Use plain read/write instead of buffered stdio
If we are just copying data from one file to another, we don't need to
fill a complete buffer, just read a chunk at a time, and write it to the
output.
2017-07-14 07:50:47 +02:00
Michael Forney
9a3b12525b Don't use buffered IO (fread) when not appropriate
fread reads the entire requested size (BUFSIZ), which causes tools to
block if only small amounts of data are available at a time. At best,
this causes unnecessary copies and inefficiency, at worst, tools like
tee and cat are almost unusable in some cases since they only display
large chunks of data at a time.
2017-07-03 21:04:14 +02:00
Michael Forney
5cb3a1eba1 libutil: Add writeall utility function
writeall makes successive write calls to write an entire buffer to the
output file descriptor. It returns the number of bytes written, or -1 on
the first error.
2017-07-03 21:04:12 +02:00
Michael Forney
529e50a7ad mkdir: Fix created directory permissions
Previously, with -p, the specified directory and all of its parents
would be 0777&~filemask (regardless of the -m flag). POSIX says parent
directories must created as (0300|~filemask)&0777, and of course if -m
is set, the specified directory should be created with those
permissions.

Additionally, POSIX says that for symbolic_mode strings, + and - should
be interpretted relative to a default mode of 0777 (not 0).

Without -p, previously the directory would be created first with
0777&~filemask (before a chmod), but POSIX says that the directory shall
at no point in time have permissions less restrictive than the -m mode
argument.

Rather than dealing with mkdir removing the filemask bits by calling
chmod afterward, just clear the umask and remove the bits manually.
2017-07-03 21:03:11 +02:00
Michael Forney
6ac5f01cc9 mkdir -p: Fail if argument exists, but is not a directory
If it is a directory, we can just return straightaway.
2017-07-03 21:03:09 +02:00
Michael Forney
a5612b0d08 Remove st != NULL checks from recursor functions
In the description of 3111908b03, it says
that the functions must be able to handle st being NULL, but recurse
always passes a valid pointer. The only function that was ever passed
NULL was rm(), but this was changed to go through recurse in
2f4ab52739, so now the checks are
pointless.
2017-07-03 21:03:02 +02:00
Hiltjo Posthuma
af392d1a76 libutil: fix leaks 2017-05-07 13:50:26 +02:00
Michael Forney
fa0e5d6378 libutil/unescape: NULL terminate unescaped string
In commit 30fd43d7f3, unescape was
simplified significantly, but the new version failed to NULL terminate
the resulting string.

This causes bad behavior in various utilities, for example tr:

Broken:

  $ echo b2 | tr '\142' '\143'
  c3

Fixed:

  $ echo b2 | tr '\142' '\143'
  c2

This bug breaks libtool's usage of tr, causing gcc to fail to build with
sbase.
2017-03-24 10:40:32 +01:00
Mattias Andrée
30fd43d7f3 libutil/unescape.c: simplify and add \E
Signed-off-by: Mattias Andrée <maandree@kth.se>
2017-02-06 15:47:01 -08:00
Mattias Andrée
9a903c63de libutil/unescape.c: only print argv0 once on error
Signed-off-by: Mattias Andrée <maandree@kth.se>
2017-02-06 14:13:40 -08:00
Michael Forney
2481042651 cp: Also preserve atime/mtime for symlinks
Laslo: Fixed style a bit and added comment
2016-12-27 14:50:58 +01:00
Michael Forney
e03a57df92 cp: Check result of utimensat
POSIX says that if duplicating the modification/access times fails, then
an error should be written to stderr.
2016-12-27 14:46:11 +01:00
Michael Forney
52e49329e5 crypt: Add some missing error checks for cryptsum
Previously, if a file failed to read in a checksum list, it would be
reported as not matched rather than a read failure.

Also, if reading from stdin failed, previously a bogus checksum would be
printed anyway.
2016-12-27 14:02:32 +01:00
Michael Forney
87f40834a3 parsemode: No need to return after eprintf
Also, since parsemode exits on failure, don't bother checking return
value in xinstall (this would never trigger anyway because mode_t can be
unsigned).
2016-12-27 13:33:35 +01:00
Michael Forney
8ca79a2993 linecmp: Handle NUL bytes properly
Test case:

if [ "$(printf 'a\na\0b' | ./sort -u)" = "$(printf 'a\na\0b')" ] ; then
	echo pass
else
	echo fail
fi
2016-07-09 10:09:50 +01:00
Mattias Andrée
44a6d65832 *sum: support - when using -c
Signed-off-by: Mattias Andrée <maandree@kth.se>
2016-03-26 08:18:47 +00:00
FRIGN
515525997c Fix linecmp() to return correct values 2016-03-11 15:38:36 +00:00
FRIGN
3debc5e064 Add linecmp() 2016-03-10 08:48:09 +00:00
FRIGN
19c0ca9830 Properly increment line lenght on edge-case in getlines() 2016-03-10 08:48:09 +00:00
FRIGN
eb9bda8787 Support NUL-containing lines in sort(1)
For sort(1) we need memmem(), which I imported from OpenBSD.
Inside sort(1), the changes involved working with the explicit lengths
given by getlines() earlier and rewriting some of the functions.

Now we can handle NUL-characters in the input just fine.
2016-03-10 08:48:09 +00:00
FRIGN
e4810f1cdb Support NUL-containing lines in cols(1)
This required an architectural change in getlines() by also storing
the line length.
2016-03-10 08:48:09 +00:00
FRIGN
a88906b423 Rever the strmem() addition and add a TODO element
strmem() was not very well thought out. The thing is the following:
If the string contains a zero character, we want to match it, and not
stop right there in place.

The "real" solution is to use memmem() where needed and replace all
functions that assume zero-terminated-strings from standard input, which
could lead to early string-breakoffs.
This requires a strict tracking of string lengths.
2016-02-26 09:54:46 +00:00
FRIGN
3396088666 Implement strmem() and use it in join(1)
We want our delimiters to also contain 0 characters and have them
handled gracefully.
To accomplish this, I wrote a function strmem(), which looks for a
certain, arbitrarily long memory subset in a given string.
memmem() is a GNU extension and forces you to call strlen every time.
2016-02-26 09:54:46 +00:00
Mattias Andrée
a392cd475e add sha512-224sum (SHA512/224) and sha512-256sum (SHA512/256)
Signed-off-by: Mattias Andrée <maandree@kth.se>
2016-02-24 10:40:57 +00:00
Mattias Andrée
ae1da536bb add sha224sum and sha384sum
Signed-off-by: Mattias Andrée <maandree@kth.se>
2016-02-24 10:15:16 +00:00
FRIGN
6adb9b8ccd Fix compilation error 2016-02-21 08:52:48 +00:00
FRIGN
70adb1252d Do a range check on the resulting octal 2016-02-21 08:52:48 +00:00
FRIGN
41a600e1b8 Allow \0ooo octal escapes
Yeah well, the old topic. POSIX allows \0123 and \123 octals in
different tools, in printf, depending on %b or other things.
We'll just keep it simple and just allow 4 digits. the 0 does not make
a difference anyway.
2016-02-21 08:52:48 +00:00
FRIGN
e40fc2b176 Check argv0 in xvprintf()
You never know, given printf'ing NULL-strings might crash the
program, we shouldn't just pass argv0 blindly to it.
2015-12-21 14:13:36 +00:00
sin
3b1b50cffa Do not indent label 2015-12-21 09:55:01 +00:00
FRIGN
94e92d9cc0 Refactor eprintf.c
When we move the exit() out of venprintf(), we can reuse it for
weprintf(), which basically had duplicate code.
I also renamed venprintf() to xvprintf (extended vprintf) so it's
more obvious what it actually does.
2015-12-21 09:34:13 +00:00
sin
67157b7c4e Use SSIZE_MAX for overflow check in parseoffset()
There's no such thing as OFF_MAX so we can't use that.  off_t is
signed, so use SSIZE_MAX which will typically match the range of
off_t.
2015-11-26 10:35:46 +00:00
sin
d24584466c Revert "enmasse: For the special case of 2 args, do not distinguish between dirs and files"
This reverts commit a564a67c4ea70e90a4dc543814458e4903869d3e.

Not as trivial as I thought.  This breaks cp when used as:
cp -r /foo/bar /baz

The old code expands this to:
cp -r /foo/bar /baz/bar
2015-11-13 14:31:34 +00:00
sin
4c1f9ecdd2 Align end of comment 2015-11-13 14:24:09 +00:00
sin
996f992ac6 enmasse: For the special case of 2 args, do not distinguish between dirs and files
This produces consistent error messages when moving or copying a file or dir to
itself.
2015-11-13 14:21:07 +00:00
FRIGN
dae33f42d4 Fix typo in libutil/fshut.c 2015-10-26 16:53:28 +00:00
FRIGN
8be7c42863 Make strtol() parsing even stricter in parseoffset()
Be strict about what we pass to it and how we handle errors.
The base-check is done by strtol anyway.
Also improve error-reporting.
2015-09-30 19:44:11 +01:00
FRIGN
870a75076d Harden parseoffset() even more
1) Check for NULL.
2) Check for empty strings.
3) Clarify error-messages.
2015-09-30 19:44:10 +01:00
FRIGN
64929039e9 Don't forget to scale in parseoffset() 2015-09-30 19:44:10 +01:00