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