From: David van Moolenbroek Date: Mon, 9 Apr 2012 16:08:26 +0000 (+0200) Subject: Create SFFS library out of HGFS X-Git-Tag: v3.2.1~616 X-Git-Url: http://zhaoyanbai.com/repos/pkcs11-keygen.html?a=commitdiff_plain;h=ef7b484e5cdbcd5f1224149fe86d8a62206cbf07;p=minix.git 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. --- 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