selinux/libselinux/utils/matchpathcon.c
Nicolas Iooss 40543dceed libselinux: silence -Wextra-semi-stmt warning
On Ubuntu 20.04, when building with clang -Werror -Wextra-semi-stmt
(which is not the default build configuration), the compiler reports:

      sha1.c:90:21: error: empty expression statement has no effect;
      remove unnecessary ';' to silence this warning
      [-Werror,-Wextra-semi-stmt]
          R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
                          ^
      In file included from selinux_restorecon.c:39:
      ./label_file.h:458:15: error: empty expression statement has no
      effect; remove unnecessary ';' to silence this warning
      [-Werror,-Wextra-semi-stmt]
                                  lineno);
                                        ^

Introduce "do { } while (0)" blocks to silence such warnings.

Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2021-07-06 11:08:11 -04:00

193 lines
4.0 KiB
C

#include <errno.h>
#include <getopt.h>
#include <limits.h>
#include <selinux/label.h>
#include <selinux/selinux.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
static __attribute__ ((__noreturn__)) void usage(const char *progname)
{
fprintf(stderr,
"usage: %s [-V] [-N] [-n] [-m type] [-f file_contexts_file] [-p prefix] [-P policy_root_path] filepath...\n",
progname);
exit(1);
}
static int printmatchpathcon(struct selabel_handle *hnd, const char *path, int header, int mode, int notrans)
{
char *buf = NULL;
int rc;
if (notrans) {
rc = selabel_lookup_raw(hnd, &buf, path, mode);
} else {
rc = selabel_lookup(hnd, &buf, path, mode);
}
if (rc < 0) {
if (errno == ENOENT) {
buf = strdup("<<none>>");
} else {
fprintf(stderr, "selabel_lookup(%s) failed: %s\n", path,
strerror(errno));
return 1;
}
}
if (header)
printf("%s\t%s\n", path, buf);
else
printf("%s\n", buf);
freecon(buf);
return 0;
}
static mode_t string_to_mode(char *s)
{
switch (s[0]) {
case 'b':
return S_IFBLK;
case 'c':
return S_IFCHR;
case 'd':
return S_IFDIR;
case 'p':
return S_IFIFO;
case 'l':
return S_IFLNK;
case 's':
return S_IFSOCK;
case 'f':
return S_IFREG;
default:
return -1;
}
return -1;
}
int main(int argc, char **argv)
{
int i, force_mode = 0;
int header = 1, opt;
int verify = 0;
int notrans = 0;
int error = 0;
int quiet = 0;
struct selabel_handle *hnd;
struct selinux_opt options[SELABEL_NOPT] = {};
if (argc < 2)
usage(argv[0]);
while ((opt = getopt(argc, argv, "m:Nnf:P:p:Vq")) > 0) {
switch (opt) {
case 'n':
header = 0;
break;
case 'm':
force_mode = string_to_mode(optarg);
if (force_mode < 0) {
fprintf(stderr, "%s: mode %s is invalid\n", argv[0], optarg);
exit(1);
}
break;
case 'V':
verify = 1;
break;
case 'N':
notrans = 1;
break;
case 'f':
options[SELABEL_OPT_PATH].type = SELABEL_OPT_PATH;
options[SELABEL_OPT_PATH].value = optarg;
break;
case 'P':
if (selinux_set_policy_root(optarg) < 0 ) {
fprintf(stderr,
"Error setting policy root %s: %s\n",
optarg,
errno ? strerror(errno) : "invalid");
exit(1);
}
break;
case 'p':
// This option has been deprecated since libselinux 2.5 (2016):
// https://github.com/SELinuxProject/selinux/commit/26e05da0fc2d0a4bd274320968a88f8acbb3b6a6
fprintf(stderr, "Warning: using %s -p is deprecated\n", argv[0]);
options[SELABEL_OPT_SUBSET].type = SELABEL_OPT_SUBSET;
options[SELABEL_OPT_SUBSET].value = optarg;
break;
case 'q':
quiet = 1;
break;
default:
usage(argv[0]);
}
}
hnd = selabel_open(SELABEL_CTX_FILE, options, SELABEL_NOPT);
if (!hnd) {
fprintf(stderr,
"Error while opening file contexts database: %s\n",
strerror(errno));
return -1;
}
for (i = optind; i < argc; i++) {
int rc, mode = 0;
struct stat buf;
char *path = argv[i];
int len = strlen(path);
if (len > 1 && path[len - 1 ] == '/')
path[len - 1 ] = '\0';
if (lstat(path, &buf) == 0)
mode = buf.st_mode;
if (force_mode)
mode = force_mode;
if (verify) {
rc = selinux_file_context_verify(path, mode);
if (quiet) {
if (rc == 1)
continue;
else
exit(1);
}
if (rc == -1) {
printf("%s error: %s\n", path, strerror(errno));
exit(1);
} else if (rc == 1) {
printf("%s verified.\n", path);
} else {
char * con;
error = 1;
if (notrans)
rc = lgetfilecon_raw(path, &con);
else
rc = lgetfilecon(path, &con);
if (rc >= 0) {
printf("%s has context %s, should be ",
path, con);
printmatchpathcon(hnd, path, 0, mode, notrans);
freecon(con);
} else {
printf
("actual context unknown: %s, should be ",
strerror(errno));
printmatchpathcon(hnd, path, 0, mode, notrans);
}
}
} else {
error |= printmatchpathcon(hnd, path, header, mode, notrans);
}
}
selabel_close(hnd);
return error;
}