17aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley/* mountpoint.c - Check if a directory is a mountpoint. 28ad2a7d440d6ace7dc0b0deac1f2b4c8e5cc3a97Elie De Brauwer * 38ad2a7d440d6ace7dc0b0deac1f2b4c8e5cc3a97Elie De Brauwer * Copyright 2012 Elie De Brauwer <eliedebrauwer@gmail.com> 48ad2a7d440d6ace7dc0b0deac1f2b4c8e5cc3a97Elie De Brauwer 5a92f4e1e2097fac6a5d35fc519861e92b39fbc8bRob LandleyUSE_MOUNTPOINT(NEWTOY(mountpoint, "<1qdx[-dx]", TOYFLAG_BIN)) 68ad2a7d440d6ace7dc0b0deac1f2b4c8e5cc3a97Elie De Brauwer 78ad2a7d440d6ace7dc0b0deac1f2b4c8e5cc3a97Elie De Brauwerconfig MOUNTPOINT 87aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley bool "mountpoint" 97aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley default y 107aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley help 117aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley usage: mountpoint [-q] [-d] directory 127aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley mountpoint [-q] [-x] device 137aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley 147aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley -q Be quiet, return zero if directory is a mountpoint 157aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley -d Print major/minor device number of the directory 167aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley -x Print major/minor device number of the block device 178ad2a7d440d6ace7dc0b0deac1f2b4c8e5cc3a97Elie De Brauwer*/ 188ad2a7d440d6ace7dc0b0deac1f2b4c8e5cc3a97Elie De Brauwer 19c0e56edaf256adb6c60c5a052525a1ffbb927901Rob Landley#define FOR_mountpoint 208ad2a7d440d6ace7dc0b0deac1f2b4c8e5cc3a97Elie De Brauwer#include "toys.h" 218ad2a7d440d6ace7dc0b0deac1f2b4c8e5cc3a97Elie De Brauwer 22afd712aabc1b5bb6782489e01b8228b9021232f0Rob Landleystatic void die(char *gripe) 23afd712aabc1b5bb6782489e01b8228b9021232f0Rob Landley{ 24afd712aabc1b5bb6782489e01b8228b9021232f0Rob Landley if (!(toys.optflags & FLAG_q)) printf("%s: not a %s\n", *toys.optargs, gripe); 25afd712aabc1b5bb6782489e01b8228b9021232f0Rob Landley 26afd712aabc1b5bb6782489e01b8228b9021232f0Rob Landley toys.exitval++; 27afd712aabc1b5bb6782489e01b8228b9021232f0Rob Landley xexit(); 28afd712aabc1b5bb6782489e01b8228b9021232f0Rob Landley} 29afd712aabc1b5bb6782489e01b8228b9021232f0Rob Landley 308ad2a7d440d6ace7dc0b0deac1f2b4c8e5cc3a97Elie De Brauwervoid mountpoint_main(void) 318ad2a7d440d6ace7dc0b0deac1f2b4c8e5cc3a97Elie De Brauwer{ 327aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley struct stat st1, st2; 33a92f4e1e2097fac6a5d35fc519861e92b39fbc8bRob Landley char *arg = *toys.optargs; 347aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley int quiet = toys.optflags & FLAG_q; 358ad2a7d440d6ace7dc0b0deac1f2b4c8e5cc3a97Elie De Brauwer 36d3a435e53c94ec25b4ae5fa2614f49ef8884e08aRob Landley if (lstat(arg, &st1)) perror_exit_raw(arg); 37a92f4e1e2097fac6a5d35fc519861e92b39fbc8bRob Landley 38a92f4e1e2097fac6a5d35fc519861e92b39fbc8bRob Landley if (toys.optflags & FLAG_x) { 397aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley if (S_ISBLK(st1.st_mode)) { 407aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley if (!quiet) printf("%u:%u\n", major(st1.st_rdev), minor(st1.st_rdev)); 41afd712aabc1b5bb6782489e01b8228b9021232f0Rob Landley 427aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley return; 437aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley } 44afd712aabc1b5bb6782489e01b8228b9021232f0Rob Landley die("block device"); 457aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley } 468ad2a7d440d6ace7dc0b0deac1f2b4c8e5cc3a97Elie De Brauwer 47afd712aabc1b5bb6782489e01b8228b9021232f0Rob Landley // TODO: Ignore the fact a file can be a mountpoint for --bind mounts. 48afd712aabc1b5bb6782489e01b8228b9021232f0Rob Landley if (!S_ISDIR(st1.st_mode)) die("directory"); 49a92f4e1e2097fac6a5d35fc519861e92b39fbc8bRob Landley 50a92f4e1e2097fac6a5d35fc519861e92b39fbc8bRob Landley arg = xmprintf("%s/..", arg); 51a92f4e1e2097fac6a5d35fc519861e92b39fbc8bRob Landley xstat(arg, &st2); 52a92f4e1e2097fac6a5d35fc519861e92b39fbc8bRob Landley if (CFG_TOYBOX_FREE) free(arg); 53a92f4e1e2097fac6a5d35fc519861e92b39fbc8bRob Landley 54a92f4e1e2097fac6a5d35fc519861e92b39fbc8bRob Landley // If the device is different, it's a mount point. If the device _and_ 55a92f4e1e2097fac6a5d35fc519861e92b39fbc8bRob Landley // inode are the same, it's probably "/". This misses --bind mounts from 56a92f4e1e2097fac6a5d35fc519861e92b39fbc8bRob Landley // elsewhere in the same filesystem, but so does the other one and in the 57a92f4e1e2097fac6a5d35fc519861e92b39fbc8bRob Landley // absence of a spec I guess that's the expected behavior? 58a92f4e1e2097fac6a5d35fc519861e92b39fbc8bRob Landley toys.exitval = !(st1.st_dev != st2.st_dev || st1.st_ino == st2.st_ino); 597aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley if (toys.optflags & FLAG_d) 607aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley printf("%u:%u\n", major(st1.st_dev), minor(st1.st_dev)); 61a92f4e1e2097fac6a5d35fc519861e92b39fbc8bRob Landley else if (!quiet) 62a92f4e1e2097fac6a5d35fc519861e92b39fbc8bRob Landley printf("%s is %sa mountpoint\n", *toys.optargs, toys.exitval ? "not " : ""); 638ad2a7d440d6ace7dc0b0deac1f2b4c8e5cc3a97Elie De Brauwer} 64