dualinit

A meta-init system for linux
Log | Files | Refs | LICENSE

mount.c (3571B)


      1 #include "mount.h"
      2 
      3 #include <stdbool.h>
      4 #include <string.h>
      5 #include <sys/mount.h>
      6 
      7 
      8 const mount_option_t mount_options[] = {
      9 	{ "ro", MS_RDONLY, false },		/* read-only */
     10 	{ "rw", MS_RDONLY, true },		/* read-write */
     11 	{ "exec", MS_NOEXEC, true },	/* permit execution of binaries */
     12 	{ "noexec", MS_NOEXEC, false }, /* don't execute binaries */
     13 	{ "suid", MS_NOSUID, true },	/* honor suid executables */
     14 	{ "nosuid", MS_NOSUID, false }, /* don't honor suid executables */
     15 	{ "dev", MS_NODEV, true },		/* interpret device files  */
     16 	{ "nodev", MS_NODEV, false },	/* don't interpret devices */
     17 
     18 	{ "sync", MS_SYNCHRONOUS, false }, /* synchronous I/O */
     19 	{ "async", MS_SYNCHRONOUS, true }, /* asynchronous I/O */
     20 
     21 	{ "dirsync", MS_DIRSYNC, false },	  /* synchronous directory modifications */
     22 	{ "remount", MS_REMOUNT, true },	  /* alter flags of mounted FS */
     23 	{ "bind", MS_BIND, false },			  /* Remount part of the tree elsewhere */
     24 	{ "rbind", MS_BIND | MS_REC, false }, /* Idem, plus mounted subtrees */
     25 #ifdef MS_NOSUB
     26 	{ "sub", MS_NOSUB, MNT_INVERT }, /* allow submounts */
     27 	{ "nosub", MS_NOSUB },			 /* don't allow submounts */
     28 #endif
     29 #ifdef MS_SILENT
     30 	{ "silent", MS_SILENT, false }, /* be quiet  */
     31 	{ "loud", MS_SILENT, true },	/* print out messages. */
     32 #endif
     33 #ifdef MS_MANDLOCK
     34 	{ "mand", MS_MANDLOCK, false },	 /* Allow mandatory locks on this FS */
     35 	{ "nomand", MS_MANDLOCK, true }, /* Forbid mandatory locks on this FS */
     36 #endif
     37 #ifdef MS_NOATIME
     38 	{ "atime", MS_NOATIME, true },	  /* Update access time */
     39 	{ "noatime", MS_NOATIME, false }, /* Do not update access time */
     40 #endif
     41 #ifdef MS_I_VERSION
     42 	{ "iversion", MS_I_VERSION, false },  /* Update inode I_version time */
     43 	{ "noiversion", MS_I_VERSION, true }, /* Don't update inode I_version time */
     44 #endif
     45 #ifdef MS_NODIRATIME
     46 	{ "diratime", MS_NODIRATIME, true },	/* Update dir access times */
     47 	{ "nodiratime", MS_NODIRATIME, false }, /* Do not update dir access times */
     48 #endif
     49 #ifdef MS_RELATIME
     50 	{ "relatime", MS_RELATIME, false },	 /* Update access times relative to mtime/ctime */
     51 	{ "norelatime", MS_RELATIME, true }, /* Update access time without regard to mtime/ctime */
     52 #endif
     53 #ifdef MS_STRICTATIME
     54 	{ "strictatime", MS_STRICTATIME, false },  /* Strict atime semantics */
     55 	{ "nostrictatime", MS_STRICTATIME, true }, /* kernel default atime */
     56 #endif
     57 #ifdef MS_LAZYTIME
     58 	{ "lazytime", MS_LAZYTIME, false }, /* Update {a,m,c}time on the in-memory inode only */
     59 	{ "nolazytime", MS_LAZYTIME, true },
     60 #endif
     61 #ifdef MS_NOSYMFOLLOW
     62 	{ "symfollow", MS_NOSYMFOLLOW, true }, /* Don't follow symlinks */
     63 	{ "nosymfollow", MS_NOSYMFOLLOW, false },
     64 #endif
     65 	{ 0 }
     66 };
     67 
     68 int mount_flags(const char* options, const char** dest_ptr) {
     69 	int flags = 0;
     70 
     71 	char option[20];
     72 	char dest[strlen(options) + 1];
     73 	int	 option_size = 0;
     74 	int	 dest_size	 = 0;
     75 
     76 	while (1) {
     77 		if (*options == ',' || *options == '\0') {
     78 			option[option_size] = '\0';
     79 
     80 			for (const mount_option_t* flg = mount_options; flg->name != NULL; flg++) {
     81 				if (strcmp(flg->name, option) == 0) {
     82 					if (flg->invert)
     83 						flags &= ~flg->flags;
     84 					else
     85 						flags |= flg->flags;
     86 					option_size = 0;
     87 					break;
     88 				}
     89 			}
     90 
     91 			if (option_size > 0) {
     92 				if (dest_size > 0)
     93 					dest[dest_size++] = ',';
     94 				memcpy(dest + dest_size, option, option_size);
     95 				dest_size += option_size;
     96 				option_size = 0;
     97 			}
     98 
     99 			if (*options == '\0')
    100 				break;
    101 		} else {
    102 			option[option_size++] = *options;
    103 		}
    104 
    105 		options++;
    106 	}
    107 
    108 	if (dest_size > 0) {
    109 		dest[dest_size] = '\0';
    110 		*dest_ptr		= strdup(dest);
    111 	} else {
    112 		*dest_ptr = NULL;
    113 	}
    114 
    115 	return flags;
    116 }