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>
35 #include <afs/afsint.h>
36 #include <rx/rx_queue.h>
40 #include "vnode.h" /* for vSmall, vLarge */
44 #include "AFS_component_version_number.c"
47 static const char *progname
= "volscan";
49 /* All columns names as a single string. */
51 static char *ColumnNames
= VOLSCAN_COLUMNS
;
53 #undef VOLSCAN_COLUMNS
55 /* Command line options */
70 * Process command line options and start scanning
72 * @param[in] as command syntax object
73 * @param[in] arock opaque object; not used
80 VolScan(struct cmd_syndesc
*as
, void *arock
)
84 VolumeId volumeId
= 0;
85 char *partNameOrId
= NULL
;
87 struct VolInfoOpt
*opt
;
89 code
= volinfo_Init(progname
);
93 code
= volinfo_Options(&opt
);
98 opt
->dumpInfo
= 0; /* volscan mode */
99 if (as
->parms
[P_CHECKOUT
].items
) {
102 if ((ti
= as
->parms
[P_PART
].items
)) {
103 partNameOrId
= ti
->data
;
105 if ((ti
= as
->parms
[P_VOLUMEID
].items
)) {
106 volumeId
= strtoul(ti
->data
, NULL
, 10);
108 if (as
->parms
[P_NOHEADING
].items
) {
109 opt
->printHeading
= 0;
111 opt
->printHeading
= 1;
113 if (as
->parms
[P_NOMAGIC
].items
) {
116 if ((ti
= as
->parms
[P_DELIM
].items
)) {
117 strncpy(opt
->columnDelim
, ti
->data
, 15);
118 opt
->columnDelim
[15] = '\0';
121 /* Limit types of volumes to scan. */
122 if (!as
->parms
[P_TYPE
].items
) {
123 opt
->scanVolType
= (SCAN_RW
| SCAN_RO
| SCAN_BK
);
125 opt
->scanVolType
= 0;
126 for (ti
= as
->parms
[P_TYPE
].items
; ti
; ti
= ti
->next
) {
127 if (strcmp(ti
->data
, "rw") == 0) {
128 opt
->scanVolType
|= SCAN_RW
;
129 } else if (strcmp(ti
->data
, "ro") == 0) {
130 opt
->scanVolType
|= SCAN_RO
;
131 } else if (strcmp(ti
->data
, "bk") == 0) {
132 opt
->scanVolType
|= SCAN_BK
;
134 fprintf(stderr
, "%s: Unknown -type value: %s\n", progname
,
141 /* Limit types of vnodes to find (plus access entries) */
142 if (!as
->parms
[P_FIND
].items
) {
143 opt
->findVnType
= (FIND_FILE
| FIND_DIR
| FIND_MOUNT
| FIND_SYMLINK
);
146 for (ti
= as
->parms
[P_FIND
].items
; ti
; ti
= ti
->next
) {
147 if (strcmp(ti
->data
, "file") == 0) {
148 opt
->findVnType
|= FIND_FILE
;
149 } else if (strcmp(ti
->data
, "dir") == 0) {
150 opt
->findVnType
|= FIND_DIR
;
151 } else if (strcmp(ti
->data
, "mount") == 0) {
152 opt
->findVnType
|= FIND_MOUNT
;
153 } else if (strcmp(ti
->data
, "symlink") == 0) {
154 opt
->findVnType
|= FIND_SYMLINK
;
155 } else if (strcmp(ti
->data
, "acl") == 0) {
156 opt
->findVnType
|= FIND_ACL
;
158 fprintf(stderr
, "%s: Unknown -find value: %s\n", progname
,
165 /* Show vnodes matching one of the mode masks */
166 for (i
= 0, ti
= as
->parms
[P_MASK
].items
; ti
; i
++, ti
= ti
->next
) {
167 if (i
>= (sizeof(opt
->modeMask
) / sizeof(*opt
->modeMask
))) {
168 fprintf(stderr
, "Too many -mask values\n");
171 opt
->modeMask
[i
] = strtol(ti
->data
, NULL
, 8);
172 if (!opt
->modeMask
[i
]) {
173 fprintf(stderr
, "Invalid -mask value: %s\n", ti
->data
);
178 /* Set which columns to be printed. */
179 if (!as
->parms
[P_OUTPUT
].items
) {
180 volinfo_AddOutputColumn("host");
181 volinfo_AddOutputColumn("desc");
182 volinfo_AddOutputColumn("fid");
183 volinfo_AddOutputColumn("dv");
184 if (opt
->findVnType
& FIND_ACL
) {
185 volinfo_AddOutputColumn("aid");
186 volinfo_AddOutputColumn("arights");
188 volinfo_AddOutputColumn("path");
190 for (ti
= as
->parms
[P_OUTPUT
].items
; ti
; ti
= ti
->next
) {
191 if (volinfo_AddOutputColumn(ti
->data
) != 0) {;
192 fprintf(stderr
, "%s: Unknown -output value: %s\n", progname
,
199 if (opt
->findVnType
& FIND_DIR
) {
200 volinfo_AddVnodeHandler(vLarge
, volinfo_PrintVnodeDetails
, NULL
);
202 if (opt
->findVnType
& (FIND_FILE
| FIND_MOUNT
| FIND_SYMLINK
)) {
203 volinfo_AddVnodeHandler(vSmall
, volinfo_PrintVnodeDetails
, NULL
);
205 if (opt
->findVnType
& FIND_ACL
) {
206 volinfo_AddVnodeHandler(vLarge
, volinfo_ScanAcl
, NULL
);
209 code
= volinfo_ScanPartitions(opt
, partNameOrId
, volumeId
);
216 * volscan program entry
219 main(int argc
, char **argv
)
222 struct cmd_syndesc
*ts
;
224 ts
= cmd_CreateSyntax(NULL
, VolScan
, NULL
, 0,
225 "Print volume vnode information");
227 cmd_AddParmAtOffset(ts
, P_CHECKOUT
, "-checkout", CMD_FLAG
, CMD_OPTIONAL
,
228 "Checkout volumes from running fileserver");
229 cmd_AddParmAtOffset(ts
, P_PART
, "-partition", CMD_SINGLE
, CMD_OPTIONAL
,
230 "AFS partition name or id (default current partition)");
231 cmd_AddParmAtOffset(ts
, P_VOLUMEID
, "-volumeid", CMD_SINGLE
, CMD_OPTIONAL
,
232 "Volume id (-partition required)");
233 cmd_AddParmAtOffset(ts
, P_TYPE
, "-type", CMD_LIST
, CMD_OPTIONAL
,
234 "Volume types: rw, ro, bk");
235 cmd_AddParmAtOffset(ts
, P_FIND
, "-find", CMD_LIST
, CMD_OPTIONAL
,
236 "Objects to find: file, dir, mount, symlink, acl");
237 cmd_AddParmAtOffset(ts
, P_MASK
, "-mask", CMD_LIST
, CMD_OPTIONAL
,
238 "Unix mode mask (example: 06000)");
239 cmd_AddParmAtOffset(ts
, P_OUTPUT
, "-output", CMD_LIST
, CMD_OPTIONAL
,
241 cmd_AddParmAtOffset(ts
, P_DELIM
, "-delim", CMD_SINGLE
, CMD_OPTIONAL
,
242 "Output field delimiter");
243 cmd_AddParmAtOffset(ts
, P_NOHEADING
, "-noheading", CMD_FLAG
, CMD_OPTIONAL
,
244 "Do not print the heading line");
245 cmd_AddParmAtOffset(ts
, P_NOMAGIC
, "-ignore-magic", CMD_FLAG
, CMD_OPTIONAL
,
246 "Skip directory vnode magic checks when looking up paths.");
248 code
= cmd_Dispatch(argc
, argv
);