aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordianshi <dianshi@main.lv>2020-06-22 21:50:17 +0100
committerdianshi <dianshi@main.lv>2020-06-22 21:50:17 +0100
commitf2b53c4cb1316bfd11068b4df1c6f25aa1133e53 (patch)
tree202f545529a3696e3bed208afc65fab0ca58c7c0
parent5f9e33ad5596bb4fc0814e59b9044bce8051c801 (diff)
downloadnmount-f2b53c4cb1316bfd11068b4df1c6f25aa1133e53.tar.gz
nmount-f2b53c4cb1316bfd11068b4df1c6f25aa1133e53.zip
First version that can mount some actual fs
-rw-r--r--Makefile3
-rw-r--r--README.txt4
-rw-r--r--nmount.c234
3 files changed, 203 insertions, 38 deletions
diff --git a/Makefile b/Makefile
index 217284f..5f8c38a 100644
--- a/Makefile
+++ b/Makefile
@@ -1,2 +1,3 @@
make:
- gcc nmount.c -o nmount \ No newline at end of file
+ gcc -Wall nmount.c -o nmount
+ gcc -static nmount.c -o nmount_static \ No newline at end of file
diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..e5ed452
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,4 @@
+
+nmount -t proc -d /proc2 -f nosuid,nodev,noexec
+nmount -v -t proc -d /Process -f nosuid,nodev,noexec
+nmount -v -t ext4 -s /dev/mmcblk0p7 -d /mnt/disk0 -f nodev,noexec,nosuid \ No newline at end of file
diff --git a/nmount.c b/nmount.c
index 8e51ec3..8142531 100644
--- a/nmount.c
+++ b/nmount.c
@@ -6,39 +6,47 @@
#include <fcntl.h>
#include <getopt.h>
#include <signal.h>
+#include <string.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+#include <errno.h>
+
/////////////////////////////////////////////////////////////////////////////////////////
/*FLAGS FROM KERNEL*/
-//#define MS_RDONLY 1 /* Mount read-only */
-//#define MS_NOSUID 2 /* Ignore suid and sgid bits */
-//#define MS_NODEV 4 /* Disallow access to device special files */
-//#define MS_NOEXEC 8 /* Disallow program execution */
-//#define MS_SYNCHRONOUS 16 /* Writes are synced at once */
-//#define MS_REMOUNT 32 /* Alter flags of a mounted FS */
-//#define MS_MANDLOCK 64 /* Allow mandatory locks on an FS */
-//#define MS_DIRSYNC 128 /* Directory modifications are synchronous */
-//#define MS_NOATIME 1024 /* Do not update access times. */
-//#define MS_NODIRATIME 2048 /* Do not update directory access times */
-//#define MS_BIND 4096
-//#define MS_MOVE 8192
-//#define MS_REC 16384
-//#define MS_VERBOSE 32768 /* War is peace. Verbosity is silence.
-// MS_VERBOSE is deprecated. */
-//#define MS_SILENT 32768
-//#define MS_POSIXACL (1<<16) /* VFS does not apply the umask */
-//#define MS_UNBINDABLE (1<<17) /* change to unbindable */
-//#define MS_PRIVATE (1<<18) /* change to private */
-//#define MS_SLAVE (1<<19) /* change to slave */
-//#define MS_SHARED (1<<20) /* change to shared */
-//#define MS_RELATIME (1<<21) /* Update atime relative to mtime/ctime. */
-//#define MS_KERNMOUNT (1<<22) /* this is a kern_mount call */
-//#define MS_I_VERSION (1<<23) /* Update inode I_version field */
-//#define MS_STRICTATIME (1<<24) /* Always perform atime updates */
-//#define MS_LAZYTIME (1<<25) /* Update the on-disk [acm]times lazily */
+#define _MS_RDONLY (1<<0)
+#define _MS_NOSUID (1<<1)
+#define _MS_NODEV (1<<2)
+#define _MS_NOEXEC (1<<3)
+#define _MS_SYNCHRONOUS (1<<4)
+#define _MS_REMOUNT (1<<5)
+#define _MS_MANDLOCK (1<<6)
+#define _MS_DIRSYNC (1<<7)
+#define _MS_NOATIME (1<<10)
+#define _MS_NODIRATIME (1<<11)
+#define _MS_BIND (1<<12)
+#define _MS_MOVE (1<<13)
+#define _MS_REC (1<<14)
+#define _MS_SILENT (1<<15)
+#define _MS_POSIXACL (1<<16)
+#define _MS_UNBINDABLE (1<<17)
+#define _MS_PRIVATE (1<<18)
+#define _MS_SLAVE (1<<19)
+#define _MS_SHARED (1<<20)
+#define _MS_RELATIME (1<<21)
+#define _MS_KERNMOUNT (1<<22)
+#define _MS_I_VERSION (1<<23)
+#define _MS_STRICTATIME (1<<24)
+#define _MS_LAZYTIME (1<<25)
#define STRUCT_LEN(VAR,STRUCT) ((sizeof(VAR)/sizeof(STRUCT))-1)
+#define max(a,b) \
+ ({ __typeof__ (a) _a = (a); \
+ __typeof__ (b) _b = (b); \
+ _a > _b ? _a : _b; })
+
typedef struct vfs_option_params {
char *val;
char *descr;
@@ -60,16 +68,17 @@ typedef struct vfs_options
{
char *options;
char *description;
- vfs_option_params **params;
+ vfs_option_params *params;
} vfs_options;
vfs_options vfs_options_proc[] =
{
- {"hidepid=\%u" ,"", &vfs_options_proc_params_hidepid},
- {"gid=\%u" ,"user group that can access process", &vfs_options_proc_params_gid},
+ {"hidepid=\%u" ,"", (struct vfs_option_params *)&vfs_options_proc_params_hidepid},
+ {"gid=\%u" ,"user group that can access process", (struct vfs_option_params *)&vfs_options_proc_params_gid},
{NULL,NULL,NULL}
};
+
static const struct vfs {
char *name;
long flags;
@@ -78,7 +87,7 @@ static const struct vfs {
} vfstab[] = {
{"devtmpfs", 0, "/Device", NULL},
{"mqueue", 0, "/MQueue/", NULL},
- {"proc", 0, "/Process", &vfs_options_proc},
+ {"proc", 0, "/Process", (struct vfs_options*)&vfs_options_proc},
{"tmpfs", 0, "/Ram", NULL},
{"sysfs", 0, "/System", NULL},
{"ext4", 0, NULL, NULL},
@@ -86,11 +95,31 @@ static const struct vfs {
{NULL, 0, NULL, NULL},
};
+static const struct mount_flags
+{
+ char *name;
+ unsigned long bitfield;
+} mountflgs[] = {
+ {"bind",_MS_BIND},
+ {"move",_MS_MOVE},
+ {"rdonly",_MS_RDONLY},
+ {"lazytime",_MS_LAZYTIME},
+ {"nodev",_MS_NODEV},
+ {"noexec",_MS_NOEXEC},
+ {"nosuid",_MS_NOSUID},
+ {"remount",_MS_REMOUNT},
+ {"silent",_MS_SILENT},
+ {"sync",_MS_SYNCHRONOUS},
+ {NULL,0},
+};
+
typedef struct {
- char *f_device;
+ char *f_source_dir;
+ char *f_target_dir;
char *f_type;
char *f_dir;
char *f_flags;//g_params.f_output = 1;
+ unsigned long mount_flags;
char *f_options;
int f_verbose;
int f_helper;
@@ -102,9 +131,9 @@ void helper(char *progname)
{
printf("Usage: %s [OPTS]\n\n"
"Version: 0.0.1 \n"
- "-d device to mount\n"
+ "-s source directory\n"
+ "-d target directory\n"
"-t filesystem type\n"
- "-d mount directory\n"
"-f mount flags\n"
"-o mount fs options\n"
"-v verbose output\n"
@@ -130,6 +159,33 @@ void sig_handler(int signo)
exit(0);
}
+int check_filetype(char *fsname)
+{
+ int i;
+ for (i=0;i<STRUCT_LEN(vfstab,struct vfs);i++)
+ {
+ if (strncmp(vfstab[i].name,fsname,max(strlen(vfstab[i].name),strlen(fsname))) == 0)
+ {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+unsigned long str2flag(char *opt)
+{
+ int i;
+ for (i=0;i<STRUCT_LEN(mountflgs, struct mount_flags);i++)
+ {
+ if (strncmp(mountflgs[i].name,opt,strlen(mountflgs[i].name)) == 0)
+ {
+ return mountflgs[i].bitfield;
+ }
+ }
+ return 0;
+}
+
int smount(
const char *source,
const char *target,
@@ -137,14 +193,26 @@ int smount(
unsigned long mountflags,
const void *data)
{
+ int ret=-1;
- return 0;
+ if (g_params.f_verbose)
+ {
+ printf("Syscal params:\n");
+ printf("source :%s\n",source);
+ printf("target :%s\n",target);
+ printf("filesystem :%s\n",filesystemtype);
+ printf("mountflags :%lu\n",mountflags);
+ printf("data :%016xxd\n",data);
+ }
+ ret = syscall(SYS_mount,source,target,filesystemtype,mountflags,data);
+
+ return ret;
}
int main(int argc, char **argv)
{
int c;
- int i;
+ int i,j,k;
printf("One big real mount\n");
@@ -153,9 +221,11 @@ int main(int argc, char **argv)
printf("cannot register signal handler\n");
exit(1);
}
+
+ memset(&g_params,0,sizeof(g_params));
//process arguments
- while ((c = getopt(argc, argv, "a")) != -1)
+ while ((c = getopt(argc, argv, "ad:t:f:o:vs:")) != -1)
{
switch (c)
{
@@ -163,7 +233,24 @@ int main(int argc, char **argv)
//g_params.f_output = 1;
g_params.f_helper = 1;
break;
-
+ case 's':
+ g_params.f_source_dir = optarg;
+ break;
+ case 'd':
+ g_params.f_target_dir = optarg;
+ break;
+ case 't':
+ g_params.f_type = optarg;
+ break;
+ case 'f':
+ g_params.f_flags = optarg;
+ break;
+ case 'o':
+ g_params.f_options = optarg;
+ break;
+ case 'v':
+ g_params.f_verbose = 1;
+ break;
default:
helper(argv[0]);
exit(1);
@@ -175,9 +262,82 @@ int main(int argc, char **argv)
for (i=0;i<STRUCT_LEN(vfstab,struct vfs);i++)
{
printf("%s %s\n",vfstab[i].name,vfstab[i].mountpoint);
+ if (vfstab[i].options != NULL)
+ {
+ j = 0;
+ while (vfstab[i].options[j].options != NULL)
+ {
+ printf("\t%s %s\n",
+ vfstab[i].options[j].options,
+ vfstab[i].options[j].description
+ );
+ k = 0;
+ while(vfstab[i].options[j].params[k].val != NULL)
+ {
+ printf("\t\t%s %s\n",
+ vfstab[i].options[j].params[k].val,
+ vfstab[i].options[j].params[k].descr
+ );
+ k++;
+ }
+ j++;
+ }
+ }
+ }
+ }
+
+ if (NULL != g_params.f_type)
+ {
+ if (check_filetype(g_params.f_type) != 1)
+ {
+ printf("Unknow file type %s\n",g_params.f_type);
+ printf("Supported formats: ");
+ for (i=0;i<STRUCT_LEN(vfstab,struct vfs);i++)
+ {
+ printf("%s ",vfstab[i].name);
+ }
+ printf("\n");
+ return 1;
}
}
+ if (NULL != g_params.f_flags)
+ {
+ char *token = strtok(g_params.f_flags,",");
+ printf("Flags: %d\n",g_params.mount_flags);
+ while ( token != NULL )
+ {
+ printf("Flags: %s\n",token);
+ g_params.mount_flags |= str2flag(token);
+ printf("Flags: %d\n",g_params.mount_flags);
+ token = strtok(NULL,",");
+ }
+ }
+
+ if (NULL != g_params.f_target_dir)
+ {
+ mkdir(g_params.f_target_dir, 0000);
+ }
+
+ if ((NULL != g_params.f_target_dir) &&
+ (NULL != g_params.f_flags) &&
+ (NULL != g_params.f_type) &&
+ (NULL != g_params.f_source_dir))
+ {
+ printf("Flags: %d\n",g_params.mount_flags);
+ int ret = smount(
+ g_params.f_source_dir,
+ g_params.f_target_dir,
+ g_params.f_type,
+ g_params.mount_flags,
+ "");
+ int err = errno;
+ printf("Mount exit code %d\n",ret);
+ if (ret==-1)
+ {
+ printf("Strerr: %d %s\n",err,strerror(err));
+ }
+ }
return 0;
}