You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

157 lines
4.1 KiB

// -*- 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;
}
/*}}}*/