Browse Source

more filesystem permission things, add rm

K. Lange 2 years ago
parent
commit
35a2a4bc5c
9 changed files with 125 additions and 51 deletions
  1. 33 0
      apps/rm.c
  2. 11 8
      apps/touch.c
  3. 4 4
      base/usr/include/kernel/fs.h
  4. 27 10
      kernel/fs/vfs.c
  5. 2 2
      kernel/sys/syscall.c
  6. 1 1
      libc/stdio/stdio.c
  7. 17 11
      modules/ext2.c
  8. 11 5
      modules/packetfs.c
  9. 19 10
      modules/tmpfs.c

+ 33 - 0
apps/rm.c

@@ -0,0 +1,33 @@
+/* This file is part of ToaruOS and is released under the terms
+ * of the NCSA / University of Illinois License - see LICENSE.md
+ * Copyright (C) 2013-2018 K. Lange
+ *
+ * rm
+ *
+ * unlink a file
+ * (in theory)
+ *
+ * TODO: Support recursive, directory removal, etc.
+ */
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+
+int main(int argc, char * argv[]) {
+	if (argc < 2) {
+		fprintf(stderr, "usage: %s FILE...\n", argv[0]);
+		return 1;
+	}
+
+	int ret = 0;
+
+	for (int i = 1; i < argc; ++i) {
+		if (unlink(argv[i]) < 0) {
+			fprintf(stderr, "%s: %s: %s\n", argv[0], argv[i], strerror(errno));
+			ret = 1;
+		}
+	}
+
+	return ret;
+}

+ 11 - 8
apps/touch.c

@@ -1,8 +1,7 @@
 /* This file is part of ToaruOS and is released under the terms
  * of the NCSA / University of Illinois License - see LICENSE.md
  * Copyright (C) 2013 K. Lange
- */
-/*
+ *
  * touch
  *
  * Creates a file or updates its last-modified date.
@@ -10,6 +9,7 @@
  */
 #include <stdio.h>
 #include <string.h>
