2007-04-05 16:48:42 +05:30
|
|
|
/*
|
|
|
|
fstabinfo.c
|
|
|
|
Gets information about /etc/fstab.
|
|
|
|
*/
|
|
|
|
|
2008-01-14 10:35:22 +05:30
|
|
|
/*
|
2008-03-26 23:23:37 +05:30
|
|
|
* Copyright 2007-2008 Roy Marples <roy@marples.name>
|
2007-11-14 20:52:04 +05:30
|
|
|
* All rights reserved
|
|
|
|
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
* SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
2008-03-11 19:09:20 +05:30
|
|
|
#include <sys/wait.h>
|
2008-03-16 22:30:56 +05:30
|
|
|
|
2007-04-05 16:48:42 +05:30
|
|
|
#include <errno.h>
|
2007-04-13 20:50:10 +05:30
|
|
|
#include <getopt.h>
|
2007-04-05 16:48:42 +05:30
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2008-03-11 19:09:20 +05:30
|
|
|
#include <unistd.h>
|
2007-04-05 16:48:42 +05:30
|
|
|
|
|
|
|
/* Yay for linux and it's non liking of POSIX functions.
|
|
|
|
Okay, we could use getfsent but the man page says use getmntent instead
|
|
|
|
AND we don't have getfsent on uclibc or dietlibc for some odd reason. */
|
|
|
|
#ifdef __linux__
|
|
|
|
#define HAVE_GETMNTENT
|
|
|
|
#include <mntent.h>
|
2008-03-11 19:09:20 +05:30
|
|
|
#define ENT mntent
|
2007-09-26 03:51:28 +05:30
|
|
|
#define START_ENT fp = setmntent ("/etc/fstab", "r");
|
2007-04-05 16:48:42 +05:30
|
|
|
#define GET_ENT getmntent (fp)
|
2007-09-26 03:51:28 +05:30
|
|
|
#define GET_ENT_FILE(_name) getmntfile (_name)
|
2007-04-05 16:48:42 +05:30
|
|
|
#define END_ENT endmntent (fp)
|
2007-10-11 15:19:54 +05:30
|
|
|
#define ENT_BLOCKDEVICE(_ent) ent->mnt_fsname
|
2007-04-05 16:48:42 +05:30
|
|
|
#define ENT_FILE(_ent) ent->mnt_dir
|
|
|
|
#define ENT_TYPE(_ent) ent->mnt_type
|
|
|
|
#define ENT_OPTS(_ent) ent->mnt_opts
|
|
|
|
#define ENT_PASS(_ent) ent->mnt_passno
|
|
|
|
#else
|
|
|
|
#define HAVE_GETFSENT
|
|
|
|
#include <fstab.h>
|
2008-03-11 19:09:20 +05:30
|
|
|
#define ENT fstab
|
2007-09-26 03:51:28 +05:30
|
|
|
#define START_ENT
|
2007-04-05 16:48:42 +05:30
|
|
|
#define GET_ENT getfsent ()
|
|
|
|
#define GET_ENT_FILE(_name) getfsfile (_name)
|
|
|
|
#define END_ENT endfsent ()
|
2007-10-11 15:19:54 +05:30
|
|
|
#define ENT_BLOCKDEVICE(_ent) ent->fs_spec
|
2007-04-05 16:48:42 +05:30
|
|
|
#define ENT_TYPE(_ent) ent->fs_vfstype
|
|
|
|
#define ENT_FILE(_ent) ent->fs_file
|
|
|
|
#define ENT_OPTS(_ent) ent->fs_mntops
|
|
|
|
#define ENT_PASS(_ent) ent->fs_passno
|
|
|
|
#endif
|
|
|
|
|
2007-07-31 21:35:56 +05:30
|
|
|
#include "builtins.h"
|
2008-01-06 19:17:39 +05:30
|
|
|
#include "einfo.h"
|
2007-09-26 03:51:28 +05:30
|
|
|
#include "rc.h"
|
2008-01-06 19:17:39 +05:30
|
|
|
#include "rc-misc.h"
|
2007-04-05 16:48:42 +05:30
|
|
|
|
|
|
|
#ifdef HAVE_GETMNTENT
|
2008-03-16 22:30:56 +05:30
|
|
|
static struct mntent *getmntfile(const char *file)
|
2007-04-05 16:48:42 +05:30
|
|
|
{
|
2008-03-16 22:30:56 +05:30
|
|
|
struct mntent *ent;
|
2007-09-26 03:51:28 +05:30
|
|
|
FILE *fp;
|
2007-04-05 16:48:42 +05:30
|
|
|
|
2007-09-26 03:51:28 +05:30
|
|
|
START_ENT;
|
2008-03-16 22:30:56 +05:30
|
|
|
while ((ent = getmntent(fp)))
|
|
|
|
if (strcmp(file, ent->mnt_dir) == 0)
|
2007-09-26 03:51:28 +05:30
|
|
|
break;
|
|
|
|
END_ENT;
|
2008-01-11 21:21:40 +05:30
|
|
|
|
2008-03-16 22:30:56 +05:30
|
|
|
return ent;
|
2007-04-05 16:48:42 +05:30
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2008-02-12 01:44:09 +05:30
|
|
|
extern const char *applet;
|
2007-12-18 23:31:05 +05:30
|
|
|
|
2008-03-16 22:30:56 +05:30
|
|
|
static int do_mount(struct ENT *ent)
|
2008-03-11 19:09:20 +05:30
|
|
|
{
|
|
|
|
char *argv[8];
|
|
|
|
pid_t pid;
|
|
|
|
int status;
|
|
|
|
|
2008-03-11 19:21:06 +05:30
|
|
|
argv[0] = (char *) "mount";
|
2008-03-11 19:09:20 +05:30
|
|
|
argv[1] = (char *) "-o";
|
2008-03-16 22:30:56 +05:30
|
|
|
argv[2] = ENT_OPTS(*ent);
|
2008-03-11 19:09:20 +05:30
|
|
|
argv[3] = (char *) "-t";
|
2008-03-16 22:30:56 +05:30
|
|
|
argv[4] = ENT_TYPE(*ent);
|
|
|
|
argv[5] = ENT_BLOCKDEVICE(*ent);
|
|
|
|
argv[6] = ENT_FILE(*ent);
|
2008-03-11 19:09:20 +05:30
|
|
|
argv[7] = NULL;
|
|
|
|
switch (pid = vfork()) {
|
|
|
|
case -1:
|
2008-03-16 22:30:56 +05:30
|
|
|
eerrorx("%s: vfork: %s", applet, strerror(errno));
|
2008-03-11 19:09:20 +05:30
|
|
|
/* NOTREACHED */
|
|
|
|
case 0:
|
2008-03-16 22:30:56 +05:30
|
|
|
execvp(argv[0], argv);
|
|
|
|
eerror("%s: execv: %s", applet, strerror(errno));
|
2008-03-11 19:09:20 +05:30
|
|
|
_exit(EXIT_FAILURE);
|
|
|
|
/* NOTREACHED */
|
|
|
|
default:
|
2008-03-16 22:30:56 +05:30
|
|
|
waitpid(pid, &status, 0);
|
|
|
|
if (WIFEXITED(status))
|
|
|
|
return WEXITSTATUS(status);
|
2008-03-11 19:09:20 +05:30
|
|
|
else
|
2008-03-16 22:30:56 +05:30
|
|
|
return -1;
|
2008-03-11 19:09:20 +05:30
|
|
|
/* NOTREACHED */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-06-28 21:14:14 +05:30
|
|
|
#include "_usage.h"
|
2008-03-11 19:09:20 +05:30
|
|
|
#define getoptstring "Mbmop:t:" getoptstring_COMMON
|
2008-02-02 01:24:46 +05:30
|
|
|
static const struct option longopts[] = {
|
2008-03-11 19:09:20 +05:30
|
|
|
{ "mount", 0, NULL, 'M' },
|
2007-10-11 15:19:54 +05:30
|
|
|
{ "blockdevice", 0, NULL, 'b' },
|
2008-03-11 19:09:20 +05:30
|
|
|
{ "mountargs", 0, NULL, 'm' },
|
2007-10-11 15:19:54 +05:30
|
|
|
{ "options", 0, NULL, 'o' },
|
|
|
|
{ "passno", 1, NULL, 'p' },
|
|
|
|
{ "fstype", 1, NULL, 't' },
|
2007-06-28 21:14:14 +05:30
|
|
|
longopts_COMMON
|
2007-04-17 18:14:32 +05:30
|
|
|
};
|
2007-09-25 21:51:38 +05:30
|
|
|
static const char * const longopts_help[] = {
|
2007-10-11 15:19:54 +05:30
|
|
|
"Extract the block device",
|
2008-04-19 22:49:59 +05:30
|
|
|
"Mounts the filesytem from the mountpoint",
|
|
|
|
"Show arguments needed to mount the entry",
|
2007-09-25 21:51:38 +05:30
|
|
|
"Extract the options field",
|
2007-10-11 15:19:54 +05:30
|
|
|
"Extract or query the pass number field",
|
|
|
|
"List entries with matching file system type",
|
2007-09-25 21:51:38 +05:30
|
|
|
longopts_help_COMMON
|
|
|
|
};
|
2007-04-17 18:14:32 +05:30
|
|
|
#include "_usage.c"
|
|
|
|
|
2007-09-26 03:51:28 +05:30
|
|
|
#define OUTPUT_FILE (1 << 1)
|
2008-03-11 19:09:20 +05:30
|
|
|
#define OUTPUT_MOUNTARGS (1 << 2)
|
2007-09-26 03:51:28 +05:30
|
|
|
#define OUTPUT_OPTIONS (1 << 3)
|
|
|
|
#define OUTPUT_PASSNO (1 << 4)
|
2007-10-11 15:19:54 +05:30
|
|
|
#define OUTPUT_BLOCKDEV (1 << 5)
|
2008-03-11 19:09:20 +05:30
|
|
|
#define OUTPUT_MOUNT (1 << 6)
|
2007-09-26 03:51:28 +05:30
|
|
|
|
2008-03-16 22:30:56 +05:30
|
|
|
int fstabinfo(int argc, char **argv)
|
2007-04-05 16:48:42 +05:30
|
|
|
{
|
2008-03-11 19:09:20 +05:30
|
|
|
struct ENT *ent;
|
2007-09-26 04:15:57 +05:30
|
|
|
int result = EXIT_SUCCESS;
|
2007-04-11 18:14:47 +05:30
|
|
|
char *token;
|
2008-05-12 14:02:19 +05:30
|
|
|
int i, p;
|
2007-05-14 17:54:18 +05:30
|
|
|
int opt;
|
2007-09-26 03:51:28 +05:30
|
|
|
int output = OUTPUT_FILE;
|
2008-03-16 22:30:56 +05:30
|
|
|
RC_STRINGLIST *files = rc_stringlist_new();
|
|
|
|
RC_STRING *file;
|
2007-09-26 03:51:28 +05:30
|
|
|
bool filtered = false;
|
2007-04-13 20:50:10 +05:30
|
|
|
|
2008-03-11 19:09:20 +05:30
|
|
|
#ifdef HAVE_GETMNTENT
|
|
|
|
FILE *fp;
|
|
|
|
#endif
|
|
|
|
|
2007-12-15 04:31:28 +05:30
|
|
|
/* Ensure that we are only quiet when explicitly told to be */
|
2008-03-16 22:30:56 +05:30
|
|
|
unsetenv("EINFO_QUIET");
|
2007-12-15 04:31:28 +05:30
|
|
|
|
2008-03-16 22:30:56 +05:30
|
|
|
while ((opt = getopt_long(argc, argv, getoptstring,
|
|
|
|
longopts, (int *) 0)) != -1)
|
2007-04-13 20:50:10 +05:30
|
|
|
{
|
2007-05-14 17:54:18 +05:30
|
|
|
switch (opt) {
|
2008-03-16 22:30:56 +05:30
|
|
|
case 'M':
|
|
|
|
output = OUTPUT_MOUNT;
|
|
|
|
break;
|
|
|
|
case 'b':
|
|
|
|
output = OUTPUT_BLOCKDEV;
|
|
|
|
break;
|
|
|
|
case 'o':
|
|
|
|
output = OUTPUT_OPTIONS;
|
|
|
|
break;
|
|
|
|
case 'm':
|
|
|
|
output = OUTPUT_MOUNTARGS;
|
|
|
|
break;
|
2007-04-11 18:14:47 +05:30
|
|
|
|
2008-03-16 22:30:56 +05:30
|
|
|
case 'p':
|
|
|
|
switch (optarg[0]) {
|
|
|
|
case '=':
|
|
|
|
case '<':
|
|
|
|
case '>':
|
|
|
|
if (sscanf(optarg + 1, "%d", &i) != 1)
|
|
|
|
eerrorx("%s: invalid passno %s",
|
|
|
|
argv[0], optarg + 1);
|
2007-04-17 18:14:32 +05:30
|
|
|
|
2007-09-26 03:51:28 +05:30
|
|
|
filtered = true;
|
2008-05-12 14:02:19 +05:30
|
|
|
opt = optarg[0];
|
2008-03-16 22:30:56 +05:30
|
|
|
START_ENT;
|
|
|
|
while ((ent = GET_ENT)) {
|
2008-05-12 14:02:19 +05:30
|
|
|
if (strcmp(ENT_FILE(ent), "none") == 0)
|
|
|
|
continue;
|
|
|
|
p = ENT_PASS(ent);
|
|
|
|
if ((opt == '=' && i == p) ||
|
|
|
|
(opt == '<' && i > p && p != 0) ||
|
|
|
|
(opt == '>' && i < p && p != 0))
|
|
|
|
rc_stringlist_add(files,
|
|
|
|
ENT_FILE(ent));
|
2007-09-26 03:51:28 +05:30
|
|
|
}
|
2008-03-16 22:30:56 +05:30
|
|
|
END_ENT;
|
2007-09-25 17:52:48 +05:30
|
|
|
break;
|
|
|
|
|
2008-03-16 22:30:56 +05:30
|
|
|
default:
|
|
|
|
rc_stringlist_add(files, optarg);
|
|
|
|
output = OUTPUT_PASSNO;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 't':
|
|
|
|
filtered = true;
|
|
|
|
while ((token = strsep(&optarg, ","))) {
|
|
|
|
START_ENT;
|
|
|
|
while ((ent = GET_ENT))
|
|
|
|
if (strcmp(token, ENT_TYPE(ent)) == 0)
|
|
|
|
rc_stringlist_add(files, ENT_FILE(ent));
|
|
|
|
END_ENT;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case_RC_COMMON_GETOPT
|
2007-04-11 18:14:47 +05:30
|
|
|
}
|
2007-09-26 03:51:28 +05:30
|
|
|
}
|
|
|
|
|
2008-03-16 22:30:56 +05:30
|
|
|
if (optind < argc) {
|
|
|
|
while (optind < argc)
|
|
|
|
rc_stringlist_add(files, argv[optind++]);
|
|
|
|
} else if (! filtered) {
|
2007-09-26 03:51:28 +05:30
|
|
|
START_ENT;
|
|
|
|
while ((ent = GET_ENT))
|
2008-03-16 22:30:56 +05:30
|
|
|
rc_stringlist_add(files, ENT_FILE(ent));
|
2007-04-11 18:14:47 +05:30
|
|
|
END_ENT;
|
|
|
|
|
2008-03-16 22:30:56 +05:30
|
|
|
if (! TAILQ_FIRST(files))
|
|
|
|
eerrorx("%s: emtpy fstab", argv[0]);
|
2007-04-11 18:14:47 +05:30
|
|
|
}
|
|
|
|
|
2007-09-26 03:51:28 +05:30
|
|
|
/* Ensure we always display something */
|
|
|
|
START_ENT;
|
2008-03-16 22:30:56 +05:30
|
|
|
TAILQ_FOREACH(file, files, entries) {
|
|
|
|
if (! (ent = GET_ENT_FILE(file->value))) {
|
2007-09-26 03:51:28 +05:30
|
|
|
result = EXIT_FAILURE;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2007-09-26 04:15:57 +05:30
|
|
|
/* No point in outputting if quiet */
|
2008-03-16 22:30:56 +05:30
|
|
|
if (rc_yesno(getenv("EINFO_QUIET")))
|
2007-09-26 04:15:57 +05:30
|
|
|
continue;
|
|
|
|
|
2007-09-26 03:51:28 +05:30
|
|
|
switch (output) {
|
2008-03-16 22:30:56 +05:30
|
|
|
case OUTPUT_BLOCKDEV:
|
|
|
|
printf("%s\n", ENT_BLOCKDEVICE(ent));
|
|
|
|
break;
|
2008-03-11 19:09:20 +05:30
|
|
|
|
2008-03-16 22:30:56 +05:30
|
|
|
case OUTPUT_MOUNT:
|
|
|
|
result += do_mount(ent);
|
|
|
|
break;
|
2008-03-11 19:09:20 +05:30
|
|
|
|
2008-03-16 22:30:56 +05:30
|
|
|
case OUTPUT_MOUNTARGS:
|
|
|
|
printf("-o %s -t %s %s %s\n",
|
|
|
|
ENT_OPTS(ent),
|
|
|
|
ENT_TYPE(ent),
|
|
|
|
ENT_BLOCKDEVICE(ent),
|
|
|
|
file->value);
|
|
|
|
break;
|
2008-03-11 19:09:20 +05:30
|
|
|
|
2008-03-16 22:30:56 +05:30
|
|
|
case OUTPUT_OPTIONS:
|
|
|
|
printf("%s\n", ENT_OPTS(ent));
|
|
|
|
break;
|
2007-09-26 03:51:28 +05:30
|
|
|
|
2008-03-16 22:30:56 +05:30
|
|
|
case OUTPUT_FILE:
|
|
|
|
printf("%s\n", file->value);
|
|
|
|
break;
|
2007-09-26 03:51:28 +05:30
|
|
|
|
2008-03-16 22:30:56 +05:30
|
|
|
case OUTPUT_PASSNO:
|
|
|
|
printf("%d\n", ENT_PASS(ent));
|
|
|
|
break;
|
2007-09-26 03:51:28 +05:30
|
|
|
}
|
|
|
|
}
|
|
|
|
END_ENT;
|
2007-09-25 07:17:02 +05:30
|
|
|
|
2008-03-16 22:30:56 +05:30
|
|
|
rc_stringlist_free(files);
|
|
|
|
exit(result);
|
2008-01-22 16:37:39 +05:30
|
|
|
/* NOTREACHED */
|
2007-04-05 16:48:42 +05:30
|
|
|
}
|