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 "testutil.h"
18#include "apr_file_io.h"
19#include "apr_file_info.h"
20#include "apr_errno.h"
21#include "apr_pools.h"
22
23static void copy_helper(abts_case *tc, const char *from, const char * to,
24                        apr_fileperms_t perms, int append, apr_pool_t *p)
25{
26    apr_status_t rv;
27    apr_status_t dest_rv;
28    apr_finfo_t copy;
29    apr_finfo_t orig;
30    apr_finfo_t dest;
31
32    dest_rv = apr_stat(&dest, to, APR_FINFO_SIZE, p);
33
34    if (!append) {
35        rv = apr_file_copy(from, to, perms, p);
36    }
37    else {
38        rv = apr_file_append(from, to, perms, p);
39    }
40    APR_ASSERT_SUCCESS(tc, "Error copying file", rv);
41
42    rv = apr_stat(&orig, from, APR_FINFO_SIZE, p);
43    APR_ASSERT_SUCCESS(tc, "Couldn't stat original file", rv);
44
45    rv = apr_stat(&copy, to, APR_FINFO_SIZE, p);
46    APR_ASSERT_SUCCESS(tc, "Couldn't stat copy file", rv);
47
48    if (!append) {
49        ABTS_ASSERT(tc, "File size differs", orig.size == copy.size);
50    }
51    else {
52        ABTS_ASSERT(tc, "File size differs",
53			            ((dest_rv == APR_SUCCESS)
54			              ? dest.size : 0) + orig.size == copy.size);
55    }
56}
57
58static void copy_short_file(abts_case *tc, void *data)
59{
60    apr_status_t rv;
61
62    /* make absolutely sure that the dest file doesn't exist. */
63    apr_file_remove("data/file_copy.txt", p);
64
65    copy_helper(tc, "data/file_datafile.txt", "data/file_copy.txt",
66                APR_FILE_SOURCE_PERMS, 0, p);
67    rv = apr_file_remove("data/file_copy.txt", p);
68    APR_ASSERT_SUCCESS(tc, "Couldn't remove copy file", rv);
69}
70
71static void copy_over_existing(abts_case *tc, void *data)
72{
73    apr_status_t rv;
74
75    /* make absolutely sure that the dest file doesn't exist. */
76    apr_file_remove("data/file_copy.txt", p);
77
78    /* This is a cheat.  I don't want to create a new file, so I just copy
79     * one file, then I copy another.  If the second copy succeeds, then
80     * this works.
81     */
82    copy_helper(tc, "data/file_datafile.txt", "data/file_copy.txt",
83                APR_FILE_SOURCE_PERMS, 0, p);
84
85    copy_helper(tc, "data/mmap_datafile.txt", "data/file_copy.txt",
86                APR_FILE_SOURCE_PERMS, 0, p);
87
88    rv = apr_file_remove("data/file_copy.txt", p);
89    APR_ASSERT_SUCCESS(tc, "Couldn't remove copy file", rv);
90}
91
92static void append_nonexist(abts_case *tc, void *data)
93{
94    apr_status_t rv;
95
96    /* make absolutely sure that the dest file doesn't exist. */
97    apr_file_remove("data/file_copy.txt", p);
98
99    copy_helper(tc, "data/file_datafile.txt", "data/file_copy.txt",
100                APR_FILE_SOURCE_PERMS, 0, p);
101    rv = apr_file_remove("data/file_copy.txt", p);
102    APR_ASSERT_SUCCESS(tc, "Couldn't remove copy file", rv);
103}
104
105static void append_exist(abts_case *tc, void *data)
106{
107    apr_status_t rv;
108
109    /* make absolutely sure that the dest file doesn't exist. */
110    apr_file_remove("data/file_copy.txt", p);
111
112    /* This is a cheat.  I don't want to create a new file, so I just copy
113     * one file, then I copy another.  If the second copy succeeds, then
114     * this works.
115     */
116    copy_helper(tc, "data/file_datafile.txt", "data/file_copy.txt",
117                APR_FILE_SOURCE_PERMS, 0, p);
118
119    copy_helper(tc, "data/mmap_datafile.txt", "data/file_copy.txt",
120                APR_FILE_SOURCE_PERMS, 1, p);
121
122    rv = apr_file_remove("data/file_copy.txt", p);
123    APR_ASSERT_SUCCESS(tc, "Couldn't remove copy file", rv);
124}
125
126abts_suite *testfilecopy(abts_suite *suite)
127{
128    suite = ADD_SUITE(suite)
129
130    abts_run_test(suite, copy_short_file, NULL);
131    abts_run_test(suite, copy_over_existing, NULL);
132
133    abts_run_test(suite, append_nonexist, NULL);
134    abts_run_test(suite, append_exist, NULL);
135
136    return suite;
137}
138
139