123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- // -*- mode: cpp; mode: fold -*-
- // Description /*{{{*/
- // $Id: dirstream.cc,v 1.3.2.1 2004/01/16 18:58:50 mdz Exp $
- /* ######################################################################
- Directory Stream
-
- This class provides a simple basic extractor that can be used for
- a number of purposes.
-
- ##################################################################### */
- /*}}}*/
- // Include Files /*{{{*/
- #include<config.h>
- #include <apt-pkg/dirstream.h>
- #include <apt-pkg/error.h>
- #include <fcntl.h>
- #include <sys/stat.h>
- #include <sys/time.h>
- #include <errno.h>
- #include <unistd.h>
- #include <apti18n.h>
- /*}}}*/
- // DirStream::DoItem - Process an item /*{{{*/
- // ---------------------------------------------------------------------
- /* This is a very simple extractor, it does not deal with things like
- overwriting directories with files and so on. */
- bool pkgDirStream::DoItem(Item &Itm,int &Fd)
- {
- switch (Itm.Type)
- {
- case Item::File:
- {
- /* Open the output file, NDELAY is used to prevent this from
- blowing up on device special files.. */
- int iFd = open(Itm.Name,O_NDELAY|O_WRONLY|O_CREAT|O_TRUNC|O_APPEND,
- Itm.Mode);
- if (iFd < 0)
- return _error->Errno("open",_("Failed to write file %s"),
- Itm.Name);
-
- // fchmod deals with umask and fchown sets the ownership
- if (fchmod(iFd,Itm.Mode) != 0)
- {
- close(iFd);
- return _error->Errno("fchmod",_("Failed to write file %s"), Itm.Name);
- }
- if (fchown(iFd,Itm.UID,Itm.GID) != 0 && errno != EPERM)
- {
- close(iFd);
- return _error->Errno("fchown",_("Failed to write file %s"), Itm.Name);
- }
- Fd = iFd;
- return true;
- }
-
- case Item::HardLink:
- case Item::SymbolicLink:
- case Item::CharDevice:
- case Item::BlockDevice:
- case Item::Directory:
- {
- struct stat Buf;
- // check if the dir is already there, if so return true
- if (stat(Itm.Name,&Buf) == 0)
- {
- if(S_ISDIR(Buf.st_mode))
- return true;
- // something else is there already, return false
- return false;
- }
- // nothing here, create the dir
- if(mkdir(Itm.Name,Itm.Mode) < 0)
- return false;
- return true;
- }
- case Item::FIFO:
- break;
- }
-
- return true;
- }
- /*}}}*/
- // DirStream::FinishedFile - Finished processing a file /*{{{*/
- // ---------------------------------------------------------------------
- /* */
- bool pkgDirStream::FinishedFile(Item &Itm,int Fd)
- {
- if (Fd < 0)
- return true;
- /* Set the modification times. The only way it can fail is if someone
- has futzed with our file, which is intolerable :> */
- struct timeval times[2];
- times[0].tv_sec = times[1].tv_sec = Itm.MTime;
- times[0].tv_usec = times[1].tv_usec = 0;
- if (utimes(Itm.Name, times) != 0)
- _error->Errno("utimes", "Failed to set modification time for %s",Itm.Name);
- if (close(Fd) != 0)
- return _error->Errno("close",_("Failed to close file %s"),Itm.Name);
- return true;
- }
- /*}}}*/
- // DirStream::Fail - Failed processing a file /*{{{*/
- // ---------------------------------------------------------------------
- /* */
- bool pkgDirStream::Fail(Item &/*Itm*/, int Fd)
- {
- if (Fd < 0)
- return true;
-
- close(Fd);
- return false;
- }
- /*}}}*/
|