#include <getopt.h>
#include <error.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mount.h>
#include <errno.h>
static const char *mounts_path = "/proc/mounts";
static void print_mounts()
{
int fd;
char buf[4096];
ssize_t n;
if ((fd = open(mounts_path, O_RDONLY)) == -1)
error(EXIT_FAILURE, errno, mounts_path);
while (1) {
if ((n = read(fd, buf, sizeof buf)) == -1)
error(EXIT_FAILURE, errno, mounts_path);
if (n == 0)
break;
if ((write(STDOUT_FILENO, buf, n)) == -1)
error(EXIT_FAILURE, errno, "write error");
}
close(fd);
}
static void __attribute__ ((noreturn)) die_bad_usage()
{
fprintf(stderr, "Try `%s --help' for more information.\n", program_invocation_name);
exit(EXIT_FAILURE);
}
static void print_help()
{
printf("Usage: %s [OPTION]\n", program_invocation_name);
printf(" or: %s [OPTION] -t TYPE DEVICE DIR\n", program_invocation_name);
puts("Mount a filesystem. If no argument is provided, list all mounted filesystems.");
putchar('\n');
puts(" -t, --types=TYPE filesystem type");
puts(" -h, --help display this help and exit");
}
int main(int argc, char **argv)
{
static const struct option longopts[] = {
{"types", required_argument, NULL, 't'},
{"help", no_argument, NULL, 'h'},
{NULL, 0, NULL, 0}
};
const char *filesystemtype, *source, *target;
int c;
filesystemtype = NULL;
while ((c = getopt_long(argc, argv, "t:h", longopts, NULL)) != -1)
switch (c) {
case 't':
filesystemtype = optarg;
break;
case 'h':
print_help();
return EXIT_SUCCESS;
case '?':
die_bad_usage();
}
if (filesystemtype) {
if (optind + 1 >= argc) {
error(0, 0, "missing operand");
die_bad_usage();
}
source = *argv[optind] ? argv[optind] : NULL;
target = argv[optind + 1];
if (mount(source, target, filesystemtype, 0, NULL) == -1)
error(EXIT_FAILURE, errno, "failed to mount %s", source ? : filesystemtype);
}
else
print_mounts();
return EXIT_SUCCESS;
}