aboutsummaryrefslogtreecommitdiff
path: root/lib/libutil
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libutil')
-rw-r--r--lib/libutil/Makefile1
-rw-r--r--lib/libutil/Symbol.map9
-rw-r--r--lib/libutil/expand_number.358
-rw-r--r--lib/libutil/expand_number.c49
-rw-r--r--lib/libutil/libutil.h8
-rw-r--r--lib/libutil/login.conf.57
-rw-r--r--lib/libutil/login_auth.34
-rw-r--r--lib/libutil/login_cap.31
-rw-r--r--lib/libutil/mntopts.310
-rw-r--r--lib/libutil/mntopts.c1
-rw-r--r--lib/libutil/tests/expand_number_test.c79
-rw-r--r--lib/libutil/uucplock.31
12 files changed, 208 insertions, 20 deletions
diff --git a/lib/libutil/Makefile b/lib/libutil/Makefile
index f8c566ca731a..f6251c093345 100644
--- a/lib/libutil/Makefile
+++ b/lib/libutil/Makefile
@@ -136,7 +136,6 @@ MLINKS+=quotafile.3 quota_on.3
MLINKS+=quotafile.3 quota_open.3
MLINKS+=quotafile.3 quota_qfname.3
MLINKS+=quotafile.3 quota_read.3
-MLINKS+=quotafile.3 quota_statfs.3
MLINKS+=quotafile.3 quota_write_limits.3
MLINKS+=quotafile.3 quota_write_usage.3
MAN+= realhostname.3
diff --git a/lib/libutil/Symbol.map b/lib/libutil/Symbol.map
index 8c8fff451cd1..2b28456f4406 100644
--- a/lib/libutil/Symbol.map
+++ b/lib/libutil/Symbol.map
@@ -13,6 +13,7 @@ FBSD_1.8 {
cpuset_parselist;
domainset_parselist;
expand_number;
+ expand_unsigned;
flopen;
flopenat;
forkpty;
@@ -119,6 +120,14 @@ FBSD_1.8 {
uu_lock;
uu_lockerr;
uu_unlock;
+
+ /*
+ * login_setcryptfmt() uses crypt_set_format() from libcrypt. To
+ * avoid forcing a hard dependency on libcrypt, we provide a weak
+ * stub. Applications that use login_setcryptfmt() should link
+ * with libcrypt, whose crypt_set_format() will override the stub.
+ */
+ crypt_set_format;
};
FBSDprivate_1.0 {
diff --git a/lib/libutil/expand_number.3 b/lib/libutil/expand_number.3
index 1b932400de69..b1833cedf406 100644
--- a/lib/libutil/expand_number.3
+++ b/lib/libutil/expand_number.3
@@ -24,11 +24,12 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd July 25, 2025
+.Dd August 6, 2025
.Dt EXPAND_NUMBER 3
.Os
.Sh NAME
-.Nm expand_number
+.Nm expand_number ,
+.Nm expand_unsigned
.Nd parse a number from human readable form
.Sh LIBRARY
.Lb libutil
@@ -38,6 +39,10 @@
.Fo expand_number
.Fa "const char *buf" "int64_t *num"
.Fc
+.Ft int
+.Fo expand_unsigned
+.Fa "const char *buf" "uint64_t *num"
+.Fc
.Sh DESCRIPTION
The
.Fn expand_number
@@ -48,6 +53,17 @@ quantity in the location pointed to by its
.Fa *num
argument.
.Pp
+The
+.Fn expand_unsigned
+function is similar to
+.Fn expand_number ,
+but accepts only positive numbers in the range
+.Bq 0, Ns Dv UINT64_MAX .
+.Pp
+Both functions interpret the input
+.Dq -0
+as 0.
+.Pp
The input string must consist of a decimal number, optionally preceded
by a
.Sq +
@@ -81,20 +97,38 @@ is interpreted as 5, and
.Dq 5kb
is interpreted as 5,120).
However, the usage of this suffix is discouraged.
+.Pp
+For backward compatibility reasons, if the compiler supports generic
+selection, a macro is provided which automatically replaces calls to
+.Fn expand_number
+with calls to
+.Fn expand_unsigned
+if the type of the actual
+.Va num
+argument is compatible with
+.Vt uint64_t * .
.Sh RETURN VALUES
.Rv -std
.Sh ERRORS
The
.Fn expand_number
-function will fail if:
+and
+.Fn expand_unsigned
+functions will fail if:
.Bl -tag -width Er
.It Bq Er EINVAL
The given string does not contain a valid number.
.It Bq Er EINVAL
An unrecognized suffix was encountered.
.It Bq Er ERANGE
-The given string represents a number which does not fit into a
-.Vt int64_t .
+The given string represents a number which does not fit into an
+.Vt int64_t
+(for
+.Fn expand_number )
+or
+.Vt uint64_t
+(for
+.Fn expand_unsigned ) .
.El
.Sh SEE ALSO
.Xr humanize_number 3
@@ -103,3 +137,17 @@ The
.Fn expand_number
function first appeared in
.Fx 6.3 .
+The original implementation did not handle negative numbers correctly,
+and it was switched to taking a
+.Vt uint64_t *
+and accepting only positive numbers in
+.Fx 9.0 .
+The
+.Fn expand_unsigned
+function was added,
+and
+.Fn expand_number
+switched back to
+.Vt int64_t * ,
+in
+.Fx 15.0 .
diff --git a/lib/libutil/expand_number.c b/lib/libutil/expand_number.c
index f4c19d7867a3..a3313ba39d98 100644
--- a/lib/libutil/expand_number.c
+++ b/lib/libutil/expand_number.c
@@ -37,13 +37,12 @@
#include <stdbool.h>
#include <stdint.h>
-int
-expand_number(const char *buf, int64_t *num)
+static int
+expand_impl(const char *buf, uint64_t *num, bool *neg)
{
char *endptr;
uintmax_t number;
unsigned int shift;
- bool neg;
int serrno;
/*
@@ -52,10 +51,10 @@ expand_number(const char *buf, int64_t *num)
while (isspace((unsigned char)*buf))
buf++;
if (*buf == '-') {
- neg = true;
+ *neg = true;
buf++;
} else {
- neg = false;
+ *neg = false;
if (*buf == '+')
buf++;
}
@@ -127,6 +126,22 @@ expand_number(const char *buf, int64_t *num)
}
number <<= shift;
+ *num = number;
+ return (0);
+}
+
+int
+(expand_number)(const char *buf, int64_t *num)
+{
+ uint64_t number;
+ bool neg;
+
+ /*
+ * Parse the number.
+ */
+ if (expand_impl(buf, &number, &neg) != 0)
+ return (-1);
+
/*
* Apply the sign and check for overflow.
*/
@@ -146,3 +161,27 @@ expand_number(const char *buf, int64_t *num)
return (0);
}
+
+int
+expand_unsigned(const char *buf, uint64_t *num)
+{
+ uint64_t number;
+ bool neg;
+
+ /*
+ * Parse the number.
+ */
+ if (expand_impl(buf, &number, &neg) != 0)
+ return (-1);
+
+ /*
+ * Negative numbers are out of range.
+ */
+ if (neg && number > 0) {
+ errno = ERANGE;
+ return (-1);
+ }
+
+ *num = number;
+ return (0);
+}
diff --git a/lib/libutil/libutil.h b/lib/libutil/libutil.h
index d27262e44daf..9b5b2abe7f09 100644
--- a/lib/libutil/libutil.h
+++ b/lib/libutil/libutil.h
@@ -89,6 +89,14 @@ __BEGIN_DECLS
void clean_environment(const char * const *_white,
const char * const *_more_white);
int expand_number(const char *_buf, int64_t *_num);
+int expand_unsigned(const char *_buf, uint64_t *_num);
+#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || \
+ __has_extension(c_generic_selections)
+#define expand_number(_buf, _num) \
+ _Generic((_num), \
+ uint64_t *: expand_unsigned, \
+ default: expand_number)((_buf), (_num))
+#endif
int extattr_namespace_to_string(int _attrnamespace, char **_string);
int extattr_string_to_namespace(const char *_string, int *_attrnamespace);
int flopen(const char *_path, int _flags, ...);
diff --git a/lib/libutil/login.conf.5 b/lib/libutil/login.conf.5
index d43fdfb761f3..27f37fb5fc30 100644
--- a/lib/libutil/login.conf.5
+++ b/lib/libutil/login.conf.5
@@ -380,14 +380,15 @@ If
is specified, then logins are only allowed during the periods given.
If
.Em times.deny
-is specified, then logins are denied during the periods given, regardless of whether
-one of the periods specified in
+is specified, then logins are denied during the periods given,
+regardless of whether one of the periods specified in
.Em times.allow
applies.
.Pp
Note that
.Xr login 1
-enforces only that the actual login falls within periods allowed by these entries.
+enforces only that the actual login falls within periods allowed by
+these entries.
Further enforcement over the life of a session requires a separate daemon to
monitor transitions from an allowed period to a non-allowed one.
.Pp
diff --git a/lib/libutil/login_auth.3 b/lib/libutil/login_auth.3
index fafe43b906e6..dd5ba3e01265 100644
--- a/lib/libutil/login_auth.3
+++ b/lib/libutil/login_auth.3
@@ -58,8 +58,8 @@
.\" .Ft int
.\" .Fn auth_timesok "login_cap_t *lc" "time_t now"
.Sh DESCRIPTION
-This set of functions support the login class authorisation style interface provided
-by
+This set of functions support the login class authorisation style
+interface provided by
.Xr login.conf 5 .
.\" .Sh RETURN VALUES
.Sh SEE ALSO
diff --git a/lib/libutil/login_cap.3 b/lib/libutil/login_cap.3
index 86142c3b19f9..48af0e3c9c46 100644
--- a/lib/libutil/login_cap.3
+++ b/lib/libutil/login_cap.3
@@ -31,6 +31,7 @@
.Nm login_getcaptime ,
.Nm login_getclass ,
.Nm login_getclassbyname ,
+.Nm login_getpath ,
.Nm login_getpwclass ,
.Nm login_getstyle ,
.Nm login_getuserclass ,
diff --git a/lib/libutil/mntopts.3 b/lib/libutil/mntopts.3
index 35f6d476fcec..28e5a02442c2 100644
--- a/lib/libutil/mntopts.3
+++ b/lib/libutil/mntopts.3
@@ -342,9 +342,9 @@ By default
.Va getmnt_silent
is zero.
.Sh SEE ALSO
+.Xr nmount 2 ,
.Xr err 3 ,
-.Xr mount 8 ,
-.Xr nmount 8
+.Xr mount 8
.Sh HISTORY
The
.Fn getmntopts
@@ -358,7 +358,7 @@ The
and
.Fn rmslashes
functions were added with
-.Xr nmount 8
+.Xr nmount 2
in
.Fx 5.0 .
The
@@ -368,7 +368,9 @@ and
functions were added in
.Fx 13.2 .
.Pp
-Historically, these functions were found in getmntopts.c in the sources for the
+Historically, these functions were found in
+.Pa getmntopts.c
+in the source code of the
.Xr mount 8
program.
As of
diff --git a/lib/libutil/mntopts.c b/lib/libutil/mntopts.c
index 1d9347e3108a..07d3dd6d98a3 100644
--- a/lib/libutil/mntopts.c
+++ b/lib/libutil/mntopts.c
@@ -185,6 +185,7 @@ getmntpoint(const char *name)
strncpy(statfsp->f_mntfromname, device, len);
}
if (stat(ddevname, &mntdevstat) == 0 &&
+ S_ISCHR(mntdevstat.st_mode) &&
mntdevstat.st_rdev == devstat.st_rdev)
return (statfsp);
}
diff --git a/lib/libutil/tests/expand_number_test.c b/lib/libutil/tests/expand_number_test.c
index 8e7458994de4..9bd339298575 100644
--- a/lib/libutil/tests/expand_number_test.c
+++ b/lib/libutil/tests/expand_number_test.c
@@ -206,10 +206,89 @@ ATF_TC_BODY(expand_number__bad, tp)
require_error(" + 1", EINVAL);
}
+ATF_TC_WITHOUT_HEAD(expand_unsigned);
+ATF_TC_BODY(expand_unsigned, tp)
+{
+ static struct tc {
+ const char *str;
+ uint64_t num;
+ int error;
+ } tcs[] = {
+ { "0", 0, 0 },
+ { "+0", 0, 0 },
+ { "-0", 0, 0 },
+ { "1", 1, 0 },
+ { "+1", 1, 0 },
+ { "-1", 0, ERANGE },
+ { "18446744073709551615", UINT64_MAX, 0 },
+ { "+18446744073709551615", UINT64_MAX, 0 },
+ { "-18446744073709551615", 0, ERANGE },
+ { 0 },
+ };
+ struct tc *tc;
+ uint64_t num;
+ int error, ret;
+
+ for (tc = tcs; tc->str != NULL; tc++) {
+ ret = expand_number(tc->str, &num);
+ error = errno;
+ if (tc->error == 0) {
+ ATF_REQUIRE_EQ_MSG(0, ret,
+ "%s ret = %d", tc->str, ret);
+ ATF_REQUIRE_EQ_MSG(tc->num, num,
+ "%s num = %ju", tc->str, (uintmax_t)num);
+ } else {
+ ATF_REQUIRE_EQ_MSG(-1, ret,
+ "%s ret = %d", tc->str, ret);
+ ATF_REQUIRE_EQ_MSG(tc->error, error,
+ "%s errno = %d", tc->str, error);
+ }
+ }
+}
+
+ATF_TC_WITHOUT_HEAD(expand_generic);
+ATF_TC_BODY(expand_generic, tp)
+{
+ uint64_t uint64;
+ int64_t int64;
+#ifdef __LP64__
+ size_t size;
+#endif
+ off_t off;
+
+ ATF_REQUIRE_EQ(0, expand_number("18446744073709551615", &uint64));
+ ATF_REQUIRE_EQ(UINT64_MAX, uint64);
+ ATF_REQUIRE_EQ(-1, expand_number("-1", &uint64));
+ ATF_REQUIRE_EQ(ERANGE, errno);
+
+ ATF_REQUIRE_EQ(0, expand_number("9223372036854775807", &int64));
+ ATF_REQUIRE_EQ(INT64_MAX, int64);
+ ATF_REQUIRE_EQ(-1, expand_number("9223372036854775808", &int64));
+ ATF_REQUIRE_EQ(ERANGE, errno);
+ ATF_REQUIRE_EQ(0, expand_number("-9223372036854775808", &int64));
+ ATF_REQUIRE_EQ(INT64_MIN, int64);
+
+#ifdef __LP64__
+ ATF_REQUIRE_EQ(0, expand_number("18446744073709551615", &size));
+ ATF_REQUIRE_EQ(UINT64_MAX, size);
+ ATF_REQUIRE_EQ(-1, expand_number("-1", &size));
+ ATF_REQUIRE_EQ(ERANGE, errno);
+#endif
+
+ ATF_REQUIRE_EQ(0, expand_number("9223372036854775807", &off));
+ ATF_REQUIRE_EQ(INT64_MAX, off);
+ ATF_REQUIRE_EQ(-1, expand_number("9223372036854775808", &off));
+ ATF_REQUIRE_EQ(ERANGE, errno);
+ ATF_REQUIRE_EQ(0, expand_number("-9223372036854775808", &off));
+ ATF_REQUIRE_EQ(INT64_MIN, off);
+}
+
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, expand_number__ok);
ATF_TP_ADD_TC(tp, expand_number__bad);
+ ATF_TP_ADD_TC(tp, expand_unsigned);
+ ATF_TP_ADD_TC(tp, expand_generic);
return (atf_no_error());
}
diff --git a/lib/libutil/uucplock.3 b/lib/libutil/uucplock.3
index dd19d0311b4e..ee8c9f6bb995 100644
--- a/lib/libutil/uucplock.3
+++ b/lib/libutil/uucplock.3
@@ -28,6 +28,7 @@
.Os
.Sh NAME
.Nm uu_lock ,
+.Nm uu_lock_txfr ,
.Nm uu_unlock ,
.Nm uu_lockerr
.Nd acquire and release control of a serial device