fixes
diff --git a/ChangeLog b/ChangeLog
index 96b1cad..1ff388f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2005-07-21  Miklos Szeredi <miklos@szeredi.hu>
+
+	* Don't change mtime/ctime/atime to local time on read/write.
+	Bug reported by Ben Grimm
+
+	* Install fuse_common.h and fuse_lowlevel.h.  Report by Christian
+	Magnusson
+
+	* fusermount: use getopt_long() for option parsing.  It allows the
+	use of '--' to stop argument scanning, so fusermount can now
+	operate on directories whose names begin with a '-'.  Patch by
+	Adam Connell
+
 2005-07-15  Miklos Szeredi <miklos@szeredi.hu>
 
 	* fusermount: add '-v', '--version' and '--help' options
diff --git a/example/hello_ll.c b/example/hello_ll.c
index 2589836..9f70865 100644
--- a/example/hello_ll.c
+++ b/example/hello_ll.c
@@ -27,13 +27,13 @@
         stbuf->st_mode = S_IFDIR | 0755;
         stbuf->st_nlink = 2;
         break;
-        
+
     case 2:
         stbuf->st_mode = S_IFREG | 0444;
         stbuf->st_nlink = 1;
         stbuf->st_size = strlen(hello_str);
         break;
-        
+
     default:
         return -1;
     }
@@ -63,7 +63,7 @@
         e.attr_timeout = 1.0;
         e.entry_timeout = 1.0;
         hello_stat(e.ino, &e.attr);
-        
+
         fuse_reply_entry(req, &e);
     }
 }
@@ -89,7 +89,6 @@
 static int reply_buf_limited(fuse_req_t req, const char *buf, size_t bufsize,
                              off_t off, size_t maxsize)
 {
-        
     if (off < bufsize)
         return fuse_reply_buf(req, buf + off, min(bufsize - off, maxsize));
     else
@@ -105,7 +104,7 @@
         fuse_reply_err(req, ENOTDIR);
     else {
         struct dirbuf b;
-    
+
         memset(&b, 0, sizeof(b));
         dirbuf_add(&b, ".", 1);
         dirbuf_add(&b, "..", 1);
diff --git a/include/Makefile.am b/include/Makefile.am
index 269e0e1..ee8a83c 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -1,6 +1,6 @@
 ## Process this file with automake to produce Makefile.in
 
 fuseincludedir=$(includedir)/fuse
-fuseinclude_HEADERS = fuse.h fuse_compat.h
+fuseinclude_HEADERS = fuse.h fuse_compat.h fuse_common.h fuse_lowlevel.h
 include_HEADERS = old/fuse.h
 noinst_HEADERS = fuse_kernel.h
diff --git a/include/fuse.h b/include/fuse.h
index 6c6cf09..e285c07 100644
--- a/include/fuse.h
+++ b/include/fuse.h
@@ -145,7 +145,7 @@
      * is permitted for the given flags.  Optionally open may also
      * return an arbitary filehandle in the fuse_file_info structure,
      * which will be passed to all file operations.
-     * 
+     *
      * Changed in version 2.2
      */
     int (*open) (const char *, struct fuse_file_info *);
@@ -197,7 +197,7 @@
      * not possible to determine if a flush is final, so each flush
      * should be treated equally.  Multiple write-flush sequences are
      * relatively rare, so this shouldn't be a problem.
-     * 
+     *
      * Changed in version 2.2
      */
     int (*flush) (const char *, struct fuse_file_info *);
@@ -266,13 +266,13 @@
      * passes non-zero offset to the filler function.  When the buffer
      * is full (or an error happens) the filler function will return
      * '1'.
-     * 
+     *
      * Introduced in version 2.3
      */
     int (*readdir) (const char *, void *, fuse_fill_dir_t, off_t,
                     struct fuse_file_info *);
 
-    /** Release directory 
+    /** Release directory
      *
      * Introduced in version 2.3
      */
@@ -293,7 +293,7 @@
      * The return value will passed in the private_data field of
      * fuse_context to all file operations and as a parameter to the
      * destroy() method.
-     * 
+     *
      * Introduced in version 2.3
      */
     void *(*init) (void);
@@ -302,7 +302,7 @@
      * Clean up filesystem
      *
      * Called on filesystem exit.
-     * 
+     *
      * Introduced in version 2.3
      */
     void (*destroy) (void *);
@@ -448,7 +448,7 @@
 
 /**
  * Obsolete, doesn't do anything
- * 
+ *
  * @return -EINVAL
  */
 int fuse_invalidate(struct fuse *f, const char *path);
diff --git a/kernel/file.c b/kernel/file.c
index 63e4380..f5e2c87 100644
--- a/kernel/file.c
+++ b/kernel/file.c
@@ -248,6 +248,8 @@
 	fuse_put_request(fc, req);
 	if (!err)
 		SetPageUptodate(page);
+	if (!(inode->i_sb->s_flags & MS_NOATIME))
+		fuse_invalidate_attr(inode);
  out:
 	unlock_page(page);
 	return err;
@@ -268,6 +270,8 @@
 			SetPageUptodate(page);
 		unlock_page(page);
 	}
+	if (!(inode->i_sb->s_flags & MS_NOATIME))
+		fuse_invalidate_attr(inode);
 	return req->out.h.error;
 }
 
