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)