diff options
author | Arch Librarian <arch@canonical.com> | 2004-09-20 16:51:46 +0000 |
---|---|---|
committer | Arch Librarian <arch@canonical.com> | 2004-09-20 16:51:46 +0000 |
commit | d669751ba187834ccc6e4fc44b070159d34b1c2b (patch) | |
tree | 59271b790c901bc99abe588550c11b4d97bfcad7 /apt-pkg/contrib/cdromutl.cc | |
parent | 65ae8fab065de81a777e679528a3859c621836da (diff) |
CDROM stuff from apt-cdrom
Author: jgg
Date: 1998-11-29 01:19:27 GMT
CDROM stuff from apt-cdrom
Diffstat (limited to 'apt-pkg/contrib/cdromutl.cc')
-rw-r--r-- | apt-pkg/contrib/cdromutl.cc | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/apt-pkg/contrib/cdromutl.cc b/apt-pkg/contrib/cdromutl.cc new file mode 100644 index 000000000..58dff94d2 --- /dev/null +++ b/apt-pkg/contrib/cdromutl.cc @@ -0,0 +1,157 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: cdromutl.cc,v 1.1 1998/11/29 01:19:27 jgg Exp $ +/* ###################################################################### + + CDROM Utilities - Some functions to manipulate CDROM mounts. + + These are here for the cdrom method and apt-cdrom. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#ifdef __GNUG__ +#pragma implementation "apt-pkg/cdromutl.h" +#endif +#include <apt-pkg/cdromutl.h> +#include <apt-pkg/error.h> +#include <apt-pkg/md5.h> +#include <apt-pkg/fileutl.h> + +#include <sys/wait.h> +#include <sys/errno.h> +#include <sys/vfs.h> +#include <dirent.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdio.h> + /*}}}*/ + +// UnmountCdrom - Unmount a cdrom /*{{{*/ +// --------------------------------------------------------------------- +/* Forking umount works much better than the umount syscall which can + leave /etc/mtab inconsitant. We drop all messages this produces. */ +bool UnmountCdrom(string Path) +{ + int Child = fork(); + if (Child < -1) + return _error->Errno("fork","Failed to fork"); + + // The child + if (Child == 0) + { + // Make all the fds /dev/null + for (int I = 0; I != 10; I++) + close(I); + for (int I = 0; I != 3; I++) + dup2(open("/dev/null",O_RDWR),I); + + const char *Args[10]; + Args[0] = "umount"; + Args[1] = Path.c_str(); + Args[2] = 0; + execvp(Args[0],(char **)Args); + exit(100); + } + + // Wait for mount + int Status = 0; + while (waitpid(Child,&Status,0) != Child) + { + if (errno == EINTR) + continue; + return _error->Errno("waitpid","Couldn't wait for subprocess"); + } + + // Check for an error code. + if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0) + return false; + return true; +} + /*}}}*/ +// MountCdrom - Mount a cdrom /*{{{*/ +// --------------------------------------------------------------------- +/* We fork mount and drop all messages */ +bool MountCdrom(string Path) +{ + int Child = fork(); + if (Child < -1) + return _error->Errno("fork","Failed to fork"); + + // The child + if (Child == 0) + { + // Make all the fds /dev/null + for (int I = 0; I != 10; I++) + close(I); + for (int I = 0; I != 3; I++) + dup2(open("/dev/null",O_RDWR),I); + + const char *Args[10]; + Args[0] = "mount"; + Args[1] = Path.c_str(); + Args[2] = 0; + execvp(Args[0],(char **)Args); + exit(100); + } + + // Wait for mount + int Status = 0; + while (waitpid(Child,&Status,0) != Child) + { + if (errno == EINTR) + continue; + return _error->Errno("waitpid","Couldn't wait for subprocess"); + } + + // Check for an error code. + if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0) + return false; + return true; +} + /*}}}*/ +// IdentCdrom - Generate a unique string for this CD /*{{{*/ +// --------------------------------------------------------------------- +/* We convert everything we hash into a string, this prevents byte size/order + from effecting the outcome. */ +bool IdentCdrom(string CD,string &Res) +{ + MD5Summation Hash; + + string StartDir = SafeGetCWD(); + if (chdir(CD.c_str()) != 0) + return _error->Errno("chdir","Unable to change to %s",CD.c_str()); + + DIR *D = opendir("."); + if (D == 0) + return _error->Errno("opendir","Unable to read %s",CD.c_str()); + + // Run over the directory + char S[300]; + for (struct dirent *Dir = readdir(D); Dir != 0; Dir = readdir(D)) + { + // Skip some files.. + if (strcmp(Dir->d_name,".") == 0 || + strcmp(Dir->d_name,"..") == 0) + continue; + + sprintf(S,"%lu",Dir->d_ino); + Hash.Add(S); + Hash.Add(Dir->d_name); + }; + + chdir(StartDir.c_str()); + closedir(D); + + // Some stats from the fsys + struct statfs Buf; + if (statfs(CD.c_str(),&Buf) != 0) + return _error->Errno("statfs","Failed to stat the cdrom"); + + sprintf(S,"%u %u",Buf.f_blocks,Buf.f_bfree); + Hash.Add(S); + + Res = Hash.Result().Value(); + return true; +} + /*}}}*/ |