[PATCH] 9P support (via libmvfs+libmixp)



Hi folks,


this patch adds 9P support to MC, so you can now easily access 9P 
fileservers. 

My future plan is to switch over the extfs stuff to separate 9P 
servers which are started on-demand.


cu
-- 
---------------------------------------------------------------------
 Enrico Weigelt    ==   metux IT service - http://www.metux.de/
---------------------------------------------------------------------
 Please visit the OpenSource QM Taskforce:
 	http://wiki.metux.de/public/OpenSource_QM_Taskforce
 Patches / Fixes for a lot dozens of packages in dozens of versions:
	http://patches.metux.de/
---------------------------------------------------------------------
Index: src/textconf.c
===================================================================
--- src/textconf.c	(.../original/mc-4.6.1)	(revision 1264)
+++ src/textconf.c	(.../trunk)	(revision 1264)
@@ -40,6 +40,9 @@
 #ifdef USE_EXT2FSLIB
     "undelfs",
 #endif
+#ifdef ENABLE_NINEP
+    "ninepfs",
+#endif
     NULL
 };
 #endif				/* USE_VFS */
Index: src/cmd.c
===================================================================
--- src/cmd.c	(.../original/mc-4.6.1)	(revision 1264)
+++ src/cmd.c	(.../trunk)	(revision 1264)
@@ -1145,6 +1145,14 @@
 	     "[FIle transfer over SHell filesystem]", "/#sh:", 1);
 }
 
+#ifdef ENABLE_NINEP
+void nineplink_cmd (void)
+{
+    nice_cd (_(" 9P link to machine "), _(machine_str),
+	    "[Plan9 File System]", "/#9p://", 1);
+}
+#endif
+
 #ifdef WITH_SMBFS
 void smblink_cmd (void)
 {
Index: src/cmd.h
===================================================================
--- src/cmd.h	(.../original/mc-4.6.1)	(revision 1264)
+++ src/cmd.h	(.../trunk)	(revision 1264)
@@ -1,6 +1,10 @@
 #ifndef __CMD_H
 #define __CMD_H
 
+#ifdef ENABLE_NINEP
+void nineplink_cmd (void);
+#endif
+
 void netlink_cmd (void);
 void ftplink_cmd (void);
 void fishlink_cmd (void);
Index: src/main.c
===================================================================
--- src/main.c	(.../original/mc-4.6.1)	(revision 1264)
+++ src/main.c	(.../trunk)	(revision 1264)
@@ -809,6 +809,9 @@
 #endif
     {' ', N_("FT&P link..."), 'P', ftplink_cmd},
     {' ', N_("S&hell link..."), 'H', fishlink_cmd},
+#ifdef ENABLE_NINEP
+    {' ', N_("&9P link..."), '9', nineplink_cmd},
+#endif
 #ifdef WITH_SMBFS
     {' ', N_("SM&B link..."), 'B', smblink_cmd},
 #endif
Index: src/Makefile.am
===================================================================
--- src/Makefile.am	(.../original/mc-4.6.1)	(revision 1264)
+++ src/Makefile.am	(.../trunk)	(revision 1264)
@@ -37,7 +37,7 @@
 endif
 endif
 
-mc_LDADD = $(EDITLIB) $(SLANGLIB) $(VFSLIB) \
+mc_LDADD = $(EDITLIB) $(SLANGLIB) $(VFSLIB) $(MVFS_LIBS) \
 	$(INTLLIBS) $(GLIB_LIBS) $(MCLIBS) $(LIBICONV)
 
 CHARSET_SRC = charsets.c charsets.h selcodepage.c selcodepage.h

Index: vfs/9p.c
===================================================================
--- vfs/9p.c	(.../original/mc-4.6.1)	(revision 0)
+++ vfs/9p.c	(.../trunk)	(revision 1264)
@@ -0,0 +1,65 @@
+/* Virtual File System: Midnight Commander file system.
+
+   Copyright (C) 1995, 1996, 1997 The Free Software Foundation
+
+   Written by Enrico Weigelt <weigelt metux de>
+   Derived from smbfs.c
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License
+   as published by the Free Software Foundation; either version 2 of
+   the License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#include <config.h>
+#include <stdio.h>
+#include "mvfs.h"
+
+static struct vfs_class vfs_ninepfs_ops =
+{
+    .name	= "ninepfs",
+    .prefix	= "9p:",
+    .flags	= VFSF_NOLINKS,
+    .init	= mc_mvfs_init,
+    .fill_names	= mc_mvfs_fill_names,
+    .open	= mc_mvfs_open,
+    .close	= mc_mvfs_close,
+    .read	= mc_mvfs_read,
+    .write	= mc_mvfs_write,
+    .opendir	= mc_mvfs_opendir,
+    .readdir	= mc_mvfs_readdir,
+    .closedir	= mc_mvfs_closedir,
+    .stat	= mc_mvfs_stat,
+    .lstat	= mc_mvfs_lstat,
+    .fstat	= mc_mvfs_fstat,
+    .chmod	= mc_mvfs_chmod,
+    .chown	= mc_mvfs_chown,
+    .utime	= mc_mvfs_utime,
+    .readlink	= mc_mvfs_readlink,
+    .symlink	= mc_mvfs_symlink,
+    .link	= mc_mvfs_link,
+    .unlink	= mc_mvfs_unlink,
+    .rename	= mc_mvfs_rename,
+    .chdir	= mc_mvfs_chdir,
+    .ferrno	= mc_mvfs_errno,
+    .lseek	= mc_mvfs_lseek,
+    .mknod	= mc_mvfs_mknod,
+    .free	= mc_mvfs_free,
+    .mkdir	= mc_mvfs_mkdir,
+    .rmdir	= mc_mvfs_rmdir
+//    .setctl	= mc_mvfs_setctl
+};
+
+void
+init_ninepfs (void)
+{
+    vfs_register_class (&vfs_ninepfs_ops);
+}
Index: vfs/vfs.c
===================================================================
--- vfs/vfs.c	(.../original/mc-4.6.1)	(revision 1264)
+++ vfs/vfs.c	(.../trunk)	(revision 1264)
@@ -943,7 +943,9 @@
     init_mcfs ();
 #endif /* WITH_MCFS */
 #endif /* USE_NETCODE */
-
+#ifdef ENABLE_NINEP
+    init_ninepfs();
+#endif
     vfs_setup_wd ();
 }
 