+#include <errno.h>
 
 int main(int argc, char * argv[]) {
 	if (argc < 2) {
@@ -17,12 +17,15 @@ int main(int argc, char * argv[]) {
 		return 1;
 	}
 
-	FILE * f = fopen(argv[1], "a");
-	if (!f) {
-		//perror(argv[0]);
-		return 1;
+	int out = 0;
+	for (int i = 1; i < argc; ++i) {
+		FILE * f = fopen(argv[i], "a");
+		if (!f) {
+			fprintf(stderr, "%s: %s: %s\n", argv[0], argv[i], strerror(errno));
+			out = 1;
+		}
+		fclose(f);
 	}
-	fclose(f);
 
-	return 0;
+	return out;
 }

+ 4 - 4
base/usr/include/kernel/fs.h

@@ -43,13 +43,13 @@ typedef void (*open_type_t) (struct fs_node *, unsigned int flags);
 typedef void (*close_type_t) (struct fs_node *);
 typedef struct dirent *(*readdir_type_t) (struct fs_node *, uint32_t);
 typedef struct fs_node *(*finddir_type_t) (struct fs_node *, char *name);
-typedef void (*create_type_t) (struct fs_node *, char *name, uint16_t permission);
-typedef void (*unlink_type_t) (struct fs_node *, char *name);
-typedef void (*mkdir_type_t) (struct fs_node *, char *name, uint16_t permission);
+typedef int (*create_type_t) (struct fs_node *, char *name, uint16_t permission);
+typedef int (*unlink_type_t) (struct fs_node *, char *name);
+typedef int (*mkdir_type_t) (struct fs_node *, char *name, uint16_t permission);
 typedef int (*ioctl_type_t) (struct fs_node *, int request, void * argp);
 typedef int (*get_size_type_t) (struct fs_node *);
 typedef int (*chmod_type_t) (struct fs_node *, int mode);
-typedef void (*symlink_type_t) (struct fs_node *, char * name, char * value);
+typedef int (*symlink_type_t) (struct fs_node *, char * name, char * value);
 typedef int (*readlink_type_t) (struct fs_node *, char * buf, size_t size);
 typedef int (*selectcheck_type_t) (struct fs_node *);
 typedef int (*selectwait_type_t) (struct fs_node *, void * process);

+ 27 - 10
kernel/fs/vfs.c

@@ -88,7 +88,7 @@ static struct dirent * readdir_mapper(fs_node_t *node, uint32_t index) {
 static fs_node_t * vfs_mapper(void) {
 	fs_node_t * fnode = malloc(sizeof(fs_node_t));
 	memset(fnode, 0x00, sizeof(fs_node_t));
-	fnode->mask = 0666;
+	fnode->mask = 0555;
 	fnode->flags   = FS_DIRECTORY;
 	fnode->readdir = readdir_mapper;
 	return fnode;
@@ -340,14 +340,17 @@ int create_file_fs(char *name, uint16_t permission) {
 		return -EACCES;
 	}
 
+	int ret = 0;
 	if (parent->create) {
-		parent->create(parent, f_path, permission);
+		ret = parent->create(parent, f_path, permission);
+	} else {
+		ret = -EINVAL;
 	}
 
 	free(path);
 	free(parent);
 
-	return 0;
+	return ret;
 }
 
 int unlink_fs(char * name) {
@@ -381,14 +384,22 @@ int unlink_fs(char * name) {
 		return -ENOENT;
 	}
 
+	if (!has_permission(parent, 02)) {
+		free(path);
+		free(parent);
+		return -EACCES;
+	}
+
+	int ret = 0;
 	if (parent->unlink) {
-		parent->unlink(parent, f_path);
+		ret = parent->unlink(parent, f_path);
+	} else {
+		ret = -EINVAL;
 	}
 
 	free(path);
 	free(parent);
-
-	return 0;
+	return ret;
 }
 
 int mkdir_fs(char *name, uint16_t permission) {
@@ -432,8 +443,11 @@ int mkdir_fs(char *name, uint16_t permission) {
 		return -ENOENT;
 	}
 
+	int ret = 0;
 	if (parent->mkdir) {
-		parent->mkdir(parent, f_path, permission);
+		ret = parent->mkdir(parent, f_path, permission);
+	} else {
+		ret = -EINVAL;
 	}
 
 	free(path);
@@ -442,7 +456,7 @@ int mkdir_fs(char *name, uint16_t permission) {
 	if (_exists) {
 		return -EEXIST;
 	}
-	return 0;
+	return ret;
 }
 
 fs_node_t *clone_fs(fs_node_t *source) {
@@ -484,14 +498,17 @@ int symlink_fs(char * target, char * name) {
 		return -ENOENT;
 	}
 
+	int ret = 0;
 	if (parent->symlink) {
-		parent->symlink(parent, target, f_path);
+		ret = parent->symlink(parent, target, f_path);
+	} else {
+		ret = -EINVAL;
 	}
 
 	free(path);
 	close_fs(parent);
 
-	return 0;
+	return ret;
 }
 
 int readlink_fs(fs_node_t *node, char * buf, uint32_t size) {

+ 2 - 2
kernel/sys/syscall.c

@@ -341,7 +341,7 @@ static int sys_chmod(char * file, int mode) {
 		/* Can group members change bits? I think it's only owners. */
 		if (current_process->user != 0 && current_process->user != fn->uid) {
 			close_fs(fn);
-			return -EPERM;
+			return -EACCES;
 		}
 		result = chmod_fs(fn, mode);
 		close_fs(fn);
@@ -359,7 +359,7 @@ static int sys_chown(char * file, int uid, int gid) {
 		/* TODO: Owners can change groups... */
 		if (current_process->user != 0) {
 			close_fs(fn);
-			return -EPERM;
+			return -EACCES;
 		}
 		result = chown_fs(fn, uid, gid);
 		close_fs(fn);

+ 1 - 1
libc/stdio/stdio.c

@@ -147,7 +147,7 @@ static void parse_mode(const char * mode, int * flags_, int * mask_) {
 	const char * x = mode;
 
 	int flags = 0;
-	int mask = 0;
+	int mask = 0644;
 
 	while (*x) {
 		if (*x == 'a') {

+ 17 - 11
modules/ext2.c

@@ -769,8 +769,8 @@ static unsigned int allocate_inode(ext2_fs_t * this) {
 	return node_no;
 }
 
-static void mkdir_ext2(fs_node_t * parent, char * name, uint16_t permission) {
-	if (!name) return;
+static int mkdir_ext2(fs_node_t * parent, char * name, uint16_t permission) {
+	if (!name) return -EINVAL;
 
 	ext2_fs_t * this = parent->device;
 
@@ -779,7 +779,7 @@ static void mkdir_ext2(fs_node_t * parent, char * name, uint16_t permission) {
 	if (check) {
 		debug_print(WARNING, "A file by this name already exists: %s", name);
 		free(check);
-		return; /* this should probably have a return value... */
+		return -EEXIST;
 	}
 
 	/* Allocate an inode for it */
@@ -860,10 +860,11 @@ static void mkdir_ext2(fs_node_t * parent, char * name, uint16_t permission) {
 
 	ext2_sync(this);
 
+	return 0;
 }
 
-static void create_ext2(fs_node_t * parent, char * name, uint16_t permission) {
-	if (!name) return;
+static int create_ext2(fs_node_t * parent, char * name, uint16_t permission) {
+	if (!name) return -EINVAL;
 
 	ext2_fs_t * this = parent->device;
 
@@ -872,7 +873,7 @@ static void create_ext2(fs_node_t * parent, char * name, uint16_t permission) {
 	if (check) {
 		debug_print(WARNING, "A file by this name already exists: %s", name);
 		free(check);
-		return; /* this should probably have a return value... */
+		return -EEXIST;
 	}
 
 	/* Allocate an inode for it */
@@ -921,6 +922,7 @@ static void create_ext2(fs_node_t * parent, char * name, uint16_t permission) {
 
 	ext2_sync(this);
 
+	return 0;
 }
 
 static int chmod_ext2(fs_node_t * node, int mode) {
@@ -1041,7 +1043,7 @@ static fs_node_t * finddir_ext2(fs_node_t *node, char *name) {
 	return outnode;
 }
 
-static void unlink_ext2(fs_node_t * node, char * name) {
+static int unlink_ext2(fs_node_t * node, char * name) {
 	/* XXX this is a very bad implementation */
 	ext2_fs_t * this = (ext2_fs_t *)node->device;
 
@@ -1085,7 +1087,7 @@ static void unlink_ext2(fs_node_t * node, char * name) {
 	free(inode);
 	if (!direntry) {
 		free(block);
-		return;
+		return -ENOENT;
 	}
 
 	direntry->inode = 0;
@@ -1094,6 +1096,8 @@ static void unlink_ext2(fs_node_t * node, char * name) {
 	free(block);
 
 	ext2_sync(this);
+
+	return 0;
 }
 
 
@@ -1262,8 +1266,8 @@ static struct dirent * readdir_ext2(fs_node_t *node, uint32_t index) {
 	return dirent;
 }
 
-static void symlink_ext2(fs_node_t * parent, char * target, char * name) {
-	if (!name) return;
+static int symlink_ext2(fs_node_t * parent, char * target, char * name) {
+	if (!name) return -EINVAL;
 
 	ext2_fs_t * this = parent->device;
 
@@ -1272,7 +1276,7 @@ static void symlink_ext2(fs_node_t * parent, char * target, char * name) {
 	if (check) {
 		debug_print(WARNING, "A file by this name already exists: %s", name);
 		free(check);
-		return; /* this should probably have a return value... */
+		return -EEXIST; /* this should probably have a return value... */
 	}
 
 	/* Allocate an inode for it */
@@ -1332,6 +1336,8 @@ static void symlink_ext2(fs_node_t * parent, char * target, char * name) {
 	free(inode);
 
 	ext2_sync(this);
+
+	return 0;
 }
 
 static int readlink_ext2(fs_node_t * node, char * buf, size_t size) {

+ 11 - 5
modules/packetfs.c

@@ -380,8 +380,8 @@ static fs_node_t * finddir_packetfs(fs_node_t * node, char * name) {
 	return NULL;
 }
 
-static void create_packetfs(fs_node_t *parent, char *name, uint16_t permission) {
-	if (!name) return;
+static int create_packetfs(fs_node_t *parent, char *name, uint16_t permission) {
+	if (!name) return -EINVAL;
 
 	pex_t * p = (pex_t *)parent->device;
 
@@ -394,7 +394,7 @@ static void create_packetfs(fs_node_t *parent, char *name, uint16_t permission)
 		if (!strcmp(name, t->name)) {
 			spin_unlock(p->lock);
 			/* Already exists */
-			return;
+			return -EEXIST;
 		}
 	}
 
@@ -413,14 +413,15 @@ static void create_packetfs(fs_node_t *parent, char *name, uint16_t permission)
 
 	spin_unlock(p->lock);
 
+	return 0;
 }
 
 static void destroy_pex(pex_ex_t * p) {
 	/* XXX */
 }
 
-static void unlink_packetfs(fs_node_t *parent, char *name) {
-	if (!name) return;
+static int unlink_packetfs(fs_node_t *parent, char *name) {
+	if (!name) return -EINVAL;
 
 	pex_t * p = (pex_t *)parent->device;
 
@@ -442,9 +443,14 @@ static void unlink_packetfs(fs_node_t *parent, char *name) {
 
 	if (i >= 0) {
 		list_remove(p->exchanges, i);
+	} else {
+		spin_unlock(p->lock);
+		return -ENOENT;
 	}
 
 	spin_unlock(p->lock);
+
+	return 0;
 }
 
 static fs_node_t * packetfs_manager(void) {

+ 19 - 10
modules/tmpfs.c

@@ -53,7 +53,7 @@ static struct tmpfs_file * tmpfs_file_new(char * name) {
 	return t;
 }
 
-static void symlink_tmpfs(fs_node_t * parent, char * target, char * name) {
+static int symlink_tmpfs(fs_node_t * parent, char * target, char * name) {
 	struct tmpfs_dir * d = (struct tmpfs_dir *)parent->device;
 	debug_print(NOTICE, "Creating TMPFS file (symlink) %s in %s", name, d->name);
 
@@ -63,7 +63,7 @@ static void symlink_tmpfs(fs_node_t * parent, char * target, char * name) {
 		if (!strcmp(name, t->name)) {
 			spin_unlock(tmpfs_lock);
 			debug_print(WARNING, "... already exists.");
-			return; /* Already exists */
+			return -EEXIST; /* Already exists */
 		}
 	}
 	spin_unlock(tmpfs_lock);
@@ -77,6 +77,8 @@ static void symlink_tmpfs(fs_node_t * parent, char * target, char * name) {
 	spin_lock(tmpfs_lock);
 	list_insert(d->files, t);
 	spin_unlock(tmpfs_lock);
+
+	return 0;
 }
 
 static int readlink_tmpfs(fs_node_t * node, char * buf, size_t size) {
@@ -403,7 +405,7 @@ static fs_node_t * finddir_tmpfs(fs_node_t * node, char * name) {
 	return NULL;
 }
 
-static void unlink_tmpfs(fs_node_t * node, char * name) {
+static int unlink_tmpfs(fs_node_t * node, char * name) {
 	struct tmpfs_dir * d = (struct tmpfs_dir *)node->device;
 	int i = -1, j = 0;
 	spin_lock(tmpfs_lock);
@@ -421,14 +423,17 @@ static void unlink_tmpfs(fs_node_t * node, char * name) {
 
 	if (i >= 0) {
 		list_remove(d->files, i);
+	} else {
+		spin_unlock(tmpfs_lock);
+		return -ENOENT;
 	}
 
 	spin_unlock(tmpfs_lock);
-	return;
+	return 0;
 }
 
-static void create_tmpfs(fs_node_t *parent, char *name, uint16_t permission) {
-	if (!name) return;
+static int create_tmpfs(fs_node_t *parent, char *name, uint16_t permission) {
+	if (!name) return -EINVAL;
 
 	struct tmpfs_dir * d = (struct tmpfs_dir *)parent->device;
 	debug_print(NOTICE, "Creating TMPFS file %s in %s", name, d->name);
@@ -439,7 +444,7 @@ static void create_tmpfs(fs_node_t *parent, char *name, uint16_t permission) {
 		if (!strcmp(name, t->name)) {
 			spin_unlock(tmpfs_lock);
 			debug_print(WARNING, "... already exists.");
-			return; /* Already exists */
+			return -EEXIST; /* Already exists */
 		}
 	}
 	spin_unlock(tmpfs_lock);
@@ -453,10 +458,12 @@ static void create_tmpfs(fs_node_t *parent, char *name, uint16_t permission) {
 	spin_lock(tmpfs_lock);
 	list_insert(d->files, t);
 	spin_unlock(tmpfs_lock);
+
+	return 0;
 }
 
-static void mkdir_tmpfs(fs_node_t * parent, char * name, uint16_t permission) {
-	if (!name) return;
+static int mkdir_tmpfs(fs_node_t * parent, char * name, uint16_t permission) {
+	if (!name) return -EINVAL;
 
 	struct tmpfs_dir * d = (struct tmpfs_dir *)parent->device;
 	debug_print(NOTICE, "Creating TMPFS directory %s (in %s)", name, d->name);
@@ -467,7 +474,7 @@ static void mkdir_tmpfs(fs_node_t * parent, char * name, uint16_t permission) {
 		if (!strcmp(name, t->name)) {
 			spin_unlock(tmpfs_lock);
 			debug_print(WARNING, "... already exists.");
-			return; /* Already exists */
+			return -EEXIST; /* Already exists */
 		}
 	}
 	spin_unlock(tmpfs_lock);
@@ -481,6 +488,8 @@ static void mkdir_tmpfs(fs_node_t * parent, char * name, uint16_t permission) {
 	spin_lock(tmpfs_lock);
 	list_insert(d->files, out);
 	spin_unlock(tmpfs_lock);
+
+	return 0;
 }
 
 static fs_node_t * tmpfs_from_dir(struct tmpfs_dir * d) {