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,
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 <http://www.gnu.org/licenses/>. */
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#include <errno.h>
#include <string.h>
#include <mntent.h>
-#include <fstab.h>
+#include "mount.h"
#define UNMOUNT_CIFS_VERSION_MAJOR "0"
-#define UNMOUNT_CIFS_VERSION_MINOR "4"
+#define UNMOUNT_CIFS_VERSION_MINOR "6"
#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
{ NULL, 0, NULL, 0 }
};
-char * thisprogram;
+const char * thisprogram;
int verboseflg = 0;
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)
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 remove_from_mtab(char * mountpoint)
{
- int rc = 0;
+ int rc;
+ int num_matches;
FILE * org_fd;
FILE * new_fd;
struct mntent * mount_entry;
/* 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 */
-
+ atexit(unlock_mtab);
+ if (lock_mtab()) {
+ printf("Mount table locked\n");
+ return -EACCES;
+ }
+
if(verboseflg)
printf("attempting to remove from mtab\n");
if(org_fd == NULL) {
printf("Can not open %s\n",MOUNTED);
+ unlock_mtab();
return -EIO;
}
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)
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;
}
/* 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;
}
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)