OSDN Git Service

* Makefile.in (CYGWIN_BINS): Add getconf.
[pf3gnuchains/pf3gnuchains4x.git] / winsup / utils / getfacl.c
1 /* getfacl.c
2
3    Copyright 2000, 2001, 2002, 2003, 2004, 2009 Red Hat Inc.
4
5    Written by Corinna Vinschen <vinschen@redhat.com>
6
7 This file is part of Cygwin.
8
9 This software is a copyrighted work licensed under the terms of the
10 Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
11 details. */
12
13 #include <pwd.h>
14 #include <grp.h>
15 #include <stdio.h>
16 #include <unistd.h>
17 #include <getopt.h>
18 #include <sys/types.h>
19 #include <sys/acl.h>
20 #include <sys/stat.h>
21 #include <string.h>
22 #include <errno.h>
23
24 static const char version[] = "$Revision$";
25 static char *prog_name;
26
27 char *
28 permstr (mode_t perm)
29 {
30   static char pbuf[4];
31
32   pbuf[0] = (perm & S_IROTH) ? 'r' : '-';
33   pbuf[1] = (perm & S_IWOTH) ? 'w' : '-';
34   pbuf[2] = (perm & S_IXOTH) ? 'x' : '-';
35   pbuf[3] = '\0';
36   return pbuf;
37 }
38
39 const char *
40 username (uid_t uid)
41 {
42   static char ubuf[256];
43   struct passwd *pw;
44
45   if ((pw = getpwuid (uid)))
46     strcpy (ubuf, pw->pw_name);
47   else
48     sprintf (ubuf, "%lu <unknown>", (unsigned long)uid);
49   return ubuf;
50 }
51
52 const char *
53 groupname (gid_t gid)
54 {
55   static char gbuf[256];
56   struct group *gr;
57
58   if ((gr = getgrgid (gid)))
59     strcpy (gbuf, gr->gr_name);
60   else
61     sprintf (gbuf, "%lu <unknown>", (unsigned long)gid);
62   return gbuf;
63 }
64
65 static void
66 usage (FILE * stream)
67 {
68   fprintf (stream, "Usage: %s [-adn] FILE [FILE2...]\n"
69             "Display file and directory access control lists (ACLs).\n"
70             "\n"
71             "  -a, --all      display the filename, the owner, the group, and\n"
72             "                 the ACL of the file\n"
73             "  -d, --dir      display the filename, the owner, the group, and\n"
74             "                 the default ACL of the directory, if it exists\n"
75             "  -h, --help     output usage information and exit\n"
76             "  -n, --noname   display user and group IDs instead of names\n"
77             "  -v, --version  output version information and exit\n"
78             "\n"
79             "When multiple files are specified on the command line, a blank\n"
80             "line separates the ACLs for each file.\n", prog_name);
81   if (stream == stdout) 
82     {
83       fprintf (stream, ""
84             "For each argument that is a regular file, special file or\n"
85             "directory, getfacl displays the owner, the group, and the ACL.\n"
86             "For directories getfacl displays additionally the default ACL.\n"
87             "\n"
88             "With no options specified, getfacl displays the filename, the\n"
89             "owner, the group, and both the ACL and the default ACL, if it\n"
90             "exists.\n"
91             "\n"
92             "The format for ACL output is as follows:\n"
93             "     # file: filename\n"
94             "     # owner: name or uid\n"
95             "     # group: name or uid\n"
96             "     user::perm\n"
97             "     user:name or uid:perm\n"
98             "     group::perm\n"
99             "     group:name or gid:perm\n"
100             "     mask:perm\n"
101             "     other:perm\n"
102             "     default:user::perm\n"
103             "     default:user:name or uid:perm\n"
104             "     default:group::perm\n"
105             "     default:group:name or gid:perm\n"
106             "     default:mask:perm\n"
107             "     default:other:perm\n"
108             "\n");
109     }
110 }
111
112 struct option longopts[] = {
113   {"all", no_argument, NULL, 'a'},
114   {"dir", no_argument, NULL, 'd'},
115   {"help", no_argument, NULL, 'h'},
116   {"noname", no_argument, NULL, 'n'},
117   {"version", no_argument, NULL, 'v'},
118   {0, no_argument, NULL, 0}
119 };
120
121 static void
122 print_version ()
123 {
124   const char *v = strchr (version, ':');
125   int len;
126   if (!v)
127     {
128       v = "?";
129       len = 1;
130     }
131   else
132     {
133       v += 2;
134       len = strchr (v, ' ') - v;
135     }
136   printf ("\
137 getfacl (cygwin) %.*s\n\
138 ACL Utility\n\
139 Copyright (c) 2000, 2001, 2002, 2003, 2004, 2009 Red Hat, Inc.\n\
140 Compiled on %s\n\
141 ", len, v, __DATE__);
142 }
143
144 int
145 main (int argc, char **argv)
146 {
147   int c;
148   int ret = 0;
149   int aopt = 0;
150   int dopt = 0;
151   int nopt = 0;
152   struct stat st;
153   aclent_t acls[MAX_ACL_ENTRIES];
154
155   prog_name = strrchr (argv[0], '/');
156   if (prog_name == NULL)
157     prog_name = strrchr (argv[0], '\\');
158   if (prog_name == NULL)
159     prog_name = argv[0];
160   else
161     prog_name++;
162
163   while ((c = getopt_long (argc, argv, "adhnv", longopts, NULL)) != EOF)
164     switch (c)
165       {
166       case 'a':
167         aopt = 1;
168         break;
169       case 'd':
170         dopt = 1;
171         break;
172       case 'h':
173         usage (stdout);
174         return 0;
175       case 'n':
176         nopt = 1;
177         break;
178       case 'v':
179         print_version ();
180         return 0;
181       default:
182         usage (stderr);
183         return 1;
184       }
185   if (optind > argc - 1)
186     {
187       usage (stderr);
188       return 1;
189     }
190   for (; optind < argc; ++optind)
191     {
192       int i, num_acls;
193       if (stat (argv[optind], &st)
194           || (num_acls = acl (argv[optind], GETACL, MAX_ACL_ENTRIES, acls)) < 0)
195         {
196           fprintf (stderr, "%s: %s: %s\n",
197                    prog_name, argv[optind], strerror (errno));
198           ret = 2;
199           continue;
200         }
201       printf ("# file: %s\n", argv[optind]);
202       if (nopt)
203         {
204           printf ("# owner: %lu\n", (unsigned long)st.st_uid);
205           printf ("# group: %lu\n", (unsigned long)st.st_gid);
206         }
207       else
208         {
209           printf ("# owner: %s\n", username (st.st_uid));
210           printf ("# group: %s\n", groupname (st.st_gid));
211         }
212       for (i = 0; i < num_acls; ++i)
213         {
214           if (acls[i].a_type & ACL_DEFAULT)
215             {
216               if (aopt)
217                 continue;
218               printf ("default:");
219             }
220           else if (dopt)
221             continue;
222           switch (acls[i].a_type & ~ACL_DEFAULT)
223             {
224             case USER_OBJ:
225               printf ("user::");
226               break;
227             case USER:
228               if (nopt)
229                 printf ("user:%lu:", (unsigned long)acls[i].a_id);
230               else
231                 printf ("user:%s:", username (acls[i].a_id));
232               break;
233             case GROUP_OBJ:
234               printf ("group::");
235               break;
236             case GROUP:
237               if (nopt)
238                 printf ("group:%lu:", (unsigned long)acls[i].a_id);
239               else
240                 printf ("group:%s:", groupname (acls[i].a_id));
241               break;
242             case CLASS_OBJ:
243               printf ("mask:");
244               break;
245             case OTHER_OBJ:
246               printf ("other:");
247               break;
248             }
249           printf ("%s\n", permstr (acls[i].a_perm));
250         }
251       putchar ('\n');
252     }
253   return ret;
254 }