]>
git.proxmox.com Git - libgit2.git/blob - src/config.c
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.
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.)
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.
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.
28 #include "hashtable.h"
30 #include "git2/config.h"
36 git_config_file
*file
;
40 void git_config_free(git_config
*cfg
)
43 git_config_file
*file
;
44 file_internal
*internal
;
46 for(i
= 0; i
< cfg
->files
.length
; ++i
){
47 internal
= git_vector_get(&cfg
->files
, i
);
48 file
= internal
->file
;
53 git_vector_free(&cfg
->files
);
57 static int config_backend_cmp(const void *a
, const void *b
)
59 const file_internal
*bk_a
= (const file_internal
*)(a
);
60 const file_internal
*bk_b
= (const file_internal
*)(b
);
62 return bk_b
->priority
- bk_a
->priority
;
65 int git_config_new(git_config
**out
)
69 cfg
= git__malloc(sizeof(git_config
));
73 memset(cfg
, 0x0, sizeof(git_config
));
75 if (git_vector_init(&cfg
->files
, 3, config_backend_cmp
) < 0) {
85 int git_config_add_file_ondisk(git_config
*cfg
, const char *path
, int priority
)
87 git_config_file
*file
= NULL
;
90 error
= git_config_file__ondisk(&file
, path
);
91 if (error
< GIT_SUCCESS
)
94 error
= git_config_add_file(cfg
, file
, priority
);
95 if (error
< GIT_SUCCESS
) {
97 * free manually; the file is not owned by the config
98 * instance yet and will not be freed on cleanup
107 int git_config_open_ondisk(git_config
**cfg
, const char *path
)
111 error
= git_config_new(cfg
);
112 if (error
< GIT_SUCCESS
)
115 error
= git_config_add_file_ondisk(*cfg
, path
, 1);
116 if (error
< GIT_SUCCESS
)
117 git_config_free(*cfg
);
122 int git_config_add_file(git_config
*cfg
, git_config_file
*file
, int priority
)
124 file_internal
*internal
;
129 if ((error
= file
->open(file
)) < GIT_SUCCESS
)
130 return git__rethrow(error
, "Failed to open config file");
132 internal
= git__malloc(sizeof(file_internal
));
133 if (internal
== NULL
)
136 internal
->file
= file
;
137 internal
->priority
= priority
;
139 if (git_vector_insert(&cfg
->files
, internal
) < 0) {
144 git_vector_sort(&cfg
->files
);
145 internal
->file
->cfg
= cfg
;
151 * Loop over all the variables
154 int git_config_foreach(git_config
*cfg
, int (*fn
)(const char *, const char *, void *), void *data
)
156 int ret
= GIT_SUCCESS
;
158 file_internal
*internal
;
159 git_config_file
*file
;
161 for(i
= 0; i
< cfg
->files
.length
&& ret
== 0; ++i
) {
162 internal
= git_vector_get(&cfg
->files
, i
);
163 file
= internal
->file
;
164 ret
= file
->foreach(file
, fn
, data
);
170 int git_config_del(git_config
*cfg
, const char *name
)
172 return git_config_set_string(cfg
, name
, NULL
);
179 int git_config_set_long(git_config
*cfg
, const char *name
, long int value
)
181 char str_value
[32]; /* All numbers should fit in here */
182 snprintf(str_value
, sizeof(str_value
), "%ld", value
);
183 return git_config_set_string(cfg
, name
, str_value
);
186 int git_config_set_int(git_config
*cfg
, const char *name
, int value
)
188 return git_config_set_long(cfg
, name
, value
);
191 int git_config_set_bool(git_config
*cfg
, const char *name
, int value
)
193 return git_config_set_string(cfg
, name
, value
? "true" : "false");
196 int git_config_set_string(git_config
*cfg
, const char *name
, const char *value
)
198 file_internal
*internal
;
199 git_config_file
*file
;
201 if (cfg
->files
.length
== 0)
202 return git__throw(GIT_EINVALIDARGS
, "Cannot set variable value; no files open in the `git_config` instance");
204 internal
= git_vector_get(&cfg
->files
, 0);
205 file
= internal
->file
;
207 return file
->set(file
, name
, value
);
214 int git_config_get_long(git_config
*cfg
, const char *name
, long int *out
)
216 const char *value
, *num_end
;
220 ret
= git_config_get_string(cfg
, name
, &value
);
221 if (ret
< GIT_SUCCESS
)
222 return git__rethrow(ret
, "Failed to get value for %s", name
);
224 ret
= git__strtol32(&num
, value
, &num_end
, 0);
225 if (ret
< GIT_SUCCESS
)
226 return git__rethrow(ret
, "Failed to get value for %s", name
);
241 num
*= 1024 * 1024 * 1024;
244 return git__throw(GIT_EINVALIDTYPE
, "Failed to get value for %s. Value is of invalid type", name
);
252 int git_config_get_int(git_config
*cfg
, const char *name
, int *out
)
257 ret
= git_config_get_long(cfg
, name
, &tmp
);
264 int git_config_get_bool(git_config
*cfg
, const char *name
, int *out
)
267 int error
= GIT_SUCCESS
;
269 error
= git_config_get_string(cfg
, name
, &value
);
270 if (error
< GIT_SUCCESS
)
271 return git__rethrow(error
, "Failed to get value for %s", name
);
273 /* A missing value means true */
279 if (!strcasecmp(value
, "true") ||
280 !strcasecmp(value
, "yes") ||
281 !strcasecmp(value
, "on")) {
285 if (!strcasecmp(value
, "false") ||
286 !strcasecmp(value
, "no") ||
287 !strcasecmp(value
, "off")) {
292 /* Try to parse it as an integer */
293 error
= git_config_get_int(cfg
, name
, out
);
294 if (error
== GIT_SUCCESS
)
297 if (error
< GIT_SUCCESS
)
298 return git__rethrow(error
, "Failed to get value for %s", name
);
302 int git_config_get_string(git_config
*cfg
, const char *name
, const char **out
)
304 file_internal
*internal
;
305 git_config_file
*file
;
306 int error
= GIT_ENOTFOUND
;
309 if (cfg
->files
.length
== 0)
310 return git__throw(GIT_EINVALIDARGS
, "Cannot get variable value; no files open in the `git_config` instance");
312 for (i
= 0; i
< cfg
->files
.length
; ++i
) {
313 internal
= git_vector_get(&cfg
->files
, i
);
314 file
= internal
->file
;
315 if ((error
= file
->get(file
, name
, out
)) == GIT_SUCCESS
)
319 return git__throw(error
, "Config value '%s' not found", name
);
322 int git_config_find_global(char *global_config_path
)
326 home
= getenv("HOME");
330 home
= getenv("USERPROFILE");
334 return git__throw(GIT_EOSERR
, "Failed to open global config file. Cannot locate the user's home directory");
336 git_path_join(global_config_path
, home
, GIT_CONFIG_FILENAME
);
338 if (git_futils_exists(global_config_path
) < GIT_SUCCESS
)
339 return git__throw(GIT_EOSERR
, "Failed to open global config file. The file does not exist");
344 int git_config_open_global(git_config
**out
)
347 char global_path
[GIT_PATH_MAX
];
349 if ((error
= git_config_find_global(global_path
)) < GIT_SUCCESS
)
352 return git_config_open_ondisk(out
, global_path
);