]> git.proxmox.com Git - libgit2.git/blame - src/libgit2/libgit2.c
Merge https://salsa.debian.org/debian/libgit2 into proxmox/bullseye
[libgit2.git] / src / libgit2 / libgit2.c
CommitLineData
e85bbd52
ET
1/*
2 * Copyright (C) the libgit2 contributors. All rights reserved.
3 *
4 * This file is part of libgit2, distributed under the GNU GPL v2 with
5 * a Linking Exception. For full terms see the included COPYING file.
6 */
7
c25aa7cd 8#include "libgit2.h"
ac3d33df 9
e85bbd52 10#include <git2.h>
ac3d33df 11#include "alloc.h"
e579e0f7 12#include "buf.h"
e85bbd52 13#include "cache.h"
c25aa7cd
PP
14#include "common.h"
15#include "filter.h"
16#include "hash.h"
17#include "index.h"
18#include "merge_driver.h"
19#include "pool.h"
20#include "mwindow.h"
22a19f5b 21#include "object.h"
35079f50 22#include "odb.h"
e579e0f7 23#include "rand.h"
452bf57c 24#include "refs.h"
c25aa7cd
PP
25#include "runtime.h"
26#include "sysdir.h"
27#include "thread.h"
28#include "threadstate.h"
29#include "git2/global.h"
30#include "streams/registry.h"
31#include "streams/mbedtls.h"
32#include "streams/openssl.h"
61acc9fa 33#include "transports/smart.h"
22a2d3d5 34#include "transports/http.h"
c25aa7cd
PP
35#include "transports/ssh.h"
36
37#ifdef GIT_WIN32
38# include "win32/w32_leakcheck.h"
39#endif
40
41/* Declarations for tuneable settings */
42extern size_t git_mwindow__window_size;
43extern size_t git_mwindow__mapped_limit;
44extern size_t git_mwindow__file_limit;
45extern size_t git_indexer__max_objects;
46extern bool git_disable_pack_keep_file_checks;
47extern int git_odb__packed_priority;
48extern int git_odb__loose_priority;
49
50char *git__user_agent;
51char *git__ssl_ciphers;
52
53static void libgit2_settings_global_shutdown(void)
54{
55 git__free(git__user_agent);
56 git__free(git__ssl_ciphers);
57 git_repository__free_extensions();
58}
59
60static int git_libgit2_settings_global_init(void)
61{
62 return git_runtime_shutdown_register(libgit2_settings_global_shutdown);
63}
64
65int git_libgit2_init(void)
66{
67 static git_runtime_init_fn init_fns[] = {
68#ifdef GIT_WIN32
69 git_win32_leakcheck_global_init,
70#endif
71 git_allocator_global_init,
72 git_threadstate_global_init,
73 git_threads_global_init,
e579e0f7 74 git_rand_global_init,
c25aa7cd
PP
75 git_hash_global_init,
76 git_sysdir_global_init,
77 git_filter_global_init,
78 git_merge_driver_global_init,
79 git_transport_ssh_global_init,
80 git_stream_registry_global_init,
81 git_openssl_stream_global_init,
82 git_mbedtls_stream_global_init,
83 git_mwindow_global_init,
84 git_pool_global_init,
85 git_libgit2_settings_global_init
86 };
87
88 return git_runtime_init(init_fns, ARRAY_SIZE(init_fns));
89}
90
91int git_libgit2_init_count(void)
92{
93 return git_runtime_init_count();
94}
95
96int git_libgit2_shutdown(void)
97{
98 return git_runtime_shutdown();
99}
e85bbd52 100
22a2d3d5 101int git_libgit2_version(int *major, int *minor, int *rev)
e85bbd52
ET
102{
103 *major = LIBGIT2_VER_MAJOR;
104 *minor = LIBGIT2_VER_MINOR;
105 *rev = LIBGIT2_VER_REVISION;
22a2d3d5
UG
106
107 return 0;
e85bbd52
ET
108}
109
ad5611d8
TR
110const char *git_libgit2_prerelease(void)
111{
112 return LIBGIT2_VER_PRERELEASE;
113}
114
8fd74c08 115int git_libgit2_features(void)
e85bbd52
ET
116{
117 return 0
118#ifdef GIT_THREADS
ebb3c506 119 | GIT_FEATURE_THREADS
e85bbd52 120#endif
a4de1ae3 121#ifdef GIT_HTTPS
ebb3c506 122 | GIT_FEATURE_HTTPS
061a0ad1 123#endif
e85bbd52 124#if defined(GIT_SSH)
ebb3c506 125 | GIT_FEATURE_SSH
0269833f
AR
126#endif
127#if defined(GIT_USE_NSEC)
128 | GIT_FEATURE_NSEC
e85bbd52
ET
129#endif
130 ;
131}
132
c25aa7cd 133static int config_level_to_sysdir(int *out, int config_level)
e85bbd52 134{
e85bbd52 135 switch (config_level) {
3eac1037 136 case GIT_CONFIG_LEVEL_SYSTEM:
c25aa7cd
PP
137 *out = GIT_SYSDIR_SYSTEM;
138 return 0;
3eac1037 139 case GIT_CONFIG_LEVEL_XDG:
c25aa7cd
PP
140 *out = GIT_SYSDIR_XDG;
141 return 0;
3eac1037 142 case GIT_CONFIG_LEVEL_GLOBAL:
c25aa7cd
PP
143 *out = GIT_SYSDIR_GLOBAL;
144 return 0;
3eac1037 145 case GIT_CONFIG_LEVEL_PROGRAMDATA:
c25aa7cd
PP
146 *out = GIT_SYSDIR_PROGRAMDATA;
147 return 0;
e85bbd52 148 default:
c25aa7cd 149 break;
e85bbd52
ET
150 }
151
c25aa7cd
PP
152 git_error_set(
153 GIT_ERROR_INVALID, "invalid config path selector %d", config_level);
154 return -1;
e85bbd52
ET
155}
156
8fd74c08 157const char *git_libgit2__user_agent(void)
de870533
CMN
158{
159 return git__user_agent;
160}
161
8fd74c08 162const char *git_libgit2__ssl_ciphers(void)
fa72d6da
DB
163{
164 return git__ssl_ciphers;
165}
166
e85bbd52
ET
167int git_libgit2_opts(int key, ...)
168{
169 int error = 0;
170 va_list ap;
171
172 va_start(ap, key);
173
174 switch (key) {
175 case GIT_OPT_SET_MWINDOW_SIZE:
176 git_mwindow__window_size = va_arg(ap, size_t);
177 break;
178
179 case GIT_OPT_GET_MWINDOW_SIZE:
180 *(va_arg(ap, size_t *)) = git_mwindow__window_size;
181 break;
182
183 case GIT_OPT_SET_MWINDOW_MAPPED_LIMIT:
184 git_mwindow__mapped_limit = va_arg(ap, size_t);
185 break;
186
187 case GIT_OPT_GET_MWINDOW_MAPPED_LIMIT:
188 *(va_arg(ap, size_t *)) = git_mwindow__mapped_limit;
189 break;
190
22a2d3d5
UG
191 case GIT_OPT_SET_MWINDOW_FILE_LIMIT:
192 git_mwindow__file_limit = va_arg(ap, size_t);
193 break;
194
195 case GIT_OPT_GET_MWINDOW_FILE_LIMIT:
196 *(va_arg(ap, size_t *)) = git_mwindow__file_limit;
197 break;
198
e85bbd52 199 case GIT_OPT_GET_SEARCH_PATH:
c25aa7cd
PP
200 {
201 int sysdir = va_arg(ap, int);
42dee8ec 202 git_buf *out = va_arg(ap, git_buf *);
e579e0f7
MB
203 git_str str = GIT_STR_INIT;
204 const git_str *tmp;
c25aa7cd 205 int level;
e85bbd52 206
e579e0f7
MB
207 if ((error = git_buf_tostr(&str, out)) < 0 ||
208 (error = config_level_to_sysdir(&level, sysdir)) < 0 ||
209 (error = git_sysdir_get(&tmp, level)) < 0 ||
210 (error = git_str_put(&str, tmp->ptr, tmp->size)) < 0)
42dee8ec
CMN
211 break;
212
e579e0f7 213 error = git_buf_fromstr(out, &str);
e85bbd52
ET
214 }
215 break;
216
217 case GIT_OPT_SET_SEARCH_PATH:
c25aa7cd
PP
218 {
219 int level;
220
221 if ((error = config_level_to_sysdir(&level, va_arg(ap, int))) >= 0)
222 error = git_sysdir_set(level, va_arg(ap, const char *));
223 }
e85bbd52
ET
224 break;
225
226 case GIT_OPT_SET_CACHE_OBJECT_LIMIT:
227 {
ac3d33df 228 git_object_t type = (git_object_t)va_arg(ap, int);
e85bbd52
ET
229 size_t size = va_arg(ap, size_t);
230 error = git_cache_set_max_object_size(type, size);
231 break;
232 }
233
234 case GIT_OPT_SET_CACHE_MAX_SIZE:
235 git_cache__max_storage = va_arg(ap, ssize_t);
236 break;
237
238 case GIT_OPT_ENABLE_CACHING:
239 git_cache__enabled = (va_arg(ap, int) != 0);
240 break;
241
242 case GIT_OPT_GET_CACHED_MEMORY:
243 *(va_arg(ap, ssize_t *)) = git_cache__current_storage.val;
244 *(va_arg(ap, ssize_t *)) = git_cache__max_storage;
245 break;
246
247 case GIT_OPT_GET_TEMPLATE_PATH:
248 {
42dee8ec 249 git_buf *out = va_arg(ap, git_buf *);
e579e0f7
MB
250 git_str str = GIT_STR_INIT;
251 const git_str *tmp;
42dee8ec 252
e579e0f7
MB
253 if ((error = git_buf_tostr(&str, out)) < 0 ||
254 (error = git_sysdir_get(&tmp, GIT_SYSDIR_TEMPLATE)) < 0 ||
255 (error = git_str_put(&str, tmp->ptr, tmp->size)) < 0)
42dee8ec 256 break;
e85bbd52 257
e579e0f7 258 error = git_buf_fromstr(out, &str);
e85bbd52
ET
259 }
260 break;
261
262 case GIT_OPT_SET_TEMPLATE_PATH:
83634d38 263 error = git_sysdir_set(GIT_SYSDIR_TEMPLATE, va_arg(ap, const char *));
e85bbd52 264 break;
737b445a
WS
265
266 case GIT_OPT_SET_SSL_CERT_LOCATIONS:
24e53d2f 267#ifdef GIT_OPENSSL
737b445a
WS
268 {
269 const char *file = va_arg(ap, const char *);
270 const char *path = va_arg(ap, const char *);
eae0bfdc 271 error = git_openssl__set_cert_location(file, path);
737b445a 272 }
ac3d33df
JK
273#elif defined(GIT_MBEDTLS)
274 {
275 const char *file = va_arg(ap, const char *);
276 const char *path = va_arg(ap, const char *);
c25aa7cd 277 error = git_mbedtls__set_cert_location(file, path);
ac3d33df 278 }
737b445a 279#else
ac3d33df 280 git_error_set(GIT_ERROR_SSL, "TLS backend doesn't support certificate locations");
737b445a
WS
281 error = -1;
282#endif
de870533
CMN
283 break;
284 case GIT_OPT_SET_USER_AGENT:
285 git__free(git__user_agent);
286 git__user_agent = git__strdup(va_arg(ap, const char *));
287 if (!git__user_agent) {
ac3d33df 288 git_error_set_oom();
de870533
CMN
289 error = -1;
290 }
291
737b445a 292 break;
22a19f5b
ET
293
294 case GIT_OPT_ENABLE_STRICT_OBJECT_CREATION:
295 git_object__strict_input_validation = (va_arg(ap, int) != 0);
296 break;
297
28d0ba0b 298 case GIT_OPT_ENABLE_STRICT_SYMBOLIC_REF_CREATION:
452bf57c
RI
299 git_reference__enable_symbolic_ref_target_validation = (va_arg(ap, int) != 0);
300 break;
301
fa72d6da 302 case GIT_OPT_SET_SSL_CIPHERS:
ac3d33df 303#if (GIT_OPENSSL || GIT_MBEDTLS)
fa72d6da
DB
304 {
305 git__free(git__ssl_ciphers);
306 git__ssl_ciphers = git__strdup(va_arg(ap, const char *));
307 if (!git__ssl_ciphers) {
ac3d33df 308 git_error_set_oom();
fa72d6da
DB
309 error = -1;
310 }
311 }
312#else
ac3d33df 313 git_error_set(GIT_ERROR_SSL, "TLS backend doesn't support custom ciphers");
fa72d6da
DB
314 error = -1;
315#endif
316 break;
317
f1dba144
AB
318 case GIT_OPT_GET_USER_AGENT:
319 {
320 git_buf *out = va_arg(ap, git_buf *);
e579e0f7
MB
321 git_str str = GIT_STR_INIT;
322
323 if ((error = git_buf_tostr(&str, out)) < 0 ||
324 (error = git_str_puts(&str, git__user_agent)) < 0)
c25aa7cd 325 break;
e579e0f7
MB
326
327 error = git_buf_fromstr(out, &str);
f1dba144
AB
328 }
329 break;
330
61acc9fa
GS
331 case GIT_OPT_ENABLE_OFS_DELTA:
332 git_smart__ofs_delta_enabled = (va_arg(ap, int) != 0);
333 break;
334
6c23704d
PS
335 case GIT_OPT_ENABLE_FSYNC_GITDIR:
336 git_repository__fsync_gitdir = (va_arg(ap, int) != 0);
6d3ad7e0
ET
337 break;
338
d5e6ca1e
SS
339 case GIT_OPT_GET_WINDOWS_SHAREMODE:
340#ifdef GIT_WIN32
341 *(va_arg(ap, unsigned long *)) = git_win32__createfile_sharemode;
342#endif
343 break;
344
345 case GIT_OPT_SET_WINDOWS_SHAREMODE:
346#ifdef GIT_WIN32
347 git_win32__createfile_sharemode = va_arg(ap, unsigned long);
348#endif
349 break;
350
35079f50
PS
351 case GIT_OPT_ENABLE_STRICT_HASH_VERIFICATION:
352 git_odb__strict_hash_verification = (va_arg(ap, int) != 0);
353 break;
354
ac3d33df
JK
355 case GIT_OPT_SET_ALLOCATOR:
356 error = git_allocator_setup(va_arg(ap, git_allocator *));
357 break;
358
359 case GIT_OPT_ENABLE_UNSAVED_INDEX_SAFETY:
360 git_index__enforce_unsaved_safety = (va_arg(ap, int) != 0);
361 break;
362
363 case GIT_OPT_SET_PACK_MAX_OBJECTS:
364 git_indexer__max_objects = va_arg(ap, size_t);
365 break;
366
367 case GIT_OPT_GET_PACK_MAX_OBJECTS:
368 *(va_arg(ap, size_t *)) = git_indexer__max_objects;
369 break;
370
22a2d3d5
UG
371 case GIT_OPT_DISABLE_PACK_KEEP_FILE_CHECKS:
372 git_disable_pack_keep_file_checks = (va_arg(ap, int) != 0);
373 break;
374
375 case GIT_OPT_ENABLE_HTTP_EXPECT_CONTINUE:
376 git_http__expect_continue = (va_arg(ap, int) != 0);
377 break;
378
c25aa7cd
PP
379 case GIT_OPT_SET_ODB_PACKED_PRIORITY:
380 git_odb__packed_priority = va_arg(ap, int);
381 break;
382
383 case GIT_OPT_SET_ODB_LOOSE_PRIORITY:
384 git_odb__loose_priority = va_arg(ap, int);
385 break;
386
387 case GIT_OPT_SET_EXTENSIONS:
388 {
389 const char **extensions = va_arg(ap, const char **);
390 size_t len = va_arg(ap, size_t);
391 error = git_repository__set_extensions(extensions, len);
392 }
393 break;
394
395 case GIT_OPT_GET_EXTENSIONS:
396 {
397 git_strarray *out = va_arg(ap, git_strarray *);
398 char **extensions;
399 size_t len;
400
401 if ((error = git_repository__extensions(&extensions, &len)) < 0)
402 break;
403
404 out->strings = extensions;
405 out->count = len;
406 }
407 break;
408
e579e0f7
MB
409 case GIT_OPT_GET_OWNER_VALIDATION:
410 *(va_arg(ap, int *)) = git_repository__validate_ownership;
411 break;
412
413 case GIT_OPT_SET_OWNER_VALIDATION:
414 git_repository__validate_ownership = (va_arg(ap, int) != 0);
415 break;
416
7bab2e8f 417 default:
ac3d33df 418 git_error_set(GIT_ERROR_INVALID, "invalid option key");
7bab2e8f 419 error = -1;
e85bbd52
ET
420 }
421
422 va_end(ap);
423
424 return error;
425}