diff options
-rw-r--r-- | source3/client/umount.cifs.c | 125 |
1 files changed, 80 insertions, 45 deletions
diff --git a/source3/client/umount.cifs.c b/source3/client/umount.cifs.c index 6e330a42a7..02ed2caba4 100644 --- a/source3/client/umount.cifs.c +++ b/source3/client/umount.cifs.c @@ -34,9 +34,10 @@ #include <errno.h> #include <string.h> #include <mntent.h> +#include <fstab.h> #define UNMOUNT_CIFS_VERSION_MAJOR "0" -#define UNMOUNT_CIFS_VERSION_MINOR "2" +#define UNMOUNT_CIFS_VERSION_MINOR "3" #ifndef UNMOUNT_CIFS_VENDOR_SUFFIX #define UNMOUNT_CIFS_VENDOR_SUFFIX "" @@ -50,6 +51,13 @@ #define MNT_EXPIRE 0x04 #endif +#ifndef MOUNTED_LOCK +#define MOUNTED_LOCK "/etc/mtab~" +#endif +#ifndef MOUNTED_TEMP +#define MOUNTED_TEMP "/etc/mtab.tmp" +#endif + #define CIFS_IOC_CHECKUMOUNT _IO(0xCF, 2) #define CIFS_MAGIC_NUMBER 0xFF534D42 /* the first four bytes of SMB PDU */ @@ -115,6 +123,73 @@ static int umount_check_perm(char * dir) return rc; } +int remove_from_mtab(char * mountpoint) +{ + int rc = 0; + FILE * org_fd; + FILE * new_fd; + struct mntent * mount_entry; + + /* Do we need to check if it is a symlink to e.g. /proc/mounts + in which case we probably do not want to update it? */ + + /* 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(verboseflg) + printf("attempting to remove from mtab\n"); + + org_fd = setmntent(MOUNTED, "r"); + + if(org_fd == NULL) { + printf("Can not open %s\n",MOUNTED); + return -EIO; + } + + new_fd = setmntent(MOUNTED_TEMP,"w"); + if(new_fd == NULL) { + printf("Can not open temp file %s", MOUNTED_TEMP); + endmntent(org_fd); + return -EIO; + } + + /* BB fix so we only remove the last entry that matches BB */ + 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(verboseflg) + printf("done updating tmp file\n"); + rc = fchmod (fileno (new_fd), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); + if(rc < 0) { + printf("error %s changing mode of %s\n", strerror(errno), + MOUNTED_TEMP); + } + endmntent(new_fd); + + rc = rename(MOUNTED_TEMP, MOUNTED); + + if(rc < 0) { + printf("failure %s renaming %s to %s\n",strerror(errno), + MOUNTED_TEMP, MOUNTED); + return -EIO; + } + + /* BB unlock_mtab - unlink(MOUNTED_LOCK) */ + + return rc; +} + int main(int argc, char ** argv) { int c; @@ -122,10 +197,8 @@ int main(int argc, char ** argv) int flags = 0; int nomtab = 0; int retry_remount = 0; - struct mntent mountent; struct statfs statbuf; char * mountpoint; - FILE * pmntfile; if(argc && argv) { thisprogram = argv[0]; @@ -238,48 +311,10 @@ int main(int argc, char ** argv) printf("Refer to the umount.cifs(8) manual page (e.g.man 8 umount.cifs)\n"); return -1; } else { - pmntfile = setmntent(MOUNTED, "a+"); - if(pmntfile) { -/* mountent.mnt_fsname = share_name; - mountent.mnt_dir = mountpoint; - mountent.mnt_type = "cifs"; - mountent.mnt_opts = malloc(220); - if(mountent.mnt_opts) { - char * mount_user = getusername(); - memset(mountent.mnt_opts,0,200); - if(flags & MS_RDONLY) - strcat(mountent.mnt_opts,"ro"); - else - strcat(mountent.mnt_opts,"rw"); - if(flags & MS_MANDLOCK) - strcat(mountent.mnt_opts,",mand"); - else - strcat(mountent.mnt_opts,",nomand"); - if(flags & MS_NOEXEC) - strcat(mountent.mnt_opts,",noexec"); - if(flags & MS_NOSUID) - strcat(mountent.mnt_opts,",nosuid"); - if(flags & MS_NODEV) - strcat(mountent.mnt_opts,",nodev"); - if(flags & MS_SYNCHRONOUS) - strcat(mountent.mnt_opts,",synch"); - if(mount_user) { - if(getuid() != 0) { - strcat(mountent.mnt_opts,",user="); - strcat(mountent.mnt_opts,mount_user); - } - free(mount_user); - } - } - mountent.mnt_freq = 0; - mountent.mnt_passno = 0; - rc = addmntent(pmntfile,&mountent); - endmntent(pmntfile); - if(mountent.mnt_opts) - free(mountent.mnt_opts);*/ - } else { - printf("could not update mount table\n"); - } + if(verboseflg) + printf("umount2 succeeded\n"); + if(nomtab == 0) + remove_from_mtab(mountpoint); } return 0; |