copy.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. /* Licensed to the Apache Software Foundation (ASF) under one or more
  2. * contributor license agreements. See the NOTICE file distributed with
  3. * this work for additional information regarding copyright ownership.
  4. * The ASF licenses this file to You under the Apache License, Version 2.0
  5. * (the "License"); you may not use this file except in compliance with
  6. * the License. You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "fspr_arch_file_io.h"
  17. #include "fspr_file_io.h"
  18. static fspr_status_t fspr_file_transfer_contents(const char *from_path,
  19. const char *to_path,
  20. fspr_int32_t flags,
  21. fspr_fileperms_t to_perms,
  22. fspr_pool_t *pool)
  23. {
  24. fspr_file_t *s, *d;
  25. fspr_status_t status;
  26. fspr_finfo_t finfo;
  27. fspr_fileperms_t perms;
  28. /* Open source file. */
  29. status = fspr_file_open(&s, from_path, APR_READ, APR_OS_DEFAULT, pool);
  30. if (status)
  31. return status;
  32. /* Maybe get its permissions. */
  33. if (to_perms == APR_FILE_SOURCE_PERMS) {
  34. status = fspr_file_info_get(&finfo, APR_FINFO_PROT, s);
  35. if (status != APR_SUCCESS && status != APR_INCOMPLETE) {
  36. fspr_file_close(s); /* toss any error */
  37. return status;
  38. }
  39. perms = finfo.protection;
  40. }
  41. else
  42. perms = to_perms;
  43. /* Open dest file. */
  44. status = fspr_file_open(&d, to_path, flags, perms, pool);
  45. if (status) {
  46. fspr_file_close(s); /* toss any error */
  47. return status;
  48. }
  49. /* Copy bytes till the cows come home. */
  50. while (1) {
  51. char buf[BUFSIZ];
  52. fspr_size_t bytes_this_time = sizeof(buf);
  53. fspr_status_t read_err;
  54. fspr_status_t write_err;
  55. /* Read 'em. */
  56. read_err = fspr_file_read(s, buf, &bytes_this_time);
  57. if (read_err && !APR_STATUS_IS_EOF(read_err)) {
  58. fspr_file_close(s); /* toss any error */
  59. fspr_file_close(d); /* toss any error */
  60. return read_err;
  61. }
  62. /* Write 'em. */
  63. write_err = fspr_file_write_full(d, buf, bytes_this_time, NULL);
  64. if (write_err) {
  65. fspr_file_close(s); /* toss any error */
  66. fspr_file_close(d); /* toss any error */
  67. return write_err;
  68. }
  69. if (read_err && APR_STATUS_IS_EOF(read_err)) {
  70. status = fspr_file_close(s);
  71. if (status) {
  72. fspr_file_close(d); /* toss any error */
  73. return status;
  74. }
  75. /* return the results of this close: an error, or success */
  76. return fspr_file_close(d);
  77. }
  78. }
  79. /* NOTREACHED */
  80. }
  81. APR_DECLARE(fspr_status_t) fspr_file_copy(const char *from_path,
  82. const char *to_path,
  83. fspr_fileperms_t perms,
  84. fspr_pool_t *pool)
  85. {
  86. return fspr_file_transfer_contents(from_path, to_path,
  87. (APR_WRITE | APR_CREATE | APR_TRUNCATE),
  88. perms,
  89. pool);
  90. }
  91. APR_DECLARE(fspr_status_t) fspr_file_append(const char *from_path,
  92. const char *to_path,
  93. fspr_fileperms_t perms,
  94. fspr_pool_t *pool)
  95. {
  96. return fspr_file_transfer_contents(from_path, to_path,
  97. (APR_WRITE | APR_CREATE | APR_APPEND),
  98. perms,
  99. pool);
  100. }