2 * Copyright (C) the libgit2 contributors. All rights reserved.
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.
8 #include "config_backend.h"
11 #include "config_entries.h"
14 git_config_backend parent
;
15 git_mutex values_mutex
;
16 git_config_entries
*entries
;
17 git_config_backend
*source
;
18 } config_snapshot_backend
;
20 static int config_error_readonly(void)
22 git_error_set(GIT_ERROR_CONFIG
, "this backend is read-only");
26 static int config_snapshot_iterator(
27 git_config_iterator
**iter
,
28 struct git_config_backend
*backend
)
30 config_snapshot_backend
*b
= GIT_CONTAINER_OF(backend
, config_snapshot_backend
, parent
);
31 git_config_entries
*entries
= NULL
;
34 if ((error
= git_config_entries_dup(&entries
, b
->entries
)) < 0 ||
35 (error
= git_config_entries_iterator_new(iter
, entries
)) < 0)
39 /* Let iterator delete duplicated entries when it's done */
40 git_config_entries_free(entries
);
44 /* release the map containing the entry as an equivalent to freeing it */
45 static void config_snapshot_entry_free(git_config_entry
*entry
)
47 git_config_entries
*entries
= (git_config_entries
*) entry
->payload
;
48 git_config_entries_free(entries
);
51 static int config_snapshot_get(git_config_backend
*cfg
, const char *key
, git_config_entry
**out
)
53 config_snapshot_backend
*b
= GIT_CONTAINER_OF(cfg
, config_snapshot_backend
, parent
);
54 git_config_entries
*entries
= NULL
;
55 git_config_entry
*entry
;
58 if (git_mutex_lock(&b
->values_mutex
) < 0) {
59 git_error_set(GIT_ERROR_OS
, "failed to lock config backend");
64 git_config_entries_incref(entries
);
65 git_mutex_unlock(&b
->values_mutex
);
67 if ((error
= (git_config_entries_get(&entry
, entries
, key
))) < 0) {
68 git_config_entries_free(entries
);
72 entry
->free
= config_snapshot_entry_free
;
73 entry
->payload
= entries
;
79 static int config_snapshot_set(git_config_backend
*cfg
, const char *name
, const char *value
)
85 return config_error_readonly();
88 static int config_snapshot_set_multivar(
89 git_config_backend
*cfg
, const char *name
, const char *regexp
, const char *value
)
96 return config_error_readonly();
99 static int config_snapshot_delete_multivar(git_config_backend
*cfg
, const char *name
, const char *regexp
)
105 return config_error_readonly();
108 static int config_snapshot_delete(git_config_backend
*cfg
, const char *name
)
113 return config_error_readonly();
116 static int config_snapshot_lock(git_config_backend
*_cfg
)
120 return config_error_readonly();
123 static int config_snapshot_unlock(git_config_backend
*_cfg
, int success
)
128 return config_error_readonly();
131 static void config_snapshot_free(git_config_backend
*_backend
)
133 config_snapshot_backend
*backend
= GIT_CONTAINER_OF(_backend
, config_snapshot_backend
, parent
);
138 git_config_entries_free(backend
->entries
);
139 git_mutex_free(&backend
->values_mutex
);
143 static int config_snapshot_open(git_config_backend
*cfg
, git_config_level_t level
, const git_repository
*repo
)
145 config_snapshot_backend
*b
= GIT_CONTAINER_OF(cfg
, config_snapshot_backend
, parent
);
146 git_config_entries
*entries
= NULL
;
147 git_config_iterator
*it
= NULL
;
148 git_config_entry
*entry
;
151 /* We're just copying data, don't care about the level or repo*/
155 if ((error
= git_config_entries_new(&entries
)) < 0 ||
156 (error
= b
->source
->iterator(&it
, b
->source
)) < 0)
159 while ((error
= git_config_next(&entry
, it
)) == 0)
160 if ((error
= git_config_entries_dup_entry(entries
, entry
)) < 0)
164 if (error
!= GIT_ITEROVER
)
169 b
->entries
= entries
;
172 git_config_iterator_free(it
);
174 git_config_entries_free(entries
);
178 int git_config_backend_snapshot(git_config_backend
**out
, git_config_backend
*source
)
180 config_snapshot_backend
*backend
;
182 backend
= git__calloc(1, sizeof(config_snapshot_backend
));
183 GIT_ERROR_CHECK_ALLOC(backend
);
185 backend
->parent
.version
= GIT_CONFIG_BACKEND_VERSION
;
186 git_mutex_init(&backend
->values_mutex
);
188 backend
->source
= source
;
190 backend
->parent
.readonly
= 1;
191 backend
->parent
.version
= GIT_CONFIG_BACKEND_VERSION
;
192 backend
->parent
.open
= config_snapshot_open
;
193 backend
->parent
.get
= config_snapshot_get
;
194 backend
->parent
.set
= config_snapshot_set
;
195 backend
->parent
.set_multivar
= config_snapshot_set_multivar
;
196 backend
->parent
.snapshot
= git_config_backend_snapshot
;
197 backend
->parent
.del
= config_snapshot_delete
;
198 backend
->parent
.del_multivar
= config_snapshot_delete_multivar
;
199 backend
->parent
.iterator
= config_snapshot_iterator
;
200 backend
->parent
.lock
= config_snapshot_lock
;
201 backend
->parent
.unlock
= config_snapshot_unlock
;
202 backend
->parent
.free
= config_snapshot_free
;
204 *out
= &backend
->parent
;