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