dirstream.cc 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. // -*- mode: cpp; mode: fold -*-
  2. // Description /*{{{*/
  3. // $Id: dirstream.cc,v 1.3.2.1 2004/01/16 18:58:50 mdz Exp $
  4. /* ######################################################################
  5. Directory Stream
  6. This class provides a simple basic extractor that can be used for
  7. a number of purposes.
  8. ##################################################################### */
  9. /*}}}*/
  10. // Include Files /*{{{*/
  11. #ifdef __GNUG__
  12. #pragma implementation "apt-pkg/dirstream.h"
  13. #endif
  14. #include <apt-pkg/dirstream.h>
  15. #include <apt-pkg/error.h>
  16. #include <fcntl.h>
  17. #include <sys/stat.h>
  18. #include <sys/types.h>
  19. #include <errno.h>
  20. #include <utime.h>
  21. #include <unistd.h>
  22. #include <apti18n.h>
  23. /*}}}*/
  24. // DirStream::DoItem - Process an item /*{{{*/
  25. // ---------------------------------------------------------------------
  26. /* This is a very simple extractor, it does not deal with things like
  27. overwriting directories with files and so on. */
  28. bool pkgDirStream::DoItem(Item &Itm,int &Fd)
  29. {
  30. switch (Itm.Type)
  31. {
  32. case Item::File:
  33. {
  34. /* Open the output file, NDELAY is used to prevent this from
  35. blowing up on device special files.. */
  36. int iFd = open(Itm.Name,O_NDELAY|O_WRONLY|O_CREAT|O_TRUNC|O_APPEND,
  37. Itm.Mode);
  38. if (iFd < 0)
  39. return _error->Errno("open",_("Failed to write file %s"),
  40. Itm.Name);
  41. // fchmod deals with umask and fchown sets the ownership
  42. if (fchmod(iFd,Itm.Mode) != 0)
  43. return _error->Errno("fchmod",_("Failed to write file %s"),
  44. Itm.Name);
  45. if (fchown(iFd,Itm.UID,Itm.GID) != 0 && errno != EPERM)
  46. return _error->Errno("fchown",_("Failed to write file %s"),
  47. Itm.Name);
  48. Fd = iFd;
  49. return true;
  50. }
  51. case Item::HardLink:
  52. case Item::SymbolicLink:
  53. case Item::CharDevice:
  54. case Item::BlockDevice:
  55. case Item::Directory:
  56. case Item::FIFO:
  57. break;
  58. }
  59. return true;
  60. }
  61. /*}}}*/
  62. // DirStream::FinishedFile - Finished processing a file /*{{{*/
  63. // ---------------------------------------------------------------------
  64. /* */
  65. bool pkgDirStream::FinishedFile(Item &Itm,int Fd)
  66. {
  67. if (Fd < 0)
  68. return true;
  69. if (close(Fd) != 0)
  70. return _error->Errno("close",_("Failed to close file %s"),Itm.Name);
  71. /* Set the modification times. The only way it can fail is if someone
  72. has futzed with our file, which is intolerable :> */
  73. struct utimbuf Time;
  74. Time.actime = Itm.MTime;
  75. Time.modtime = Itm.MTime;
  76. if (utime(Itm.Name,&Time) != 0)
  77. _error->Errno("utime",_("Failed to close file %s"),Itm.Name);
  78. return true;
  79. }
  80. /*}}}*/
  81. // DirStream::Fail - Failed processing a file /*{{{*/
  82. // ---------------------------------------------------------------------
  83. /* */
  84. bool pkgDirStream::Fail(Item &Itm,int Fd)
  85. {
  86. if (Fd < 0)
  87. return true;
  88. close(Fd);
  89. return false;
  90. }
  91. /*}}}*/