{"thread":{"id":"2534","subject":"[PATCH 1/3] Add function git_config_set()","startedAt":"2005-11-15T21:36:11Z","lastAt":"2005-11-15T21:36:11Z","messageCount":1,"participants":["Johannes Schindelin"],"isPatch":true,"patchVersion":1,"patchTotal":3},"messages":[{"id":"11934","messageId":"Pine.LNX.4.63.0511152233030.2152@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"2534","inReplyTo":null,"subject":"[PATCH 1/3] Add function git_config_set()","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2005-11-15T21:36:11Z","receivedAt":"2005-11-15T21:36:11Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"\nThis function does exactly what you think it does. Given a key and a value,\nit sets the key (in the form \"core.filemode\") to the value.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n\n---\n\n cache.h  |    1 \n config.c |  145 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n 2 files changed, 146 insertions(+), 0 deletions(-)\n\napplies-to: a54ecd1a81180a8d860a6554e6fc71dcab3327ef\nc38f654a4387ed503a8ea445824e49b44a796c61\ndiff --git a/cache.h b/cache.h\nindex 9a6bfb9..91070ae 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -384,6 +384,7 @@ extern int git_default_config(const char\n extern int git_config(config_fn_t fn);\n extern int git_config_int(const char *, const char *);\n extern int git_config_bool(const char *, const char *);\n+extern int git_config_set(const char *, const char *);\n \n #define MAX_GITNAME (1000)\n extern char git_default_email[MAX_GITNAME];\ndiff --git a/config.c b/config.c\nindex bd35138..1b39290 100644\n--- a/config.c\n+++ b/config.c\n@@ -247,3 +247,148 @@ int git_config(config_fn_t fn)\n \t}\n \treturn ret;\n }\n+\n+static struct {\n+\tint baselen;\n+\tconst char* key;\n+\tconst char* value;\n+\toff_t offset;\n+\tenum { START, SECTION_SEEN, SECTION_END_SEEN, KEY_SEEN } state;\n+} store;\n+\n+static int store_aux(const char* key, const char* value)\n+{\n+\tswitch (store.state) {\n+\t\tcase KEY_SEEN:\n+\t\t\tif (!strcmp(key, store.key))\n+\t\t\t\tstore.offset = ftell(config_file);\n+\t\t\tbreak;\n+\t\tcase SECTION_SEEN:\n+\t\t\tif (strncmp(key, store.key, store.baselen+1)) {\n+\t\t\t\tstore.offset = ftell(config_file);\n+\t\t\t\tstore.state = SECTION_END_SEEN;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\tcase SECTION_END_SEEN:\n+\t\tcase START:\n+\t\t\tif (!strcmp(key, store.key)) {\n+\t\t\t\tstore.offset = ftell(config_file);\n+\t\t\t\tstore.state = KEY_SEEN;\n+\t\t\t} else if(!strncmp(key, store.key, store.baselen))\n+\t\t\t\tstore.state = SECTION_SEEN;\n+\t}\n+\treturn 0;\n+}\n+\n+static void store_write_section(int fd)\n+{\n+\twrite(fd, \"[\", 1);\n+\twrite(fd, store.key, store.baselen);\n+\twrite(fd, \"]\\n\", 2);\n+}\n+\n+static void store_write_pair(int fd)\n+{\n+\tint i;\n+\n+\twrite(fd, \"\\t\", 1);\n+\twrite(fd, store.key+store.baselen+1,\n+\t\tstrlen(store.key+store.baselen+1));\n+\twrite(fd, \" = \", 3);\n+\tfor (i = 0; store.value[i]; i++)\n+\t\tswitch (store.value[i]) {\n+\t\tcase '\\n': write(fd, \"\\\\n\", 2); break;\n+\t\tcase '\\t': write(fd, \"\\\\t\", 2); break;\n+\t\tcase '\"': case '\\\\': write(fd, \"\\\\\", 1);\n+\t\tdefault: write(fd, store.value+i, 1);\n+\t}\n+\twrite(fd, \"\\n\", 1);\n+}\n+\n+int git_config_set(const char* key, const char* value)\n+{\n+\tint i;\n+\tstruct stat st;\n+\tint fd;\n+\tchar* config_file = strdup(git_path(\"config\"));\n+\tchar* lock_file = strdup(git_path(\"config.lock\"));\n+\n+\tfor (store.baselen = 0;\n+\t\t\tkey[store.baselen] != '.' && key[store.baselen];\n+\t\t\tstore.baselen++);\n+\tif (!key[store.baselen]) {\n+\t\tfprintf(stderr, \"key does not contain a section: %s\\n\", key);\n+\t\treturn 2;\n+\t}\n+\n+\tfor (i = 0; key[i]; i++)\n+\t\tif (i != store.baselen && !isalpha(key[i])) {\n+\t\t\tfprintf(stderr, \"invalid key: %s\\n\", key);\n+\t\t\treturn 1;\n+\t\t}\n+\n+\tstore.key = key;\n+\tstore.value = value;\n+\n+\tfd = open(lock_file, O_WRONLY | O_CREAT | O_EXCL, 0666);\n+\tif (fd < 0) {\n+\t\tfprintf(stderr, \"could not lock config file\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\tif (stat(config_file, &st)) {\n+\t\t/* write new file */\n+\t\tstatic const char contents[] =\n+\t\t\t\"#\\n\"\n+\t\t\t\"# This is the config file\\n\"\n+\t\t\t\"#\\n\"\n+\t\t\t\"\\n\";\n+\n+\t\twrite(fd, contents, sizeof(contents)-1);\n+\t\tstore_write_section(fd);\n+\t\tstore_write_pair(fd);\n+\t} else{\n+\t\tint in_fd;\n+\t\tchar* contents;\n+\t\tint offset;\n+\n+\t\tstore.offset = 0;\n+\t\tstore.state = START;\n+\n+\t\tif (git_config(store_aux)) {\n+\t\t\tfprintf(stderr, \"invalid config file\\n\");\n+\t\t\treturn 3;\n+\t\t}\n+\n+\t\tin_fd = open(config_file, O_RDONLY, 0666);\n+\t\tcontents = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, in_fd, 0);\n+\t\tclose(in_fd);\n+\n+\t\tif (store.offset == 0)\n+\t\t\toffset = st.st_size;\n+\t\telse {\n+\t\t\tfor (offset = store.offset-2; offset > 0 \n+\t\t\t\t\t&& contents[offset] != '\\n'; offset--);\n+\t\t\toffset++;\n+\t\t}\n+\t\twrite(fd, contents, offset);\n+\t\tif (store.state == START)\n+\t\t\tstore_write_section(fd);\n+\t\tstore_write_pair(fd);\n+\t\tif (store.offset > offset)\n+\t\t\twrite(fd, contents + store.offset,\n+\t\t\t\tst.st_size - store.offset);\n+\t\t\n+\t\tunlink(config_file);\n+\t}\n+\n+\tclose(fd);\n+\n+\tif (rename(lock_file, config_file) < 0) {\n+\t\tfprintf(stderr, \"Could not rename the lock file?\\n\");\n+\t\treturn 4;\n+\t}\n+\n+\treturn 0;\n+}\n+\n---\n0.99.9.GIT\n"}]}