Whamcloud - gitweb
LU-8055 ldev: File system label filtering
[fs/lustre-release.git] / lustre / tests / checkstat.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
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.
9  *
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).
15  *
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.sun.com/software/products/lustre/docs/GPLv2.pdf
19  *
20  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21  * CA 95054 USA or visit www.sun.com if you need additional information or
22  * have any questions.
23  *
24  * GPL HEADER END
25  */
26 /*
27  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
28  * Use is subject to license terms.
29  *
30  * Copyright (c) 2011, Intel Corporation.
31  */
32 /*
33  * Test program to compare the attributes of a files to verify that it
34  * desired file attributes are present.  This file predates availability
35  * of the stat(3) utility and is deprecated.  Either test(3) ([ ]) or
36  * stat(3) should be used in all new tests.
37  *
38  * This file is part of Lustre, http://www.lustre.org/
39  * Lustre is a trademark of Sun Microsystems, Inc.
40  */
41
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <sys/types.h>
45 #include <sys/stat.h>
46 #include <unistd.h>
47 #include <errno.h>
48 #include <string.h>
49 #include <pwd.h>
50 #include <grp.h>
51
52 void
53 usage (char *argv0, int help)
54 {
55         char *progname = strrchr(argv0, '/');
56
57         if (progname == NULL)
58                 progname = argv0;
59
60         fprintf (help ? stdout : stderr,
61                  "Usage: %s [flags] file[s]\n",
62                  progname);
63
64         if (!help)
65         {
66                 fprintf (stderr, "   or try '-h' for help\n");
67                 exit (1);
68         }
69
70         printf ("Check given files have...\n");
71         printf (" -p    permission       file must have required permissions\n");
72         printf (" -t    dir|file|link    file must be of the specified type\n");
73         printf (" -l    link_name        file must be a link to the given name\n");
74         printf (" -s    size             file must have the given size\n");
75         printf (" -u    user             file must be owned by given user\n");
76         printf (" -g    group            file must be owned by given group\n");
77         printf (" -f                     follow symlinks\n");
78         printf (" -a                     file must be absent\n");
79         printf (" -v                     increase verbosity\n");
80         printf (" -h                     print help\n");
81         printf (" Exit status is 0 on success, 1 on failure\n");
82 }
83
84 int
85 main (int argc, char **argv)
86 {
87         int           c;
88         struct stat64 buf;
89         int           perms = -1;
90         uid_t         uid = (uid_t)-1;
91         gid_t         gid = (gid_t)-1;
92         char         *type = NULL;
93         long          absent = 0;
94         char         *checklink = NULL;
95         int           verbose = 0;
96         long long     size = -1;
97         int           follow = 0;
98         char         *term;
99
100         while ((c = getopt (argc, argv, "p:t:l:s:u:g:avfh")) != -1)
101                 switch (c)
102                 {
103                 case 'p':
104                         perms = (int)strtol (optarg, &term, 0);
105                         if (term == optarg)
106                         {
107                                 fprintf (stderr, "Can't parse permission %s\n", optarg);
108                                 return (1);
109                         }
110                         break;
111
112                 case 'l':
113                         checklink = optarg;
114                         break;
115
116                 case 's':
117                         size = strtoll (optarg, &term, 0);
118                         if (term == optarg)
119                         {
120                                 fprintf (stderr, "Can't parse size %s\n", optarg);
121                                 return (1);
122                         }
123                         break;
124
125                 case 'u':
126                         if (*optarg == '#')
127                         {
128                                 uid = (uid_t)strtol (optarg + 1, &term, 0);
129                                 if (term == optarg + 1)
130                                 {
131                                         fprintf (stderr, "Can't parse numeric uid %s\n", optarg);
132                                         return (1);
133                                 }
134                         } else {
135                                 struct passwd *pw = getpwnam (optarg);
136
137                                 if (pw == NULL)
138                                 {
139                                         fprintf (stderr, "Can't find user %s\n", optarg);
140                                         return (1);
141                                 }
142                                 uid = pw->pw_uid;
143                         }
144                         break;
145
146                 case 'g':
147                         if (*optarg == '#')
148                         {
149                                 gid = (gid_t)strtol (optarg + 1, &term, 0);
150                                 if (term == optarg + 1)
151                                 {
152                                         fprintf (stderr, "Can't parse numeric gid %s\n", optarg);
153                                         return (1);
154                                 }
155                         } else {
156                                 struct group *gr = getgrnam (optarg);
157
158                                 if (gr == NULL)
159                                 {
160                                         fprintf (stderr, "Can't find group %s\n", optarg);
161                                         return (1);
162                                 }
163                                 uid = gr->gr_gid;
164                         }
165                         break;
166
167                 case 't':
168                         type = optarg;
169                         break;
170
171                 case 'a':
172                         absent = 1;
173                         break;
174
175                 case 'v':
176                         verbose++;
177                         break;
178
179                 case 'f':
180                         follow++;
181                         break;
182
183                 case 'h':
184                         usage (argv[0], 1);
185                         return (0);
186
187                 default:
188                         usage (argv[0], 0);
189                 }
190
191         if (optind == argc)
192                 usage (argv[0], 0);
193
194         do
195         {
196                 char *fname = argv[optind];
197                 int rc = follow ? stat64 (fname, &buf) : lstat64 (fname, &buf);
198
199                 if (rc != 0)
200                 {
201                         if (!(absent && errno == ENOENT))
202                         {
203                                 if (verbose)
204                                         printf ("Can't %sstat %s: %s\n",
205                                                 follow ? "" : "l",
206                                                 fname, strerror (errno));
207                                 return (1);
208                         }
209
210                         if (verbose)
211                                 printf ("%s: absent OK\n", fname);
212                         continue;
213                 }
214
215                 if (absent)
216                 {
217                         if (verbose)
218                                 printf ("%s exists\n", fname);
219                         return (1);
220                 }
221
222                 if (type != NULL)
223                 {
224                         if (!strcmp (type, "d") ||
225                             !strcmp (type, "dir"))
226                         {
227                                 if (!S_ISDIR (buf.st_mode))
228                                 {
229                                         if (verbose)
230                                                 printf ("%s is not a directory\n",
231                                                          fname);
232                                         return (1);
233                                 }
234                         }
235                         else if (!strcmp (type, "f") ||
236                                  !strcmp (type, "file"))
237                         {
238                                 if (!S_ISREG (buf.st_mode))
239                                 {
240                                         if (verbose)
241                                                 printf ("%s is not a regular file\n",
242                                                         fname);
243                                         return (1);
244                                 }
245                         }
246                         else if (!strcmp (type, "l") ||
247                                  !strcmp (type, "link"))
248                         {
249                                 if (!S_ISLNK (buf.st_mode))
250                                 {
251                                         if (verbose)
252                                                 printf ("%s is not a link\n",
253                                                         fname);
254                                         return (1);
255                                 }
256                         }
257                         else
258                         {
259                                 fprintf (stderr, "Can't parse file type %s\n",
260                                          type);
261                                 return (1);
262                         }
263
264                         if (verbose)
265                                 printf ("%s has type %s OK\n", fname, type);
266                 }
267
268                 if (perms != -1)
269                 {
270                         if ((buf.st_mode & ~S_IFMT) != perms)
271                         {
272                                 if (verbose)
273                                         printf ("%s has perms 0%o, not 0%o\n",
274                                                 fname, (buf.st_mode & ~S_IFMT),
275                                                 perms);
276                                 return (1);
277                         }
278
279                         if (verbose)
280                                 printf ("%s has perms 0%o OK\n",
281                                         fname, perms);
282                 }
283
284                 if (size != -1) {
285                         if (buf.st_size != size) {
286                                 if (verbose)
287                                         printf("%s has size %lld, not %lld\n",
288                                                fname, (long long)buf.st_size,
289                                                size);
290                                 return 1;
291                         }
292
293                         if (verbose)
294                                 printf("%s has size %lld OK\n", fname, size);
295                 }
296
297                 if (checklink != NULL)
298                 {
299                         static char lname[4<<10];
300
301                         rc = readlink (fname, lname, sizeof (lname) - 1);
302
303                         if (rc < 0)
304                         {
305                                 if (verbose)
306                                         printf ("%s: can't read link: %s\n",
307                                                 fname, strerror (errno));
308                                 return (1);
309                         }
310
311                         lname[rc] = 0;
312                         if (strcmp (checklink, lname))
313                         {
314                                 if (verbose)
315                                         printf ("%s is a link to %s and not %s\n",
316                                                 fname, lname, checklink);
317                                 return (1);
318                         }
319
320                         if (verbose)
321                                 printf ("%s links to %s OK\n", fname, checklink);
322                 }
323
324                 if (uid != (uid_t)-1)
325                 {
326                         if (buf.st_uid != uid)
327                         {
328                                 if (verbose)
329                                         printf ("%s is owned by user #%ld and not #%ld\n",
330                                                 fname, (long)buf.st_uid, (long)uid);
331                                 return (1);
332                         }
333
334                         if (verbose)
335                                 printf ("%s is owned by user #%ld OK\n",
336                                         fname, (long)uid);
337                 }
338
339                 if (gid != (gid_t)-1)
340                 {
341                         if (buf.st_gid != gid)
342                         {
343                                 if (verbose)
344                                         printf ("%s is owned by group #%ld and not #%ld\n",
345                                                 fname, (long)buf.st_gid, (long)gid);
346                                 return (1);
347                         }
348
349                         if (verbose)
350                                 printf ("%s is owned by group #%ld OK\n",
351                                         fname, (long)gid);
352                 }
353         } while (++optind < argc);
354
355         return (0);
356 }