master xplshn/aruu / cmd / linux / mountpoint.c
  1/* See LICENSE file for copyright and license details. */
  2
  3
  4#include <sys/stat.h>
  5#include <sys/sysmacros.h>
  6#include <sys/types.h>
  7
  8#include <mntent.h>
  9#include <stdio.h>
 10#include <stdlib.h>
 11#include <string.h>
 12#include <unistd.h>
 13
 14#include "util.h"
 15
 16static void
 17usage(void)
 18{
 19	eprintf("usage: %s [-dqx] target\n", argv0);
 20}
 21
 22// ?man mountpoint: check if a directory is a mountpoint
 23// ?man arguments: target
 24// ?man determine if a directory is a mountpoint
 25int
 26main(int argc, char *argv[])
 27{
 28	int dflag = 0, qflag = 0, xflag = 0;
 29	int ret = 0;
 30	struct mntent *me = NULL;
 31	FILE *fp;
 32	struct stat st1, st2;
 33
 34	ARGBEGIN {
 35	// ?man -d: specify directory
 36	case 'd':
 37		dflag = 1;
 38		break;
 39	// ?man -q: quiet mode; suppress output
 40	case 'q':
 41		qflag = 1;
 42		break;
 43	// ?man -x: hex format or match whole lines
 44	case 'x':
 45		xflag = 1;
 46		break;
 47	default:
 48		usage();
 49	} ARGEND;
 50
 51	if (argc < 1)
 52		usage();
 53
 54	if (stat(argv[0], &st1) < 0) {
 55		if (qflag)
 56			return 1;
 57		eprintf("stat %s:", argv[0]);
 58	}
 59
 60	if (xflag) {
 61		if (!S_ISBLK(st1.st_mode)) {
 62			if (qflag)
 63				return 1;
 64			eprintf("stat: %s: not a block device\n",
 65				argv[0]);
 66		}
 67		printf("%u:%u\n", major(st1.st_rdev),
 68		       minor(st1.st_rdev));
 69		return 0;
 70	}
 71
 72	if (!S_ISDIR(st1.st_mode)) {
 73		if (qflag)
 74			return 1;
 75		eprintf("stat %s: not a directory\n", argv[0]);
 76	}
 77
 78	if (dflag) {
 79		printf("%u:%u\n", major(st1.st_dev),
 80		       minor(st1.st_dev));
 81		return 0;
 82	}
 83
 84	fp = setmntent("/proc/mounts", "r");
 85	if (!fp) {
 86		if (qflag)
 87			return 1;
 88		eprintf("setmntent %s:", "/proc/mounts");
 89	}
 90	while ((me = getmntent(fp)) != NULL) {
 91		if (stat(me->mnt_dir, &st2) < 0) {
 92			if (qflag)
 93				return 1;
 94			eprintf("stat %s:", me->mnt_dir);
 95		}
 96		if (st1.st_dev == st2.st_dev &&
 97		    st1.st_ino == st2.st_ino)
 98			break;
 99	}
100	endmntent(fp);
101
102	if (me == NULL)
103		ret = 1;
104
105	if (!qflag)
106		printf("%s %s a mountpoint\n", argv[0],
107		       !ret ? "is" : "is not");
108
109	return ret;
110}