blob: 8244e38d19b99b146eb3d2986e4e03609d11d194 [file] [log] [blame]
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2003-2005 Silicon Graphics, Inc.
* All Rights Reserved.
*/
#include "path.h"
#include "command.h"
#include "input.h"
#include "init.h"
char *progname;
int exitcode;
int expert;
bool foreign_allowed = false;
static char **projopts; /* table of project names (cmdline) */
static int nprojopts; /* number of entries in name table. */
static void
add_project_opt(
char *optarg)
{
nprojopts++;
projopts = realloc(projopts, sizeof(char*) * nprojopts);
if (!projopts) {
perror("realloc");
exit(1);
}
projopts[nprojopts - 1] = optarg;
}
static void
usage(void)
{
fprintf(stderr,
_("Usage: %s [-V] [-x] [-f] [-p prog] [-c cmd]... [-d project]... [path]\n"),
progname);
exit(1);
}
void
init_cvtnum(
unsigned int *blocksize,
unsigned int *sectsize)
{
*blocksize = 4096;
*sectsize = 512;
}
static void
init_commands(void)
{
edit_init();
free_init();
help_init();
path_init();
project_init();
quot_init();
quota_init();
quit_init();
report_init();
state_init();
}
/*
* This function allows xfs_quota commands to iterate across all discovered
* quota enabled filesystems. Commands that should not iterate all filesystems
* should specify CMD_FLAG_ONESHOT in their command flags.
*/
static int
filesystem_iterator(
int index)
{
if (index >= fs_count)
return 0;
do {
fs_path = &fs_table[index++];
/* skip project quota entries */
if ((fs_path->fs_flags & FS_PROJECT_PATH))
continue;
/* only consider foreign filesystems if told so */
if (!foreign_allowed && (fs_path->fs_flags & FS_FOREIGN))
continue;
/* We can use this one */
break;
} while (index < fs_count);
if (fs_path->fs_flags & FS_PROJECT_PATH)
return 0;
if (!foreign_allowed && (fs_path->fs_flags & FS_FOREIGN))
return 0;
if (index > fs_count)
return 0;
return index;
}
static int
init_check_command(
const cmdinfo_t *ct)
{
if (!fs_path)
return 1;
/* If it's an XFS filesystem, always run the command. */
if (!(fs_path->fs_flags & FS_FOREIGN))
return 1;
/* If the user specified foreign filesystems are ok (-f), run cmd. */
if (foreign_allowed &&
(ct->flags & CMD_FLAG_FOREIGN_OK))
return 1;
/* If cmd not allowed on foreign fs, regardless of -f flag, skip it. */
if (!(ct->flags & CMD_FLAG_FOREIGN_OK)) {
fprintf(stderr, _("%s: command is for XFS filesystems only\n"),
ct->name);
return 0;
}
/* foreign fs, but cmd only allowed via -f flag. Skip it. */
fprintf(stderr,
_("%s: foreign filesystem. Invoke xfs_quota with -f to enable.\n"),
ct->name);
return 0;
}
static void
init(
int argc,
char **argv)
{
int c;
progname = basename(argv[0]);
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
while ((c = getopt(argc, argv, "c:d:D:fP:p:t:xV")) != EOF) {
switch (c) {
case 'c': /* commands */
add_user_command(optarg);
break;
case 'd':
add_project_opt(optarg);
break;
case 'f':
foreign_allowed = true;
break;
case 't':
mtab_file = optarg;
break;
case 'D':
projects_file = optarg;
break;
case 'P':
projid_file = optarg;
break;
case 'p':
progname = optarg;
break;
case 'x':
expert++;
break;
case 'V':
printf(_("%s version %s\n"), progname, VERSION);
exit(0);
default:
usage();
}
}
fs_table_initialise(argc - optind, &argv[optind], nprojopts, projopts);
free(projopts);
init_commands();
add_command_iterator(filesystem_iterator);
add_check_command(init_check_command);
/*
* Ensure that global commands don't end up with an invalid path pointer
* by setting the default device at the first specified on the CLI
*/
if (argc != optind)
fs_path = fs_table_lookup(argv[optind], FS_MOUNT_POINT);
else
fs_path = &fs_table[0];
}
int
main(
int argc,
char **argv)
{
init(argc, argv);
command_loop();
return exitcode;
}