/* * Copyright (c) 2005 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. */ #include "sm/generic.h" SM_RCSID("@(#)$Id: statit.c,v 1.3 2006/12/26 20:09:08 ca Exp $") #include "sm/assert.h" #include "sm/error.h" #include "sm/test.h" #include "sm/stat.h" #include "sm/sysexits.h" #include static int Verbose = 0; #define STATIT_MODE 0x01 #define STATIT_UID 0x02 #define STATIT_GID 0x04 #define CMPIT_MODE 0x10 #define CMPIT_UID 0x20 #define CMPIT_GID 0x40 #define MODE_MASK 07777 static int statit(const char *path, int opts, mode_t mode, uid_t uid, gid_t gid) { int r; struct stat sb; r = stat(path, &sb); if (r != 0) { fprintf(stderr, "errno=%d\n", errno); return r; } if (opts & STATIT_MODE) fprintf(stdout, "%o\n", sb.st_mode & MODE_MASK); if (opts & STATIT_UID) fprintf(stdout, "%d\n", (int) sb.st_uid); if (opts & STATIT_GID) fprintf(stdout, "%d\n", (int) sb.st_gid); if (opts & CMPIT_MODE && mode != (sb.st_mode & MODE_MASK)) { fprintf(stdout, "file=%s, mismatch=mode, expected=%o, got=%o\n", path, mode, sb.st_mode & MODE_MASK); r = 1; } if (opts & CMPIT_UID && uid != sb.st_uid) { fprintf(stdout, "file=%s, mismatch=uid, expected=%d, got=%d\n", path, (int) uid, (int) sb.st_uid); r = 1; } if (opts & CMPIT_GID && gid != sb.st_gid) { fprintf(stdout, "file=%s, mismatch=gid, expected=%d, got=%d\n", path, (int) gid, (int) sb.st_gid); r = 1; } return r; } int main(int argc, char *argv[]) { int c, opts, r; mode_t mode; uid_t uid; gid_t gid; char *name; opts = 0; mode = 0; uid = 0; gid = 0; while ((c = getopt(argc, argv, "G:gM:mU:uV")) != -1) { switch (c) { case 'G': opts |= CMPIT_GID; gid = strtol(optarg, NULL, 0); break; case 'g': opts |= STATIT_GID; break; case 'M': opts |= CMPIT_MODE; mode = strtol(optarg, NULL, 0); break; case 'm': opts |= STATIT_MODE; break; case 'U': opts |= CMPIT_UID; uid = strtol(optarg, NULL, 0); break; case 'u': opts |= STATIT_UID; break; case 'V': ++Verbose; break; default: /* usage(argv[0]); */ return EX_USAGE; } } argc -= optind; argv += optind; r = 0; for (c = 0; c < argc; c++) { name = argv[c]; if (name == NULL || *name == '\0') continue; r |= statit(name, opts, mode, uid, gid); } return r; }