@@ -484,8 +488,8 @@
 			clear_page_dirty(page);
 			SetPageUptodate(page);
 		}
-	} else if (err == -EINTR || err == -EIO)
-		fuse_invalidate_attr(inode);
+	}
+	fuse_invalidate_attr(inode);
 	return err;
 }
 
@@ -577,7 +581,8 @@
 		if (write && pos > i_size_read(inode))
 			i_size_write(inode, pos);
 		*ppos = pos;
-	} else if (write && (res == -EINTR || res == -EIO))
+	}
+	if (write || !(inode->i_sb->s_flags & MS_NOATIME))
 		fuse_invalidate_attr(inode);
 
 	return res;
@@ -642,7 +647,7 @@
 static struct file_operations fuse_file_operations = {
 	.llseek		= generic_file_llseek,
 #ifdef KERNEL_2_6
-	.read		= generic_file_read,	
+	.read		= generic_file_read,
 #else
 	.read		= fuse_file_read,
 #endif
diff --git a/kernel/inode.c b/kernel/inode.c
index 5dacb22..7717ef1 100644
--- a/kernel/inode.c
+++ b/kernel/inode.c
@@ -199,6 +199,7 @@
 		return NULL;
 
 	if ((inode->i_state & I_NEW)) {
+		inode->i_flags |= S_NOATIME|S_NOCMTIME;
 		inode->i_generation = generation;
 		inode->i_data.backing_dev_info = &fc->bdi;
 		fuse_init_inode(inode, attr);
@@ -424,7 +425,7 @@
 			return 0;
 		}
 	}
-	
+
 	if (!d->fd_present || !d->rootmode_present ||
 	    !d->user_id_present || !d->group_id_present)
 		return 0;
diff --git a/lib/fuse.c b/lib/fuse.c
index 79ce5e7..0ee4ab4 100644
--- a/lib/fuse.c
+++ b/lib/fuse.c
@@ -550,7 +550,7 @@
                         int err)
 {
     if (!err) {
-        if (fuse_reply_entry(req, e) == -ENOENT) 
+        if (fuse_reply_entry(req, e) == -ENOENT)
             forget_node(req_fuse(req), e->ino, 1);
     } else
         reply_err(req, err);
@@ -1353,7 +1353,7 @@
                             struct fuse_file_info *llfi)
 {
     struct fuse *f = req_fuse_prepare(req);
-    struct fuse_file_info fi;    
+    struct fuse_file_info fi;
     struct fuse_dirhandle *dh = get_dirhandle(llfi, &fi);
     if (f->op.releasedir) {
         char *path;
@@ -1698,7 +1698,7 @@
             if (fuse_ll_is_lib_option(opt)) {
                 size_t optlen = strlen(opt);
                 if (strcmp(opt, "debug") == 0)
-                    f->flags |= FUSE_DEBUG;                
+                    f->flags |= FUSE_DEBUG;
                 memmove(d, opt, optlen);
                 d += optlen;
                 *d++ = ',';
diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c
index b89ad93..4635e32 100644
--- a/lib/fuse_lowlevel.c
+++ b/lib/fuse_lowlevel.c
@@ -319,7 +319,7 @@
 
     memset(&arg, 0, sizeof(arg));
     arg.fh = f->fh;
-    
+
     return send_reply_req(req, &arg, sizeof(arg));
 }
 
@@ -329,7 +329,7 @@
 
     memset(&arg, 0, sizeof(arg));
     arg.size = count;
-    
+
     return send_reply_req(req, &arg, sizeof(arg));
 }
 
@@ -344,7 +344,7 @@
 
     memset(&arg, 0, sizeof(arg));
     convert_statfs(statfs, &arg.st);
-    
+
     return send_reply_req(req, &arg, sizeof(arg));
 }
 
