]>
Commit | Line | Data |
---|---|---|
959ef981 | 1 | // SPDX-License-Identifier: GPL-2.0 |
5aead01d | 2 | /* |
da23017d NS |
3 | * Copyright (c) 2003-2005 Silicon Graphics, Inc. |
4 | * All Rights Reserved. | |
5aead01d NS |
5 | */ |
6 | ||
42b4c8e8 | 7 | #include "libfrog/paths.h" |
6b803e5a CH |
8 | #include "command.h" |
9 | #include "input.h" | |
5aead01d NS |
10 | #include "init.h" |
11 | ||
12 | char *progname; | |
13 | int exitcode; | |
14 | int expert; | |
29647c8d | 15 | bool foreign_allowed = false; |
5aead01d NS |
16 | |
17 | static char **projopts; /* table of project names (cmdline) */ | |
18 | static int nprojopts; /* number of entries in name table. */ | |
19 | ||
20 | static void | |
21 | add_project_opt( | |
22 | char *optarg) | |
23 | { | |
24 | nprojopts++; | |
25 | projopts = realloc(projopts, sizeof(char*) * nprojopts); | |
26 | if (!projopts) { | |
27 | perror("realloc"); | |
28 | exit(1); | |
29 | } | |
30 | projopts[nprojopts - 1] = optarg; | |
31 | } | |
32 | ||
33 | static void | |
34 | usage(void) | |
35 | { | |
36 | fprintf(stderr, | |
29647c8d | 37 | _("Usage: %s [-V] [-x] [-f] [-p prog] [-c cmd]... [-d project]... [path]\n"), |
5aead01d NS |
38 | progname); |
39 | exit(1); | |
40 | } | |
41 | ||
42 | void | |
43 | init_cvtnum( | |
cb7ba2b0 CH |
44 | unsigned int *blocksize, |
45 | unsigned int *sectsize) | |
5aead01d NS |
46 | { |
47 | *blocksize = 4096; | |
48 | *sectsize = 512; | |
49 | } | |
50 | ||
51 | static void | |
52 | init_commands(void) | |
53 | { | |
54 | edit_init(); | |
55 | free_init(); | |
56 | help_init(); | |
57 | path_init(); | |
58 | project_init(); | |
59 | quot_init(); | |
60 | quota_init(); | |
61 | quit_init(); | |
62 | report_init(); | |
63 | state_init(); | |
64 | } | |
65 | ||
ef346a25 DC |
66 | /* |
67 | * This function allows xfs_quota commands to iterate across all discovered | |
68 | * quota enabled filesystems. Commands that should not iterate all filesystems | |
69 | * should specify CMD_FLAG_ONESHOT in their command flags. | |
70 | */ | |
5aead01d | 71 | static int |
ef346a25 | 72 | filesystem_iterator( |
5aead01d NS |
73 | int index) |
74 | { | |
75 | if (index >= fs_count) | |
76 | return 0; | |
77 | ||
78 | do { | |
79 | fs_path = &fs_table[index++]; | |
29647c8d BD |
80 | /* skip project quota entries */ |
81 | if ((fs_path->fs_flags & FS_PROJECT_PATH)) | |
82 | continue; | |
83 | ||
84 | /* only consider foreign filesystems if told so */ | |
85 | if (!foreign_allowed && (fs_path->fs_flags & FS_FOREIGN)) | |
86 | continue; | |
87 | ||
88 | /* We can use this one */ | |
89 | break; | |
90 | } while (index < fs_count); | |
5aead01d | 91 | |
fa13a00f NS |
92 | if (fs_path->fs_flags & FS_PROJECT_PATH) |
93 | return 0; | |
29647c8d BD |
94 | if (!foreign_allowed && (fs_path->fs_flags & FS_FOREIGN)) |
95 | return 0; | |
5aead01d NS |
96 | if (index > fs_count) |
97 | return 0; | |
98 | return index; | |
99 | } | |
100 | ||
29647c8d BD |
101 | static int |
102 | init_check_command( | |
103 | const cmdinfo_t *ct) | |
104 | { | |
b20b6c22 BD |
105 | if (!fs_path) |
106 | return 1; | |
107 | ||
2ba39cd3 | 108 | /* If it's an XFS filesystem, always run the command. */ |
b20b6c22 BD |
109 | if (!(fs_path->fs_flags & FS_FOREIGN)) |
110 | return 1; | |
111 | ||
2ba39cd3 | 112 | /* If the user specified foreign filesystems are ok (-f), run cmd. */ |
b20b6c22 BD |
113 | if (foreign_allowed && |
114 | (ct->flags & CMD_FLAG_FOREIGN_OK)) | |
115 | return 1; | |
116 | ||
2ba39cd3 BD |
117 | /* If cmd not allowed on foreign fs, regardless of -f flag, skip it. */ |
118 | if (!(ct->flags & CMD_FLAG_FOREIGN_OK)) { | |
119 | fprintf(stderr, _("%s: command is for XFS filesystems only\n"), | |
120 | ct->name); | |
121 | return 0; | |
122 | } | |
123 | ||
124 | /* foreign fs, but cmd only allowed via -f flag. Skip it. */ | |
125 | fprintf(stderr, | |
126 | _("%s: foreign filesystem. Invoke xfs_quota with -f to enable.\n"), | |
b20b6c22 BD |
127 | ct->name); |
128 | return 0; | |
29647c8d BD |
129 | } |
130 | ||
5aead01d NS |
131 | static void |
132 | init( | |
133 | int argc, | |
134 | char **argv) | |
135 | { | |
136 | int c; | |
137 | ||
138 | progname = basename(argv[0]); | |
139 | setlocale(LC_ALL, ""); | |
140 | bindtextdomain(PACKAGE, LOCALEDIR); | |
141 | textdomain(PACKAGE); | |
142 | ||
29647c8d | 143 | while ((c = getopt(argc, argv, "c:d:D:fP:p:t:xV")) != EOF) { |
5aead01d NS |
144 | switch (c) { |
145 | case 'c': /* commands */ | |
146 | add_user_command(optarg); | |
147 | break; | |
148 | case 'd': | |
149 | add_project_opt(optarg); | |
150 | break; | |
29647c8d BD |
151 | case 'f': |
152 | foreign_allowed = true; | |
88dabc17 | 153 | break; |
5aead01d NS |
154 | case 't': |
155 | mtab_file = optarg; | |
156 | break; | |
157 | case 'D': | |
158 | projects_file = optarg; | |
159 | break; | |
160 | case 'P': | |
161 | projid_file = optarg; | |
162 | break; | |
163 | case 'p': | |
164 | progname = optarg; | |
165 | break; | |
166 | case 'x': | |
167 | expert++; | |
168 | break; | |
169 | case 'V': | |
170 | printf(_("%s version %s\n"), progname, VERSION); | |
171 | exit(0); | |
172 | default: | |
173 | usage(); | |
174 | } | |
175 | } | |
176 | ||
0900efe4 AE |
177 | fs_table_initialise(argc - optind, &argv[optind], nprojopts, projopts); |
178 | free(projopts); | |
5aead01d NS |
179 | |
180 | init_commands(); | |
ef346a25 | 181 | add_command_iterator(filesystem_iterator); |
29647c8d | 182 | add_check_command(init_check_command); |
36298cce DC |
183 | |
184 | /* | |
185 | * Ensure that global commands don't end up with an invalid path pointer | |
186 | * by setting the default device at the first specified on the CLI | |
187 | */ | |
188 | if (argc != optind) | |
189 | fs_path = fs_table_lookup(argv[optind], FS_MOUNT_POINT); | |
190 | else | |
191 | fs_path = &fs_table[0]; | |
5aead01d NS |
192 | } |
193 | ||
194 | int | |
195 | main( | |
196 | int argc, | |
197 | char **argv) | |
198 | { | |
199 | init(argc, argv); | |
200 | command_loop(); | |
201 | return exitcode; | |
202 | } |