X-Git-Url: http://git.samba.org/?a=blobdiff_plain;f=source%2Fclient%2Fumount.cifs.c;h=ab94a20c60c19abd62fb3f6d32dbda70fcd1e635;hb=118fd6213d5f6419f654e9226a41d527c04346f7;hp=88a9776b04822423fbdad8ead44e34dea14ffa6f;hpb=ed27740397817c1f1b14ba187139c877dbf22168;p=samba.git
diff --git a/source/client/umount.cifs.c b/source/client/umount.cifs.c
index 88a9776b048..ab94a20c60c 100644
--- a/source/client/umount.cifs.c
+++ b/source/client/umount.cifs.c
@@ -4,7 +4,7 @@
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
@@ -13,8 +13,7 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+ along with this program. If not, see . */
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
@@ -34,14 +33,22 @@
#include
#include
#include
-#include
#define UNMOUNT_CIFS_VERSION_MAJOR "0"
-#define UNMOUNT_CIFS_VERSION_MINOR "4"
+#define UNMOUNT_CIFS_VERSION_MINOR "5"
#ifndef UNMOUNT_CIFS_VENDOR_SUFFIX
-#define UNMOUNT_CIFS_VENDOR_SUFFIX ""
-#endif
+ #ifdef _SAMBA_BUILD_
+ #include "include/version.h"
+ #ifdef SAMBA_VERSION_VENDOR_SUFFIX
+ #define UNMOUNT_CIFS_VENDOR_SUFFIX "-"SAMBA_VERSION_OFFICIAL_STRING"-"SAMBA_VERSION_VENDOR_SUFFIX
+ #else
+ #define UNMOUNT_CIFS_VENDOR_SUFFIX "-"SAMBA_VERSION_OFFICIAL_STRING
+ #endif /* SAMBA_VERSION_OFFICIAL_STRING and SAMBA_VERSION_VENDOR_SUFFIX */
+ #else
+ #define UNMOUNT_CIFS_VENDOR_SUFFIX ""
+ #endif /* _SAMBA_BUILD_ */
+#endif /* UNMOUNT_CIFS_VENDOR_SUFFIX */
#ifndef MNT_DETACH
#define MNT_DETACH 0x02
@@ -75,7 +82,7 @@ static struct option longopts[] = {
{ NULL, 0, NULL, 0 }
};
-char * thisprogram;
+const char * thisprogram;
int verboseflg = 0;
static void umount_cifs_usage(void)
@@ -93,7 +100,8 @@ static void umount_cifs_usage(void)
printf("\n\tman 8 umount.cifs\n");
printf("\nTo display the version number of the cifs umount utility:");
printf("\n\t%s -V\n",thisprogram);
- printf("\nNote that invoking the umount utility on cifs mounts, can execute /sbin/umount.cifs (if it is present and -i is not specified to umount).\n");
+ printf("\nInvoking the umount utility on cifs mounts, can execute");
+ printf(" /sbin/umount.cifs (if present and umount -i is not specified.\n");
}
static int umount_check_perm(char * dir)
@@ -118,18 +126,39 @@ static int umount_check_perm(char * dir)
if(verboseflg)
printf("ioctl returned %d with errno %d %s\n",rc,errno,strerror(errno));
- if(rc == ENOTTY)
- printf("user unmounting via %s is an optional feature of the cifs filesystem driver (cifs.ko)\n\tand requires cifs.ko version 1.32 or later\n",thisprogram);
- else if (rc > 0)
+ if(rc == ENOTTY) {
+ printf("user unmounting via %s is an optional feature of",thisprogram);
+ printf(" the cifs filesystem driver (cifs.ko)");
+ printf("\n\tand requires cifs.ko version 1.32 or later\n");
+ } else if (rc > 0)
printf("user unmount of %s failed with %d %s\n",dir,errno,strerror(errno));
close(fileid);
return rc;
}
-int remove_from_mtab(char * mountpoint)
+static int lock_mtab(void)
+{
+ int rc;
+
+ rc = mknod(MOUNTED_LOCK , 0600, 0);
+ if(rc == -1)
+ printf("\ngetting lock file %s failed with %s\n",MOUNTED_LOCK,
+ strerror(errno));
+
+ return rc;
+
+}
+
+static void unlock_mtab(void)
{
- int rc = 0;
+ unlink(MOUNTED_LOCK);
+}
+
+static int remove_from_mtab(char * mountpoint)
+{
+ int rc;
+ int num_matches;
FILE * org_fd;
FILE * new_fd;
struct mntent * mount_entry;
@@ -139,11 +168,11 @@ int remove_from_mtab(char * mountpoint)
/* Do we first need to check if it is writable? */
- /* BB lock_mtab - the smbumount and mount-utils package appear to lock
- in a different incompat. way, and it seems that mount-utils have
- changed the way they lock a few times. We should fix this someday
- or at least find out how the mount-utils are supposed to handle this */
-
+ if (lock_mtab()) {
+ printf("Mount table locked\n");
+ return -EACCES;
+ }
+
if(verboseflg)
printf("attempting to remove from mtab\n");
@@ -151,6 +180,7 @@ int remove_from_mtab(char * mountpoint)
if(org_fd == NULL) {
printf("Can not open %s\n",MOUNTED);
+ unlock_mtab();
return -EIO;
}
@@ -158,18 +188,40 @@ int remove_from_mtab(char * mountpoint)
if(new_fd == NULL) {
printf("Can not open temp file %s", MOUNTED_TEMP);
endmntent(org_fd);
+ unlock_mtab();
return -EIO;
}
/* BB fix so we only remove the last entry that matches BB */
+ num_matches = 0;
+ while((mount_entry = getmntent(org_fd)) != NULL) {
+ if(strcmp(mount_entry->mnt_dir, mountpoint) == 0) {
+ num_matches++;
+ }
+ }
+ if(verboseflg)
+ printf("%d matching entries in mount table\n", num_matches);
+
+ /* Is there a better way to seek back to the first entry in mtab? */
+ endmntent(org_fd);
+ org_fd = setmntent(MOUNTED, "r");
+
+ if(org_fd == NULL) {
+ printf("Can not open %s\n",MOUNTED);
+ unlock_mtab();
+ return -EIO;
+ }
+
while((mount_entry = getmntent(org_fd)) != NULL) {
if(strcmp(mount_entry->mnt_dir, mountpoint) != 0) {
addmntent(new_fd, mount_entry);
} else {
- if(verboseflg)
- printf("entry not copied (removed)\n");
+ if(num_matches != 1) {
+ addmntent(new_fd, mount_entry);
+ num_matches--;
+ } else if(verboseflg)
+ printf("entry not copied (ie entry is removed)\n");
}
-
}
if(verboseflg)
@@ -186,10 +238,11 @@ int remove_from_mtab(char * mountpoint)
if(rc < 0) {
printf("failure %s renaming %s to %s\n",strerror(errno),
MOUNTED_TEMP, MOUNTED);
+ unlock_mtab();
return -EIO;
}
- /* BB unlock_mtab - unlink(MOUNTED_LOCK) */
+ unlock_mtab();
return rc;
}
@@ -288,11 +341,18 @@ int main(int argc, char ** argv)
/* fixup path if needed */
+ /* Trim any trailing slashes */
+ while ((strlen(mountpoint) > 1) &&
+ (mountpoint[strlen(mountpoint)-1] == '/'))
+ {
+ mountpoint[strlen(mountpoint)-1] = '\0';
+ }
+
/* make sure that this is a cifs filesystem */
rc = statfs(mountpoint, &statbuf);
if(rc || (statbuf.f_type != CIFS_MAGIC_NUMBER)) {
- printf("Wrong filesystem. This utility only unmounts cifs filesystems.\n");
+ printf("This utility only unmounts cifs filesystems.\n");
return -EINVAL;
}
@@ -312,7 +372,7 @@ int main(int argc, char ** argv)
default:
printf("unmount error %d = %s\n",errno,strerror(errno));
}
- printf("Refer to the umount.cifs(8) manual page (e.g.man 8 umount.cifs)\n");
+ printf("Refer to the umount.cifs(8) manual page (man 8 umount.cifs)\n");
return -1;
} else {
if(verboseflg)