added and documented '-x' switch
[util-vserver.git] / util-vserver / src / showattr.c
1 // $Id$
2
3 // Copyright (C) 2003 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
4 // based on showattr.cc by Jacques Gelinas
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 as published by
8 // the Free Software Foundation; either version 2, or (at your option)
9 // any later version.
10 //  
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15 //  
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
20 #ifdef HAVE_CONFIG_H
21 #  include <config.h>
22 #endif
23
24 #include "fstool.h"
25 #include "util.h"
26
27 #include <lib/fmt.h>
28 #include <lib/vserver.h>
29 #include <lib/vserver-internal.h>
30
31 #include <stdio.h>
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <fcntl.h>
35
36 struct option const
37 CMDLINE_OPTIONS[] = {
38   { "help",     no_argument,  0, CMD_HELP },
39   { "version",  no_argument,  0, CMD_VERSION },
40 #ifdef VC_ENABLE_API_LEGACY
41   { "legacy",    no_argument, 0, CMD_LEGACY },
42 #endif
43   { 0,0,0,0 }
44 };
45
46 char const              CMDLINE_OPTIONS_SHORT[] = "Radx";
47
48 void
49 showHelp(int fd, char const *cmd, int res)
50 {
51   WRITE_MSG(fd, "Usage:  ");
52   WRITE_STR(fd, cmd);
53   WRITE_MSG(fd,
54             " [-Radx] [--] <file>*\n\n"
55             " Options:\n"
56             "   -R  ...  recurse through directories\n"
57             "   -a  ...  display files starting with '.' also\n"
58             "   -d  ...  list directories like other files instead of listing\n"
59             "            their content\n"
60             "   -x  ...  do not cross filesystems\n\n"
61             "Please report bugs to " PACKAGE_BUGREPORT "\n");
62   exit(res);
63 }
64
65 void
66 showVersion()
67 {
68   WRITE_MSG(1,
69             "showattr " VERSION " -- shows vserver specific file attributes\n"
70             "This program is part of " PACKAGE_STRING "\n\n"
71             "Copyright (C) 2004 Enrico Scholz\n"
72             VERSION_COPYRIGHT_DISCLAIMER);
73   exit(0);
74 }
75
76 void
77 fixupParams(struct Arguments UNUSED * args, int UNUSED argc)
78 {
79 }
80
81 static bool
82 getFlags(char const *name, struct stat const *exp_st, long *flags)
83 {
84   int           fd = open(name, O_RDONLY);
85   int           rc;
86   
87   if (fd==-1) {
88     perror("open()");
89     return false;
90   }
91
92   if (exp_st)
93     checkForRace(fd, name, exp_st);
94
95   rc = vc_X_get_ext2flags(fd, flags);
96   *flags &= VC_IMMUTABLE_ALL;
97
98   if (rc==-1)
99     perror("vc_X_get_ext2flags()");
100
101   close(fd);
102   return rc!=-1;
103 }
104
105 static void
106 writePadded(long num)
107 {
108   char          buf[sizeof(num)*2+1];
109   size_t        l = utilvserver_fmt_xulong(buf, num);
110
111   if (l<8) write(1, "00000000", 8-l);
112   write(1, buf, l);
113 }
114
115 #ifdef VC_ENABLE_API_LEGACY
116 static bool
117 handleFileLegacy(char const *name, char const *display_name,
118                  struct stat const *exp_st)
119 {
120   long          flags;
121
122   if (S_ISLNK(exp_st->st_mode)) {
123     write(1, display_name, strlen(display_name));
124     write(1, "  -\n", 2);
125     return true;
126   }
127
128   if (!getFlags(name, exp_st, &flags)) {
129     perror(display_name);
130     return false;
131   }
132
133   write(1, display_name, strlen(display_name));
134   write(1, "\t", 1);
135   writePadded(flags);
136   write(1, "\n", 1);
137
138   return true;
139 }
140 #endif
141
142 bool
143 handleFile(char const *name, char const *display_name,
144            struct stat const *exp_st)
145 {
146   bool          res = true;
147 #ifdef VC_ENABLE_API_LEGACY
148   if (global_args->is_legacy)
149     return handleFileLegacy(name, display_name, exp_st);
150 #endif
151   
152   if (S_ISLNK(exp_st->st_mode)) {
153     write(1, "--------", 8);
154   }
155   else {
156     long                flags;
157
158     if (getFlags(name, exp_st, &flags))
159       writePadded(flags);
160     else {
161       write(1, "ERR     ", 8);
162       res = false;
163     }
164   }
165
166   write(1, "  ", 2);
167   write(1, display_name, strlen(display_name));
168   write(1, "\n", 1);
169
170   return res;
171 }