diff --git a/usr.bin/runat/Makefile.xattr b/usr.bin/runat/Makefile --- a/usr.bin/runat/Makefile.xattr +++ b/usr.bin/runat/Makefile @@ -0,0 +1,3 @@ +PROG= runat + +.include diff --git a/usr.bin/runat/runat.1.xattr b/usr.bin/runat/runat.1 --- a/usr.bin/runat/runat.1.xattr +++ b/usr.bin/runat/runat.1 @@ -0,0 +1,76 @@ +.\" Copyright (c) 2025 Rick Macklem. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.Dd April 15, 2025 +.Dt RUNAT 1 +.Os +.Sh NAME +.Nm runat +.Nd run a shell command on a named attribute directory +.Sh SYNOPSIS +.Nm +.Op Fl c +.Op Fl - +.Op Ar file +.Op Ar shell command +.Sh DESCRIPTION +The +.Nm +utility runs the shell command on the named attribute directory for the +.Fa file +argument. +It does a +.Fn fchdir +system call in a child process to change the current working directory into the +named attribute directory for the +.Fa file +argument and then performs the shell command via +.Xr system 3 . +.Pp +The options are as follows: +.Bl -tag -width indent +.It Fl c +Create the named attribute directory if it does not already exist. +.It Fl - +Used if the +.Fa file +argument happens to be called +.Dq -c . +.El +.Sh EXAMPLES +For a file called +.Dq myfile : +.Bd -literal +$ runat myfile ls -l # lists the attributes for myfile +$ runat myfile cp /etc/hosts attrhosts # creates attrhosts +$ runat myfile cat attrhosts # displays contents of attrhosts +.Ed +.Sh SEE ALSO +.Xr open 2 , +.Xr system 3 , +.Xr named_attribute 7 +.Sh HISTORY +The +.Nm +utility first appeared in +.Fx 15.0 . diff --git a/usr.bin/runat/runat.c.xattr b/usr.bin/runat/runat.c --- a/usr.bin/runat/runat.c.xattr +++ b/usr.bin/runat/runat.c @@ -0,0 +1,107 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2025 Rick Macklem + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static void +usage(void) +{ + (void)fprintf(stderr, "usage: runat [-create/--] " + "\n"); + exit(1); +} + +int +main(int argc, char *argv[]) +{ + int fmode, i, file_fd, nameddir_fd, outsiz, sysret; + char *buf; + long named_enabled; + size_t pos, siz; + + fmode = O_NAMEDATTR | O_RDONLY; + if (argc <= 2) + usage(); + argv++; + argc--; + if (strcmp(argv[0], "-create") == 0) { + fmode |= O_CREAT; + argv++; + argc--; + } else if (strcmp(argv[0], "--") == 0) { + argv++; + argc--; + } + if (argc < 2) + usage(); + + named_enabled = pathconf(argv[0], _PC_NAMEDATTR_ENABLED); + if (named_enabled <= 0) + errx(1, "Named attributes not enabled for %s", argv[0]); + + /* Generate the string for system(3). */ + siz = 0; + for (i = 1; i < argc; i++) + siz += strlen(argv[i]) + 1; + buf = malloc(siz); + if (buf == NULL) + errx(1, "Cannot malloc"); + pos = 0; + for (i = 1; i < argc; i++) { + outsiz = snprintf(&buf[pos], siz, "%s ", argv[i]); + if ((size_t)outsiz > siz) + errx(1, "Arguments too large"); + pos += outsiz; + siz -= outsiz; + } + buf[pos - 1] = '\0'; + + file_fd = open(argv[0], O_RDONLY, 0); + if (file_fd < 0) + err(1, "Cannot open %s", argv[0]); + nameddir_fd = openat(file_fd, ".", fmode, 0); + if (nameddir_fd < 0) + err(1, "Cannot open named attribute directory " + "for %s", argv[0]); + close(file_fd); + + if (fchdir(nameddir_fd) < 0) + err(1, "Cannot fchdir to named attribute dir"); + close(nameddir_fd); + sysret = system(buf); + if (sysret == -1 || sysret == 127) + sysret = 1; + exit(sysret); +}