Index: vfs/mvfs.h
===================================================================
--- vfs/mvfs.h	(.../original/mc-4.6.1)	(revision 0)
+++ vfs/mvfs.h	(.../trunk)	(revision 1264)
@@ -0,0 +1,60 @@
+/* Virtual File System: Midnight Commander file system.
+
+   Copyright (C) 1995, 1996, 1997 The Free Software Foundation
+
+   Written by Enrico Weigelt <weigelt metux de>
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License
+   as published by the Free Software Foundation; either version 2 of
+   the License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#ifndef __MC_MVFS_H
+#define __MC_MVFS_H
+
+#include <config.h>
+#include <mvfs/mvfs.h>
+
+#include "utilvfs.h"
+#include "vfs.h"
+#include "vfs-impl.h"
+
+int   mc_mvfs_init         (struct vfs_class *me);
+int   mc_mvfs_errno        (struct vfs_class *me);
+int   mc_mvfs_chmod        (struct vfs_class *me, const char *path, int mode);
+int   mc_mvfs_chown        (struct vfs_class *me, const char *path, int owner, int group);
+int   mc_mvfs_utime        (struct vfs_class *me, const char *path, struct utimbuf *times);
+int   mc_mvfs_readlink     (struct vfs_class *me, const char *path, char *buf, size_t size);
+int   mc_mvfs_symlink      (struct vfs_class *me, const char *n1,   const char *n2);
+int   mc_mvfs_stat         (struct vfs_class *me, const char *path, struct stat *buf);
+int   mc_mvfs_lstat        (struct vfs_class *me, const char *path, struct stat *buf);
+int   mc_mvfs_mknod        (struct vfs_class *me, const char *path, int mode, int dev);
+int   mc_mvfs_mkdir        (struct vfs_class *me, const char *path, mode_t mode);
+int   mc_mvfs_rmdir        (struct vfs_class *me, const char *path);
+int   mc_mvfs_link         (struct vfs_class *me, const char *p1,   const char *p2);
+int   mc_mvfs_rename       (struct vfs_class *me, const char *a,    const char *b);
+void* mc_mvfs_open         (struct vfs_class *me, const char *file, int flags, int mode);
+void* mc_mvfs_opendir      (struct vfs_class *me, const char *dirname);
+int   mc_mvfs_chdir        (struct vfs_class *me, const char *path);
+int   mc_mvfs_unlink       (struct vfs_class *me, const char *path);
+int   mc_mvfs_read         (void *data, char *buffer, int count);
+int   mc_mvfs_write        (void *data, const char *buf, int nbyte);
+int   mc_mvfs_close        (void *data);
+void* mc_mvfs_readdir      (void *info);
+int   mc_mvfs_closedir     (void *info);
+int   mc_mvfs_lseek        (void *data, off_t offset, int whence);
+int   mc_mvfs_fstat        (void *data, struct stat *buf);
+int   mc_mvfs_convert_stat (struct stat* buf, MVFS_STAT* s);
+void  mc_mvfs_free         (vfsid id);
+void  mc_mvfs_fill_names (struct vfs_class *me, fill_names_f func);
+
+#endif
Index: vfs/Makefile.am
===================================================================
--- vfs/Makefile.am	(.../original/mc-4.6.1)	(revision 1264)
+++ vfs/Makefile.am	(.../trunk)	(revision 1264)
@@ -12,6 +12,15 @@
 AM_CFLAGS = $(GLIB_CFLAGS)
 endif
 
+# MVFS may be required by multiple FS'ses (eg. 9P)
+MVFS_SOURCES=mvfs.c
+
+if ENABLE_NINEP
+BASICFILES_NINEP=9p.c
+BASICFILES_MVFS=$(MVFS_SOURCES)
+AM_CFLAGS+=$(MVFS_CFLAGS)
+endif
+
 BASICFILES = 			\
 	cpio.c			\
 	direntry.c		\
@@ -21,7 +30,9 @@
 	tar.c			\
 	sfs.c			\
 	utilvfs.c		\
-	vfs.c
+	vfs.c			\
+	$(BASICFILES_MVFS)	\
+	$(BASICFILES_NINEP)
 
 VFSHDRS = 			\
 	ftpfs.h 		\

Index: vfs/mvfs.c
===================================================================
--- vfs/mvfs.c	(.../original/mc-4.6.1)	(revision 0)
+++ vfs/mvfs.c	(.../trunk)	(revision 1264)
@@ -0,0 +1,488 @@
+/* Virtual File System: Midnight Commander file system.
+
+   Copyright (C) 1995, 1996, 1997 The Free Software Foundation
+
+   Written by Enrico Weigelt <weigelt metux de>
+   Derived from smbfs.c
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License
+   as published by the Free Software Foundation; either version 2 of
+   the License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#include "mvfs.h"
+
+#include <config.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <string.h>
+#include <inttypes.h>
+#include <errno.h>
+#include <grp.h>
+#include <pwd.h>
+
+#include "utilvfs.h"
+
+#include "vfs.h"
+#include "vfs-impl.h"
+#include <mvfs/mvfs.h>
+#include <9p-mixp/mixp.h>
+#include <mvfs/autoconnect_ops.h>
+#include <mvfs/metacache_ops.h>
+
+// __DEBUG_MVFS
+
+static MVFS_FILESYSTEM* acfs = NULL;
+static MVFS_FILESYSTEM* stack_fs = NULL;
+static int my_errno;
+
+/* stuff that is same with each connection */
+static mode_t myumask = 0755;
+static int got_user = 0;
+static int got_pass = 0;
+static char password[256];
+static char username[256];
+
+static inline const char* _translate_filename(const char* file)
+{
+    if (file==NULL)
+	return NULL;
+    const char* s = strchr(file,'#');
+    if (s)
+	return s+1;
+    return file;
+}
+
+int mc_mvfs_init (struct vfs_class * me)
+{
+    myumask = umask (0);
+    umask (myumask);
+    myumask = ~myumask;
+
+    if (getenv ("USER")) {
+	char *p;
+
+	strcpy (username, getenv ("USER"));
+	got_user = 1;
+#ifdef __DEBUG_MVFS
+	fprintf(stderr,"mc_mvfs_init(): $USER:%s\n", username);
+#endif
+	if ((p = strchr (username, '%'))) {
+	    *p = 0;
+	    strcpy (password, p + 1);
+	    got_pass = 1;
+	    memset (strchr (getenv ("USER"), '%') + 1, 'X', strlen (password));
+#ifdef __DEBUG_MVFS
+	    fprintf (stderr,"mc_mvfs_init(): $USER%%pass: %s%%%s\n",username, password);
+#endif
+	}
+//	strupper (username);
+    }
+    if (getenv ("PASSWD")) {
+	strcpy (password, getenv ("PASSWD"));
+	got_pass = 1;
+    }
+    
+    acfs = mvfs_autoconnectfs_create();
+    stack_fs = mvfs_metacachefs_create_1(acfs);
+
+    return 1;
+}
+
+int mc_mvfs_read (void *data, char *buffer, int count)
+{
+    MVFS_FILE* fp = (MVFS_FILE*)data;
+    int ret = mvfs_file_read(fp, buffer, count);
+    if (ret<0)
+    {
+	my_errno = -ret;
+	return -1;
+    }
+    return ret;
+}
+
+int mc_mvfs_write (void *data, const char *buf, int nbyte)
+{
+    MVFS_FILE* fp = (MVFS_FILE*)data;
+    int ret = mvfs_file_write(fp, buf, nbyte);
+    if (ret<0)
+    {
+	my_errno = -ret;
+	return -1;
+    }
+    return ret;
+}
+
+int mc_mvfs_close (void *data)
+{
+    MVFS_FILE* fp = (MVFS_FILE*) data;
+    mvfs_file_unref(fp);
+    return 0;	// -1 indicates error
+}
+
+int mc_mvfs_errno (struct vfs_class *me)
+{
+#ifdef __DEBUG_MVFS
+    fprintf(stderr,"mc_mvfs_errno: %s\n", g_strerror(my_errno));
+#endif
+    return my_errno;
+}
+
+void * mc_mvfs_readdir(void *info)
+{
+    static union vfs_dirent mc_mvfs_readdir_data;
+
+    MVFS_FILE* fp = (MVFS_FILE*)info;
+    MVFS_STAT* s  = mvfs_file_scan(info);
+
+    if (s==NULL)
+	return NULL;
+
+    mc_mvfs_readdir_data.dent.d_ino    = 0;
+    mc_mvfs_readdir_data.dent.d_off    = 0;
+    mc_mvfs_readdir_data.dent.d_reclen = -1;	// FIXME !!!
+    mc_mvfs_readdir_data.dent.d_type   = 0;
+    memset(mc_mvfs_readdir_data.dent.d_name, 0, sizeof(mc_mvfs_readdir_data.dent.d_name));
+    strncpy(mc_mvfs_readdir_data.dent.d_name, s->name, sizeof(mc_mvfs_readdir_data.dent.d_name)-1);
+
+    compute_namelen(&mc_mvfs_readdir_data.dent);
+    return &mc_mvfs_readdir_data;
+}
+
+int mc_mvfs_closedir (void *info)
+{
+    MVFS_FILE* fp = (MVFS_FILE*)info;
+    mvfs_file_unref(fp);
+    return 0;
+}
+
+int mc_mvfs_chmod (struct vfs_class *me, const char *path, int mode)
+{
+#ifdef __DEBUG_MVFS
+    fprintf(stderr,"mc_mvfs_chmod(path:%s, mode:%d)\n", path, mode);
+#endif
+    int ret = mvfs_fs_chmod(stack_fs, _translate_filename(path), mode);
+    if (ret==0)
+	return 0;
+    my_errno = -ret;
+    return -1;
+}
+
+static inline char* uid2name(uid_t uid)
+{
+    endpwent();
+    struct passwd* pw = getpwuid(uid);
+    char* n = strdup((pw==NULL) ? "INCOGNITO" : pw->pw_name);
+    endpwent();
+    return n;
+}
+
+static inline char* gid2name(gid_t gid)
+{
+    endgrent();
+    struct group* gr = getgrgid(gid);
+    char* n = strdup((gr==NULL) ? "INCOGNITO" : gr->gr_name);
+    endgrent();
+    return n;
+}
+    
+int mc_mvfs_chown (struct vfs_class *me, const char *path, int owner, int group)
+{
+#ifdef __DEBUG_MVFS
+    fprintf(stderr,"mc_mvfs_chown(path:%s, owner:%d, group:%d)\n", path, owner, group);
+#endif
+    char* uname = uid2name(owner);
+    char* gname = gid2name(group);
+
+    int ret = mvfs_fs_chown(stack_fs, _translate_filename(path), uname, gname);
+    free(uname);
+    free(gname);
+
+    if (ret<0)
+    {
+	my_errno = -ret;
+	return 0;
+    }
+    return 0;
+}
+
+int mc_mvfs_utime (struct vfs_class *me, const char *path, struct utimbuf *times)
+{
+#ifdef __DEBUG_MVFS
+    fprintf(stderr,"mc_mvfs_utime(path:%s)\n", path);
+#endif
+    my_errno = EOPNOTSUPP;
+    return -1;
+}
+
+int mc_mvfs_readlink (struct vfs_class *me, const char *path, char *buf, size_t size)
+{
+#ifdef __DEBUG_MVFS
+    fprintf(stderr,"mc_mvfs_readlink(path:%s, buf:%s, size:%d)\n", path, buf, (int) size);
+#endif
+    if ((buf==0)||(size<3))
+    {
+	my_errno = EFAULT;
+	return -1;
+    }
+    MVFS_SYMLINK l = mvfs_fs_readlink(stack_fs, path);
+    if (l.errcode != 0)
+    {
+	my_errno = l.errcode;
+	return -1;
+    }
+    
+    my_errno = 0;
+    strncpy(buf, l.target, size);
+    return strlen(buf);
+}
+
+int mc_mvfs_symlink (struct vfs_class *me, const char *n1, const char *n2)
+{
+#ifdef __DEBUG_MVFS
+    fprintf(stderr,"mc_mvfs_symlink(n1:%s, n2:%s)\n", n1, n2);
+#endif
+    int ret = mvfs_fs_symlink(stack_fs, n1, n2);
+    if (ret<0)
+    {
+	my_errno = -ret;
+	return -1;
+    }
+    return ret;
+}
+
+int mc_mvfs_convert_stat(struct stat* buf, MVFS_STAT* s)
+{
+    if (s==NULL)
+    {
+	fprintf(stderr,"mc_mvfs_convert_stat(): NULL stat passed\n");
+	memset(buf, 0, sizeof(struct stat));
+	return 0;
+    }
+    
+    if (buf==NULL)
+    {
+	fprintf(stderr,"mc_mvfs_convert_stat() GOT NO BUFFER !\n");
+	return 0;
+    }
+    
+    buf->st_dev   = 0;
+    buf->st_ino   = 1;
+    buf->st_mode  = s->mode;
+    buf->st_nlink = 1;
+    buf->st_size  = s->size;
+    buf->st_atime = s->atime;
+    buf->st_mtime = s->mtime;
+    buf->st_ctime = s->ctime;
+
+    struct passwd* pw = getpwnam(s->uid);
+    struct group*  gr = getgrnam(s->gid);
+
+    buf->st_uid = (pw ? pw->pw_uid : 0);	// FIXME: should we use -1 ?
+    buf->st_gid = (gr ? gr->gr_gid : 0);
+
+    return 1;
+}
+
+int mc_mvfs_stat (struct vfs_class * me, const char *path, struct stat *buf)
+{    
+    MVFS_STAT* s = mvfs_fs_statfile(stack_fs, _translate_filename(path));
+    if (!mc_mvfs_convert_stat(buf,s))
+    {
+#ifdef __DEBUG_MVFS
+	fprintf(stderr, "mc_mvfs_fstat() failed for %s\n", path);
+#endif
+	my_errno = EFAULT;
+	return -EFAULT;
+    }
+    
+    mvfs_stat_free(s);
+    return 0;
+}
+
+// FIXME: should use an separate lstat call, which isn't yet supported by MVFS ;-o
+// (currently no special support for symlinks)
+int mc_mvfs_lstat (struct vfs_class * me, const char *path, struct stat *buf)
+{    
+    MVFS_STAT* s = mvfs_fs_statfile(stack_fs, _translate_filename(path));
+    if (!mc_mvfs_convert_stat(buf,s))
+    {
+#ifdef __DEBUG_MVFS
+	fprintf(stderr, "mc_mvfs_fstat() failed for %s\n", path);
+#endif
+	my_errno = EFAULT;
+	return -EFAULT;
+    }
+    
+    mvfs_stat_free(s);
+    return 0;
+}
+
+int mc_mvfs_lseek (void *data, off_t offset, int whence)
+{
+    MVFS_FILE* fp = (MVFS_FILE*)data;
+    return mvfs_file_seek(fp, offset, whence);
+}
+
+int mc_mvfs_mknod (struct vfs_class *me, const char *path, int mode, int dev)
+{
+#ifdef __DEBUG_MVFS
+    fprintf(stderr,"9P->mknod(path:%s, mode:%d, dev:%d)\n", path, mode, dev);
+#endif
+    my_errno = EOPNOTSUPP;
+    return -1;
+}
+
+int mc_mvfs_mkdir (struct vfs_class * me, const char *path, mode_t mode)
+{
+#ifdef __DEBUG_MVFS
+    fprintf(stderr,"9P->mkdir(path:%s, mode:%d)\n", path, (int) mode);
+#endif
+    int ret = mvfs_fs_mkdir(stack_fs, path, mode);
+    if (ret!=0)
+    {
+	my_errno = -ret;
+	return -1;
+    }
+    return 0;
+}
+
+int mc_mvfs_rmdir (struct vfs_class *me, const char *path)
+{
+#ifdef __DEBUG_MVFS
+    fprintf(stderr,"9P->rmdir(path:%s)\n", path);
+#endif
+    int ret = mvfs_fs_unlink(stack_fs, path);
+    if (ret!=0)
+    {
+	my_errno = -ret;
+	return -1;
+    }
+    return 0;
+}
+
+int mc_mvfs_link (struct vfs_class *me, const char *p1, const char *p2)
+{
+#ifdef __DEBUG_MVFS
+    fprintf(stderr,"9P->link(p1:%s, p2:%s)\n", p1, p2);
+#endif
+    my_errno = EOPNOTSUPP;
+    return -1;
+}
+
+void * mc_mvfs_open (struct vfs_class *me, const char *filename, int flags, int mode)
+{
+    const char* file = _translate_filename(filename);
+#ifdef __DEBUG_MVFS
+    fprintf(stderr,"mc_mvfs_open: filename=\"%s\" translated=\"%s\"\n", filename, file);
+#endif
+    MVFS_FILE* f = mvfs_fs_openfile(stack_fs, file, mode);
+    return f;
+}
+
+// FIXME
+void * mc_mvfs_opendir (struct vfs_class *me, const char *dirname)
+{
+#ifdef __DEBUG_MVFS
+    fprintf(stderr,"mc_mvfs_opendir: dirname=\"%s\"\n", dirname);
+#endif
+    return mc_mvfs_open(me,dirname,0,0);
+}
+
+int mc_mvfs_chdir (struct vfs_class *me, const char *path)
+{
+#ifdef __DEBUG_MVFS
+    fprintf(stderr,"mc_mvfs_chdir: dirname=\"%s\"\n", path);
+#endif
+    MVFS_FILE* f = (MVFS_FILE*) mc_mvfs_opendir(me, path);
+    if (f)
+    {
+	mvfs_file_unref(f);
+	return 0;
+    }
+#ifdef __DEBUG_MVFS
+    fprintf(stderr,"mc_mvfs_chdir() failed to open: %s\n", path);
+#endif
+    return -1;	// FIXME: be some bite more chdir() conformant ;-O
+}
+
+int mc_mvfs_unlink (struct vfs_class *me, const char *path)
+{
+#ifdef __DEBUG_MVFS
+    fprintf(stderr,"unlink not supported yet: filename=\"%s\"\n", path);
+#endif
+    my_errno = EOPNOTSUPP;
+    return -1;
+}
+
+int mc_mvfs_rename (struct vfs_class *me, const char *a, const char *b)
+{
+#ifdef __DEBUG_MVFS
+    fprintf(stderr,"rename not supported yet\n");
+#endif
+    my_errno = EOPNOTSUPP;
+}
+
+int mc_mvfs_fstat (void *data, struct stat *buf)
+{
+    MVFS_STAT* s = mvfs_file_stat((MVFS_FILE*)data);
+    if (!mc_mvfs_convert_stat(buf,s))
+    {
+#ifdef __DEBUG_MVFS
+	fprintf(stderr, "mc_mvfs_fstat() failed\n");
+#endif
+	my_errno = EFAULT;
+	return -EFAULT;
+    }
+
+    mvfs_stat_free(s);
+    return 0;
+}
+
+void mc_mvfs_free (vfsid id)
+{
+#ifdef __DEBUG_MVFS
+    fprintf(stderr,"9P->free(%p)\n", id);
+#endif
+}
+
+void mc_mvfs_fill_names (struct vfs_class *me, fill_names_f func)
+{
+    char* srvlist = mvfs_autoconnectfs_getconnections(stack_fs);
+
+    if (srvlist == NULL)
+	return;
+
+    char* walk;	
+    for (walk=srvlist; walk[0]!=0;)
+    {
+	char* delim = strchr(walk,'\n');
+	if (delim)
+	{
+	    // we got more
+	    *delim = 0;
+	    if (walk[0])
+		(*func)(walk);
+	    walk = delim+1;
+	}
+	else
+	{
+	    if (walk[0])
+		(*func)(walk);
+	    // this was the last ... goto out
+	    goto out;
+	}
+    }
+
+out:
+    free(srvlist);
+}
Index: config.h.in
===================================================================
--- config.h.in	(.../original/mc-4.6.1)	(revision 1264)
+++ config.h.in	(.../trunk)	(revision 1264)
@@ -11,6 +11,9 @@
 /* Define if `d_ino' is member of `struct directory' */
 #undef D_INO_IN_DIRENT
 
