/*
* 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 <stdio.h>
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;
}
syntax highlighted by Code2HTML, v. 0.9.1