4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.gnu.org/licenses/gpl-2.0.html
23 * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Use is subject to license terms.
26 * Copyright (c) 2011, Intel Corporation.
29 * Test program to compare the attributes of a files to verify that it
30 * desired file attributes are present. This file predates availability
31 * of the stat(3) utility and is deprecated. Either test(3) ([ ]) or
32 * stat(3) should be used in all new tests.
34 * This file is part of Lustre, http://www.lustre.org/
39 #include <sys/types.h>
48 usage(char *argv0, int help)
50 char *progname = strrchr(argv0, '/');
55 fprintf(help ? stdout : stderr,
56 "Usage: %s [flags] file[s]\n",
60 fprintf(stderr, " or try '-h' for help\n");
64 printf("Check given files have...\n");
65 printf(" -p permission file must have required permissions\n");
66 printf(" -t dir|file|link file must be of the specified type\n");
67 printf(" -l link_name file must be a link to the given name\n");
68 printf(" -s size file must have the given size\n");
69 printf(" -u user file must be owned by given user\n");
70 printf(" -g group file must be owned by given group\n");
71 printf(" -f follow symlinks\n");
72 printf(" -a file must be absent\n");
73 printf(" -v increase verbosity\n");
74 printf(" -h print help\n");
75 printf(" Exit status is 0 on success, 1 on failure\n");
78 /* using realpath() implies the paths must be resolved/exist
79 * so this will fail for dangling links
81 int check_canonical(char *lname, char *checklink, int verbose)
84 char *checklink_canon;
86 lname_canon = realpath(lname, NULL);
87 if (lname_canon == NULL) {
89 printf("%s: can't canonicalize: %s\n",
90 lname, strerror(errno));
94 checklink_canon = realpath(checklink, NULL);
95 if (checklink_canon == NULL) {
97 printf("%s: can't canonicalize: %s\n",
98 checklink, strerror(errno));
102 if (strcmp(checklink_canon, lname_canon)) {
104 free(checklink_canon);
108 free(checklink_canon);
113 main(int argc, char **argv)
118 uid_t uid = (uid_t)-1;
119 gid_t gid = (gid_t)-1;
122 char *checklink = NULL;
128 while ((c = getopt(argc, argv, "p:t:l:s:u:g:avfh")) != -1)
131 perms = (int)strtol(optarg, &term, 0);
132 if (term == optarg) {
133 fprintf(stderr, "Can't parse permission %s\n",
144 size = strtoll(optarg, &term, 0);
145 if (term == optarg) {
146 fprintf(stderr, "Can't parse size %s\n",
153 if (*optarg == '#') {
154 uid = (uid_t)strtol(optarg + 1, &term, 0);
156 if (term == optarg + 1) {
158 "Can't parse numeric uid %s\n",
163 struct passwd *pw = getpwnam(optarg);
166 fprintf(stderr, "Can't find user %s\n",
175 if (*optarg == '#') {
176 gid = (gid_t)strtol(optarg + 1, &term, 0);
178 if (term == optarg + 1) {
180 "Can't parse numeric gid %s\n",
185 struct group *gr = getgrnam(optarg);
189 "Can't find group %s\n",
225 char *fname = argv[optind];
226 int rc = follow ? stat64(fname, &buf) : lstat64(fname, &buf);
229 if (!(absent && errno == ENOENT)) {
231 printf("Can't %sstat %s: %s\n",
233 fname, strerror(errno));
238 printf("%s: absent OK\n", fname);
244 printf("%s exists\n", fname);
249 if (!strcmp(type, "d") ||
250 !strcmp(type, "dir")) {
251 if (!S_ISDIR(buf.st_mode)) {
253 printf("%s is not a directory\n",
257 } else if (!strcmp(type, "f") ||
258 !strcmp(type, "file")) {
259 if (!S_ISREG(buf.st_mode)) {
261 printf("%s is not a regular file\n",
265 } else if (!strcmp(type, "l") ||
266 !strcmp(type, "link")) {
267 if (!S_ISLNK(buf.st_mode)) {
269 printf("%s is not a link\n",
274 fprintf(stderr, "Can't parse file type %s\n",
280 printf("%s has type %s OK\n", fname, type);
284 if ((buf.st_mode & ~S_IFMT) != perms) {
286 printf("%s has perms 0%o, not 0%o\n",
287 fname, (buf.st_mode & ~S_IFMT),
293 printf("%s has perms 0%o OK\n",
298 if (buf.st_size != size) {
300 printf("%s has size %lld, not %lld\n",
301 fname, (long long)buf.st_size,
307 printf("%s has size %lld OK\n", fname, size);
311 static char lname[4 << 10];
313 rc = readlink(fname, lname, sizeof(lname) - 1);
317 printf("%s: can't read link: %s\n",
318 fname, strerror(errno));
324 /* just in case, try to also match the canonicalized
327 if (strcmp(checklink, lname) &&
328 check_canonical(lname, checklink, verbose)) {
330 printf("%s is a link to %s and not %s\n",
331 fname, lname, checklink);
336 printf("%s links to %s OK\n", fname, checklink);
339 if (uid != (uid_t)-1) {
340 if (buf.st_uid != uid) {
342 printf("%s is owned by user #%ld and not #%ld\n",
343 fname, (long)buf.st_uid, (long)uid);
348 printf("%s is owned by user #%ld OK\n",
352 if (gid != (gid_t)-1) {
353 if (buf.st_gid != gid) {
355 printf("%s is owned by group #%ld and not #%ld\n",
356 fname, (long)buf.st_gid, (long)gid);
361 printf("%s is owned by group #%ld OK\n",
364 } while (++optind < argc);