]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - quota/init.c
xfs: fix maxicount division by zero error
[thirdparty/xfsprogs-dev.git] / quota / init.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2003-2005 Silicon Graphics, Inc.
4 * All Rights Reserved.
5 */
6
7 #include "libfrog/paths.h"
8 #include "command.h"
9 #include "input.h"
10 #include "init.h"
11
12 char *progname;
13 int exitcode;
14 int expert;
15 bool foreign_allowed = false;
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,
37 _("Usage: %s [-V] [-x] [-f] [-p prog] [-c cmd]... [-d project]... [path]\n"),
38 progname);
39 exit(1);
40 }
41
42 void
43 init_cvtnum(
44 unsigned int *blocksize,
45 unsigned int *sectsize)
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
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 */
71 static int
72 filesystem_iterator(
73 int index)
74 {
75 if (index >= fs_count)
76 return 0;
77
78 do {
79 fs_path = &fs_table[index++];
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);
91
92 if (fs_path->fs_flags & FS_PROJECT_PATH)
93 return 0;
94 if (!foreign_allowed && (fs_path->fs_flags & FS_FOREIGN))
95 return 0;
96 if (index > fs_count)
97 return 0;
98 return index;
99 }
100
101 static int
102 init_check_command(
103 const cmdinfo_t *ct)
104 {
105 if (!fs_path)
106 return 1;
107
108 /* If it's an XFS filesystem, always run the command. */
109 if (!(fs_path->fs_flags & FS_FOREIGN))
110 return 1;
111
112 /* If the user specified foreign filesystems are ok (-f), run cmd. */
113 if (foreign_allowed &&
114 (ct->flags & CMD_FLAG_FOREIGN_OK))
115 return 1;
116
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"),
127 ct->name);
128 return 0;
129 }
130
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
143 while ((c = getopt(argc, argv, "c:d:D:fP:p:t:xV")) != EOF) {
144 switch (c) {
145 case 'c': /* commands */
146 add_user_command(optarg);
147 break;
148 case 'd':
149 add_project_opt(optarg);
150 break;
151 case 'f':
152 foreign_allowed = true;
153 break;
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
177 fs_table_initialise(argc - optind, &argv[optind], nprojopts, projopts);
178 free(projopts);
179
180 init_commands();
181 add_command_iterator(filesystem_iterator);
182 add_check_command(init_check_command);
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];
192 }
193
194 int
195 main(
196 int argc,
197 char **argv)
198 {
199 init(argc, argv);
200 command_loop();
201 return exitcode;
202 }