@@ -354,7 +354,7 @@
 
     memset(&arg, 0, sizeof(arg));
     arg.size = count;
-    
+
     return send_reply_req(req, &arg, sizeof(arg));
 }
 
@@ -468,7 +468,7 @@
                     struct fuse_open_in *arg)
 {
     struct fuse_file_info fi;
-    
+
     memset(&fi, 0, sizeof(fi));
     fi.flags = arg->flags;
 
@@ -735,7 +735,7 @@
         fprintf(stderr, "fuse: failed to allocate request\n");
         goto out;
     }
-    
+
     req->f = f;
     req->unique = in->unique;
     req->ctx.uid = in->uid;
diff --git a/lib/fuse_mt.c b/lib/fuse_mt.c
index c9fe63c..c9d85a8 100644
--- a/lib/fuse_mt.c
+++ b/lib/fuse_mt.c
@@ -22,7 +22,7 @@
 static struct fuse_context *mt_getcontext(void)
 {
     struct fuse_context *ctx;
-        
+
     ctx = (struct fuse_context *) pthread_getspecific(context_key);
     if (ctx == NULL) {
         ctx = (struct fuse_context *) malloc(sizeof(struct fuse_context));
diff --git a/lib/helper.c b/lib/helper.c
index d8e694f..681197d 100644
--- a/lib/helper.c
+++ b/lib/helper.c
@@ -293,7 +293,6 @@
 }
 
 static struct fuse *fuse_setup_common(int argc, char *argv[],
-                                      
                                       const struct fuse_operations *op,
                                       size_t op_size,
                                       char **mountpoint,
diff --git a/lib/mount.c b/lib/mount.c
index 86ad2be..01081bb 100644
--- a/lib/mount.c
+++ b/lib/mount.c
@@ -72,8 +72,8 @@
     const char *mountprog = FUSERMOUNT_PROG;
     char umount_cmd[1024];
 
-    snprintf(umount_cmd, sizeof(umount_cmd) - 1, "%s -u -q -z %s", mountprog,
-             mountpoint);
+    snprintf(umount_cmd, sizeof(umount_cmd) - 1, "%s -u -q -z -- %s",
+             mountprog, mountpoint);
 
     umount_cmd[sizeof(umount_cmd) - 1] = '\0';
     system(umount_cmd);
@@ -106,8 +106,17 @@
 
     if(pid == 0) {
         char env[10];
-        const char *argv[] = {mountprog, opts ? "-o" : mountpoint, opts,
-                              mountpoint, NULL};
+        const char *argv[32];
+        int a = 0;
+        
+        argv[a++] = mountprog;
+        if (opts) {
+            argv[a++] = "-o";
+            argv[a++] = opts;
+        }
+        argv[a++] = "--";
+        argv[a++] = mountpoint;
+        argv[a++] = NULL;
 
         close(fds[1]);
         fcntl(fds[0], F_SETFD, 0);
diff --git a/test/test.c b/test/test.c
index 4e7711c..dfc9fea 100644
--- a/test/test.c
+++ b/test/test.c
@@ -33,7 +33,7 @@
 
 static void start_test(const char *fmt, ...)
      __attribute__ ((format (printf, 1, 2)));
-     
+
 static void test_error(const char *func, const char *msg, ...)
 {
     va_list ap;
@@ -254,7 +254,7 @@
 {
     int res;
     int fd;
-    
+
     unlink(path);
     fd = creat(path, 0644);
     if (fd == -1) {
@@ -335,7 +335,7 @@
     res = check_mode(path, 0755);
     if (res == -1)
         return -1;
-    
+
     for (i = 0; dir_files[i]; i++) {
         char fpath[1024];
         sprintf(fpath, "%s/%s", path, dir_files[i]);
@@ -365,7 +365,7 @@
     res = create_file(testfile, data, datalen);
     if (res == -1)
         return -1;
-    
+
     res = truncate(testfile, len);
     if (res == -1) {
         PERROR("truncate");
@@ -374,7 +374,7 @@
     res = check_size(testfile, len);
     if (res == -1)
         return -1;
-    
+
     if (len > 0) {
         if (len <= datalen) {
             res = check_data(testfile, data, 0, len);
@@ -468,7 +468,7 @@
     res = create_file(testfile, data, datalen);
     if (res == -1)
         return -1;
-    
+
     unlink(testfile2);
     res = symlink(testfile, testfile2);
     if (res == -1) {
@@ -521,7 +521,7 @@
     res = create_file(testfile, data, datalen);
     if (res == -1)
         return -1;
-    
+
     unlink(testfile2);
     res = rename(testfile, testfile2);
     if (res == -1) {
@@ -562,7 +562,7 @@
     res = create_dir(testdir, testdir_files);
     if (res == -1)
         return -1;
-    
+
     rmdir(testdir2);
     res = rename(testdir, testdir2);
     if (res == -1) {
diff --git a/util/fusermount.c b/util/fusermount.c
index 8702ffb..1fe3127 100644
--- a/util/fusermount.c
+++ b/util/fusermount.c
@@ -23,6 +23,7 @@
 #include <string.h>
 #include <ctype.h>
 #include <unistd.h>
+#include <getopt.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <pwd.h>
@@ -694,13 +695,13 @@
                     progname, origmnt, strerror(errno));
             return -1;
         }
-        
+
         if ((stbuf->st_mode & S_ISVTX) && stbuf->st_uid != getuid()) {
             fprintf(stderr, "%s: mountpoint %s not owned by user\n",
                     progname, origmnt);
             return -1;
         }
-        
+
         res = access(mnt, W_OK);
         if (res == -1) {
             fprintf(stderr, "%s: user has no write access to mountpoint %s\n",
@@ -1014,25 +1015,34 @@
 
 int main(int argc, char *argv[])
 {
-    int a;
+    int ch;
     int fd;
     int res;
     char *origmnt;
     char *mnt;
-    int unmount = 0;
-    int lazy = 0;
+    static int unmount = 0;
+    static int lazy = 0;
+    static int quiet = 0;
     char *commfd;
-    int quiet = 0;
     int cfd;
     const char *opts = "";
 
-    progname = argv[0];
+    static const struct option long_opts[] = {
+        {"unmount", no_argument, NULL, 'u'},
+        {"lazy",    no_argument, NULL, 'z'},
+        {"quiet",   no_argument, NULL, 'q'},
+        {"help",    no_argument, NULL, 'h'},
+        {"version", no_argument, NULL, 'v'},
+        {0, 0, 0, 0}};
 
-    for (a = 1; a < argc; a++) {
-        if (argv[a][0] != '-')
-            break;
+    progname = strdup(argv[0]);
+    if (progname == NULL) {
+        fprintf(stderr, "%s: failed to allocate memory\n", argv[0]);
+        exit(1);
+    }
 
-        switch (argv[a][1]) {
+    while ((ch = getopt_long(argc, argv, "hvo:uzq", long_opts, NULL)) != -1) {
+        switch (ch) {
         case 'h':
             usage();
             break;
@@ -1042,12 +1052,7 @@
             break;
 
         case 'o':
-            a++;
-            if (a == argc) {
-                fprintf(stderr, "%s: missing argument to -o\n", progname);
-                exit(1);
-            }
-            opts = argv[a];
+            opts = optarg;
             break;
 
         case 'u':
@@ -1062,17 +1067,7 @@
             quiet = 1;
             break;
 
-        case '-':
-            if (strcmp(&argv[a][2], "help") == 0)
-                usage();
-            else if (strcmp(&argv[a][2], "version") == 0)
-                show_version();
-
-            /* fall through */
-
         default:
-            fprintf(stderr, "%s: unknown option '%s'\n", progname, argv[a]);
-            fprintf(stderr, "Try `%s -h' for more information\n", progname);
             exit(1);
         }
     }
@@ -1082,12 +1077,12 @@
         exit(1);
     }
 
-    if (a == argc) {
+    if (optind >= argc) {
         fprintf(stderr, "%s: missing mountpoint argument\n", progname);
         exit(1);
     }
 
-    origmnt = argv[a++];
+    origmnt = argv[optind];
 
     drop_privs();
     mnt = resolve_path(origmnt);