PL3118 and PL3131 fix: provide new option "--barrier" to showattr and
[util-vserver.git] / src / showattr.c
1 // $Id: showattr.c,v 1.1.4.1 2003/11/18 22:31:10 ensc Exp $
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 #include "compat.h"
24
25 #include <stdio.h>
26 #include <errno.h>
27 #include <string.h>
28 #include <unistd.h>
29 #include <fcntl.h>
30 #include <sys/ioctl.h>
31
32 #include "ext2fs.h"
33
34
35 // Patch to help compile this utility on unpatched kernel source
36 #ifndef EXT2_IUNLINK_FL
37 /* Set both bits for backward compatibility */
38 #define EXT2_IUNLINK_FL 0x08008000
39 #endif
40
41 #ifndef EXT2_BARRIER_FL
42 #define EXT2_BARRIER_FL 0x04000000
43 #endif
44
45 /*
46         Get the extended attributes of a file
47 */
48 static int getext2flags (const char *fname, long *flags)
49 {
50         int ret = -1;
51         int fd = open (fname,O_RDONLY);
52         if (fd == -1){
53                 fprintf (stderr,"Can't open file %s (%s)\n",fname,strerror(errno));
54         }else{
55                 *flags = 0;
56                 ret = ioctl (fd,EXT2_IOC_GETFLAGS,flags);
57                 close (fd);
58                 if (ret == -1){
59                         fprintf (stderr,"Can't get ext2 flags on file %s (%s)\n"
60                                 ,fname,strerror(errno));
61                 }
62         }
63         return ret;
64 }
65
66 /*
67         Set the extended attributes of a file
68 */
69 static int setext2flags (const char *fname, long flags)
70 {
71         int ret = -1;
72         int fd = open (fname,O_RDONLY);
73         if (fd == -1){
74                 fprintf (stderr,"Can't open file %s (%s)\n",fname,strerror(errno));
75         }else{
76                 ret = ioctl (fd,EXT2_IOC_SETFLAGS,&flags);
77                 close (fd);
78                 if (ret == -1){
79                         fprintf (stderr,"Can't set ext2 flags on file %s (%s)\n"
80                                 ,fname,strerror(errno));
81                 }
82         }
83         return ret;
84 }
85
86
87 int main (int argc, char *argv[])
88 {
89         int ret = -1;
90         if (argc <= 1){
91                 fprintf (stderr
92                         ,"showattr file ...\n"
93                          "\n"
94                          "Presents extended file attribute.\n"
95                          "\n"
96                          "setattr --immutable --immulink file ...\n"
97                          "\n"
98                          "Sets the extended file attributes.\n"
99                          "\n"
100                          "These utilities exist as an interim until lsattr and\n"
101                          "chattr are updated.\n"
102                         );
103         }else if (strstr(argv[0],"showattr")!=NULL){
104                 int i;
105                 for (i=1; i<argc; i++){
106                         long flags;
107                         ret = getext2flags (argv[i],&flags);
108                         if (ret == -1){
109                                 break;
110                         }else{
111                                 printf ("%s\t%08lx\n",argv[i],flags);
112                         }
113                 }
114         }else if (strstr(argv[0],"setattr")!=NULL){
115                 long flags, add_flags = 0, remove_flags = 0;
116                 int  i;
117                 ret = 0;
118                 for (i=1; i<argc; i++){
119                         const char *arg = argv[i];
120                         if (strncmp(arg,"--",2)==0){
121                                 if (strcmp(arg,"--immutable")==0){
122                                         add_flags |= EXT2_IMMUTABLE_FL;
123                                 }else if (strcmp(arg,"--!immutable")==0 || strcmp(arg,"--~immutable")==0){
124                                         remove_flags |= EXT2_IMMUTABLE_FL;
125                                 }else if (strcmp(arg,"--immulink")==0){
126                                         add_flags |= EXT2_IUNLINK_FL;
127                                 }else if (strcmp(arg,"--!immulink")==0 || strcmp(arg,"--~immulink")==0){
128                                         remove_flags |= EXT2_IUNLINK_FL;
129                                 }else if (strcmp(arg,"--barrier")==0){
130                                         add_flags |= EXT2_BARRIER_FL;
131                                 }else if (strcmp(arg,"--!barrier")==0 || strcmp(arg,"--~barrier")==0){
132                                         remove_flags |= EXT2_BARRIER_FL;
133                                 }else{
134                                         fprintf (stderr,"Invalid option %s\n",arg);
135                                         ret = -1;
136                                         break;
137                                 }
138                         }else{
139                                 ret = getext2flags (arg,&flags);
140                                 if (ret == -1){
141                                         break;
142                                 }
143                                 flags |= add_flags;
144                                 flags &= ~remove_flags;
145                                 ret = setext2flags (arg,flags);
146                                 if (ret == -1){
147                                         break;
148                                 }
149                         }
150                 }
151         }
152         return ret;
153 }
154