fix
diff --git a/ChangeLog b/ChangeLog
index cd1da1d..162916e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,9 +1,15 @@
 2004-02-20  Miklos Szeredi <mszeredi@inf.bme.hu>
 
+	* removed old way of mounting (fusermount mountpoint program)
+
 	* more kernel interface changes:
 
 	* added nanosecond precision to file times
 
+	* removed interface version from mount data
+
+	* added /proc/fs/fuse/version which contains MAJOR.MINOR
+
 2004-02-19  Miklos Szeredi <mszeredi@inf.bme.hu>
 
 	* statfs library API changed to match other methods.  Since this
diff --git a/include/linux/fuse.h b/include/linux/fuse.h
index 10ef186..834c1be 100644
--- a/include/linux/fuse.h
+++ b/include/linux/fuse.h
@@ -20,11 +20,11 @@
 /** Opening this will yield a new control file */
 #define FUSE_DEV "/proc/fs/fuse/dev"
 
+/** The file containing the version in the form MAJOR.MINOR */
+#define FUSE_VERSION_FILE "/proc/fs/fuse/version"
+
 /** Data passed to mount */
 struct fuse_mount_data {
-	/** Must be set to FUSE_KERNEL_VERSION */
-	int version;
-	
 	/** The control file descriptor */
 	int fd;
 	
diff --git a/kernel/dev.c b/kernel/dev.c
index a31615d..43af356 100644
--- a/kernel/dev.c
+++ b/kernel/dev.c
@@ -611,10 +611,17 @@
 	.release	= fuse_dev_release,
 };
 
