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 17#include "apr_arch_file_io.h" 18#include "apr_file_io.h" 19 20static apr_status_t apr_file_transfer_contents(const char *from_path, 21 const char *to_path, 22 apr_int32_t flags, 23 apr_fileperms_t to_perms, 24 apr_pool_t *pool) 25{ 26 apr_file_t *s, *d; 27 apr_status_t status; 28 apr_finfo_t finfo; 29 apr_fileperms_t perms; 30 31 /* Open source file. */ 32 status = apr_file_open(&s, from_path, APR_FOPEN_READ, APR_OS_DEFAULT, pool); 33 if (status) 34 return status; 35 36 /* Maybe get its permissions. */ 37 if (to_perms == APR_FILE_SOURCE_PERMS) { 38 status = apr_file_info_get(&finfo, APR_FINFO_PROT, s); 39 if (status != APR_SUCCESS && status != APR_INCOMPLETE) { 40 apr_file_close(s); /* toss any error */ 41 return status; 42 } 43 perms = finfo.protection; 44 apr_file_perms_set(to_path, perms); /* ignore any failure */ 45 } 46 else 47 perms = to_perms; 48 49 /* Open dest file. */ 50 status = apr_file_open(&d, to_path, flags, perms, pool); 51 if (status) { 52 apr_file_close(s); /* toss any error */ 53 return status; 54 } 55 56#if BUFSIZ > APR_FILE_DEFAULT_BUFSIZE 57#define COPY_BUFSIZ BUFSIZ 58#else 59#define COPY_BUFSIZ APR_FILE_DEFAULT_BUFSIZE 60#endif 61 62 /* Copy bytes till the cows come home. */ 63 while (1) { 64 char buf[COPY_BUFSIZ]; 65 apr_size_t bytes_this_time = sizeof(buf); 66 apr_status_t read_err; 67 apr_status_t write_err; 68 69 /* Read 'em. */ 70 read_err = apr_file_read(s, buf, &bytes_this_time); 71 if (read_err && !APR_STATUS_IS_EOF(read_err)) { 72 apr_file_close(s); /* toss any error */ 73 apr_file_close(d); /* toss any error */ 74 return read_err; 75 } 76 77 /* Write 'em. */ 78 write_err = apr_file_write_full(d, buf, bytes_this_time, NULL); 79 if (write_err) { 80 apr_file_close(s); /* toss any error */ 81 apr_file_close(d); /* toss any error */ 82 return write_err; 83 } 84 85 if (read_err && APR_STATUS_IS_EOF(read_err)) { 86 status = apr_file_close(s); 87 if (status) { 88 apr_file_close(d); /* toss any error */ 89 return status; 90 } 91 92 /* return the results of this close: an error, or success */ 93 return apr_file_close(d); 94 } 95 } 96 /* NOTREACHED */ 97} 98 99APR_DECLARE(apr_status_t) apr_file_copy(const char *from_path, 100 const char *to_path, 101 apr_fileperms_t perms, 102 apr_pool_t *pool) 103{ 104 return apr_file_transfer_contents(from_path, to_path, 105 (APR_FOPEN_WRITE | APR_FOPEN_CREATE | APR_FOPEN_TRUNCATE), 106 perms, 107 pool); 108} 109 110APR_DECLARE(apr_status_t) apr_file_append(const char *from_path, 111 const char *to_path, 112 apr_fileperms_t perms, 113 apr_pool_t *pool) 114{ 115 return apr_file_transfer_contents(from_path, to_path, 116 (APR_FOPEN_WRITE | APR_FOPEN_CREATE | APR_FOPEN_APPEND), 117 perms, 118 pool); 119} 120