master xplshn/aruu / cmd / linux / mountpoint.c
  1/* See LICENSE file for copyright and license details. */
  2
  3#include <sys/stat.h>
  4#include <sys/sysmacros.h>
  5#include <sys/types.h>
  6
  7#include <mntent.h>
  8#include <stdio.h>
  9#include <stdlib.h>
 10#include <string.h>
 11#include <unistd.h>
 12
 13#include "paths.h"
 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  {
 36    // ?man -d: specify directory
 37    case 'd':
 38      dflag = 1;
 39      break;
 40    // ?man -q: quiet mode; suppress output
 41    case 'q':
 42      qflag = 1;
 43      break;
 44    // ?man -x: hex format or match whole lines
 45    case 'x':
 46      xflag = 1;
 47      break;
 48    default:
 49      usage();
 50  }
 51  ARGEND;
 52
 53  if (argc < 1)
 54    usage();
 55
 56  if (stat(argv[0], &st1) < 0) {
 57    if (qflag)
 58      return 1;
 59    eprintf("stat %s:", argv[0]);
 60  }
 61
 62  if (xflag) {
 63    if (!S_ISBLK(st1.st_mode)) {
 64      if (qflag)
 65        return 1;
 66      eprintf("stat: %s: not a block device\n", argv[0]);
 67    }
 68    printf("%u:%u\n", major(st1.st_rdev), 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), minor(st1.st_dev));
 80    return 0;
 81  }
 82
 83  fp = setmntent(ARUU_LINUX_PATH_PROC_MOUNTS, "r");
 84  if (!fp) {
 85    if (qflag)
 86      return 1;
 87    eprintf("setmntent %s:", ARUU_LINUX_PATH_PROC_MOUNTS);
 88  }
 89  while ((me = getmntent(fp)) != NULL) {
 90    if (stat(me->mnt_dir, &st2) < 0) {
 91      if (qflag)
 92        return 1;
 93      eprintf("stat %s:", me->mnt_dir);
 94    }
 95    if (st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino)
 96      break;
 97  }
 98  endmntent(fp);
 99
100  if (me == NULL)
101    ret = 1;
102
103  if (!qflag)
104    printf("%s %s a mountpoint\n", argv[0], !ret ? "is" : "is not");
105
106  return ret;
107}