Browse Source

ident a CD without changing directory

tags/debian/1.5_alpha1
David Kalnischkies 4 years ago
parent
commit
e91dd46e3f
1 changed files with 23 additions and 23 deletions
  1. +23
    -23
      apt-pkg/contrib/cdromutl.cc

+ 23
- 23
apt-pkg/contrib/cdromutl.cc View File

@@ -184,26 +184,32 @@ bool IdentCdrom(string CD,string &Res,unsigned int Version)
MD5Summation Hash;
bool writable_media = false;

int dirfd = open(CD.c_str(), O_RDONLY | O_DIRECTORY | O_CLOEXEC);
if (dirfd == -1)
return _error->Errno("open",_("Unable to read %s"),CD.c_str());

// if we are on a writable medium (like a usb-stick) that is just
// used like a cdrom don't use "." as it will constantly change,
// use .disk instead
if (access(CD.c_str(), W_OK) == 0 && DirectoryExists(CD+string("/.disk")))
if (faccessat(dirfd, ".", W_OK, 0) == 0)
{
writable_media = true;
CD = CD.append("/.disk");
if (_config->FindB("Debug::aptcdrom",false) == true)
std::clog << "Found writable cdrom, using alternative path: " << CD
<< std::endl;
int diskfd = openat(dirfd, "./.disk", O_RDONLY | O_DIRECTORY | O_CLOEXEC, 0);
if (diskfd != -1)
{
close(dirfd);
dirfd = diskfd;
writable_media = true;
CD = CD.append("/.disk");
if (_config->FindB("Debug::aptcdrom",false) == true)
std::clog << "Found writable cdrom, using alternative path: " << CD
<< std::endl;
}
}

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)
DIR * const D = fdopendir(dirfd);
if (D == nullptr)
return _error->Errno("opendir",_("Unable to read %s"),CD.c_str());

/* Run over the directory, we assume that the reader order will never
change as the media is read-only. In theory if the kernel did
some sort of wacked caching this might not be true.. */
@@ -222,31 +228,24 @@ bool IdentCdrom(string CD,string &Res,unsigned int Version)
else
{
struct stat Buf;
if (stat(Dir->d_name,&Buf) != 0)
if (fstatat(dirfd, Dir->d_name, &Buf, 0) != 0)
continue;
strprintf(S, "%lu", (unsigned long)Buf.st_mtime);
}

Hash.Add(S.c_str());
Hash.Add(Dir->d_name);
};

if (chdir(StartDir.c_str()) != 0) {
_error->Errno("chdir",_("Unable to change to %s"),StartDir.c_str());
closedir(D);
return false;
}
closedir(D);

// Some stats from the fsys
std::string S;
if (_config->FindB("Debug::identcdrom",false) == false)
{
struct statvfs Buf;
if (statvfs(CD.c_str(),&Buf) != 0)
if (fstatvfs(dirfd, &Buf) != 0)
return _error->Errno("statfs",_("Failed to stat the cdrom"));

// We use a kilobyte block size to advoid overflow
// We use a kilobyte block size to avoid overflow
if (writable_media)
{
strprintf(S, "%lu", (unsigned long)(Buf.f_blocks*(Buf.f_bsize/1024)));
@@ -260,6 +259,7 @@ bool IdentCdrom(string CD,string &Res,unsigned int Version)
else
strprintf(S, "-%u.debug", Version);

closedir(D);
Res = Hash.Result().Value() + S;
return true;
}


Loading…
Cancel
Save