+/* Define to enable 9P */
+#undef ENABLE_NINEP
+
 /* Define to 1 if translation of program messages to the user's native
    language is requested. */
 #undef ENABLE_NLS
Index: configure.ac
===================================================================
--- configure.ac	(.../original/mc-4.6.1)	(revision 1264)
+++ configure.ac	(.../trunk)	(revision 1264)
@@ -564,6 +564,17 @@
     fi
 fi
 
+dnl
+dnl 9P support via libmvfs
+dnl
+AC_ARG_ENABLE([9p],
+ 	      [  --enable-9p              Support for Plan9 Resource sharing protocol (via libmvfs) [[no]]])
+if test "x$enable_9p" != xno; then
+     AC_DEFINE(ENABLE_NINEP, 1, [Define to enable 9P])
+     PKG_CHECK_MODULES([MVFS],[libmvfs libmixp])
+     vfs_flags="$vfs_flags, ninepfs"
+fi
+
 ri_GCC_WARNINGS
 
 AC_SUBST(CFLAGS)
@@ -582,6 +593,7 @@
   AC_CONFIG_SUBDIRS([vfs/samba])
 fi
 
+AM_CONDITIONAL(ENABLE_NINEP, [test "$enable_9p" = "yes"])
 AM_CONDITIONAL(USE_EDIT, [test -n "$use_edit"])
 AM_CONDITIONAL(USE_VFS, [test "x$use_vfs" = xyes])
 AM_CONDITIONAL(USE_VFS_NET, [test x"$use_net_code" = xtrue])

Index: README.MVFS-9P
===================================================================
--- README.MVFS-9P	(.../original/mc-4.6.1)	(revision 0)
+++ README.MVFS-9P	(.../trunk)	(revision 1264)
@@ -0,0 +1,19 @@
+
+This branch of mc has support for 9P via the mvfs library.
+
+To build it you need to have these libs installed:
+
+    * libmixp		(http://releases.metux.de/libmixp/)
+    * libmvfs		(http://releases.metux.de/libmvfs/)
+
+The files added are:
+
+    * mvfs.c	the actual mc-vfs -> mvfs bridge'ing
+    * 9p.c	registere ninep:// for the 9P filesystem protocol, going through mvfs
+
+
+In future, several synthetic filesystems will be replaced as 9P servers and started 
+by mvfs on-demand, so eventually replacing much of the extfs stuff some day ;-O
+
+
+    Enrico Weigelt, metux IT service <weigelt metux de>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]