Changeset View
Changeset View
Standalone View
Standalone View
head/usr.bin/soelim/soelim.c
Show All 21 Lines | |||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
*/ | */ | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <sys/capsicum.h> | |||||
#include <sys/types.h> | #include <sys/types.h> | ||||
#include <ctype.h> | #include <ctype.h> | ||||
#include <err.h> | #include <err.h> | ||||
#include <errno.h> | |||||
#include <fcntl.h> | |||||
#include <limits.h> | #include <limits.h> | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <stringlist.h> | #include <stringlist.h> | ||||
#include <termios.h> | |||||
#include <unistd.h> | #include <unistd.h> | ||||
#define C_OPTION 0x1 | #define C_OPTION 0x1 | ||||
static StringList *includes; | static StringList *includes; | ||||
static void | static void | ||||
usage(void) | usage(void) | ||||
{ | { | ||||
fprintf(stderr, "usage: soelim [-Crtv] [-I dir] [files]\n"); | fprintf(stderr, "usage: soelim [-Crtv] [-I dir] [files]\n"); | ||||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | ||||
} | } | ||||
static const char * | |||||
relpath(const char *path) | |||||
{ | |||||
oshogbo: Style should be one free line if there is no variables. | |||||
while (*path == '/' && *path != '\0') | |||||
path++; | |||||
return (path); | |||||
} | |||||
static FILE * | static FILE * | ||||
soelim_fopen(const char *name) | soelim_fopen(int rootfd, const char *name) | ||||
{ | { | ||||
FILE *f; | |||||
char path[PATH_MAX]; | char path[PATH_MAX]; | ||||
size_t i; | size_t i; | ||||
int fd; | |||||
if (strcmp(name, "-") == 0) | if (strcmp(name, "-") == 0) | ||||
return (stdin); | return (stdin); | ||||
if ((f = fopen(name, "r")) != NULL) | if ((fd = openat(rootfd, relpath(name), O_RDONLY)) != -1) | ||||
return (f); | return (fdopen(fd, "r")); | ||||
oshogboUnsubmitted Not Done Inline ActionsCan fail. oshogbo: Can fail. | |||||
if (*name == '/') { | if (*name == '/') { | ||||
warn("can't open '%s'", name); | warn("can't open '%s'", name); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
for (i = 0; i < includes->sl_cur; i++) { | for (i = 0; i < includes->sl_cur; i++) { | ||||
snprintf(path, sizeof(path), "%s/%s", includes->sl_str[i], | snprintf(path, sizeof(path), "%s/%s", includes->sl_str[i], | ||||
name); | name); | ||||
if ((f = fopen(path, "r")) != NULL) | if ((fd = openat(rootfd, relpath(path), O_RDONLY)) != -1) | ||||
return (f); | return (fdopen(fd, "r")); | ||||
oshogboUnsubmitted Not Done Inline ActionsCan fail. oshogbo: Can fail. | |||||
} | } | ||||
warn("can't open '%s'", name); | warn("can't open '%s'", name); | ||||
return (f); | return (NULL); | ||||
} | } | ||||
static int | static int | ||||
soelim_file(FILE *f, int flag) | soelim_file(int rootfd, FILE *f, int flag) | ||||
{ | { | ||||
char *line = NULL; | char *line = NULL; | ||||
char *walk, *cp; | char *walk, *cp; | ||||
size_t linecap = 0; | size_t linecap = 0; | ||||
ssize_t linelen; | ssize_t linelen; | ||||
if (f == NULL) | if (f == NULL) | ||||
return (1); | return (1); | ||||
Show All 19 Lines | while ((linelen = getline(&line, &linecap, f)) > 0) { | ||||
*cp = 0; | *cp = 0; | ||||
if (cp < line + linelen) | if (cp < line + linelen) | ||||
cp++; | cp++; | ||||
if (*walk == '\0') { | if (*walk == '\0') { | ||||
printf("%s", line); | printf("%s", line); | ||||
continue; | continue; | ||||
} | } | ||||
if (soelim_file(soelim_fopen(walk), flag) == 1) { | if (soelim_file(rootfd, soelim_fopen(rootfd, walk), flag) == 1) { | ||||
free(line); | free(line); | ||||
return (1); | return (1); | ||||
} | } | ||||
if (*cp != '\0') | if (*cp != '\0') | ||||
printf("%s", cp); | printf("%s", cp); | ||||
} | } | ||||
free(line); | free(line); | ||||
fclose(f); | fclose(f); | ||||
return (0); | return (0); | ||||
} | } | ||||
int | int | ||||
main(int argc, char **argv) | main(int argc, char **argv) | ||||
{ | { | ||||
int ch, i; | int ch, i, rootfd; | ||||
int ret = 0; | int ret = 0; | ||||
int flags = 0; | int flags = 0; | ||||
unsigned long cmd; | |||||
char cwd[MAXPATHLEN]; | |||||
cap_rights_t rights; | |||||
includes = sl_init(); | includes = sl_init(); | ||||
sl_add(includes, getcwd(cwd, sizeof(cwd))); | |||||
oshogboUnsubmitted Not Done Inline Actionsgetcwd - can fail. oshogbo: getcwd - can fail. | |||||
if (includes == NULL) | if (includes == NULL) | ||||
err(EXIT_FAILURE, "sl_init()"); | err(EXIT_FAILURE, "sl_init()"); | ||||
while ((ch = getopt(argc, argv, "CrtvI:")) != -1) { | while ((ch = getopt(argc, argv, "CrtvI:")) != -1) { | ||||
switch (ch) { | switch (ch) { | ||||
case 'C': | case 'C': | ||||
flags |= C_OPTION; | flags |= C_OPTION; | ||||
break; | break; | ||||
Show All 9 Lines | default: | ||||
sl_free(includes, 0); | sl_free(includes, 0); | ||||
usage(); | usage(); | ||||
} | } | ||||
} | } | ||||
argc -= optind; | argc -= optind; | ||||
argv += optind; | argv += optind; | ||||
cap_rights_init(&rights, CAP_READ, CAP_FSTAT, CAP_IOCTL); | |||||
/* | |||||
* EBADF in case stdin is closed by the caller | |||||
oshogboUnsubmitted Not Done Inline ActionsDot on the on of the comment ;P oshogbo: Dot on the on of the comment ;P | |||||
*/ | |||||
if (cap_rights_limit(STDIN_FILENO, &rights) < 0 && errno != ENOSYS | |||||
&& errno != EBADF) | |||||
err(EXIT_FAILURE, "unable to limit rights for stdin"); | |||||
cap_rights_init(&rights, CAP_WRITE, CAP_FSTAT, CAP_IOCTL); | |||||
if (cap_rights_limit(STDOUT_FILENO, &rights) < 0 && errno != ENOSYS) | |||||
err(EXIT_FAILURE, "unable to limit rights for stdout"); | |||||
if (cap_rights_limit(STDERR_FILENO, &rights) < 0 && errno != ENOSYS) | |||||
err(EXIT_FAILURE, "unable to limit rights for stderr"); | |||||
rootfd = open("/", O_DIRECTORY | O_RDONLY); | |||||
oshogboUnsubmitted Not Done Inline ActionsCan fail. oshogbo: Can fail. | |||||
cap_rights_init(&rights, CAP_READ, CAP_LOOKUP, CAP_FSTAT, CAP_FCNTL); | |||||
if (cap_rights_limit(rootfd, &rights) < 0 && errno != ENOSYS) | |||||
err(EXIT_FAILURE, "unable to limit rights"); | |||||
cmd = TIOCGETA; | |||||
if (cap_ioctls_limit(STDOUT_FILENO, &cmd, 1) < 0 && errno != ENOSYS) | |||||
err(EXIT_FAILURE, "unable to limit ioctls for stdout"); | |||||
if (cap_ioctls_limit(STDERR_FILENO, &cmd, 1) < 0 && errno != ENOSYS) | |||||
err(EXIT_FAILURE, "unable to limit ioctls for stderr"); | |||||
if (cap_ioctls_limit(STDIN_FILENO, &cmd, 1) < 0 && errno != ENOSYS) | |||||
err(EXIT_FAILURE, "unable to limit ioctls for stdin"); | |||||
if (cap_enter() < 0 && errno != ENOSYS) | |||||
err(EXIT_FAILURE, "unable to enter capability mode"); | |||||
if (argc == 0) | if (argc == 0) | ||||
ret = soelim_file(stdin, flags); | ret = soelim_file(rootfd, stdin, flags); | ||||
for (i = 0; i < argc; i++) | for (i = 0; i < argc; i++) | ||||
ret = soelim_file(soelim_fopen(argv[i]), flags); | ret = soelim_file(rootfd, soelim_fopen(rootfd, argv[i]), flags); | ||||
sl_free(includes, 0); | sl_free(includes, 0); | ||||
close(rootfd); | |||||
return (ret); | return (ret); | ||||
} | } |
Style should be one free line if there is no variables.