rewrote completely
[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[] = "Rad";
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             " [-Rad] [--] <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             "Please report bugs to " PACKAGE_BUGREPORT "\n");
61   exit(res);
62 }
63
64 void
65 showVersion()
66 {
67   WRITE_MSG(1,
68             "showattr " VERSION " -- shows vserver specific file attributes\n"
69             "This program is part of " PACKAGE_STRING "\n\n"
70             "Copyright (C) 2004 Enrico Scholz\n"
71             VERSION_COPYRIGHT_DISCLAIMER);
72   exit(0);
73 }
74
75 void
76 checkParams(struct Arguments const UNUSED * args, int UNUSED argc)
77 {
78 }
79
80 static bool
81 getFlags(char const *name, struct stat const *exp_st, long *flags)
82 {
83   int           fd = open(name, O_RDONLY);
84   int           rc;
85   
86   if (fd==-1) {
87     perror("open()");
88     return false;
89   }
90
91   if (exp_st)
92     checkForRace(fd, name, exp_st);
93
94   rc = vc_X_get_ext2flags(fd, flags);
95   *flags &= VC_IMMUTABLE_ALL;
96
97   if (rc==-1)
98     perror("vc_X_get_ext2flags()");
99
100   close(fd);
101   return rc!=-1;
102 }
103
104 static void
105 writePadded(long num)
106 {
107   char          buf[sizeof(num)*2+1];
108   size_t        l = utilvserver_fmt_xulong(buf, num);
109
110   if (l<8) write(1, "00000000", 8-l);
111   write(1, buf, l);
112 }
113
114 #ifdef VC_ENABLE_API_LEGACY
115 static bool
116 handleFileLegacy(char const *name, char const *display_name,
117                  struct stat const *exp_st)
118 {
119   long          flags;
120
121   if (S_ISLNK(exp_st->st_mode)) {
122     write(1, display_name, strlen(display_name));
123     write(1, "  -\n", 2);
124     return true;
125   }
126
127   if (!getFlags(name, exp_st, &flags)) {
128     perror(display_name);
129     return false;
130   }
131
132   write(1, display_name, strlen(display_name));
133   write(1, "\t", 1);
134   writePadded(flags);
135   write(1, "\n", 1);
136
137   return true;
138 }
139 #endif
140
141 bool
142 handleFile(char const *name, char const *display_name,
143            struct stat const *exp_st)
144 {
145   bool          res = true;
146 #ifdef VC_ENABLE_API_LEGACY
147   if (global_args->is_legacy)
148     return handleFileLegacy(name, display_name, exp_st);
149 #endif
150   
151   if (S_ISLNK(exp_st->st_mode)) {
152     write(1, "--------", 8);
153   }
154   else {
155     long                flags;
156
157     if (getFlags(name, exp_st, &flags))
158       writePadded(flags);
159     else {
160       write(1, "ERR     ", 8);
161       res = false;
162     }
163   }
164
165   write(1, "  ", 2);
166   write(1, display_name, strlen(display_name));
167   write(1, "\n", 1);
168
169   return res;
170 }