updated/enhanced for new API
[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 #include <ctype.h>
36
37 struct option const
38 CMDLINE_OPTIONS[] = {
39   { "help",     no_argument,  0, CMD_HELP },
40   { "version",  no_argument,  0, CMD_VERSION },
41 #ifdef VC_ENABLE_API_LEGACY
42   { "legacy",    no_argument, 0, CMD_LEGACY },
43 #endif
44   { 0,0,0,0 }
45 };
46
47 char const              CMDLINE_OPTIONS_SHORT[] = "Radx";
48
49 void
50 showHelp(int fd, char const *cmd, int res)
51 {
52   WRITE_MSG(fd, "Usage:  ");
53   WRITE_STR(fd, cmd);
54   WRITE_MSG(fd,
55             " [-Radx] [--] <file>*\n\n"
56             " Options:\n"
57             "   -R  ...  recurse through directories\n"
58             "   -a  ...  display files starting with '.' also\n"
59             "   -d  ...  list directories like other files instead of listing\n"
60             "            their content\n"
61             "   -x  ...  do not cross filesystems\n\n"
62             "Please report bugs to " PACKAGE_BUGREPORT "\n");
63   exit(res);
64 }
65
66 void
67 showVersion()
68 {
69   WRITE_MSG(1,
70             "showattr " VERSION " -- shows vserver specific file attributes\n"
71             "This program is part of " PACKAGE_STRING "\n\n"
72             "Copyright (C) 2004 Enrico Scholz\n"
73             VERSION_COPYRIGHT_DISCLAIMER);
74   exit(0);
75 }
76
77 void
78 fixupParams(struct Arguments UNUSED * args, int UNUSED argc)
79 {
80 }
81
82 static bool
83 getFlags(char const *name, struct stat const *exp_st, uint32_t *flags, uint32_t *mask)
84 {
85   xid_t         xid;
86   *mask = ~0;
87   
88   if (vc_get_iattr_compat(name, exp_st->st_dev, exp_st->st_ino,
89                           &xid, flags, mask)==-1) {
90     perror("vc_get_iattr_compat()");
91     return false;
92   }
93
94   return true;
95 }
96
97 bool
98 handleFile(char const *name, char const *display_name,
99            struct stat const *exp_st)
100 {
101   bool          res = true;
102   char          buf[40];
103   char          *ptr = buf;
104
105   memset(buf, ' ', sizeof buf);
106   if (!(S_ISREG(exp_st->st_mode) || S_ISDIR(exp_st->st_mode))) {
107     memcpy(ptr, "------", 6);
108   }
109   else {
110     uint32_t            flags;
111     uint32_t            mask;
112
113     if (getFlags(name, exp_st, &flags, &mask)) {
114         //                                   1       1       0       0
115         //                            fedcba9876543210fedcba9876543210
116       static char const MARKER[33] = ".......x......ib.............hwa";
117       int               i;
118       uint32_t          used_flags = (VC_IATTR_XID|VC_IATTR_ADMIN|
119                                       VC_IATTR_WATCH|VC_IATTR_HIDE|
120                                       VC_IATTR_BARRIER|VC_IATTR_IUNLINK);
121
122       for (i=0; i<32; ++i) {
123         if (used_flags & 1) {
124           if (!   (mask  & 1) ) *ptr++ = '-';
125           else if (flags & 1)   *ptr++ = toupper(MARKER[31-i]);
126           else                  *ptr++ = MARKER[31-i];
127         }
128
129         used_flags >>= 1;
130         flags      >>= 1;
131         mask       >>= 1;
132       }
133     }      
134     else {
135       memcpy(buf, "ERR   ", 6);
136       res = false;
137     }
138   }
139
140   write(1, buf, 8);
141   write(1, display_name, strlen(display_name));
142   write(1, "\n", 1);
143
144   return res;
145 }