summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2003-02-05 15:55:08 +0000
committerGerald Carter <jerry@samba.org>2003-02-05 15:55:08 +0000
commitb70a22702b0bcd37b87d8d049567610d89d9fafa (patch)
treeefe309a5be7812b4904fc35896f060baa48a83ec
parenta699c0ca5efc29143256f85851675df0cf29a668 (diff)
downloadsamba-b70a22702b0bcd37b87d8d049567610d89d9fafa.tar.gz
apply umount lazy patch from Mandrake
-rw-r--r--source/client/smbumount.c140
1 files changed, 129 insertions, 11 deletions
diff --git a/source/client/smbumount.c b/source/client/smbumount.c
index 20b6820fb76..2c2243528d6 100644
--- a/source/client/smbumount.c
+++ b/source/client/smbumount.c
@@ -15,6 +15,10 @@
#include <linux/smb_mount.h>
#include <linux/smb_fs.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
/* This is a (hopefully) temporary hack due to the fact that
sizeof( uid_t ) != sizeof( __kernel_uid_t ) under glibc.
This may change in the future and smb.h may get fixed in the
@@ -43,9 +47,9 @@ umount_ok(const char *mount_point)
__kernel_uid_t mount_uid;
if (fid == -1) {
- fprintf(stderr, "Could not open %s: %s\n",
- mount_point, strerror(errno));
- return -1;
+ /* fprintf(stderr, "Could not open %s: %s\n",
+ mount_point, strerror(errno)); */
+ return 1; /* maybe try again */
}
if (ioctl(fid, SMB_IOC_GETMOUNTUID, &mount_uid) != 0) {
@@ -65,6 +69,92 @@ umount_ok(const char *mount_point)
return 0;
}
+#define MAX_READLINKS 32
+/* myrealpath from mount, it could get REAL path under a broken connection */
+char *myrealpath(const char *path, char *resolved_path, int maxreslth)
+{
+ int readlinks = 0,m,n;
+ char *npath,*buf;
+ char link_path[PATH_MAX + 1];
+
+ npath = resolved_path;
+
+ if(*path != '/')
+ {
+ if(!getcwd(npath, maxreslth - 2))
+ return NULL;
+ npath += strlen(npath);
+ if(npath[-1] != '/')
+ *(npath++) = '/';
+ else
+ {
+ *npath++ = '/';
+ path++;
+ }
+ }
+
+ while(*path != '\0')
+ {
+ if(*path == '/')
+ {
+ path++;
+ continue;
+ }
+ if(*path == '.' && (path[1] == '\0' || path[1] == '/'))
+ {
+ path++;
+ continue;
+ }
+ if(*path == '.' && path[1] == '.' &&
+ (path[2] == '\0' || path[2] == '/'))
+ {
+ path += 2;
+ while(npath > resolved_path + 1 &&
+ (--npath)[-1] != '/');
+ continue;
+ }
+ while(*path != '\0' && *path != '/')
+ {
+ if(npath-resolved_path > maxreslth - 2)
+ return NULL;
+ *npath++ = *path++;
+ }
+ if(readlinks++ > MAX_READLINKS)
+ return NULL;
+ *npath = '\0';
+ n = readlink(resolved_path, link_path, PATH_MAX);
+ if(n < 0)
+ {
+ if(errno != EINVAL) return NULL;
+ }
+ else
+ {
+ link_path[n] = '\0';
+ if(*link_path == '/')
+ npath = resolved_path;
+ else while(*(--npath) != '/');
+ m = strlen(path);
+ if((buf = malloc(m + n + 1)) == NULL)
+ {
+ fprintf(stderr,"Not enough memory.\n");
+ return NULL;
+ }
+ memcpy(buf, link_path, n);
+ memcpy(buf + n, path, m + 1);
+ path = buf;
+ }
+ *npath++ = '/';
+ }
+ if(npath != resolved_path + 1)
+ {
+ while(npath > resolved_path && npath[-1] == '/')
+ npath--;
+ if(npath == resolved_path) return NULL;
+ }
+ *npath = '\0';
+ return resolved_path;
+}
+
/* Make a canonical pathname from PATH. Returns a freshly malloced string.
It is up the *caller* to ensure that the PATH is sensible. i.e.
canonicalize ("/dev/fd0/.") returns "/dev/fd0" even though ``/dev/fd0/.''
@@ -73,7 +163,8 @@ umount_ok(const char *mount_point)
static char *
canonicalize (char *path)
{
- char *canonical = malloc (PATH_MAX + 1);
+ char *npath,*canonical = malloc (PATH_MAX + 1);
+ int i;
if (!canonical) {
fprintf(stderr, "Error! Not enough memory!\n");
@@ -87,11 +178,18 @@ canonicalize (char *path)
if (path == NULL)
return NULL;
-
- if (realpath (path, canonical))
+
+/* if (realpath (path, canonical)) */
+ if(myrealpath(path, canonical, PATH_MAX))
return canonical;
pstrcpy (canonical, path);
+ if((i = strlen(canonical)) > 1 && i <= PATH_MAX)
+ {
+ path = canonical + i;
+ while(*(--path) == '/')
+ *path = '\0';
+ }
return canonical;
}
@@ -122,14 +220,34 @@ main(int argc, char *argv[])
exit(1);
}
- if (umount_ok(mount_point) != 0) {
- exit(1);
+ if ((fd = umount_ok(mount_point)) != 0) {
+ if(fd == 1)
+ {
+ if((fd = umount_ok(mount_point)) != 0)
+ {
+ if(fd == 1)
+ {
+ fprintf(stderr, "Could not open %s: %s\n",
+ mount_point, strerror(errno));
+ }
+ exit(1);
+ }
+ }
+ else exit(1);
}
+#if !defined(MNT_DETACH)
+ #define MNT_DETACH 2
+#endif
+
if (umount(mount_point) != 0) {
- fprintf(stderr, "Could not umount %s: %s\n",
- mount_point, strerror(errno));
- exit(1);
+ /* fprintf(stderr, "Could not umount %s: %s\n,Trying lazy umount.\n",
+ mount_point, strerror(errno)); */
+ if(umount2(mount_point,MNT_DETACH) != 0)
+ {
+ fprintf(stderr, "Lazy umount failed.\n");
+ return 1;
+ }
}
if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1)