summaryrefslogtreecommitdiff
path: root/apt-pkg/contrib/cdromutl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'apt-pkg/contrib/cdromutl.cc')
-rw-r--r--apt-pkg/contrib/cdromutl.cc157
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;
+}
+ /*}}}*/