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,
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);