]> git.proxmox.com Git - libgit2.git/blob - tests/test_helpers.c
fileops/repository: create (most) directories with 0777 permissions
[libgit2.git] / tests / test_helpers.c
1 /*
2 * This file is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License, version 2,
4 * as published by the Free Software Foundation.
5 *
6 * In addition to the permissions in the GNU General Public License,
7 * the authors give you unlimited permission to link the compiled
8 * version of this file into combinations with other programs,
9 * and to distribute those combinations without any restriction
10 * coming from the use of this file. (The General Public License
11 * restrictions do apply in other respects; for example, they cover
12 * modification of the file, and distribution when not linked into
13 * a combined executable.)
14 *
15 * This file is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; see the file COPYING. If not, write to
22 * the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 * Boston, MA 02110-1301, USA.
24 */
25
26 #include "common.h"
27 #include "test_helpers.h"
28 #include "fileops.h"
29
30 int write_object_data(char *file, void *data, size_t len)
31 {
32 git_file fd;
33 int ret;
34
35 if ((fd = p_creat(file, S_IREAD | S_IWRITE)) < 0)
36 return -1;
37 ret = p_write(fd, data, len);
38 p_close(fd);
39
40 return ret;
41 }
42
43 int write_object_files(const char *odb_dir, object_data *d)
44 {
45 if (p_mkdir(odb_dir, GIT_OBJECT_DIR_MODE) < 0) {
46 int err = errno;
47 fprintf(stderr, "can't make directory \"%s\"", odb_dir);
48 if (err == EEXIST)
49 fprintf(stderr, " (already exists)");
50 fprintf(stderr, "\n");
51 return -1;
52 }
53
54 if ((p_mkdir(d->dir, GIT_OBJECT_DIR_MODE) < 0) && (errno != EEXIST)) {
55 fprintf(stderr, "can't make object directory \"%s\"\n", d->dir);
56 return -1;
57 }
58 if (write_object_data(d->file, d->bytes, d->blen) < 0) {
59 fprintf(stderr, "can't write object file \"%s\"\n", d->file);
60 return -1;
61 }
62
63 return 0;
64 }
65
66 int remove_object_files(const char *odb_dir, object_data *d)
67 {
68 if (p_unlink(d->file) < 0) {
69 fprintf(stderr, "can't delete object file \"%s\"\n", d->file);
70 return -1;
71 }
72 if ((p_rmdir(d->dir) < 0) && (errno != ENOTEMPTY)) {
73 fprintf(stderr, "can't remove object directory \"%s\"\n", d->dir);
74 return -1;
75 }
76
77 if (p_rmdir(odb_dir) < 0) {
78 fprintf(stderr, "can't remove directory \"%s\"\n", odb_dir);
79 return -1;
80 }
81
82 return 0;
83 }
84
85 void locate_loose_object(const char *repository_folder, git_object *object, char **out, char **out_folder)
86 {
87 static const char *objects_folder = "objects/";
88
89 char *ptr, *full_path, *top_folder;
90 int path_length, objects_length;
91
92 assert(repository_folder && object);
93
94 objects_length = strlen(objects_folder);
95 path_length = strlen(repository_folder);
96 ptr = full_path = git__malloc(path_length + objects_length + GIT_OID_HEXSZ + 3);
97
98 strcpy(ptr, repository_folder);
99 strcpy(ptr + path_length, objects_folder);
100
101 ptr = top_folder = ptr + path_length + objects_length;
102 *ptr++ = '/';
103 git_oid_pathfmt(ptr, git_object_id(object));
104 ptr += GIT_OID_HEXSZ + 1;
105 *ptr = 0;
106
107 *out = full_path;
108
109 if (out_folder)
110 *out_folder = top_folder;
111 }
112
113 int loose_object_dir_mode(const char *repository_folder, git_object *object)
114 {
115 char *object_path;
116 size_t pos;
117 struct stat st;
118
119 locate_loose_object(repository_folder, object, &object_path, NULL);
120
121 pos = strlen(object_path);
122 while (pos--) {
123 if (object_path[pos] == '/') {
124 object_path[pos] = 0;
125 break;
126 }
127 }
128
129 assert(p_stat(object_path, &st) == 0);
130 free(object_path);
131
132 return st.st_mode;
133 }
134
135 int remove_loose_object(const char *repository_folder, git_object *object)
136 {
137 char *full_path, *top_folder;
138
139 locate_loose_object(repository_folder, object, &full_path, &top_folder);
140
141 if (p_unlink(full_path) < 0) {
142 fprintf(stderr, "can't delete object file \"%s\"\n", full_path);
143 return -1;
144 }
145
146 *top_folder = 0;
147
148 if ((p_rmdir(full_path) < 0) && (errno != ENOTEMPTY)) {
149 fprintf(stderr, "can't remove object directory \"%s\"\n", full_path);
150 return -1;
151 }
152
153 free(full_path);
154
155 return GIT_SUCCESS;
156 }
157
158 int cmp_objects(git_rawobj *o, object_data *d)
159 {
160 if (o->type != git_object_string2type(d->type))
161 return -1;
162 if (o->len != d->dlen)
163 return -1;
164 if ((o->len > 0) && (memcmp(o->data, d->data, o->len) != 0))
165 return -1;
166 return 0;
167 }
168
169 int copy_file(const char *src, const char *dst)
170 {
171 git_fbuffer source_buf;
172 git_file dst_fd;
173 int error = GIT_ERROR;
174
175 if (git_futils_readbuffer(&source_buf, src) < GIT_SUCCESS)
176 return GIT_ENOTFOUND;
177
178 dst_fd = git_futils_creat_withpath(dst, 0777, 0644);
179 if (dst_fd < 0)
180 goto cleanup;
181
182 error = p_write(dst_fd, source_buf.data, source_buf.len);
183
184 cleanup:
185 git_futils_freebuffer(&source_buf);
186 p_close(dst_fd);
187
188 return error;
189 }
190
191 int cmp_files(const char *a, const char *b)
192 {
193 git_fbuffer buf_a, buf_b;
194 int error = GIT_ERROR;
195
196 if (git_futils_readbuffer(&buf_a, a) < GIT_SUCCESS)
197 return GIT_ERROR;
198
199 if (git_futils_readbuffer(&buf_b, b) < GIT_SUCCESS) {
200 git_futils_freebuffer(&buf_a);
201 return GIT_ERROR;
202 }
203
204 if (buf_a.len == buf_b.len && !memcmp(buf_a.data, buf_b.data, buf_a.len))
205 error = GIT_SUCCESS;
206
207 git_futils_freebuffer(&buf_a);
208 git_futils_freebuffer(&buf_b);
209
210 return error;
211 }
212
213 typedef struct {
214 size_t src_len, dst_len;
215 char *dst;
216 } copydir_data;
217
218 static int copy_filesystem_element_recurs(void *_data, char *source)
219 {
220 copydir_data *data = (copydir_data *)_data;
221
222 data->dst[data->dst_len] = 0;
223 git_path_join(data->dst, data->dst, source + data->src_len);
224
225 if (git_futils_isdir(source) == GIT_SUCCESS)
226 return git_futils_direach(source, GIT_PATH_MAX, copy_filesystem_element_recurs, _data);
227
228 return copy_file(source, data->dst);
229 }
230
231 int copydir_recurs(const char *source_directory_path, const char *destination_directory_path)
232 {
233 char source_buffer[GIT_PATH_MAX];
234 char dest_buffer[GIT_PATH_MAX];
235 copydir_data data;
236
237 /* Source has to exist, Destination hast to _not_ exist */
238 if (git_futils_isdir(source_directory_path) != GIT_SUCCESS ||
239 git_futils_isdir(destination_directory_path) == GIT_SUCCESS)
240 return GIT_EINVALIDPATH;
241
242 git_path_join(source_buffer, source_directory_path, "");
243 data.src_len = strlen(source_buffer);
244
245 git_path_join(dest_buffer, destination_directory_path, "");
246 data.dst = dest_buffer;
247 data.dst_len = strlen(dest_buffer);
248
249 return copy_filesystem_element_recurs(&data, source_buffer);
250 }
251
252 int open_temp_repo(git_repository **repo, const char *path)
253 {
254 if (copydir_recurs(path, TEMP_REPO_FOLDER) < GIT_SUCCESS) {
255 printf("\nFailed to create temporary folder. Aborting test suite.\n");
256 exit(-1);
257 }
258
259 return git_repository_open(repo, TEMP_REPO_FOLDER);
260 }
261
262 void close_temp_repo(git_repository *repo)
263 {
264 git_repository_free(repo);
265 if (git_futils_rmdir_r(TEMP_REPO_FOLDER, 1) < GIT_SUCCESS) {
266 printf("\nFailed to remove temporary folder. Aborting test suite.\n");
267 exit(-1);
268 }
269 }
270
271 static int remove_placeholders_recurs(void *filename, char *path)
272 {
273 char passed_filename[GIT_PATH_MAX];
274 char *data = (char *)filename;
275
276 if (!git_futils_isdir(path))
277 return git_futils_direach(path, GIT_PATH_MAX, remove_placeholders_recurs, data);
278
279 if (git_path_basename_r(passed_filename, sizeof(passed_filename), path) < GIT_SUCCESS)
280 return GIT_EINVALIDPATH;
281
282 if (!strcmp(data, passed_filename))
283 return p_unlink(path);
284
285 return GIT_SUCCESS;
286 }
287
288 int remove_placeholders(char *directory_path, char *filename)
289 {
290 char buffer[GIT_PATH_MAX];
291
292 if (git_futils_isdir(directory_path))
293 return GIT_EINVALIDPATH;
294
295 strcpy(buffer, directory_path);
296 return remove_placeholders_recurs(filename, buffer);
297 }