From ef7b484e5cdbcd5f1224149fe86d8a62206cbf07 Mon Sep 17 00:00:00 2001 From: David van Moolenbroek Date: Mon, 9 Apr 2012 18:08:26 +0200 Subject: [PATCH] Create SFFS library out of HGFS This Shared Folders File System library (libsffs) now contains all the file system logic originally in HGFS. The actual HGFS server code is now a stub that passes on all the work to libsffs. The libhgfs library is changed accordingly. --- include/Makefile.minix.inc | 2 +- include/minix/hgfs.h | 55 +------ include/minix/sffs.h | 69 +++++++++ lib/Makefile | 6 +- lib/libhgfs/Makefile | 2 +- lib/libhgfs/attr.c | 30 ++-- lib/libhgfs/dir.c | 10 +- lib/libhgfs/file.c | 14 +- lib/libhgfs/{misc.c => hgfs.c} | 35 ++++- lib/libhgfs/inc.h | 13 +- lib/libhgfs/proto.h | 27 +++- lib/libsffs/Makefile | 9 ++ {servers/hgfs => lib/libsffs}/const.h | 4 + {servers/hgfs => lib/libsffs}/dentry.c | 2 +- lib/libsffs/glo.h | 19 +++ {servers/hgfs => lib/libsffs}/handle.c | 17 ++- lib/libsffs/inc.h | 24 +++ {servers/hgfs => lib/libsffs}/inode.c | 18 +-- {servers/hgfs => lib/libsffs}/inode.h | 18 +-- {servers/hgfs => lib/libsffs}/link.c | 65 ++++---- {servers/hgfs => lib/libsffs}/lookup.c | 50 +++--- lib/libsffs/main.c | 154 +++++++++++++++++++ {servers/hgfs => lib/libsffs}/misc.c | 6 +- {servers/hgfs => lib/libsffs}/mount.c | 36 ++--- {servers/hgfs => lib/libsffs}/name.c | 4 +- {servers/hgfs => lib/libsffs}/path.c | 7 +- {servers/hgfs => lib/libsffs}/proto.h | 14 +- {servers/hgfs => lib/libsffs}/read.c | 14 +- {servers/hgfs => lib/libsffs}/stat.c | 34 ++--- {servers/hgfs => lib/libsffs}/table.c | 0 lib/libsffs/type.h | 13 ++ {servers/hgfs => lib/libsffs}/util.c | 2 +- {servers/hgfs => lib/libsffs}/verify.c | 19 +-- {servers/hgfs => lib/libsffs}/write.c | 16 +- servers/hgfs/Makefile | 8 +- servers/hgfs/glo.h | 12 -- servers/hgfs/hgfs.c | 106 +++++++++++++ servers/hgfs/inc.h | 39 ----- servers/hgfs/main.c | 204 ------------------------- servers/hgfs/type.h | 19 --- share/mk/bsd.prog.mk | 2 +- 41 files changed, 664 insertions(+), 534 deletions(-) create mode 100644 include/minix/sffs.h rename lib/libhgfs/{misc.c => hgfs.c} (52%) create mode 100644 lib/libsffs/Makefile rename {servers/hgfs => lib/libsffs}/const.h (84%) rename {servers/hgfs => lib/libsffs}/dentry.c (98%) create mode 100644 lib/libsffs/glo.h rename {servers/hgfs => lib/libsffs}/handle.c (80%) create mode 100644 lib/libsffs/inc.h rename {servers/hgfs => lib/libsffs}/inode.c (94%) rename {servers/hgfs => lib/libsffs}/inode.h (93%) rename {servers/hgfs => lib/libsffs}/link.c (86%) rename {servers/hgfs => lib/libsffs}/lookup.c (83%) create mode 100644 lib/libsffs/main.c rename {servers/hgfs => lib/libsffs}/misc.c (93%) rename {servers/hgfs => lib/libsffs}/mount.c (68%) rename {servers/hgfs => lib/libsffs}/name.c (94%) rename {servers/hgfs => lib/libsffs}/path.c (91%) rename {servers/hgfs => lib/libsffs}/proto.h (83%) rename {servers/hgfs => lib/libsffs}/read.c (94%) rename {servers/hgfs => lib/libsffs}/stat.c (84%) rename {servers/hgfs => lib/libsffs}/table.c (100%) create mode 100644 lib/libsffs/type.h rename {servers/hgfs => lib/libsffs}/util.c (95%) rename {servers/hgfs => lib/libsffs}/verify.c (89%) rename {servers/hgfs => lib/libsffs}/write.c (91%) delete mode 100644 servers/hgfs/glo.h create mode 100644 servers/hgfs/hgfs.c delete mode 100644 servers/hgfs/inc.h delete mode 100644 servers/hgfs/main.c delete mode 100644 servers/hgfs/type.h diff --git a/include/Makefile.minix.inc b/include/Makefile.minix.inc index 7d540865e..d095e992d 100644 --- a/include/Makefile.minix.inc +++ b/include/Makefile.minix.inc @@ -14,7 +14,7 @@ INCS+= minix/acpi.h minix/audio_fw.h minix/bitmap.h \ minix/keymap.h minix/limits.h minix/mthread.h minix/minlib.h \ minix/netdriver.h minix/optset.h minix/partition.h minix/portio.h \ minix/priv.h minix/procfs.h minix/profile.h minix/queryparam.h \ - minix/rs.h minix/safecopies.h minix/sched.h minix/sef.h \ + minix/rs.h minix/safecopies.h minix/sched.h minix/sef.h minix/sffs.h \ minix/sound.h minix/spin.h minix/sys_config.h minix/sysinfo.h \ minix/syslib.h minix/sysutil.h minix/timers.h minix/type.h \ minix/tty.h minix/u64.h minix/usb.h minix/usb_ch9.h minix/vbox.h \ diff --git a/include/minix/hgfs.h b/include/minix/hgfs.h index 06d630edb..3e5a216a5 100644 --- a/include/minix/hgfs.h +++ b/include/minix/hgfs.h @@ -1,56 +1,11 @@ /* Part of libhgfs - (c) 2009, D.C. van Moolenbroek */ -#ifndef _HGFS_H -#define _HGFS_H +#ifndef _MINIX_HGFS_H +#define _MINIX_HGFS_H -#include -#include -#include +#include -typedef void *hgfs_file_t; /* handle to open file */ -typedef void *hgfs_dir_t; /* handle to directory search */ - -struct hgfs_attr { - u32_t a_mask; /* which fields to retrieve/set */ - mode_t a_mode; /* file type and permissions */ - u64_t a_size; /* file size */ - struct timespec a_crtime; /* file creation time */ - struct timespec a_atime; /* file access time */ - struct timespec a_mtime; /* file modification time */ - struct timespec a_ctime; /* file change time */ -}; - -#define HGFS_ATTR_SIZE 0x01 /* get/set file size */ -#define HGFS_ATTR_CRTIME 0x02 /* get/set file creation time */ -#define HGFS_ATTR_ATIME 0x04 /* get/set file access time */ -#define HGFS_ATTR_MTIME 0x08 /* get/set file modification time */ -#define HGFS_ATTR_CTIME 0x10 /* get/set file change time */ -#define HGFS_ATTR_MODE 0x20 /* get/set file mode */ - -int hgfs_init(void); +int hgfs_init(const struct sffs_table **tablep); void hgfs_cleanup(void); -int hgfs_open(char *path, int flags, int mode, hgfs_file_t *handle); -int hgfs_read(hgfs_file_t handle, char *buf, size_t size, u64_t offset); -int hgfs_write(hgfs_file_t handle, char *buf, size_t len, u64_t offset); -int hgfs_close(hgfs_file_t handle); - -size_t hgfs_readbuf(char **ptr); -size_t hgfs_writebuf(char **ptr); - -int hgfs_opendir(char *path, hgfs_dir_t *handle); -int hgfs_readdir(hgfs_dir_t handle, unsigned int index, char *buf, - size_t size, struct hgfs_attr *attr); -int hgfs_closedir(hgfs_dir_t handle); - -int hgfs_getattr(char *path, struct hgfs_attr *attr); -int hgfs_setattr(char *path, struct hgfs_attr *attr); - -int hgfs_mkdir(char *path, int mode); -int hgfs_unlink(char *path); -int hgfs_rmdir(char *path); -int hgfs_rename(char *opath, char *npath); - -int hgfs_queryvol(char *path, u64_t *free, u64_t *total); - -#endif /* _HGFS_H */ +#endif /* _MINIX_HGFS_H */ diff --git a/include/minix/sffs.h b/include/minix/sffs.h new file mode 100644 index 000000000..ee8425340 --- /dev/null +++ b/include/minix/sffs.h @@ -0,0 +1,69 @@ +/* Part of libsffs - (c) 2012, D.C. van Moolenbroek */ + +#ifndef _MINIX_SFFS_H +#define _MINIX_SFFS_H + +#include +#include +#include + +typedef void *sffs_file_t; /* handle to open file */ +typedef void *sffs_dir_t; /* handle to directory search */ + +struct sffs_attr { + u32_t a_mask; /* which fields to retrieve/set */ + mode_t a_mode; /* file type and permissions */ + u64_t a_size; /* file size */ + struct timespec a_crtime; /* file creation time */ + struct timespec a_atime; /* file access time */ + struct timespec a_mtime; /* file modification time */ + struct timespec a_ctime; /* file change time */ +}; + +#define SFFS_ATTR_SIZE 0x01 /* get/set file size */ +#define SFFS_ATTR_CRTIME 0x02 /* get/set file creation time */ +#define SFFS_ATTR_ATIME 0x04 /* get/set file access time */ +#define SFFS_ATTR_MTIME 0x08 /* get/set file modification time */ +#define SFFS_ATTR_CTIME 0x10 /* get/set file change time */ +#define SFFS_ATTR_MODE 0x20 /* get/set file mode */ + +struct sffs_table { + int (*t_open)(char *path, int flags, int mode, sffs_file_t *handle); + ssize_t (*t_read)(sffs_file_t handle, char *buf, size_t size, u64_t pos); + ssize_t (*t_write)(sffs_file_t handle, char *buf, size_t size, u64_t pos); + int (*t_close)(sffs_file_t handle); + + size_t (*t_readbuf)(char **ptr); + size_t (*t_writebuf)(char **ptr); + + int (*t_opendir)(char *path, sffs_dir_t *handle); + int (*t_readdir)(sffs_dir_t handle, unsigned int index, char *buf, + size_t size, struct sffs_attr *attr); + int (*t_closedir)(sffs_dir_t handle); + + int (*t_getattr)(char *path, struct sffs_attr *attr); + int (*t_setattr)(char *path, struct sffs_attr *attr); + + int (*t_mkdir)(char *path, int mode); + int (*t_unlink)(char *path); + int (*t_rmdir)(char *path); + int (*t_rename)(char *opath, char *npath); + + int (*t_queryvol)(char *path, u64_t *free, u64_t *total); +}; + +struct sffs_params { + char p_prefix[PATH_MAX]; /* prefix for all paths used */ + uid_t p_uid; /* UID that owns all files */ + gid_t p_gid; /* GID that owns all files */ + unsigned int p_file_mask; /* AND-mask to apply to file permissions */ + unsigned int p_dir_mask; /* AND-mask to apply to directory perms */ + int p_case_insens; /* case insensitivity flag */ +}; + +int sffs_init(char *name, const struct sffs_table *table, + struct sffs_params *params); +void sffs_signal(int signo); +void sffs_loop(void); + +#endif /* _MINIX_SFFS_H */ diff --git a/lib/Makefile b/lib/Makefile index 93f203dbf..86c4c9f84 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -2,11 +2,11 @@ SUBDIR= csu libcompat_minix libc libblockdriver libchardriver \ libnetdriver libedit libm libsys libtimers libutil \ - libl libhgfs libz libfetch libvtreefs libaudiodriver libmthread \ + libl libz libfetch libvtreefs libaudiodriver libmthread \ libexec libdevman libusb libminlib libasyn \ libddekit libminixfs libbdev libelf libminc libcrypt libterminfo \ - libcurses libvassert libutil libpuffs librefuse libbz2 libarchive libprop \ - libnetsock + libcurses libvassert libutil libpuffs librefuse libbz2 libarchive \ + libprop libnetsock libsffs libhgfs SUBDIR+= ../external/public-domain/xz/lib diff --git a/lib/libhgfs/Makefile b/lib/libhgfs/Makefile index d6d7a5292..49dad1731 100644 --- a/lib/libhgfs/Makefile +++ b/lib/libhgfs/Makefile @@ -2,6 +2,6 @@ LIB= hgfs SRCS= backdoor.S attr.c channel.c dir.c error.c file.c \ - info.c link.c misc.c path.c rpc.c time.c + hgfs.c info.c link.c path.c rpc.c time.c .include diff --git a/lib/libhgfs/attr.c b/lib/libhgfs/attr.c index 0043192b7..4814c7b40 100644 --- a/lib/libhgfs/attr.c +++ b/lib/libhgfs/attr.c @@ -8,7 +8,7 @@ * attr_get * *===========================================================================*/ void attr_get(attr) -struct hgfs_attr *attr; +struct sffs_attr *attr; { /* Get attribute information from the RPC buffer, storing the requested parts * in the given attr structure. @@ -20,16 +20,16 @@ struct hgfs_attr *attr; size_lo = RPC_NEXT32; size_hi = RPC_NEXT32; - if (attr->a_mask & HGFS_ATTR_SIZE) + if (attr->a_mask & SFFS_ATTR_SIZE) attr->a_size = make64(size_lo, size_hi); - time_get((attr->a_mask & HGFS_ATTR_CRTIME) ? &attr->a_crtime : NULL); - time_get((attr->a_mask & HGFS_ATTR_ATIME) ? &attr->a_atime : NULL); - time_get((attr->a_mask & HGFS_ATTR_MTIME) ? &attr->a_mtime : NULL); - time_get((attr->a_mask & HGFS_ATTR_CTIME) ? &attr->a_ctime : NULL); + time_get((attr->a_mask & SFFS_ATTR_CRTIME) ? &attr->a_crtime : NULL); + time_get((attr->a_mask & SFFS_ATTR_ATIME) ? &attr->a_atime : NULL); + time_get((attr->a_mask & SFFS_ATTR_MTIME) ? &attr->a_mtime : NULL); + time_get((attr->a_mask & SFFS_ATTR_CTIME) ? &attr->a_ctime : NULL); mode |= HGFS_PERM_TO_MODE(RPC_NEXT8); - if (attr->a_mask & HGFS_ATTR_MODE) attr->a_mode = mode; + if (attr->a_mask & SFFS_ATTR_MODE) attr->a_mode = mode; } /*===========================================================================* @@ -37,7 +37,7 @@ struct hgfs_attr *attr; *===========================================================================*/ int hgfs_getattr(path, attr) char *path; -struct hgfs_attr *attr; +struct sffs_attr *attr; { /* Get selected attributes of a file by path name. */ @@ -60,7 +60,7 @@ struct hgfs_attr *attr; *===========================================================================*/ int hgfs_setattr(path, attr) char *path; -struct hgfs_attr *attr; +struct sffs_attr *attr; { /* Set selected attributes of a file by path name. */ @@ -74,14 +74,14 @@ struct hgfs_attr *attr; * HGFS protocol version (v2/v3). */ mask = 0; - if (attr->a_mask & HGFS_ATTR_MODE) mask |= HGFS_ATTR_MODE; - if (attr->a_mask & HGFS_ATTR_SIZE) mask |= HGFS_ATTR_SIZE; - if (attr->a_mask & HGFS_ATTR_CRTIME) mask |= HGFS_ATTR_CRTIME; - if (attr->a_mask & HGFS_ATTR_ATIME) + if (attr->a_mask & SFFS_ATTR_MODE) mask |= HGFS_ATTR_MODE; + if (attr->a_mask & SFFS_ATTR_SIZE) mask |= HGFS_ATTR_SIZE; + if (attr->a_mask & SFFS_ATTR_CRTIME) mask |= HGFS_ATTR_CRTIME; + if (attr->a_mask & SFFS_ATTR_ATIME) mask |= HGFS_ATTR_ATIME | HGFS_ATTR_ATIME_SET; - if (attr->a_mask & HGFS_ATTR_MTIME) + if (attr->a_mask & SFFS_ATTR_MTIME) mask |= HGFS_ATTR_MTIME | HGFS_ATTR_MTIME_SET; - if (attr->a_mask & HGFS_ATTR_CTIME) mask |= HGFS_ATTR_CTIME; + if (attr->a_mask & SFFS_ATTR_CTIME) mask |= HGFS_ATTR_CTIME; RPC_NEXT8 = mask; diff --git a/lib/libhgfs/dir.c b/lib/libhgfs/dir.c index c73bf52c2..006a8f3c5 100644 --- a/lib/libhgfs/dir.c +++ b/lib/libhgfs/dir.c @@ -7,7 +7,7 @@ *===========================================================================*/ int hgfs_opendir(path, handle) char *path; -hgfs_dir_t *handle; +sffs_dir_t *handle; { /* Open a directory. Store a directory handle upon success. */ @@ -20,7 +20,7 @@ hgfs_dir_t *handle; if ((r = rpc_query()) != OK) return r; - *handle = (hgfs_dir_t)RPC_NEXT32; + *handle = (sffs_dir_t)RPC_NEXT32; return OK; } @@ -29,11 +29,11 @@ hgfs_dir_t *handle; * hgfs_readdir * *===========================================================================*/ int hgfs_readdir(handle, index, buf, size, attr) -hgfs_dir_t handle; +sffs_dir_t handle; unsigned int index; char *buf; size_t size; -struct hgfs_attr *attr; +struct sffs_attr *attr; { /* Read a directory entry from an open directory, using a zero-based index * number. Upon success, the resulting path name is stored in the given buffer @@ -67,7 +67,7 @@ struct hgfs_attr *attr; * hgfs_closedir * *===========================================================================*/ int hgfs_closedir(handle) -hgfs_dir_t handle; +sffs_dir_t handle; { /* Close an open directory. */ diff --git a/lib/libhgfs/file.c b/lib/libhgfs/file.c index 6fdeeb1b4..12f21c692 100644 --- a/lib/libhgfs/file.c +++ b/lib/libhgfs/file.c @@ -12,7 +12,7 @@ int hgfs_open(path, flags, mode, handle) char *path; /* path name to open */ int flags; /* open flags to use */ int mode; /* mode to create (user bits only) */ -hgfs_file_t *handle; /* place to store resulting handle */ +sffs_file_t *handle; /* place to store resulting handle */ { /* Open a file. Store a file handle upon success. */ @@ -42,7 +42,7 @@ hgfs_file_t *handle; /* place to store resulting handle */ if ((r = rpc_query()) != OK) return r; - *handle = (hgfs_file_t)RPC_NEXT32; + *handle = (sffs_file_t)RPC_NEXT32; return OK; } @@ -50,8 +50,8 @@ hgfs_file_t *handle; /* place to store resulting handle */ /*===========================================================================* * hgfs_read * *===========================================================================*/ -int hgfs_read(handle, buf, size, off) -hgfs_file_t handle; /* handle to open file */ +ssize_t hgfs_read(handle, buf, size, off) +sffs_file_t handle; /* handle to open file */ char *buf; /* data buffer or NULL */ size_t size; /* maximum number of bytes to read */ u64_t off; /* file offset */ @@ -84,8 +84,8 @@ u64_t off; /* file offset */ /*===========================================================================* * hgfs_write * *===========================================================================*/ -int hgfs_write(handle, buf, len, off) -hgfs_file_t handle; /* handle to open file */ +ssize_t hgfs_write(handle, buf, len, off) +sffs_file_t handle; /* handle to open file */ char *buf; /* data buffer or NULL */ size_t len; /* number of bytes to write */ u64_t off; /* file offset */ @@ -116,7 +116,7 @@ u64_t off; /* file offset */ * hgfs_close * *===========================================================================*/ int hgfs_close(handle) -hgfs_file_t handle; /* handle to open file */ +sffs_file_t handle; /* handle to open file */ { /* Close an open file. */ diff --git a/lib/libhgfs/misc.c b/lib/libhgfs/hgfs.c similarity index 52% rename from lib/libhgfs/misc.c rename to lib/libhgfs/hgfs.c index d81c5c71e..a7cbce5ff 100644 --- a/lib/libhgfs/misc.c +++ b/lib/libhgfs/hgfs.c @@ -2,18 +2,48 @@ #include "inc.h" +struct sffs_table hgfs_table = { + .t_open = hgfs_open, + .t_read = hgfs_read, + .t_write = hgfs_write, + .t_close = hgfs_close, + + .t_readbuf = hgfs_readbuf, + .t_writebuf = hgfs_writebuf, + + .t_opendir = hgfs_opendir, + .t_readdir = hgfs_readdir, + .t_closedir = hgfs_closedir, + + .t_getattr = hgfs_getattr, + .t_setattr = hgfs_setattr, + + .t_mkdir = hgfs_mkdir, + .t_unlink = hgfs_unlink, + .t_rmdir = hgfs_rmdir, + .t_rename = hgfs_rename, + + .t_queryvol = hgfs_queryvol, +}; + /*===========================================================================* * hgfs_init * *===========================================================================*/ -int hgfs_init() +int hgfs_init(const struct sffs_table **tablep) { /* Initialize the library. Return OK on success, or a negative error code * otherwise. If EAGAIN is returned, shared folders are disabled. */ + int r; time_init(); - return rpc_open(); + r = rpc_open(); + + if (r == OK) + *tablep = &hgfs_table; + + return r; } /*===========================================================================* @@ -26,3 +56,4 @@ void hgfs_cleanup() rpc_close(); } + diff --git a/lib/libhgfs/inc.h b/lib/libhgfs/inc.h index dcfd277c3..beb379648 100644 --- a/lib/libhgfs/inc.h +++ b/lib/libhgfs/inc.h @@ -1,16 +1,7 @@ /* Part of libhgfs - (c) 2009, D.C. van Moolenbroek */ -#ifndef __NBSD_LIBC -#define _POSIX_SOURCE 1 /* need PATH_MAX */ -#endif -#define _SYSTEM 1 /* need negative error codes */ - -#include -#include - -#include -#include - +#include +#include #include #define PREFIX(x) __libhgfs_##x diff --git a/lib/libhgfs/proto.h b/lib/libhgfs/proto.h index 7d38c72ed..e213d409c 100644 --- a/lib/libhgfs/proto.h +++ b/lib/libhgfs/proto.h @@ -2,7 +2,9 @@ /* attr.c */ #define attr_get PREFIX(attr_get) -void attr_get(struct hgfs_attr *attr); +void attr_get(struct sffs_attr *attr); +int hgfs_getattr(char *path, struct sffs_attr *attr); +int hgfs_setattr(char *path, struct sffs_attr *attr); /* backdoor.s */ #define backdoor PREFIX(backdoor) @@ -22,10 +24,33 @@ void channel_close(struct channel *ch); int channel_send(struct channel *ch, char *buf, int len); int channel_recv(struct channel *ch, char *buf, int max); +/* dir.c */ +int hgfs_opendir(char *path, sffs_dir_t *handle); +int hgfs_readdir(sffs_dir_t handle, unsigned int index, char *buf, size_t size, + struct sffs_attr *attr); +int hgfs_closedir(sffs_dir_t handle); + /* error.c */ #define error_convert PREFIX(error_convert) int error_convert(int err); +/* file.c */ +int hgfs_open(char *path, int flags, int mode, sffs_file_t *handle); +ssize_t hgfs_read(sffs_file_t handle, char *buf, size_t size, u64_t offset); +ssize_t hgfs_write(sffs_file_t handle, char *buf, size_t len, u64_t offset); +int hgfs_close(sffs_file_t handle); +size_t hgfs_readbuf(char **ptr); +size_t hgfs_writebuf(char **ptr); + +/* info.c */ +int hgfs_queryvol(char *path, u64_t *free, u64_t *total); + +/* link.c */ +int hgfs_mkdir(char *path, int mode); +int hgfs_unlink(char *path); +int hgfs_rmdir(char *path); +int hgfs_rename(char *opath, char *npath); + /* path.c */ #define path_put PREFIX(path_put) #define path_get PREFIX(path_get) diff --git a/lib/libsffs/Makefile b/lib/libsffs/Makefile new file mode 100644 index 000000000..615e52801 --- /dev/null +++ b/lib/libsffs/Makefile @@ -0,0 +1,9 @@ +# Makefile for libsffs +.include + +LIB= sffs + +SRCS= dentry.c handle.c inode.c link.c lookup.c main.c misc.c mount.c \ + name.c path.c read.c stat.c table.c util.c verify.c write.c + +.include diff --git a/servers/hgfs/const.h b/lib/libsffs/const.h similarity index 84% rename from servers/hgfs/const.h rename to lib/libsffs/const.h index 9b1bf337f..ca6c37886 100644 --- a/servers/hgfs/const.h +++ b/lib/libsffs/const.h @@ -1,3 +1,5 @@ +#ifndef _SFFS_CONST_H +#define _SFFS_CONST_H /* Number of inodes. */ /* The following number must not exceed 16. The i_num field is only a short. */ @@ -10,3 +12,5 @@ * Also used by getdents. This is not the underlying data transfer unit size. */ #define BLOCK_SIZE 4096 + +#endif /* _SFFS_CONST_H */ diff --git a/servers/hgfs/dentry.c b/lib/libsffs/dentry.c similarity index 98% rename from servers/hgfs/dentry.c rename to lib/libsffs/dentry.c index 26a938c75..076226ecc 100644 --- a/servers/hgfs/dentry.c +++ b/lib/libsffs/dentry.c @@ -177,7 +177,7 @@ char *name; unsigned int val; char buf[NAME_MAX+1], *p; - dprintf(("HGFS: hash_dentry for '%s'\n", name)); + dprintf(("%s: hash_dentry for '%s'\n", sffs_name, name)); normalize_name(buf, name); diff --git a/lib/libsffs/glo.h b/lib/libsffs/glo.h new file mode 100644 index 000000000..d0ef5d98f --- /dev/null +++ b/lib/libsffs/glo.h @@ -0,0 +1,19 @@ +#ifndef _SFFS_GLO_H +#define _SFFS_GLO_H + +#ifdef _TABLE +#undef EXTERN +#define EXTERN +#endif + +EXTERN char *sffs_name; /* file server name */ +EXTERN const struct sffs_table *sffs_table; /* call table */ +EXTERN struct sffs_params *sffs_params; /* parameters */ + +EXTERN message m_in; /* request message */ +EXTERN message m_out; /* reply message */ +EXTERN struct state state; /* global state */ + +extern int(*call_vec[]) (void); + +#endif /* _SFFS_GLO_H */ diff --git a/servers/hgfs/handle.c b/lib/libsffs/handle.c similarity index 80% rename from servers/hgfs/handle.c rename to lib/libsffs/handle.c index 27ee1fe07..d4663580f 100644 --- a/servers/hgfs/handle.c +++ b/lib/libsffs/handle.c @@ -31,17 +31,17 @@ struct inode *ino; return r; if (IS_DIR(ino)) { - r = hgfs_opendir(path, &ino->i_dir); + r = sffs_table->t_opendir(path, &ino->i_dir); } else { - if (!state.read_only) - r = hgfs_open(path, O_RDWR, 0, &ino->i_file); + if (!state.s_read_only) + r = sffs_table->t_open(path, O_RDWR, 0, &ino->i_file); /* Protection or mount status might prevent us from writing. With the * information that we have available, this is the best we can do.. */ - if (state.read_only || r != OK) - r = hgfs_open(path, O_RDONLY, 0, &ino->i_file); + if (state.s_read_only || r != OK) + r = sffs_table->t_open(path, O_RDONLY, 0, &ino->i_file); } if (r != OK) @@ -67,12 +67,13 @@ struct inode *ino; /* We ignore any errors here, because we can't deal with them anyway. */ if (IS_DIR(ino)) - r = hgfs_closedir(ino->i_dir); + r = sffs_table->t_closedir(ino->i_dir); else - r = hgfs_close(ino->i_file); + r = sffs_table->t_close(ino->i_file); if (r != OK) - printf("HGFS: put_handle: handle close operation returned %d\n", r); + printf("%s: put_handle: handle close operation returned %d\n", + sffs_name, r); ino->i_flags &= ~I_HANDLE; } diff --git a/lib/libsffs/inc.h b/lib/libsffs/inc.h new file mode 100644 index 000000000..cffad59da --- /dev/null +++ b/lib/libsffs/inc.h @@ -0,0 +1,24 @@ +#ifndef _SFFS_INC_H +#define _SFFS_INC_H + +#include +#include +#include +#include +#include +#include +#include + +#if DEBUG +#define dprintf(x) printf x +#else +#define dprintf(x) +#endif + +#include "type.h" +#include "const.h" +#include "proto.h" +#include "glo.h" +#include "inode.h" + +#endif /* _SFFS_INC_H */ diff --git a/servers/hgfs/inode.c b/lib/libsffs/inode.c similarity index 94% rename from servers/hgfs/inode.c rename to lib/libsffs/inode.c index 0320bde32..7b2e969b4 100644 --- a/servers/hgfs/inode.c +++ b/lib/libsffs/inode.c @@ -34,8 +34,8 @@ struct inode *init_inode() TAILQ_INIT(&free_list); - dprintf(("HGFS: %d inodes, %u bytes each, equals %u bytes\n", - NUM_INODES, sizeof(struct inode), sizeof(inodes))); + dprintf(("%s: %d inodes, %u bytes each, equals %u bytes\n", + sffs_name, NUM_INODES, sizeof(struct inode), sizeof(inodes))); /* Mark all inodes except the root inode as free. */ for (index = 1; index < NUM_INODES; index++) { @@ -76,7 +76,7 @@ ino_t ino_nr; /* Inode 0 (= index -1) is not a valid inode number. */ index = INODE_INDEX(ino_nr); if (index < 0) { - printf("HGFS: VFS passed invalid inode number!\n"); + printf("%s: VFS passed invalid inode number!\n", sffs_name); return NULL; } @@ -87,14 +87,14 @@ ino_t ino_nr; /* Make sure the generation number matches. */ if (INODE_GEN(ino_nr) != ino->i_gen) { - printf("HGFS: VFS passed outdated inode number!\n"); + printf("%s: VFS passed outdated inode number!\n", sffs_name); return NULL; } /* The VFS/FS protocol only uses referenced inodes. */ if (ino->i_ref == 0) - printf("HGFS: VFS passed unused inode!\n"); + printf("%s: VFS passed unused inode!\n", sffs_name); return ino; } @@ -109,7 +109,7 @@ struct inode *ino; * count were zero before, remove the inode from the free list. */ - dprintf(("HGFS: get_inode(%p) ['%s']\n", ino, ino->i_name)); + dprintf(("%s: get_inode(%p) ['%s']\n", sffs_name, ino, ino->i_name)); /* (INUSE, CACHED) -> INUSE */ @@ -134,7 +134,7 @@ struct inode *ino; * reached zero, mark the inode as cached or free. */ - dprintf(("HGFS: put_inode(%p) ['%s']\n", ino, ino->i_name)); + dprintf(("%s: put_inode(%p) ['%s']\n", sffs_name, ino, ino->i_name)); assert(ino != NULL); assert(ino->i_ref > 0); @@ -199,7 +199,7 @@ struct inode *ino; parent = ino->i_parent; LIST_REMOVE(ino, i_next); - + if (parent->i_ref == 0 && !HAS_CHILDREN(parent)) { if (parent->i_parent == NULL) TAILQ_INSERT_HEAD(&free_list, parent, i_free); @@ -223,7 +223,7 @@ struct inode *get_free_inode() /* If there are no inodes on the free list, we cannot satisfy the request. */ if (TAILQ_EMPTY(&free_list)) { - printf("HGFS: out of inodes!\n"); + printf("%s: out of inodes!\n", sffs_name); return NULL; } diff --git a/servers/hgfs/inode.h b/lib/libsffs/inode.h similarity index 93% rename from servers/hgfs/inode.h rename to lib/libsffs/inode.h index 42c820943..65c219491 100644 --- a/servers/hgfs/inode.h +++ b/lib/libsffs/inode.h @@ -1,5 +1,5 @@ -#ifndef _INODE_H -#define _INODE_H +#ifndef _SFFS_INODE_H +#define _SFFS_INODE_H /* We cannot use inode number 0, so to be able to use bitmasks to combine * inode and generation numbers, we have to use one fewer than the maximum of @@ -62,17 +62,13 @@ struct inode { unsigned short i_ref; /* VFS reference count */ unsigned short i_flags; /* any combination of I_* flags */ union { - TAILQ_ENTRY(inode) u_free; /* free list chain entry */ - hgfs_file_t u_file; /* handle to open file */ - hgfs_dir_t u_dir; /* handle to open directory */ - } i_u; + TAILQ_ENTRY(inode) i_free; /* free list chain entry */ + sffs_file_t i_file; /* handle to open file */ + sffs_dir_t i_dir; /* handle to open directory */ + }; char i_name[NAME_MAX+1]; /* entry name in parent directory */ }; -#define i_free i_u.u_free -#define i_file i_u.u_file -#define i_dir i_u.u_dir - #define I_DIR 0x01 /* this inode represents a directory */ #define I_HANDLE 0x02 /* this inode has an open handle */ @@ -89,4 +85,4 @@ struct inode { #define MODE_TO_DIRFLAG(m) (S_ISDIR(m) ? I_DIR : 0) -#endif /* _INODE_H */ +#endif /* _SFFS_INODE_H */ diff --git a/servers/hgfs/link.c b/lib/libsffs/link.c similarity index 86% rename from servers/hgfs/link.c rename to lib/libsffs/link.c index 51b6d906a..be877cc7f 100644 --- a/servers/hgfs/link.c +++ b/lib/libsffs/link.c @@ -26,12 +26,12 @@ int do_create() */ char path[PATH_MAX], name[NAME_MAX+1]; struct inode *parent, *ino; - struct hgfs_attr attr; - hgfs_file_t handle; + struct sffs_attr attr; + sffs_file_t handle; int r; /* We cannot create files on a read-only file system. */ - if (state.read_only) + if (state.s_read_only) return EROFS; /* Get path, name, parent inode and possibly inode for the given path. */ @@ -59,7 +59,8 @@ int do_create() } /* Perform the actual create call. */ - r = hgfs_open(path, O_CREAT | O_EXCL | O_RDWR, m_in.REQ_MODE, &handle); + r = sffs_table->t_open(path, O_CREAT | O_EXCL | O_RDWR, m_in.REQ_MODE, + &handle); if (r != OK) { /* Let's not try to be too clever with error codes here. If something @@ -73,17 +74,17 @@ int do_create() } /* Get the created file's attributes. */ - attr.a_mask = HGFS_ATTR_MODE | HGFS_ATTR_SIZE; - r = hgfs_getattr(path, &attr); + attr.a_mask = SFFS_ATTR_MODE | SFFS_ATTR_SIZE; + r = sffs_table->t_getattr(path, &attr); /* If this fails, or returns a directory, we have a problem. This * scenario is in fact possible with race conditions. * Simulate a close and return a somewhat appropriate error. */ if (r != OK || S_ISDIR(attr.a_mode)) { - printf("HGFS: lost file after creation!\n"); + printf("%s: lost file after creation!\n", sffs_name); - hgfs_close(handle); + sffs_table->t_close(handle); if (ino != NULL) { del_dentry(ino); @@ -94,7 +95,7 @@ int do_create() return (r == OK) ? EEXIST : r; } - /* We do assume that the HGFS open(O_CREAT|O_EXCL) did its job. + /* We do assume that the underlying open(O_CREAT|O_EXCL) call did its job. * If we previousy found an inode, get rid of it now. It's old. */ if (ino != NULL) { @@ -118,8 +119,8 @@ int do_create() m_out.RES_MODE = get_mode(ino, attr.a_mode); m_out.RES_FILE_SIZE_HI = ex64hi(attr.a_size); m_out.RES_FILE_SIZE_LO = ex64lo(attr.a_size); - m_out.RES_UID = opt.uid; - m_out.RES_GID = opt.gid; + m_out.RES_UID = sffs_params->p_uid; + m_out.RES_GID = sffs_params->p_gid; m_out.RES_DEV = NO_DEV; return OK; @@ -137,7 +138,7 @@ int do_mkdir() int r; /* We cannot create directories on a read-only file system. */ - if (state.read_only) + if (state.s_read_only) return EROFS; /* Get the path string and possibly an inode for the given path. */ @@ -153,7 +154,7 @@ int do_mkdir() return r; /* Perform the actual mkdir call. */ - r = hgfs_mkdir(path, m_in.REQ_MODE); + r = sffs_table->t_mkdir(path, m_in.REQ_MODE); if (r != OK) { if (ino != NULL) @@ -181,50 +182,50 @@ static int force_remove(path, dir) char *path; /* path to file or directory */ int dir; /* TRUE iff directory */ { -/* Remove a file or directory. Wrapper around hgfs_unlink and hgfs_rmdir that - * makes the target temporarily writable if the operation fails with an access - * denied error. On Windows hosts, read-only files or directories cannot be - * removed (even though they can be renamed). In general, the HGFS server - * follows the behavior of the host file system, but this case just confuses - * the hell out of the MINIX userland.. +/* Remove a file or directory. Wrapper around unlink and rmdir that makes the + * target temporarily writable if the operation fails with an access denied + * error. On Windows hosts, read-only files or directories cannot be removed + * (even though they can be renamed). In general, the SFFS library follows the + * behavior of the host file system, but this case just confuses the hell out + * of the MINIX userland.. */ - struct hgfs_attr attr; + struct sffs_attr attr; int r, r2; /* First try to remove the target. */ if (dir) - r = hgfs_rmdir(path); + r = sffs_table->t_rmdir(path); else - r = hgfs_unlink(path); + r = sffs_table->t_unlink(path); if (r != EACCES) return r; /* If this fails with an access error, retrieve the target's mode. */ - attr.a_mask = HGFS_ATTR_MODE; + attr.a_mask = SFFS_ATTR_MODE; - r2 = hgfs_getattr(path, &attr); + r2 = sffs_table->t_getattr(path, &attr); if (r2 != OK || (attr.a_mode & S_IWUSR)) return r; /* If the target is not writable, temporarily set it to writable. */ attr.a_mode |= S_IWUSR; - r2 = hgfs_setattr(path, &attr); + r2 = sffs_table->t_setattr(path, &attr); if (r2 != OK) return r; /* Then try the original operation again. */ if (dir) - r = hgfs_rmdir(path); + r = sffs_table->t_rmdir(path); else - r = hgfs_unlink(path); + r = sffs_table->t_unlink(path); if (r == OK) return r; /* If the operation still fails, unset the writable bit again. */ attr.a_mode &= ~S_IWUSR; - hgfs_setattr(path, &attr); + sffs_table->t_setattr(path, &attr); return r; } @@ -241,7 +242,7 @@ int do_unlink() int r; /* We cannot delete files on a read-only file system. */ - if (state.read_only) + if (state.s_read_only) return EROFS; /* Get the path string and possibly preexisting inode for the given path. */ @@ -288,7 +289,7 @@ int do_rmdir() int r; /* We cannot remove directories on a read-only file system. */ - if (state.read_only) + if (state.s_read_only) return EROFS; /* Get the path string and possibly preexisting inode for the given path. */ @@ -338,7 +339,7 @@ int do_rename() int r; /* We cannot do rename on a read-only file system. */ - if (state.read_only) + if (state.s_read_only) return EROFS; /* Get path strings, names, directory inodes and possibly preexisting inodes @@ -368,7 +369,7 @@ int do_rename() } /* Perform the actual rename call. */ - r = hgfs_rename(old_path, new_path); + r = sffs_table->t_rename(old_path, new_path); /* If we failed, or if we have nothing further to do: both inodes are * NULL, or they both refer to the same file. diff --git a/servers/hgfs/lookup.c b/lib/libsffs/lookup.c similarity index 83% rename from servers/hgfs/lookup.c rename to lib/libsffs/lookup.c index eb0154e97..e964f2730 100644 --- a/servers/hgfs/lookup.c +++ b/lib/libsffs/lookup.c @@ -10,13 +10,13 @@ #include "inc.h" static int get_mask(vfs_ucred_t *ucred); -static int access_as_dir(struct inode *ino, struct hgfs_attr *attr, int +static int access_as_dir(struct inode *ino, struct sffs_attr *attr, int uid, int mask); static int next_name(char **ptr, char **start, char name[NAME_MAX+1]); static int go_up(char path[PATH_MAX], struct inode *ino, struct inode - **res_ino, struct hgfs_attr *attr); + **res_ino, struct sffs_attr *attr); static int go_down(char path[PATH_MAX], struct inode *ino, char *name, - struct inode **res_ino, struct hgfs_attr *attr); + struct inode **res_ino, struct sffs_attr *attr); /*===========================================================================* * get_mask * @@ -29,12 +29,12 @@ vfs_ucred_t *ucred; /* credentials of the caller */ */ int i; - if (ucred->vu_uid == opt.uid) return S_IXUSR; + if (ucred->vu_uid == sffs_params->p_uid) return S_IXUSR; - if (ucred->vu_gid == opt.gid) return S_IXGRP; + if (ucred->vu_gid == sffs_params->p_gid) return S_IXGRP; for (i = 0; i < ucred->vu_ngroups; i++) - if (ucred->vu_sgroups[i] == opt.gid) return S_IXGRP; + if (ucred->vu_sgroups[i] == sffs_params->p_gid) return S_IXGRP; return S_IXOTH; } @@ -44,7 +44,7 @@ vfs_ucred_t *ucred; /* credentials of the caller */ *===========================================================================*/ static int access_as_dir(ino, attr, uid, mask) struct inode *ino; /* the inode to test */ -struct hgfs_attr *attr; /* attributes of the inode */ +struct sffs_attr *attr; /* attributes of the inode */ int uid; /* UID of the caller */ int mask; /* search access mask of the caller */ { @@ -53,7 +53,7 @@ int mask; /* search access mask of the caller */ */ mode_t mode; - assert(attr->a_mask & HGFS_ATTR_MODE); + assert(attr->a_mask & SFFS_ATTR_MODE); /* The inode must be a directory to begin with. */ if (!IS_DIR(ino)) return ENOTDIR; @@ -106,7 +106,7 @@ static int go_up(path, ino, res_ino, attr) char path[PATH_MAX]; /* path to take the last part from */ struct inode *ino; /* inode of the current directory */ struct inode **res_ino; /* place to store resulting inode */ -struct hgfs_attr *attr; /* place to store inode attributes */ +struct sffs_attr *attr; /* place to store inode attributes */ { /* Given an inode, progress into the parent directory. */ @@ -136,7 +136,7 @@ char path[PATH_MAX]; /* path to add the name to */ struct inode *parent; /* inode of the current directory */ char *name; /* name of the directory entry */ struct inode **res_ino; /* place to store resulting inode */ -struct hgfs_attr *attr; /* place to store inode attributes */ +struct sffs_attr *attr; /* place to store inode attributes */ { /* Given a directory inode and a name, progress into a directory entry. */ @@ -146,18 +146,18 @@ struct hgfs_attr *attr; /* place to store inode attributes */ if ((r = push_path(path, name)) != OK) return r; - dprintf(("HGFS: go_down: name '%s', path now '%s'\n", name, path)); + dprintf(("%s: go_down: name '%s', path now '%s'\n", sffs_name, name, path)); ino = lookup_dentry(parent, name); - dprintf(("HGFS: lookup_dentry('%s') returned %p\n", name, ino)); + dprintf(("%s: lookup_dentry('%s') returned %p\n", sffs_name, name, ino)); if (ino != NULL) r = verify_path(path, ino, attr, &stale); else - r = hgfs_getattr(path, attr); + r = sffs_table->t_getattr(path, attr); - dprintf(("HGFS: path query returned %d\n", r)); + dprintf(("%s: path query returned %d\n", sffs_name, r)); if (r != OK) { if (ino != NULL) { @@ -170,13 +170,13 @@ struct hgfs_attr *attr; /* place to store inode attributes */ return r; } - dprintf(("HGFS: name '%s'\n", name)); + dprintf(("%s: name '%s'\n", sffs_name, name)); if (ino == NULL) { if ((ino = get_free_inode()) == NULL) return ENFILE; - dprintf(("HGFS: inode %p ref %d\n", ino, ino->i_ref)); + dprintf(("%s: inode %p ref %d\n", sffs_name, ino, ino->i_ref)); ino->i_flags = MODE_TO_DIRFLAG(attr->a_mode); @@ -197,7 +197,7 @@ int do_lookup() ino_t dir_ino_nr, root_ino_nr; struct inode *cur_ino, *root_ino; struct inode *next_ino = NULL; - struct hgfs_attr attr; + struct sffs_attr attr; char buf[PATH_MAX], path[PATH_MAX]; char name[NAME_MAX+1]; char *ptr, *last; @@ -221,7 +221,7 @@ int do_lookup() return r; if (buf[len-1] != 0) { - printf("HGFS: VFS did not zero-terminate path!\n"); + printf("%s: VFS did not zero-terminate path!\n", sffs_name); return EINVAL; } @@ -231,7 +231,7 @@ int do_lookup() */ if (m_in.REQ_FLAGS & PATH_GET_UCRED) { if (m_in.REQ_UCRED_SIZE != sizeof(ucred)) { - printf("HGFS: bad credential structure size\n"); + printf("%s: bad credential structure size\n", sffs_name); return EINVAL; } @@ -251,12 +251,12 @@ int do_lookup() mask = get_mask(&ucred); /* Start the actual lookup. */ - dprintf(("HGFS: lookup: got query '%s'\n", buf)); + dprintf(("%s: lookup: got query '%s'\n", sffs_name, buf)); if ((cur_ino = find_inode(dir_ino_nr)) == NULL) return EINVAL; - attr.a_mask = HGFS_ATTR_MODE | HGFS_ATTR_SIZE; + attr.a_mask = SFFS_ATTR_MODE | SFFS_ATTR_SIZE; if ((r = verify_inode(cur_ino, path, &attr)) != OK) return r; @@ -279,7 +279,7 @@ int do_lookup() if ((r = next_name(&ptr, &last, name)) != OK) break; - dprintf(("HGFS: lookup: next name '%s'\n", name)); + dprintf(("%s: lookup: next name '%s'\n", sffs_name, name)); if (!strcmp(name, ".") || (cur_ino == root_ino && !strcmp(name, ".."))) @@ -304,7 +304,7 @@ int do_lookup() cur_ino = next_ino; } - dprintf(("HGFS: lookup: result %d\n", r)); + dprintf(("%s: lookup: result %d\n", sffs_name, r)); if (r != OK) { put_inode(cur_ino); @@ -324,8 +324,8 @@ int do_lookup() m_out.RES_MODE = get_mode(cur_ino, attr.a_mode); m_out.RES_FILE_SIZE_HI = ex64hi(attr.a_size); m_out.RES_FILE_SIZE_LO = ex64lo(attr.a_size); - m_out.RES_UID = opt.uid; - m_out.RES_GID = opt.gid; + m_out.RES_UID = sffs_params->p_uid; + m_out.RES_GID = sffs_params->p_gid; m_out.RES_DEV = NO_DEV; return OK; diff --git a/lib/libsffs/main.c b/lib/libsffs/main.c new file mode 100644 index 000000000..b45b7847e --- /dev/null +++ b/lib/libsffs/main.c @@ -0,0 +1,154 @@ +/* This file contains the SFFS initialization code and message loop. + * + * The entry points into this file are: + * sffs_init initialization + * sffs_signal signal handler + * sffs_loop main message loop + * + * Created: + * April 2009 (D.C. van Moolenbroek) + */ + +#include "inc.h" + +/*===========================================================================* + * sffs_init * + *===========================================================================*/ +int sffs_init(char *name, const struct sffs_table *table, + struct sffs_params *params) +{ +/* Initialize this file server. Called at startup time. + */ + int i; + + /* Make sure that the given path prefix doesn't end with a slash. */ + i = strlen(params->p_prefix); + while (i > 0 && params->p_prefix[i - 1] == '/') i--; + params->p_prefix[i] = 0; + + state.s_mounted = FALSE; + state.s_signaled = FALSE; + + sffs_name = name; + sffs_table = table; + sffs_params = params; + + return OK; +} + +/*===========================================================================* + * sffs_signal * + *===========================================================================*/ +void sffs_signal(int signo) +{ + + /* Only check for termination signal, ignore anything else. */ + if (signo != SIGTERM) return; + + /* We can now terminate if we have also been unmounted. */ + state.s_signaled = TRUE; + + if (state.s_mounted) { + dprintf(("%s: got SIGTERM, still mounted\n", sffs_name)); + } else { + dprintf(("%s: got SIGTERM, shutting down\n", sffs_name)); + + /* Break out of the main loop, giving the main program the chance to + * perform further cleanup. This causes sef_receive() to return with + * an EINTR error code. + */ + sef_cancel(); + } +} + +/*===========================================================================* + * get_work * + *===========================================================================*/ +static int get_work(who_e) +endpoint_t *who_e; +{ +/* Receive a request message from VFS. Return TRUE if a new message is ready + * to be processed, or FALSE if sef_stop() was called from the signal handler. + */ + int r; + + if ((r = sef_receive(ANY, &m_in)) != OK) { + if (r != EINTR) + panic("receive failed: %d", r); + + return FALSE; + } + + *who_e = m_in.m_source; + return TRUE; +} + +/*===========================================================================* + * send_reply * + *===========================================================================*/ +static void send_reply(err, transid) +int err; /* resulting error code */ +int transid; +{ +/* Send a reply message to the requesting party, with the given error code. + */ + int r; + + m_out.m_type = err; + if (IS_VFS_FS_TRANSID(transid)) { + /* If a transaction ID was set, reset it */ + m_out.m_type = TRNS_ADD_ID(m_out.m_type, transid); + } + if ((r = send(m_in.m_source, &m_out)) != OK) + printf("%s: send failed (%d)\n", sffs_name, r); +} + +/*===========================================================================* + * sffs_loop * + *===========================================================================*/ +void sffs_loop(void) +{ +/* The main function of this file server. After initializing, loop, receiving + * one request from VFS at a time, processing it, and sending a reply back to + * VFS. Termination occurs when we both have been unmounted and have received + * a termination signal. + */ + endpoint_t who_e; + int call_nr, err, transid; + + while (state.s_mounted || !state.s_signaled) { + if (!get_work(&who_e)) + continue; /* Recheck running conditions */ + + transid = TRNS_GET_ID(m_in.m_type); + m_in.m_type = TRNS_DEL_ID(m_in.m_type); + if (m_in.m_type == 0) { + assert(!IS_VFS_FS_TRANSID(transid)); + m_in.m_type = transid; /* Backwards compat. */ + transid = 0; + } else + assert(IS_VFS_FS_TRANSID(transid)); + + call_nr = m_in.m_type; + if (who_e != VFS_PROC_NR) { + continue; + } + + if (state.s_mounted || call_nr == REQ_READSUPER) { + call_nr -= VFS_BASE; + + dprintf(("%s: call %d\n", sffs_name, call_nr)); + + if (call_nr >= 0 && call_nr < NREQS) { + err = (*call_vec[call_nr])(); + } else { + err = ENOSYS; + } + + dprintf(("%s: call %d result %d\n", sffs_name, call_nr, err)); + } + else err = EINVAL; + + send_reply(err, transid); + } +} diff --git a/servers/hgfs/misc.c b/lib/libsffs/misc.c similarity index 93% rename from servers/hgfs/misc.c rename to lib/libsffs/misc.c index ad9aca32d..54e203b3b 100644 --- a/servers/hgfs/misc.c +++ b/lib/libsffs/misc.c @@ -52,7 +52,7 @@ int do_statvfs() if ((r = verify_inode(ino, path, NULL)) != OK) return r; - if ((r = hgfs_queryvol(path, &free, &total)) != OK) + if ((r = sffs_table->t_queryvol(path, &free, &total)) != OK) return r; memset(&statvfs, 0, sizeof(statvfs)); @@ -68,8 +68,8 @@ int do_statvfs() statvfs.f_files = 0; statvfs.f_ffree = 0; statvfs.f_favail = 0; - statvfs.f_fsid = state.dev; - statvfs.f_flag = state.read_only ? ST_RDONLY : 0; + statvfs.f_fsid = state.s_dev; + statvfs.f_flag = state.s_read_only ? ST_RDONLY : 0; statvfs.f_flag |= ST_NOTRUNC; statvfs.f_namemax = NAME_MAX; diff --git a/servers/hgfs/mount.c b/lib/libsffs/mount.c similarity index 68% rename from servers/hgfs/mount.c rename to lib/libsffs/mount.c index 729ea01f6..1649f2c5c 100644 --- a/servers/hgfs/mount.c +++ b/lib/libsffs/mount.c @@ -19,35 +19,38 @@ int do_readsuper() */ char path[PATH_MAX]; struct inode *ino; - struct hgfs_attr attr; + struct sffs_attr attr; int r; - dprintf(("HGFS: readsuper (dev %x, flags %x)\n", - (dev_t) m_in.REQ_DEV, m_in.REQ_FLAGS)); + dprintf(("%s: readsuper (dev %x, flags %x)\n", + sffs_name, (dev_t) m_in.REQ_DEV, m_in.REQ_FLAGS)); if (m_in.REQ_FLAGS & REQ_ISROOT) { - printf("HGFS: attempt to mount as root device\n"); + printf("%s: attempt to mount as root device\n", sffs_name); return EINVAL; } - state.read_only = !!(m_in.REQ_FLAGS & REQ_RDONLY); - state.dev = m_in.REQ_DEV; + state.s_read_only = !!(m_in.REQ_FLAGS & REQ_RDONLY); + state.s_dev = m_in.REQ_DEV; init_dentry(); ino = init_inode(); - attr.a_mask = HGFS_ATTR_MODE | HGFS_ATTR_SIZE; + attr.a_mask = SFFS_ATTR_MODE | SFFS_ATTR_SIZE; /* We cannot continue if we fail to get the properties of the root inode at * all, because we cannot guess the details of the root node to return to * VFS. Print a (hopefully) helpful error message, and abort the mount. */ if ((r = verify_inode(ino, path, &attr)) != OK) { - if (opt.prefix[0] && (r == ENOENT || r == EACCES)) - printf("HGFS: unable to access the given prefix directory\n"); + if (r == EAGAIN) + printf("%s: shared folders disabled\n", sffs_name); + else if (sffs_params->p_prefix[0] && (r == ENOENT || r == EACCES)) + printf("%s: unable to access the given prefix directory\n", + sffs_name); else - printf("HGFS: unable to access shared folders\n"); + printf("%s: unable to access shared folders\n", sffs_name); return r; } @@ -56,13 +59,12 @@ int do_readsuper() m_out.RES_MODE = get_mode(ino, attr.a_mode); m_out.RES_FILE_SIZE_HI = ex64hi(attr.a_size); m_out.RES_FILE_SIZE_LO = ex64lo(attr.a_size); - m_out.RES_UID = opt.uid; - m_out.RES_GID = opt.gid; + m_out.RES_UID = sffs_params->p_uid; + m_out.RES_GID = sffs_params->p_gid; m_out.RES_DEV = NO_DEV; - m_out.RES_CONREQS = 1; /* We can handle only 1 request at a time */ - state.mounted = TRUE; + state.s_mounted = TRUE; return OK; } @@ -76,7 +78,7 @@ int do_unmount() */ struct inode *ino; - dprintf(("HGFS: do_unmount\n")); + dprintf(("%s: do_unmount\n", sffs_name)); /* Decrease the reference count of the root inode. */ if ((ino = find_inode(ROOT_INODE_NR)) == NULL) @@ -86,9 +88,9 @@ int do_unmount() /* There should not be any referenced inodes anymore now. */ if (have_used_inode()) - printf("HGFS: in-use inodes left at unmount time!\n"); + printf("%s: in-use inodes left at unmount time!\n", sffs_name); - state.mounted = FALSE; + state.s_mounted = FALSE; return OK; } diff --git a/servers/hgfs/name.c b/lib/libsffs/name.c similarity index 94% rename from servers/hgfs/name.c rename to lib/libsffs/name.c index 28a8d4254..8aeee562c 100644 --- a/servers/hgfs/name.c +++ b/lib/libsffs/name.c @@ -28,7 +28,7 @@ char *src; assert(size <= NAME_MAX+1); - if (opt.case_insens) { + if (sffs_params->p_case_insens) { for (i = 0; i < size; i++) *dst++ = tolower(*src++); } @@ -47,7 +47,7 @@ char *name2; */ int r; - if (opt.case_insens) + if (sffs_params->p_case_insens) r = strcasecmp(name1, name2); else r = strcmp(name1, name2); diff --git a/servers/hgfs/path.c b/lib/libsffs/path.c similarity index 91% rename from servers/hgfs/path.c rename to lib/libsffs/path.c index 0ba1384be..272ca4245 100644 --- a/servers/hgfs/path.c +++ b/lib/libsffs/path.c @@ -26,10 +26,11 @@ struct inode *ino; p = &buf[sizeof(buf) - 1]; p[0] = 0; - dprintf(("HGFS: make_path: constructing path for inode %d\n", ino->i_num)); + dprintf(("%s: make_path: constructing path for inode %d\n", + sffs_name, ino->i_num)); /* Get the length of the prefix, skipping any leading slashes. */ - for (prefix = opt.prefix; prefix[0] == '/'; prefix++); + for (prefix = sffs_params->p_prefix; prefix[0] == '/'; prefix++); plen = strlen(prefix); /* Construct the path right-to-left in a temporary buffer first. */ @@ -60,7 +61,7 @@ struct inode *ino; strcpy(path, prefix); strcpy(&path[plen], p); - dprintf(("HGFS: make_path: resulting path is '%s'\n", path)); + dprintf(("%s: make_path: resulting path is '%s'\n", sffs_name, path)); return OK; } diff --git a/servers/hgfs/proto.h b/lib/libsffs/proto.h similarity index 83% rename from servers/hgfs/proto.h rename to lib/libsffs/proto.h index 2958b3b8d..fcc1a76aa 100644 --- a/servers/hgfs/proto.h +++ b/lib/libsffs/proto.h @@ -1,3 +1,5 @@ +#ifndef _SFFS_PROTO_H +#define _SFFS_PROTO_H /* dentry.c */ void init_dentry(void); @@ -67,13 +69,15 @@ int do_noop(void); int no_sys(void); /* verify.c */ -int verify_path(char *path, struct inode *ino, struct hgfs_attr *attr, +int verify_path(char *path, struct inode *ino, struct sffs_attr *attr, int *stale); -int verify_inode(struct inode *ino, char path[PATH_MAX], struct - hgfs_attr *attr); -int verify_dentry(struct inode *parent, char name[NAME_MAX+1], char - path[PATH_MAX], struct inode **res_ino); +int verify_inode(struct inode *ino, char path[PATH_MAX], + struct sffs_attr *attr); +int verify_dentry(struct inode *parent, char name[NAME_MAX+1], + char path[PATH_MAX], struct inode **res_ino); /* write.c */ int do_write(void); int do_ftrunc(void); + +#endif /* _SFFS_PROTO_H */ diff --git a/servers/hgfs/read.c b/lib/libsffs/read.c similarity index 94% rename from servers/hgfs/read.c rename to lib/libsffs/read.c index 4f0eae527..a8ddf0812 100644 --- a/servers/hgfs/read.c +++ b/lib/libsffs/read.c @@ -41,14 +41,14 @@ int do_read() assert(count > 0); - /* Use the buffer from libhgfs to eliminate extra copying. */ - size = hgfs_readbuf(&ptr); + /* Use the buffer from below to eliminate extra copying. */ + size = sffs_table->t_readbuf(&ptr); off = 0; while (count > 0) { chunk = MIN(count, size); - if ((r = hgfs_read(ino->i_file, ptr, chunk, pos)) <= 0) + if ((r = sffs_table->t_read(ino->i_file, ptr, chunk, pos)) <= 0) break; chunk = r; @@ -84,14 +84,14 @@ int do_getdents() char name[NAME_MAX+1]; struct inode *ino, *child; struct dirent *dent; - struct hgfs_attr attr; + struct sffs_attr attr; size_t len, off, user_off, user_left; off_t pos; int r; /* must be at least sizeof(struct dirent) + NAME_MAX */ static char buf[BLOCK_SIZE]; - attr.a_mask = HGFS_ATTR_MODE; + attr.a_mask = SFFS_ATTR_MODE; if ((ino = find_inode(m_in.REQ_INODE_NR)) == NULL) return EINVAL; @@ -141,8 +141,8 @@ int do_getdents() } else { /* Any other entry, not being "." or "..". */ - r = hgfs_readdir(ino->i_dir, pos - 2, name, sizeof(name), - &attr); + r = sffs_table->t_readdir(ino->i_dir, pos - 2, name, + sizeof(name), &attr); if (r != OK) { /* No more entries? Then close the handle and stop. */ diff --git a/servers/hgfs/stat.c b/lib/libsffs/stat.c similarity index 84% rename from servers/hgfs/stat.c rename to lib/libsffs/stat.c index eb0a5dec3..a3351d71e 100644 --- a/servers/hgfs/stat.c +++ b/lib/libsffs/stat.c @@ -26,11 +26,11 @@ int mode; mode = mode | (mode >> 3) | (mode >> 6); if (IS_DIR(ino)) - mode = S_IFDIR | (mode & opt.dir_mask); + mode = S_IFDIR | (mode & sffs_params->p_dir_mask); else - mode = S_IFREG | (mode & opt.file_mask); + mode = S_IFREG | (mode & sffs_params->p_file_mask); - if (state.read_only) + if (state.s_read_only) mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH); return mode; @@ -44,7 +44,7 @@ int do_stat() /* Retrieve inode status. */ struct inode *ino; - struct hgfs_attr attr; + struct sffs_attr attr; struct stat stat; char path[PATH_MAX]; ino_t ino_nr; @@ -56,19 +56,19 @@ int do_stat() if ((ino = find_inode(ino_nr)) == NULL) return EINVAL; - attr.a_mask = HGFS_ATTR_MODE | HGFS_ATTR_SIZE | HGFS_ATTR_CRTIME | - HGFS_ATTR_ATIME | HGFS_ATTR_MTIME | HGFS_ATTR_CTIME; + attr.a_mask = SFFS_ATTR_MODE | SFFS_ATTR_SIZE | SFFS_ATTR_CRTIME | + SFFS_ATTR_ATIME | SFFS_ATTR_MTIME | SFFS_ATTR_CTIME; if ((r = verify_inode(ino, path, &attr)) != OK) return r; memset(&stat, 0, sizeof(struct stat)); - stat.st_dev = state.dev; + stat.st_dev = state.s_dev; stat.st_ino = ino_nr; stat.st_mode = get_mode(ino, attr.a_mode); - stat.st_uid = opt.uid; - stat.st_gid = opt.gid; + stat.st_uid = sffs_params->p_uid; + stat.st_gid = sffs_params->p_gid; stat.st_rdev = NO_DEV; if (cmp64u(attr.a_size, LONG_MAX) > 0) stat.st_size = LONG_MAX; @@ -109,10 +109,10 @@ int do_chmod() */ struct inode *ino; char path[PATH_MAX]; - struct hgfs_attr attr; + struct sffs_attr attr; int r; - if (state.read_only) + if (state.s_read_only) return EROFS; if ((ino = find_inode(m_in.REQ_INODE_NR)) == NULL) @@ -122,10 +122,10 @@ int do_chmod() return r; /* Set the new file mode. */ - attr.a_mask = HGFS_ATTR_MODE; + attr.a_mask = SFFS_ATTR_MODE; attr.a_mode = m_in.REQ_MODE; /* no need to convert in this direction */ - if ((r = hgfs_setattr(path, &attr)) != OK) + if ((r = sffs_table->t_setattr(path, &attr)) != OK) return r; /* We have no idea what really happened. Query for the mode again. */ @@ -146,10 +146,10 @@ int do_utime() */ struct inode *ino; char path[PATH_MAX]; - struct hgfs_attr attr; + struct sffs_attr attr; int r; - if (state.read_only) + if (state.s_read_only) return EROFS; if ((ino = find_inode(m_in.REQ_INODE_NR)) == NULL) @@ -158,11 +158,11 @@ int do_utime() if ((r = verify_inode(ino, path, NULL)) != OK) return r; - attr.a_mask = HGFS_ATTR_ATIME | HGFS_ATTR_MTIME; + attr.a_mask = SFFS_ATTR_ATIME | SFFS_ATTR_MTIME; attr.a_atime.tv_sec = m_in.REQ_ACTIME; attr.a_atime.tv_nsec = 0; attr.a_mtime.tv_sec = m_in.REQ_MODTIME; attr.a_mtime.tv_nsec = 0; - return hgfs_setattr(path, &attr); + return sffs_table->t_setattr(path, &attr); } diff --git a/servers/hgfs/table.c b/lib/libsffs/table.c similarity index 100% rename from servers/hgfs/table.c rename to lib/libsffs/table.c diff --git a/lib/libsffs/type.h b/lib/libsffs/type.h new file mode 100644 index 000000000..c5ad74e9b --- /dev/null +++ b/lib/libsffs/type.h @@ -0,0 +1,13 @@ +#ifndef _SFFS_TYPE_H +#define _SFFS_TYPE_H + +/* Structure with global file system state. */ +struct state { + int s_mounted; /* is the file system mounted? */ + int s_signaled; /* have we received a SIGTERM? */ + int s_read_only; /* is the file system mounted read-only? note, + * has no relation to the shared folder mode */ + dev_t s_dev; /* device the file system is mounted on */ +}; + +#endif /* _SFFS_TYPE_H */ diff --git a/servers/hgfs/util.c b/lib/libsffs/util.c similarity index 95% rename from servers/hgfs/util.c rename to lib/libsffs/util.c index cf23e183a..3664dbc36 100644 --- a/servers/hgfs/util.c +++ b/lib/libsffs/util.c @@ -32,7 +32,7 @@ char name[NAME_MAX+1]; /* buffer in which store the result */ if (r != OK) return r; if (name[len-1] != 0) { - printf("HGFS: VFS did not zero-terminate path component!\n"); + printf("%s: VFS did not zero-terminate path component!\n", sffs_name); return EINVAL; } diff --git a/servers/hgfs/verify.c b/lib/libsffs/verify.c similarity index 89% rename from servers/hgfs/verify.c rename to lib/libsffs/verify.c index e4da75d46..1d4eab9c9 100644 --- a/servers/hgfs/verify.c +++ b/lib/libsffs/verify.c @@ -17,7 +17,7 @@ int verify_path(path, ino, attr, stale) char path[PATH_MAX]; struct inode *ino; -struct hgfs_attr *attr; +struct sffs_attr *attr; int *stale; { /* Given a path, and the inode associated with that path, verify if the inode @@ -32,11 +32,12 @@ int *stale; */ int r; - attr->a_mask |= HGFS_ATTR_MODE; + attr->a_mask |= SFFS_ATTR_MODE; - r = hgfs_getattr(path, attr); + r = sffs_table->t_getattr(path, attr); - dprintf(("HGFS: verify_path: getattr('%s') returned %d\n", path, r)); + dprintf(("%s: verify_path: getattr('%s') returned %d\n", + sffs_name, path, r)); if (r != OK) { /* If we are told that the path does not exist, delete the inode */ @@ -63,14 +64,14 @@ int *stale; int verify_inode(ino, path, attr) struct inode *ino; /* inode to verify */ char path[PATH_MAX]; /* buffer in which to store the path */ -struct hgfs_attr *attr; /* buffer for attributes, or NULL */ +struct sffs_attr *attr; /* buffer for attributes, or NULL */ { /* Given an inode, construct a path identifying the inode, and check whether * that path is still valid for that inode (as far as we can tell). As a side * effect, store attributes in the given attribute structure if not NULL (its * a_mask member must then be set). */ - struct hgfs_attr attr2; + struct sffs_attr attr2; int r; if ((r = make_path(path, ino)) != OK) return r; @@ -104,13 +105,13 @@ struct inode **res_ino; /* pointer for addressed inode (or NULL) */ if ((r = verify_inode(parent, path, NULL)) != OK) return r; - dprintf(("HGFS: verify_dentry: given path is '%s', name '%s'\n", path, - name)); + dprintf(("%s: verify_dentry: given path is '%s', name '%s'\n", + sffs_name, path, name)); if ((r = push_path(path, name)) != OK) return r; - dprintf(("HGFS: verify_dentry: path now '%s'\n", path)); + dprintf(("%s: verify_dentry: path now '%s'\n", sffs_name, path)); *res_ino = lookup_dentry(parent, name); diff --git a/servers/hgfs/write.c b/lib/libsffs/write.c similarity index 91% rename from servers/hgfs/write.c rename to lib/libsffs/write.c index ab21bba2a..91000d1fe 100644 --- a/servers/hgfs/write.c +++ b/lib/libsffs/write.c @@ -41,8 +41,8 @@ cp_grant_id_t *grantp; assert(count > 0); - /* Use the buffer from libhgfs to eliminate extra copying. */ - size = hgfs_writebuf(&ptr); + /* Use the buffer from below to eliminate extra copying. */ + size = sffs_table->t_writebuf(&ptr); off = 0; while (count > 0) { @@ -59,7 +59,7 @@ cp_grant_id_t *grantp; memset(ptr, 0, chunk); } - if ((r = hgfs_write(ino->i_file, ptr, chunk, pos)) <= 0) + if ((r = sffs_table->t_write(ino->i_file, ptr, chunk, pos)) <= 0) break; count -= r; @@ -89,7 +89,7 @@ int do_write() cp_grant_id_t grant; int r; - if (state.read_only) + if (state.s_read_only) return EROFS; if ((ino = find_inode(m_in.REQ_INODE_NR)) == NULL) @@ -122,12 +122,12 @@ int do_ftrunc() */ char path[PATH_MAX]; struct inode *ino; - struct hgfs_attr attr; + struct sffs_attr attr; u64_t start, end, delta; size_t count; int r; - if (state.read_only) + if (state.s_read_only) return EROFS; if ((ino = find_inode(m_in.REQ_INODE_NR)) == NULL) @@ -143,10 +143,10 @@ int do_ftrunc() if ((r = verify_inode(ino, path, NULL)) != OK) return r; - attr.a_mask = HGFS_ATTR_SIZE; + attr.a_mask = SFFS_ATTR_SIZE; attr.a_size = start; - r = hgfs_setattr(path, &attr); + r = sffs_table->t_setattr(path, &attr); } else { /* Write zeroes to the file. We can't create holes. */ if (cmp64(end, start) <= 0) return EINVAL; diff --git a/servers/hgfs/Makefile b/servers/hgfs/Makefile index cb8d9636c..534e30087 100644 --- a/servers/hgfs/Makefile +++ b/servers/hgfs/Makefile @@ -1,11 +1,9 @@ # Makefile for VMware Host/Guest File System (HGFS) server PROG= hgfs -SRCS= dentry.c handle.c inode.c link.c lookup.c main.c \ - misc.c mount.c name.c path.c read.c stat.c table.c \ - util.c verify.c write.c +SRCS= hgfs.c -DPADD+= ${LIBHGFS} ${LIBSYS} -LDADD+= -lhgfs -lsys +DPADD+= ${LIBSFFS} ${LIBHGFS} ${LIBSYS} +LDADD+= -lsffs -lhgfs -lsys MAN= diff --git a/servers/hgfs/glo.h b/servers/hgfs/glo.h deleted file mode 100644 index 11087202e..000000000 --- a/servers/hgfs/glo.h +++ /dev/null @@ -1,12 +0,0 @@ - -#ifdef _TABLE -#undef EXTERN -#define EXTERN -#endif - -EXTERN message m_in; /* request message */ -EXTERN message m_out; /* reply message */ -EXTERN struct state state; /* global state */ -EXTERN struct opt opt; /* global options */ - -extern int(*call_vec[]) (void); diff --git a/servers/hgfs/hgfs.c b/servers/hgfs/hgfs.c new file mode 100644 index 000000000..95a9bdaa7 --- /dev/null +++ b/servers/hgfs/hgfs.c @@ -0,0 +1,106 @@ +/* This file contains the implementation of the HGFS file system server. + * The file system side is handled by libsffs, whereas the host communication + * is handled by libhgfs. This file mainly contains the glue between them. + * + * The entry points into this file are: + * main main program function + * + * Created: + * April 2009 (D.C. van Moolenbroek) + */ + +#include +#include +#include +#include + +static struct sffs_params params; + +static struct optset optset_table[] = { + { "prefix", OPT_STRING, params.p_prefix, sizeof(params.p_prefix) }, + { "uid", OPT_INT, ¶ms.p_uid, 10 }, + { "gid", OPT_INT, ¶ms.p_gid, 10 }, + { "fmask", OPT_INT, ¶ms.p_file_mask, 8 }, + { "dmask", OPT_INT, ¶ms.p_dir_mask, 8 }, + { "icase", OPT_BOOL, ¶ms.p_case_insens, TRUE }, + { "noicase", OPT_BOOL, ¶ms.p_case_insens, FALSE }, + { NULL, 0, NULL, 0 } +}; + +/*===========================================================================* + * sef_cb_init_fresh * + *===========================================================================*/ +static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info)) +{ +/* Initialize this file server. Called at startup time. + */ + const struct sffs_table *table; + int i, r; + + /* Defaults */ + params.p_prefix[0] = 0; + params.p_uid = 0; + params.p_gid = 0; + params.p_file_mask = 0755; + params.p_dir_mask = 0755; + params.p_case_insens = FALSE; + + /* If we have been given an options string, parse options from there. */ + for (i = 1; i < env_argc - 1; i++) + if (!strcmp(env_argv[i], "-o")) + optset_parse(optset_table, env_argv[++i]); + + /* Initialize the HGFS library. If this fails, exit immediately. */ + if ((r = hgfs_init(&table)) != OK) { + if (r == EAGAIN) + printf("HGFS: shared folders are disabled\n"); + else + printf("HGFS: unable to initialize HGFS library (%d)\n", r); + + return r; + } + + /* Now initialize the SFFS library. */ + if ((r = sffs_init("HGFS", table, ¶ms)) != OK) { + hgfs_cleanup(); + + return r; + } + + return OK; +} + +/*===========================================================================* + * sef_local_startup * + *===========================================================================*/ +static void sef_local_startup(void) +{ +/* Local SEF initialization. + */ + + /* Register init callback. */ + sef_setcb_init_fresh(sef_cb_init_fresh); + + /* Register signal callback. SFFS handles this. */ + sef_setcb_signal_handler(sffs_signal); + + sef_startup(); +} + +/*===========================================================================* + * main * + *===========================================================================*/ +int main(int argc, char **argv) +{ +/* The main function of this file server. + */ + + env_setargs(argc, argv); + sef_local_startup(); + + sffs_loop(); + + hgfs_cleanup(); + + return 0; +} diff --git a/servers/hgfs/inc.h b/servers/hgfs/inc.h deleted file mode 100644 index 915255f12..000000000 --- a/servers/hgfs/inc.h +++ /dev/null @@ -1,39 +0,0 @@ - -#define _POSIX_SOURCE 1 /* for signal handling */ -#define _SYSTEM 1 /* for negative error values */ -#define _MINIX 1 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if DEBUG -#define dprintf(x) printf x -#else -#define dprintf(x) -#endif - -#include -#include -#include -#include -#include -#include - -#include - -#include "type.h" -#include "const.h" -#include "proto.h" -#include "glo.h" - -#include "inode.h" diff --git a/servers/hgfs/main.c b/servers/hgfs/main.c deleted file mode 100644 index 7c2b7b93a..000000000 --- a/servers/hgfs/main.c +++ /dev/null @@ -1,204 +0,0 @@ -/* This file contains the main message loop of the HGFS file system server. - * - * The entry points into this file are: - * main main program function - * - * Created: - * April 2009 (D.C. van Moolenbroek) - */ - -#include "inc.h" - -#include -#include -#include - -static void get_work(endpoint_t *who_e); -static void send_reply(int err, int transid); - -static struct optset optset_table[] = { - { "prefix", OPT_STRING, opt.prefix, sizeof(opt.prefix) }, - { "uid", OPT_INT, &opt.uid, 10 }, - { "gid", OPT_INT, &opt.gid, 10 }, - { "fmask", OPT_INT, &opt.file_mask, 8 }, - { "dmask", OPT_INT, &opt.dir_mask, 8 }, - { "icase", OPT_BOOL, &opt.case_insens, TRUE }, - { "noicase", OPT_BOOL, &opt.case_insens, FALSE }, - { NULL, 0, NULL, 0 } -}; - -/* SEF functions and variables. */ -static void sef_local_startup(void); -static int sef_cb_init_fresh(int type, sef_init_info_t *info); -static void sef_cb_signal_handler(int signo); - -/*===========================================================================* - * sef_cb_init_fresh * - *===========================================================================*/ -static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info)) -{ -/* Initialize this file server. Called at startup time. - */ - int i, r; - - /* Defaults */ - opt.prefix[0] = 0; - opt.uid = 0; - opt.gid = 0; - opt.file_mask = 0755; - opt.dir_mask = 0755; - opt.case_insens = FALSE; - - /* If we have been given an options string, parse options from there. */ - for (i = 1; i < env_argc - 1; i++) - if (!strcmp(env_argv[i], "-o")) - optset_parse(optset_table, env_argv[++i]); - - /* Make sure that the given path prefix doesn't end with a slash. */ - for (i = strlen(opt.prefix); i > 0 && opt.prefix[i - 1] == '/'; i--); - opt.prefix[i] = 0; - - /* Initialize the HGFS library. If this fails, exit immediately. */ - r = hgfs_init(); - if (r != OK) { - if (r == EAGAIN) - printf("HGFS: shared folders are disabled\n"); - else - printf("HGFS: unable to initialize HGFS library (%d)\n", r); - - return r; - } - - state.mounted = FALSE; - - return OK; -} - -/*===========================================================================* - * sef_cb_signal_handler * - *===========================================================================*/ -static void sef_cb_signal_handler(int signo) -{ - /* Only check for termination signal, ignore anything else. */ - if (signo != SIGTERM) return; - - if (state.mounted) { - dprintf(("HGFS: got SIGTERM, still mounted\n")); - } - else { - dprintf(("HGFS: got SIGTERM, shutting down\n")); - - /* Pass on the cleanup request to the HGFS library. */ - hgfs_cleanup(); - exit(0); - } -} - -/*===========================================================================* - * sef_local_startup * - *===========================================================================*/ -static void sef_local_startup(void) -{ - /* Register init callbacks. */ - sef_setcb_init_fresh(sef_cb_init_fresh); - sef_setcb_init_restart(sef_cb_init_fresh); - - /* No live update support yet. */ - - /* Register signal callbacks. */ - sef_setcb_signal_handler(sef_cb_signal_handler); - - sef_startup(); -} - -/*===========================================================================* - * main * - *===========================================================================*/ -int main(argc, argv) -int argc; -char *argv[]; -{ -/* The main function of this file server. After initializing, loop forever - * receiving one request from VFS at a time, processing it, and sending a - * reply back to VFS. - */ - endpoint_t who_e; - int call_nr, err, transid; - - env_setargs(argc, argv); - sef_local_startup(); - - for (;;) { - get_work(&who_e); - - transid = TRNS_GET_ID(m_in.m_type); - m_in.m_type = TRNS_DEL_ID(m_in.m_type); - if (m_in.m_type == 0) { - assert(!IS_VFS_FS_TRANSID(transid)); - m_in.m_type = transid; /* Backwards compat. */ - transid = 0; - } else - assert(IS_VFS_FS_TRANSID(transid)); - - call_nr = m_in.m_type; - if (who_e != VFS_PROC_NR) { - continue; - } - - if (state.mounted || call_nr == REQ_READSUPER) { - call_nr -= VFS_BASE; - - dprintf(("HGFS: call %d\n", call_nr)); - - if (call_nr >= 0 && call_nr < NREQS) { - err = (*call_vec[call_nr])(); - } else { - err = ENOSYS; - } - - dprintf(("HGFS: call %d result %d\n", call_nr, err)); - } - else err = EINVAL; - - send_reply(err, transid); - } - - return 0; -} - -/*===========================================================================* - * get_work * - *===========================================================================*/ -static void get_work(who_e) -endpoint_t *who_e; -{ -/* Receive a request message from VFS. Return the request call number. - */ - int r; - - if ((r = sef_receive(ANY, &m_in)) != OK) - panic("receive failed: %d", r); - - *who_e = m_in.m_source; -} - -/*===========================================================================* - * send_reply * - *===========================================================================*/ -static void send_reply(err, transid) -int err; /* resulting error code */ -int transid; -{ -/* Send a reply message to the requesting party, with the given error code. - */ - int r; - - m_out.m_type = err; - if (IS_VFS_FS_TRANSID(transid)) { - /* If a transaction ID was set, reset it */ - m_out.m_type = TRNS_ADD_ID(m_out.m_type, transid); - } - if ((r = send(m_in.m_source, &m_out)) != OK) - printf("HGFS: send failed (%d)\n", r); -} - diff --git a/servers/hgfs/type.h b/servers/hgfs/type.h deleted file mode 100644 index 590ec1f55..000000000 --- a/servers/hgfs/type.h +++ /dev/null @@ -1,19 +0,0 @@ - -/* Structure with global file system state. */ -struct state { - int mounted; /* is the file system mounted? */ - int read_only; /* is the file system mounted read-only? note, - * has no relation to the shared folder mode */ - dev_t dev; /* device the file system is mounted on */ -}; - -/* Structure with options affecting global behavior. */ -struct opt { - char prefix[PATH_MAX]; /* prefix for all paths used */ - uid_t uid; /* UID that owns all files */ - gid_t gid; /* GID that owns all files */ - unsigned int file_mask; /* AND-mask to apply to file permissions */ - unsigned int dir_mask; /* AND-mask to apply to directory perm's */ - int case_insens; /* case insensitivity flag; has no relation - * to the hosts's shared folder naming */ -}; diff --git a/share/mk/bsd.prog.mk b/share/mk/bsd.prog.mk index ff069fae1..103849697 100644 --- a/share/mk/bsd.prog.mk +++ b/share/mk/bsd.prog.mk @@ -59,7 +59,7 @@ MKDEP_SUFFIXES?= .o .ln # rumpfs_tmpfs rumpfs_udf rumpfs_ufs .for _lib in \ c curses blockdriver chardriver netdriver edit end m sys timers util \ - bz2 l hgfs audiodriver exec ddekit devman usb elf bdev + bz2 l audiodriver exec ddekit devman usb elf bdev sffs hgfs .ifndef LIB${_lib:tu} LIB${_lib:tu}= ${DESTDIR}/usr/lib/lib${_lib}.a .MADE: ${LIB${_lib:tu}} # Note: ${DESTDIR} will be expanded