copy.cc 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. // -*- mode: cpp; mode: fold -*-
  2. // Description /*{{{*/
  3. // $Id: copy.cc,v 1.2 1998/10/25 07:07:29 jgg Exp $
  4. /* ######################################################################
  5. Copy URI - This method takes a uri like a file: uri and copies it
  6. to the destination file.
  7. ##################################################################### */
  8. /*}}}*/
  9. // Include Files /*{{{*/
  10. #include <apt-pkg/fileutl.h>
  11. #include <strutl.h>
  12. #include <apt-pkg/error.h>
  13. #include <sys/stat.h>
  14. #include <utime.h>
  15. #include <unistd.h>
  16. #include <stdio.h>
  17. /*}}}*/
  18. // Fail - Generate a failure message /*{{{*/
  19. // ---------------------------------------------------------------------
  20. /* */
  21. void Fail(string URI)
  22. {
  23. string Err = "Undetermined Error";
  24. if (_error->empty() == false)
  25. _error->PopMessage(Err);
  26. printf("400 URI Failure\n"
  27. "URI: %s\n"
  28. "Message: %s\n\n",URI.c_str(),Err.c_str());
  29. _error->Discard();
  30. }
  31. /*}}}*/
  32. int main()
  33. {
  34. setlinebuf(stdout);
  35. SetNonBlock(STDIN_FILENO,true);
  36. printf("100 Capabilities\n"
  37. "Version: 1.0\n"
  38. "Pipeline: true\n\n");
  39. vector<string> Messages;
  40. while (1)
  41. {
  42. if (WaitFd(STDIN_FILENO) == false ||
  43. ReadMessages(STDIN_FILENO,Messages) == false)
  44. return 0;
  45. while (Messages.empty() == false)
  46. {
  47. string Message = Messages.front();
  48. Messages.erase(Messages.begin());
  49. // Fetch the message number
  50. char *End;
  51. int Number = strtol(Message.c_str(),&End,10);
  52. if (End == Message.c_str())
  53. {
  54. cerr << "Malformed message!" << endl;
  55. return 100;
  56. }
  57. // We only understand 600 URI Fetch messages
  58. if (Number != 600)
  59. continue;
  60. // Grab the URI bit
  61. string URI = LookupTag(Message,"URI");
  62. string Target = LookupTag(Message,"Filename");
  63. // Grab the filename
  64. string::size_type Pos = URI.find(':');
  65. if (Pos == string::npos)
  66. {
  67. _error->Error("Invalid message");
  68. Fail(URI);
  69. continue;
  70. }
  71. string File = string(URI,Pos+1);
  72. // Start the reply message
  73. string Result = "201 URI Done";
  74. Result += "\nURI: " + URI;
  75. Result += "\nFileName: " + Target;
  76. // See if the file exists
  77. FileFd From(File,FileFd::ReadOnly);
  78. FileFd To(Target,FileFd::WriteEmpty);
  79. To.EraseOnFailure();
  80. if (_error->PendingError() == true)
  81. {
  82. Fail(URI);
  83. continue;
  84. }
  85. // Copy the file
  86. if (CopyFile(From,To) == false)
  87. {
  88. Fail(URI);
  89. continue;
  90. }
  91. From.Close();
  92. To.Close();
  93. // Transfer the modification times
  94. struct stat Buf;
  95. if (stat(File.c_str(),&Buf) != 0)
  96. {
  97. _error->Errno("stat","Failed to stat");
  98. Fail(URI);
  99. continue;
  100. }
  101. struct utimbuf TimeBuf;
  102. TimeBuf.actime = Buf.st_atime;
  103. TimeBuf.modtime = Buf.st_mtime;
  104. if (utime(Target.c_str(),&TimeBuf) != 0)
  105. {
  106. _error->Errno("utime","Failed to set modification time");
  107. Fail(URI);
  108. continue;
  109. }
  110. // Send the message
  111. Result += "\n\n";
  112. if (write(STDOUT_FILENO,Result.begin(),Result.length()) !=
  113. (signed)Result.length())
  114. return 100;
  115. }
  116. }
  117. return 0;
  118. }