+static int read_version(char *page, char **start, off_t off, int count,
+			   int *eof, void *data)
+{
+	char *s = page;
+	s += sprintf(s, "%i.%i\n", FUSE_KERNEL_VERSION,
+		     FUSE_KERNEL_MINOR_VERSION);
+	return s - page;
+}
+
 int fuse_dev_init()
 {
-	int ret;
-
 	proc_fs_fuse = NULL;
 	proc_fuse_dev = NULL;
 
@@ -624,33 +631,31 @@
 	if(!fuse_req_cachep)
 		return -ENOMEM;
 
-	ret = -ENOMEM;
 	proc_fs_fuse = proc_mkdir("fuse", proc_root_fs);
-	if(!proc_fs_fuse) {
-		printk("fuse: failed to create directory in /proc/fs\n");
-		goto err;
+	if(proc_fs_fuse) {
+		struct proc_dir_entry *de;
+
+		proc_fs_fuse->owner = THIS_MODULE;
+		proc_fuse_dev = create_proc_entry("dev", S_IFSOCK | 0666,
+						  proc_fs_fuse);
+		if(proc_fuse_dev) {
+			proc_fuse_dev->owner = THIS_MODULE;
+			proc_fuse_dev->proc_fops = &fuse_dev_operations;
+		}
+		de = create_proc_entry("version", S_IFREG | 0444, proc_fs_fuse);
+		if (de) {
+			de->owner = THIS_MODULE;
+			de->read_proc = read_version;
+		}
 	}
-
-	proc_fs_fuse->owner = THIS_MODULE;
-	proc_fuse_dev = create_proc_entry("dev", S_IFSOCK | 0666, proc_fs_fuse);
-	if(!proc_fuse_dev) {
-		printk("fuse: failed to create entry in /proc/fs/fuse\n");
-		goto err;
-	}
-
-	proc_fuse_dev->proc_fops = &fuse_dev_operations;
-
 	return 0;
-
-  err:
-	fuse_dev_cleanup();
-	return ret;
 }
 
 void fuse_dev_cleanup()
 {
 	if(proc_fs_fuse) {
 		remove_proc_entry("dev", proc_fs_fuse);
+		remove_proc_entry("version", proc_fs_fuse);
 		remove_proc_entry("fuse", proc_root_fs);
 	}
 	
diff --git a/kernel/inode.c b/kernel/inode.c
index 08bf3c9..8f82029 100644
--- a/kernel/inode.c
+++ b/kernel/inode.c
@@ -119,11 +119,6 @@
 		return NULL;
 	}
 
-	if(d->version != FUSE_KERNEL_VERSION) {
-		printk("fuse_read_super: Bad version: %i\n", d->version);
-		return NULL;
-	}
-
 	file = fget(d->fd);
 	ino = NULL;
 	if(file)
diff --git a/lib/fuse.c b/lib/fuse.c
index 2e6950d..9d0783d 100644
--- a/lib/fuse.c
+++ b/lib/fuse.c
@@ -1106,6 +1106,9 @@
 
 void fuse_loop(struct fuse *f)
 {
+    if(f == NULL)
+        return;
+
     while(1) {
         struct fuse_cmd *cmd;
 
@@ -1133,6 +1136,35 @@
         return &f->context;
 }
 
+static int check_version(struct fuse *f)
+{
+    int res;
+    FILE *vf = fopen(FUSE_VERSION_FILE, "r");
+    if(vf == NULL) {
+        fprintf(stderr, "fuse: kernel interface too old, need >= %i.%i\n",
+                FUSE_KERNEL_VERSION, FUSE_KERNEL_MINOR_VERSION);
+        return -1;
+    }
+    res = fscanf(vf, "%i.%i", &f->majorver, &f->minorver);
+    fclose(vf);
+    if(res != 2) {
+        fprintf(stderr, "fuse: error reading %s\n", FUSE_VERSION_FILE);
+        return -1;
+    }
+    if(f->majorver != FUSE_KERNEL_VERSION) {
+        fprintf(stderr, "fuse: bad kernel interface major version: needs %i\n",
+                FUSE_KERNEL_VERSION);
+        return -1;
+    }
+    if(f->minorver < FUSE_KERNEL_MINOR_VERSION) {
+        fprintf(stderr, "fuse: kernel interface too old: need >= %i.%i",
+                FUSE_KERNEL_VERSION, FUSE_KERNEL_MINOR_VERSION);
+        return -1;
+    }    
+    
+    return 0;
+}
+
 struct fuse *fuse_new(int fd, int flags, const struct fuse_operations *op)
 {
     struct fuse *f;
@@ -1140,6 +1172,11 @@
 
     f = (struct fuse *) calloc(1, sizeof(struct fuse));
 
+    if(check_version(f) == -1) {
+        free(f);
+        return NULL;
+    }
+
     f->flags = flags;
     f->fd = fd;
     f->ctr = 0;
diff --git a/lib/fuse_i.h b/lib/fuse_i.h
index 4eaa5ba..ce81604 100644
--- a/lib/fuse_i.h
+++ b/lib/fuse_i.h
@@ -41,6 +41,8 @@
     struct fuse_context context;
     pthread_key_t context_key;
     volatile int exited;
+    int majorver;
+    int minorver;
 };
 
 struct fuse_dirhandle {
diff --git a/lib/fuse_mt.c b/lib/fuse_mt.c
index f1a2e5c..40da6ed 100644
--- a/lib/fuse_mt.c
+++ b/lib/fuse_mt.c
@@ -114,5 +114,8 @@
 
 void fuse_loop_mt(struct fuse *f)
 {
+    if(f == NULL)
+        return;
+
     __fuse_loop_mt(f, (fuse_processor_t) __fuse_process_cmd, NULL);
 }
diff --git a/lib/helper.c b/lib/helper.c
index d417d90..7cbb9eb 100644
--- a/lib/helper.c
+++ b/lib/helper.c
@@ -15,9 +15,6 @@
 #include <limits.h>
 #include <signal.h>
 
-#define FUSE_MOUNTED_ENV        "_FUSE_MOUNTED"
-#define FUSE_UMOUNT_CMD_ENV     "_FUSE_UNMOUNT_CMD"
-
 static struct fuse *fuse;
 
 static void usage(char *progname)
@@ -73,21 +70,14 @@
 
 void fuse_main(int argc, char *argv[], const struct fuse_operations *op)
 {
-    int argctr = 1;
+    int argctr = 2;
     int flags;
     int multithreaded;
-    char *isreexec = getenv(FUSE_MOUNTED_ENV);
     int fuse_fd;
     char *fuse_mountpoint = NULL;
     char umount_cmd[1024] = "";
     char **fusermount_args = NULL;
     
-    if(!isreexec) {
-        if(argc < 2 || argv[1][0] == '-')
-            usage(argv[0]);
-        argctr ++;
-    }
-
     flags = 0;
     multithreaded = 1;
     for(; argctr < argc && !fusermount_args; argctr ++) {
@@ -106,10 +96,7 @@
                 break;
                 
             case '-':
-                if(!isreexec)
-                    fusermount_args = &argv[argctr+1];
-                else
-                    invalid_option(argv, argctr);
+                fusermount_args = &argv[argctr+1];
                 break;
                 
             default:
@@ -119,30 +106,16 @@
             invalid_option(argv, argctr);
     }
 
-    if(!isreexec) {
-        fuse_mountpoint = strdup(argv[1]);
-        fuse_fd = fuse_mount(fuse_mountpoint, (const char **) fusermount_args);
-        if(fuse_fd == -1)
-            exit(1);
-    } else {
-        char *tmpstr;
-
-        /* Old (obsolescent) way of doing the mount: 
-           
-             fusermount [options] mountpoint [program [args ...]]
-
-           fusermount execs this program and passes the control file
-           descriptor dup()-ed to stdin */
-        fuse_fd = 0;
-        
-        tmpstr = getenv(FUSE_UMOUNT_CMD_ENV);
-        if(tmpstr != NULL)
-            strncpy(umount_cmd, tmpstr, sizeof(umount_cmd) - 1);
-    }
+    fuse_mountpoint = strdup(argv[1]);
+    fuse_fd = fuse_mount(fuse_mountpoint, (const char **) fusermount_args);
+    if(fuse_fd == -1)
+        exit(1);
 
     set_signal_handlers();
 
     fuse = fuse_new(fuse_fd, flags, op);
+    if(fuse == NULL)
+        exit(1);
 
     if(multithreaded)
         fuse_loop_mt(fuse);
diff --git a/util/fusermount.c b/util/fusermount.c
index ee4c005..6d27372 100644
--- a/util/fusermount.c
+++ b/util/fusermount.c
@@ -37,9 +37,6 @@
 
 #define FUSE_DEV "/proc/fs/fuse/dev"
 
-#define FUSE_MOUNTED_ENV        "_FUSE_MOUNTED"
-#define FUSE_UMOUNT_CMD_ENV     "_FUSE_UNMOUNT_CMD"
-#define FUSE_KERNEL_VERSION_ENV "_FUSE_KERNEL_VERSION"
 #define FUSE_COMMFD_ENV         "_FUSE_COMMFD"
 
 const char *progname;
@@ -303,7 +300,6 @@
             return -1;
     }
     
-    data.version = FUSE_KERNEL_VERSION;
     data.fd = fd;
     data.rootmode = rootmode;
     data.uid = getuid();
@@ -476,7 +472,7 @@
 static void usage()
 {
     fprintf(stderr,
-            "%s: [options] mountpoint [program [args ...]]\n"
+            "%s: [options] mountpoint\n"
             "Options:\n"
             " -h       print help\n"
             " -u       unmount\n"
@@ -498,15 +494,11 @@
     char *origmnt;
     char *mnt;
     int unmount = 0;
-    char **userprog;
-    int numargs;
-    char mypath[PATH_MAX];
-    char *unmount_cmd;
     char *commfd;
     const char *fsname = NULL;
-    char verstr[128];
     int flags = 0;
     int quiet = 0;
+    int cfd;
 
     progname = argv[0];
     
@@ -599,60 +591,19 @@
     }
 
     commfd = getenv(FUSE_COMMFD_ENV);
-
-    if(a == argc && commfd == NULL) {
-        fprintf(stderr, "%s: Missing program argument\n", progname);
+    if(commfd == NULL) {
+        fprintf(stderr, "%s: old style mounting not supported\n", progname);
         exit(1);
     }
-    
-    userprog = argv + a;
-    numargs = argc - a;
-    
+
     fd = mount_fuse(mnt, flags, fsname);
     if(fd == -1)
         exit(1);
 
-    if(commfd != NULL) {
-        int cfd = atoi(commfd);
-        res = send_fd(cfd, fd);
-        if(res == -1)
-            exit(1);
-        exit(0);
-    }
+    cfd = atoi(commfd);
+    res = send_fd(cfd, fd);
+    if(res == -1)
+        exit(1);
 
-    /* Dup the file descriptor to stdin */
-    if(fd != 0) {
-        dup2(fd, 0);
-        close(fd);
-    }
-
-    /* Strangely this doesn't work after dropping permissions... */
-    res = readlink("/proc/self/exe", mypath, sizeof(mypath) - 1);
-    if(res == -1) {
-        fprintf(stderr, "%s: failed to determine self path: %s\n",
-                progname, strerror(errno));
-        strcpy(mypath, "fusermount");
-        fprintf(stderr, "using %s as the default\n", mypath);
-    }
-    else 
-        mypath[res] = '\0';
-
-    /* Drop setuid/setgid permissions */
-    setuid(getuid());
-    setgid(getgid());
-
-    unmount_cmd = (char *) malloc(strlen(mypath) + strlen(mnt) + 64);
-    sprintf(unmount_cmd, "%s -u -q %s", mypath, mnt);
-    setenv(FUSE_UMOUNT_CMD_ENV, unmount_cmd, 1);
-    sprintf(verstr, "%i", FUSE_KERNEL_VERSION);
-    setenv(FUSE_KERNEL_VERSION_ENV, verstr, 1);
-    setenv(FUSE_MOUNTED_ENV, "", 1);
-
-    execvp(userprog[0], userprog);
-    fprintf(stderr, "%s: failed to exec %s: %s\n", progname, userprog[0],
-            strerror(errno));
-
-    close(0);
-    system(unmount_cmd);
-    return 1;
+    return 0;
 }