145 lines
3.2 KiB
C
145 lines
3.2 KiB
C
|
|
#include <lib.h>
|
|
#define mount _mount
|
|
#define umount _umount
|
|
#include <string.h>
|
|
#include <sys/mount.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <sys/stat.h>
|
|
#include <minix/syslib.h>
|
|
#include <minix/rs.h>
|
|
#include <minix/paths.h>
|
|
#define OK 0
|
|
|
|
#define FSPATH "/sbin/"
|
|
#define FSDEFAULT "mfs"
|
|
|
|
PRIVATE int rs_down(char *label)
|
|
{
|
|
char cmd[200];
|
|
if(strlen(_PATH_SERVICE)+strlen(label)+50 >= sizeof(cmd))
|
|
return -1;
|
|
sprintf(cmd, _PATH_SERVICE " down '%s'", label);
|
|
return system(cmd);
|
|
}
|
|
|
|
PUBLIC int mount(special, name, mountflags, type, args)
|
|
char *name, *special, *type, *args;
|
|
int mountflags;
|
|
{
|
|
int r;
|
|
message m;
|
|
struct stat statbuf;
|
|
char label[16];
|
|
char path[60];
|
|
char cmd[200];
|
|
char *p;
|
|
int reuse;
|
|
|
|
/* Default values. */
|
|
if (type == NULL) type = FSDEFAULT;
|
|
if (args == NULL) args = "";
|
|
reuse = 0;
|
|
|
|
/* Check mount flags */
|
|
if(mountflags & MS_REUSE) {
|
|
reuse = 1;
|
|
mountflags &= ~MS_REUSE; /* Temporary: turn off to not confuse VFS */
|
|
}
|
|
|
|
/* Make a label for the file system process. This label must be unique and
|
|
* may currently not exceed 16 characters including terminating null. For
|
|
* requests with an associated block device, we use the last path component
|
|
* name of the block special file (truncated to 12 characters, which is
|
|
* hopefully enough). For requests with no associated block device, we use
|
|
* the device number and inode of the mount point, in hexadecimal form.
|
|
*/
|
|
if (special) {
|
|
p = strrchr(special, '/');
|
|
p = p ? p + 1 : special;
|
|
if (strchr(p, '\'')) {
|
|
errno = EINVAL;
|
|
return -1;
|
|
}
|
|
sprintf(label, "fs_%.12s", p);
|
|
} else {
|
|
if (stat(name, &statbuf) < 0) return -1;
|
|
sprintf(label, "fs_%04x%x", statbuf.st_dev, statbuf.st_ino);
|
|
}
|
|
|
|
/* Tell VFS that we are passing in a 16-byte label. */
|
|
mountflags |= MS_LABEL16;
|
|
|
|
/* See if the given type is even remotely valid. */
|
|
if(strlen(FSPATH)+strlen(type) >= sizeof(path)) {
|
|
errno = E2BIG;
|
|
return -1;
|
|
}
|
|
strcpy(path, FSPATH);
|
|
strcat(path, type);
|
|
|
|
if(stat(path, &statbuf) != 0) {
|
|
errno = EINVAL;
|
|
return -1;
|
|
}
|
|
|
|
/* Sanity check on user input. */
|
|
if(strchr(args, '\'')) {
|
|
errno = EINVAL;
|
|
return -1;
|
|
}
|
|
|
|
if(strlen(_PATH_SERVICE)+strlen(path)+strlen(label)+
|
|
strlen(_PATH_SYSTEM_CONF)+strlen(args)+50 >= sizeof(cmd)) {
|
|
errno = E2BIG;
|
|
return -1;
|
|
}
|
|
|
|
sprintf(cmd, _PATH_SERVICE " %sup %s -label '%s' -config " _PATH_SYSTEM_CONF
|
|
" -args '%s%s'",
|
|
reuse ? "-r ": "", path, label, args[0] ? "-o " : "", args);
|
|
|
|
if((r = system(cmd)) != 0) {
|
|
fprintf(stderr, "mount: couldn't run %s\n", cmd);
|
|
errno = r;
|
|
return -1;
|
|
}
|
|
|
|
/* Now perform mount(). */
|
|
m.m1_i1 = special ? strlen(special) + 1 : 0;
|
|
m.m1_i2 = strlen(name) + 1;
|
|
m.m1_i3 = mountflags;
|
|
m.m1_p1 = special;
|
|
m.m1_p2 = name;
|
|
m.m1_p3 = label;
|
|
r = _syscall(VFS_PROC_NR, MOUNT, &m);
|
|
|
|
if(r != OK) {
|
|
/* If mount() failed, tell RS to shutdown MFS process.
|
|
* No error check - won't do anything with this error anyway.
|
|
*/
|
|
rs_down(label);
|
|
}
|
|
|
|
return r;
|
|
}
|
|
|
|
PUBLIC int umount(name)
|
|
_CONST char *name;
|
|
{
|
|
message m;
|
|
int r;
|
|
|
|
_loadname(name, &m);
|
|
r = _syscall(VFS_PROC_NR, UMOUNT, &m);
|
|
|
|
if(r == OK) {
|
|
/* VFS returns the label of the unmounted file system in the reply.
|
|
* As of writing, the size of the m3_ca1 field is 16 bytes.
|
|
*/
|
|
rs_down(m.m3_ca1);
|
|
}
|
|
|
|
return r;
|
|
}
|