2 * Copyright 2013-2014, Sine Nomine Associates
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
17 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #include <afsconfig.h>
30 #include <afs/param.h>
34 #include <afs/afsint.h>
35 #include <rx/rx_queue.h>
39 #include "vnode.h" /* for vSmall, vLarge */
43 #include "AFS_component_version_number.c"
46 static const char *progname
= "volscan";
48 /* All columns names as a single string. */
50 static char *ColumnNames
= VOLSCAN_COLUMNS
;
52 #undef VOLSCAN_COLUMNS
54 /* Command line options */
69 * Process command line options and start scanning
71 * @param[in] as command syntax object
72 * @param[in] arock opaque object; not used
79 VolScan(struct cmd_syndesc
*as
, void *arock
)
83 VolumeId volumeId
= 0;
84 char *partNameOrId
= NULL
;
86 struct VolInfoOpt
*opt
;
88 code
= volinfo_Init(progname
);
92 code
= volinfo_Options(&opt
);
97 opt
->dumpInfo
= 0; /* volscan mode */
98 if (as
->parms
[P_CHECKOUT
].items
) {
101 if ((ti
= as
->parms
[P_PART
].items
)) {
102 partNameOrId
= ti
->data
;
104 if ((ti
= as
->parms
[P_VOLUMEID
].items
)) {
105 volumeId
= strtoul(ti
->data
, NULL
, 10);
107 if (as
->parms
[P_NOHEADING
].items
) {
108 opt
->printHeading
= 0;
110 opt
->printHeading
= 1;
112 if (as
->parms
[P_NOMAGIC
].items
) {
115 if ((ti
= as
->parms
[P_DELIM
].items
)) {
116 strncpy(opt
->columnDelim
, ti
->data
, 15);
117 opt
->columnDelim
[15] = '\0';
120 /* Limit types of volumes to scan. */
121 if (!as
->parms
[P_TYPE
].items
) {
122 opt
->scanVolType
= (SCAN_RW
| SCAN_RO
| SCAN_BK
);
124 opt
->scanVolType
= 0;
125 for (ti
= as
->parms
[P_TYPE
].items
; ti
; ti
= ti
->next
) {
126 if (strcmp(ti
->data
, "rw") == 0) {
127 opt
->scanVolType
|= SCAN_RW
;
128 } else if (strcmp(ti
->data
, "ro") == 0) {
129 opt
->scanVolType
|= SCAN_RO
;
130 } else if (strcmp(ti
->data
, "bk") == 0) {
131 opt
->scanVolType
|= SCAN_BK
;
133 fprintf(stderr
, "%s: Unknown -type value: %s\n", progname
,
140 /* Limit types of vnodes to find (plus access entries) */
141 if (!as
->parms
[P_FIND
].items
) {
142 opt
->findVnType
= (FIND_FILE
| FIND_DIR
| FIND_MOUNT
| FIND_SYMLINK
);
145 for (ti
= as
->parms
[P_FIND
].items
; ti
; ti
= ti
->next
) {
146 if (strcmp(ti
->data
, "file") == 0) {
147 opt
->findVnType
|= FIND_FILE
;
148 } else if (strcmp(ti
->data
, "dir") == 0) {
149 opt
->findVnType
|= FIND_DIR
;
150 } else if (strcmp(ti
->data
, "mount") == 0) {
151 opt
->findVnType
|= FIND_MOUNT
;
152 } else if (strcmp(ti
->data
, "symlink") == 0) {
153 opt
->findVnType
|= FIND_SYMLINK
;
154 } else if (strcmp(ti
->data
, "acl") == 0) {
155 opt
->findVnType
|= FIND_ACL
;
157 fprintf(stderr
, "%s: Unknown -find value: %s\n", progname
,
164 /* Show vnodes matching one of the mode masks */
165 for (i
= 0, ti
= as
->parms
[P_MASK
].items
; ti
; i
++, ti
= ti
->next
) {
166 if (i
>= (sizeof(opt
->modeMask
) / sizeof(*opt
->modeMask
))) {
167 fprintf(stderr
, "Too many -mask values\n");
170 opt
->modeMask
[i
] = strtol(ti
->data
, NULL
, 8);
171 if (!opt
->modeMask
[i
]) {
172 fprintf(stderr
, "Invalid -mask value: %s\n", ti
->data
);
177 /* Set which columns to be printed. */
178 if (!as
->parms
[P_OUTPUT
].items
) {
179 volinfo_AddOutputColumn("host");
180 volinfo_AddOutputColumn("desc");
181 volinfo_AddOutputColumn("fid");
182 volinfo_AddOutputColumn("dv");
183 if (opt
->findVnType
& FIND_ACL
) {
184 volinfo_AddOutputColumn("aid");
185 volinfo_AddOutputColumn("arights");
187 volinfo_AddOutputColumn("path");
189 for (ti
= as
->parms
[P_OUTPUT
].items
; ti
; ti
= ti
->next
) {
190 if (volinfo_AddOutputColumn(ti
->data
) != 0) {;
191 fprintf(stderr
, "%s: Unknown -output value: %s\n", progname
,
198 if (opt
->findVnType
& FIND_DIR
) {
199 volinfo_AddVnodeHandler(vLarge
, volinfo_PrintVnodeDetails
, NULL
);
201 if (opt
->findVnType
& (FIND_FILE
| FIND_MOUNT
| FIND_SYMLINK
)) {
202 volinfo_AddVnodeHandler(vSmall
, volinfo_PrintVnodeDetails
, NULL
);
204 if (opt
->findVnType
& FIND_ACL
) {
205 volinfo_AddVnodeHandler(vLarge
, volinfo_ScanAcl
, NULL
);
208 code
= volinfo_ScanPartitions(opt
, partNameOrId
, volumeId
);
215 * volscan program entry
218 main(int argc
, char **argv
)
221 struct cmd_syndesc
*ts
;
223 ts
= cmd_CreateSyntax(NULL
, VolScan
, NULL
,
224 "Print volume vnode information");
226 cmd_AddParm(ts
, "-checkout", CMD_FLAG
, CMD_OPTIONAL
,
227 "Checkout volumes from running fileserver");
228 cmd_AddParm(ts
, "-partition", CMD_SINGLE
, CMD_OPTIONAL
,
229 "AFS partition name or id (default current partition)");
230 cmd_AddParm(ts
, "-volumeid", CMD_SINGLE
, CMD_OPTIONAL
,
231 "Volume id (-partition required)");
232 cmd_AddParm(ts
, "-type", CMD_LIST
, CMD_OPTIONAL
,
233 "Volume types: rw, ro, bk");
234 cmd_AddParm(ts
, "-find", CMD_LIST
, CMD_OPTIONAL
,
235 "Objects to find: file, dir, mount, symlink, acl");
236 cmd_AddParm(ts
, "-mask", CMD_LIST
, (CMD_OPTIONAL
| CMD_HIDE
),
237 "Unix mode mask (example: 06000)");
238 cmd_AddParm(ts
, "-output", CMD_LIST
, CMD_OPTIONAL
,
240 cmd_AddParm(ts
, "-delim", CMD_SINGLE
, CMD_OPTIONAL
,
241 "Output field delimiter");
242 cmd_AddParm(ts
, "-noheading", CMD_FLAG
, CMD_OPTIONAL
,
243 "Do not print the heading line");
244 cmd_AddParm(ts
, "-ignore-magic", CMD_FLAG
, CMD_OPTIONAL
,
245 "Skip directory vnode magic checks when looking up paths.");
247 code
= cmd_Dispatch(argc
, argv
);