dirstream.cc 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. // -*- mode: cpp; mode: fold -*-
  2. // Description /*{{{*/
  3. // $Id: dirstream.cc,v 1.2 2001/02/20 07:03:16 jgg 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. /*}}}*/
  23. // DirStream::DoItem - Process an item /*{{{*/
  24. // ---------------------------------------------------------------------
  25. /* This is a very simple extractor, it does not deal with things like
  26. overwriting directories with files and so on. */
  27. bool pkgDirStream::DoItem(Item &Itm,int &Fd)
  28. {
  29. switch (Itm.Type)
  30. {
  31. case Item::File:
  32. {
  33. /* Open the output file, NDELAY is used to prevent this from
  34. blowing up on device special files.. */
  35. int iFd = open(Itm.Name,O_NDELAY|O_WRONLY|O_CREAT|O_TRUNC|O_APPEND,
  36. Itm.Mode);
  37. if (iFd < 0)
  38. return _error->Errno("open","Failed write file %s",
  39. Itm.Name);
  40. // fchmod deals with umask and fchown sets the ownership
  41. if (fchmod(iFd,Itm.Mode) != 0)
  42. return _error->Errno("fchmod","Failed write file %s",
  43. Itm.Name);
  44. if (fchown(iFd,Itm.UID,Itm.GID) != 0 && errno != EPERM)
  45. return _error->Errno("fchown","Failed write file %s",
  46. Itm.Name);
  47. Fd = iFd;
  48. return true;
  49. }
  50. case Item::HardLink:
  51. case Item::SymbolicLink:
  52. case Item::CharDevice:
  53. case Item::BlockDevice:
  54. case Item::Directory:
  55. case Item::FIFO:
  56. break;
  57. }
  58. return true;
  59. }
  60. /*}}}*/
  61. // DirStream::FinishedFile - Finished processing a file /*{{{*/
  62. // ---------------------------------------------------------------------
  63. /* */
  64. bool pkgDirStream::FinishedFile(Item &Itm,int Fd)
  65. {
  66. if (Fd < 0)
  67. return true;
  68. if (close(Fd) != 0)
  69. return _error->Errno("close","Failed to close file %s",Itm.Name);
  70. /* Set the modification times. The only way it can fail is if someone
  71. has futzed with our file, which is intolerable :> */
  72. struct utimbuf Time;
  73. Time.actime = Itm.MTime;
  74. Time.modtime = Itm.MTime;
  75. if (utime(Itm.Name,&Time) != 0)
  76. _error->Errno("utime","Failed to close file %s",Itm.Name);
  77. return true;
  78. }
  79. /*}}}*/
  80. // DirStream::Fail - Failed processing a file /*{{{*/
  81. // ---------------------------------------------------------------------
  82. /* */
  83. bool pkgDirStream::Fail(Item &Itm,int Fd)
  84. {
  85. if (Fd < 0)
  86. return true;
  87. close(Fd);
  88. return false;
  89. }
  90. /*}}}*/