1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2024 Oxide Computer Company
14 */
15
16 /*
17 * Check certain aspects of files for the overwrite test that are a bit harder
18 * to do in the shell.
19 */
20
21 #include <stdlib.h>
22 #include <unistd.h>
23 #include <err.h>
24 #include <sys/stat.h>
25
26 typedef enum {
27 CT_UNSET,
28 CT_NOPERMS,
29 CT_DOOR
30 } check_type_t;
31
32 int
main(int argc,char * argv[])33 main(int argc, char *argv[])
34 {
35 int c;
36 struct stat st;
37 check_type_t type = CT_UNSET;
38
39 if (argc == 1) {
40 errx(EXIT_FAILURE, "missing required arguments");
41 }
42
43 while ((c = getopt(argc, argv, ":dn")) != -1) {
44 switch (c) {
45 case 'd':
46 type = CT_DOOR;
47 break;
48 case 'n':
49 type = CT_NOPERMS;
50 break;
51 case ':':
52 errx(EXIT_FAILURE, "option -%c requires an operand", c);
53 case '?':
54 errx(EXIT_FAILURE, "unknown option -%c", c);
55 }
56 }
57
58 argv += optind;
59 argc -= optind;
60
61 if (argc != 1) {
62 errx(EXIT_FAILURE, "expected a file to look at but have %d "
63 "args", argc);
64 }
65
66 if (stat(argv[0], &st) != 0) {
67 err(EXIT_FAILURE, "failed to stat %s", argv[0]);
68 }
69
70 switch (type) {
71 case CT_UNSET:
72 errx(EXIT_FAILURE, "missing a check type option");
73 case CT_NOPERMS:
74 if (S_ISREG(st.st_mode) == 0) {
75 errx(EXIT_FAILURE, "%s is not a regular file: 0x%x",
76 argv[0], st.st_mode);
77 } else if ((st.st_mode & S_IAMB) != 0) {
78 errx(EXIT_FAILURE, "%s ended up with perms somehow: "
79 "found 0o%o", argv[0], st.st_mode & S_IAMB);
80 }
81 break;
82 case CT_DOOR:
83 if (S_ISDOOR(st.st_mode) == 0) {
84 errx(EXIT_FAILURE, "%s is not a door: 0x%x",
85 argv[0], st.st_mode);
86 }
87 break;
88 }
89
90 return (EXIT_SUCCESS);
91 }
92