diff options
Diffstat (limited to 'src/blogc-git-receiver')
-rw-r--r-- | src/blogc-git-receiver/main.c | 44 | ||||
-rw-r--r-- | src/blogc-git-receiver/post-receive.c | 91 | ||||
-rw-r--r-- | src/blogc-git-receiver/post-receive.h | 14 | ||||
-rw-r--r-- | src/blogc-git-receiver/pre-receive-parser.c | 84 | ||||
-rw-r--r-- | src/blogc-git-receiver/pre-receive-parser.h | 17 | ||||
-rw-r--r-- | src/blogc-git-receiver/pre-receive.c | 318 | ||||
-rw-r--r-- | src/blogc-git-receiver/pre-receive.h | 14 | ||||
-rw-r--r-- | src/blogc-git-receiver/settings.c | 110 | ||||
-rw-r--r-- | src/blogc-git-receiver/settings.h | 19 | ||||
-rw-r--r-- | src/blogc-git-receiver/shell-command-parser.c | 101 | ||||
-rw-r--r-- | src/blogc-git-receiver/shell-command-parser.h | 14 | ||||
-rw-r--r-- | src/blogc-git-receiver/shell.c | 190 | ||||
-rw-r--r-- | src/blogc-git-receiver/shell.h | 15 |
13 files changed, 0 insertions, 1031 deletions
diff --git a/src/blogc-git-receiver/main.c b/src/blogc-git-receiver/main.c deleted file mode 100644 index 13218dd..0000000 --- a/src/blogc-git-receiver/main.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * blogc: A blog compiler. - * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br> - * - * This program can be distributed under the terms of the BSD License. - * See the file LICENSE. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <libgen.h> -#include "shell.h" -#include "pre-receive.h" -#include "post-receive.h" - - -int -main(int argc, char *argv[]) -{ - if (argc > 0) { - if (0 == strcmp(basename(argv[0]), "pre-receive")) - return bgr_pre_receive_hook(argc, argv); - if (0 == strcmp(basename(argv[0]), "post-receive")) - return bgr_post_receive_hook(argc, argv); - } - - if (argc == 3 && (0 == strcmp(argv[1], "-c"))) { - return bgr_shell(argc, argv); - } - - // this is a hack to make blogc-git-receiver work out-of-the-box as a - // `command=` in authorized_keys file. it will only work if the command - // path is absolute. - char *ssh_orig = getenv("SSH_ORIGINAL_COMMAND"); - if (argc == 1 && ssh_orig != NULL && argv[0][0] == '/') { - setenv("SHELL", argv[0], 1); - char* _argv[] = {argv[0], "-c", ssh_orig}; - return bgr_shell(3, _argv); - } - - fprintf(stderr, "error: this is a special shell, go away!\n"); - return 1; -} diff --git a/src/blogc-git-receiver/post-receive.c b/src/blogc-git-receiver/post-receive.c deleted file mode 100644 index 17a8aa7..0000000 --- a/src/blogc-git-receiver/post-receive.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * blogc: A blog compiler. - * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br> - * - * This program can be distributed under the terms of the BSD License. - * See the file LICENSE. - */ - -#include <errno.h> -#include <string.h> -#include <stdio.h> -#include <libgen.h> -#include <unistd.h> -#include <stdlib.h> -#include "../common/utils.h" -#include "../common/config-parser.h" -#include "settings.h" -#include "post-receive.h" - - -int -bgr_post_receive_hook(int argc, char *argv[]) -{ - int rv = 0; - char *mirror = NULL; - - char *hooks_dir = dirname(argv[0]); // this was validated by main() - char *real_hooks_dir = realpath(hooks_dir, NULL); - if (real_hooks_dir == NULL) { - fprintf(stderr, "error: failed to guess repository root: %s\n", - strerror(errno)); - return 1; - } - - char *repo_path = bc_strdup(dirname(real_hooks_dir)); - free(real_hooks_dir); - if (0 != chdir(repo_path)) { - fprintf(stderr, "error: failed to change to repository root\n"); - rv = 1; - goto cleanup; - } - - // local repository settings should take precedence, so if the repo have - // the 'mirror' remote, just push to it. - // this will be removed at some point, but will be kept for compatibility - // with old setups. - if ((0 == system("git config --local remote.mirror.pushurl > /dev/null")) || - (0 == system("git config --local remote.mirror.url > /dev/null"))) - { - mirror = bc_strdup("mirror"); - goto push; - } - - bc_config_t *config = bgr_settings_parse(); - if (config == NULL) { - fprintf(stderr, "warning: repository mirroring disabled\n"); - goto cleanup; - } - - char *section = bgr_settings_get_section(config, repo_path); - if (section == NULL) { - fprintf(stderr, "warning: repository mirroring disabled\n"); - bc_config_free(config); - goto cleanup; - } - - mirror = bc_strdup(bc_config_get(config, section, "mirror")); - free(section); - bc_config_free(config); - - if (mirror == NULL) { - fprintf(stderr, "warning: repository mirroring disabled\n"); - goto cleanup; - } - -push: - - { - char *git_cmd = bc_strdup_printf("git push --mirror %s", mirror); - if (0 != system(git_cmd)) - fprintf(stderr, "warning: failed push to git mirror\n"); - free(git_cmd); - } - - free(mirror); - -cleanup: - free(repo_path); - - return rv; -} diff --git a/src/blogc-git-receiver/post-receive.h b/src/blogc-git-receiver/post-receive.h deleted file mode 100644 index fc56dc3..0000000 --- a/src/blogc-git-receiver/post-receive.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * blogc: A blog compiler. - * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br> - * - * This program can be distributed under the terms of the BSD License. - * See the file LICENSE. - */ - -#ifndef _POST_RECEIVE_H -#define _POST_RECEIVE_H - -int bgr_post_receive_hook(int argc, char *argv[]); - -#endif /* _POST_RECEIVE_H */ diff --git a/src/blogc-git-receiver/pre-receive-parser.c b/src/blogc-git-receiver/pre-receive-parser.c deleted file mode 100644 index 61a533c..0000000 --- a/src/blogc-git-receiver/pre-receive-parser.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * blogc: A blog compiler. - * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br> - * - * This program can be distributed under the terms of the BSD License. - * See the file LICENSE. - */ - -#include <stddef.h> -#include <stdlib.h> -#include <string.h> -#include "../common/utils.h" -#include "pre-receive-parser.h" - -typedef enum { - START_OLD = 1, - OLD, - START_NEW, - NEW, - START_REF, - REF -} input_state_t; - - -bc_trie_t* -bgr_pre_receive_parse(const char *input, size_t input_len) -{ - input_state_t state = START_OLD; - size_t start = 0; - size_t start_new = 0; - - bc_trie_t* rv = bc_trie_new(free); - - for (size_t current = 0; current < input_len; current++) { - - char c = input[current]; - - switch (state) { - case START_OLD: - start = current; - state = OLD; - break; - case OLD: - if (c != ' ') - break; - // no need to store old - state = START_NEW; - break; - case START_NEW: - start = current; - state = NEW; - break; - case NEW: - if (c != ' ') - break; - state = START_REF; - start_new = start; - break; - case START_REF: - start = current; - state = REF; - break; - case REF: - if (c != '\n') - break; - state = START_OLD; - if ((current - start > 11) && - (0 == strncmp("refs/heads/", input + start, 11))) - { - char *key = bc_strndup(input + start + 11, current - start - 11); - bc_trie_insert(rv, key, bc_strndup(input + start_new, start - 1 - start_new)); - free(key); - } - break; - } - } - - if (bc_trie_size(rv) == 0) { - bc_trie_free(rv); - return NULL; - } - - return rv; -} diff --git a/src/blogc-git-receiver/pre-receive-parser.h b/src/blogc-git-receiver/pre-receive-parser.h deleted file mode 100644 index 45a9da8..0000000 --- a/src/blogc-git-receiver/pre-receive-parser.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * blogc: A blog compiler. - * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br> - * - * This program can be distributed under the terms of the BSD License. - * See the file LICENSE. - */ - -#ifndef _PRE_RECEIVE_PARSER_H -#define _PRE_RECEIVE_PARSER_H - -#include <stddef.h> -#include "../common/utils.h" - -bc_trie_t* bgr_pre_receive_parse(const char *input, size_t input_len); - -#endif /* _PRE_RECEIVE_PARSER_H */ diff --git a/src/blogc-git-receiver/pre-receive.c b/src/blogc-git-receiver/pre-receive.c deleted file mode 100644 index 12d29cf..0000000 --- a/src/blogc-git-receiver/pre-receive.c +++ /dev/null @@ -1,318 +0,0 @@ -/* - * blogc: A blog compiler. - * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br> - * - * This program can be distributed under the terms of the BSD License. - * See the file LICENSE. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/stat.h> -#include <unistd.h> -#include <errno.h> -#include <dirent.h> -#include <time.h> -#include <libgen.h> -#include "../common/compat.h" -#include "../common/utils.h" -#include "../common/stdin.h" -#include "settings.h" -#include "pre-receive-parser.h" -#include "pre-receive.h" - - -static size_t -cpu_count(void) -{ -#ifdef _SC_NPROCESSORS_ONLN - long num = sysconf(_SC_NPROCESSORS_ONLN); - if (num >= 1) - return (size_t) num; -#endif - return 1; -} - - -static void -rmdir_recursive(const char *dir) -{ - if (dir == NULL) - return; - struct stat buf; - if (0 != stat(dir, &buf)) { - return; - } - if (!S_ISDIR(buf.st_mode)) { - fprintf(stderr, "error: trying to remove invalid directory: %s\n", dir); - exit(2); - } - DIR *d = opendir(dir); - if (d == NULL) { - fprintf(stderr, "error: failed to open directory: %s\n", - strerror(errno)); - exit(2); - } - struct dirent *e; - while (NULL != (e = readdir(d))) { - if ((0 == strcmp(e->d_name, ".")) || (0 == strcmp(e->d_name, ".."))) - continue; - char *f = bc_strdup_printf("%s/%s", dir, e->d_name); - if (0 != stat(f, &buf)) { - fprintf(stderr, "error: failed to stat directory entry (%s): %s\n", - e->d_name, strerror(errno)); - free(f); - exit(2); - } - if (S_ISDIR(buf.st_mode)) { - rmdir_recursive(f); - } - else if (0 != unlink(f)) { - fprintf(stderr, "error: failed to remove file (%s): %s\n", f, - strerror(errno)); - free(f); - exit(2); - } - free(f); - } - if (0 != closedir(d)) { - fprintf(stderr, "error: failed to close directory: %s\n", - strerror(errno)); - exit(2); - } - if (0 != rmdir(dir)) { - fprintf(stderr, "error: failed to remove directory: %s\n", - strerror(errno)); - exit(2); - } -} - - -int -bgr_pre_receive_hook(int argc, char *argv[]) -{ - int rv = 0; - char *ref = NULL; - char *output_dir = NULL; - char *tmpdir = NULL; - char *sym = NULL; - - char *hooks_dir = dirname(argv[0]); // this was validated by main() - char *real_hooks_dir = realpath(hooks_dir, NULL); - if (real_hooks_dir == NULL) { - fprintf(stderr, "error: failed to guess repository root: %s\n", - strerror(errno)); - return 1; - } - - char *repo_dir = bc_strdup(dirname(real_hooks_dir)); - free(real_hooks_dir); - if (0 != chdir(repo_dir)) { - fprintf(stderr, "error: failed to change to repository root\n"); - rv = 1; - goto cleanup; - } - - bc_config_t *config = bgr_settings_parse(); - if (config == NULL) { - goto default_sym; - } - - char *section = bgr_settings_get_section(config, repo_dir); - if (section == NULL) { - bc_config_free(config); - goto default_sym; - } - - const char *sym_tmp = bc_config_get(config, section, "symlink"); - if (sym_tmp == NULL) { - free(section); - bc_config_free(config); - goto default_sym; - } - - sym = bc_str_starts_with(sym_tmp, "/") ? bc_strdup(sym_tmp) : - bc_strdup_printf("%s/%s", repo_dir, sym_tmp); - free(section); - bc_config_free(config); - -default_sym: - - if (sym == NULL) { - sym = bc_strdup_printf("%s/htdocs", repo_dir); - } - - if (NULL == getenv("GIT_DIR")) { - if (0 != access(sym, R_OK)) { - fprintf(stderr, "error: no previous build found. nothing to " - "rebuild.\n"); - rv = 1; - goto cleanup; - } - char *build_dir = realpath(sym, NULL); - if (build_dir == NULL) { - fprintf(stderr, "error: failed to get the hash of last built " - "commit: %s\n", strerror(errno)); - rv = 1; - goto cleanup; - } - char **pieces = bc_str_split(basename(build_dir), '-', 2); - free(build_dir); - if (bc_strv_length(pieces) != 2) { - fprintf(stderr, "error: failed to parse the hash of last built " - "commit.\n"); - bc_strv_free(pieces); - rv = 1; - goto cleanup; - } - ref = bc_strdup(pieces[0]); - bc_strv_free(pieces); - } - else { - size_t input_len; - char *input = bc_stdin_read(&input_len); - bc_trie_t *branches = bgr_pre_receive_parse(input, input_len); - - // try 'master' by default to avoid breaking existing setups - ref = bc_strdup(bc_trie_lookup(branches, "master")); - if (ref == NULL) { - // try 'main' - ref = bc_strdup(bc_trie_lookup(branches, "main")); - } - - bc_trie_free(branches); - free(input); - } - - if (ref == NULL) { - fprintf(stderr, "warning: no suitable branch found. " - "nothing to deploy.\n"); - goto cleanup; - } - - char dir[] = "/tmp/blogc_XXXXXX"; - if (NULL == mkdtemp(dir)) { - rv = 1; - goto cleanup; - } - tmpdir = dir; - - char *git_archive_cmd = bc_strdup_printf( - "git archive \"%s\" | tar -x -C \"%s\" -f -", ref, tmpdir); - if (0 != system(git_archive_cmd)) { - fprintf(stderr, "error: failed to extract git content to temporary " - "directory: %s\n", tmpdir); - rv = 1; - free(git_archive_cmd); - goto cleanup; - } - free(git_archive_cmd); - - if (0 != chdir(tmpdir)) { - fprintf(stderr, "error: failed to chdir (%s): %s\n", tmpdir, - strerror(errno)); - rv = 1; - goto cleanup; - } - - char *buildsd = bgr_settings_get_builds_dir(); - if (buildsd == NULL) { - fprintf(stderr, "error: failed to find builds directory path\n"); - rv = 1; - goto cleanup; - } - - unsigned long epoch = time(NULL); - output_dir = bc_strdup_printf("%s/%s-%lu", buildsd, ref, epoch); - free(buildsd); - - if (0 == access(output_dir, F_OK)) { - char *tmp = output_dir; - output_dir = bc_strdup_printf("%s-", tmp); - free(tmp); - } - - // detect if we will run blogc-make, make or nothing, and generate the - // command. - char *build_cmd = NULL; - if (0 == access("blogcfile", F_OK)) { - int status_bmake = system("blogc-make -v 2> /dev/null > /dev/null"); - if (127 == bc_compat_status_code(status_bmake)) { - fprintf(stderr, "error: failed to find blogc-make binary\n"); - rv = 1; - goto cleanup; - } - build_cmd = bc_strdup_printf("OUTPUT_DIR=\"%s\" blogc-make -V all", - output_dir); - } - else if ((0 == access("Makefile", F_OK)) || (0 == access("GNUMakefile", F_OK))) { - const char *make_impl = NULL; - - int status_gmake = system("gmake -f /dev/null 2> /dev/null > /dev/null"); - if (127 != bc_compat_status_code(status_gmake)) { - make_impl = "gmake"; - } - else { - int status_make = system("make -f /dev/null 2> /dev/null > /dev/null"); - if (127 != bc_compat_status_code(status_make)) { - make_impl = "make"; - } - } - - if (make_impl == NULL) { - fprintf(stderr, "error: no 'make' implementation found\n"); - rv = 1; - goto cleanup; - } - build_cmd = bc_strdup_printf( - "%s -j%d OUTPUT_DIR=\"%s\" BLOGC_GIT_RECEIVER=1", make_impl, - cpu_count(), output_dir); - } - else { - fprintf(stderr, "warning: no blogcfile or Makefile found. skipping ...\n"); - goto cleanup; - } - - fprintf(stdout, "running command: %s\n\n", build_cmd); - fflush(stdout); - if (0 != system(build_cmd)) { - fprintf(stderr, "error: failed to build website ...\n"); - rmdir_recursive(output_dir); - free(build_cmd); - rv = 1; - goto cleanup; - } - free(build_cmd); - - char *htdocs_sym = realpath(sym, NULL); - if ((htdocs_sym != NULL) && (0 != unlink(sym))) { - fprintf(stderr, "error: failed to remove symlink (%s): %s\n", sym, - strerror(errno)); - rmdir_recursive(output_dir); - rv = 1; - goto cleanup2; - } - - if (0 != symlink(output_dir, sym)) { - fprintf(stderr, "error: failed to create symlink (%s): %s\n", sym, - strerror(errno)); - rmdir_recursive(output_dir); - rv = 1; - goto cleanup2; - } - - if (htdocs_sym != NULL) - rmdir_recursive(htdocs_sym); - -cleanup2: - free(htdocs_sym); - -cleanup: - free(sym); - free(ref); - free(output_dir); - rmdir_recursive(tmpdir); - free(repo_dir); - return rv; -} diff --git a/src/blogc-git-receiver/pre-receive.h b/src/blogc-git-receiver/pre-receive.h deleted file mode 100644 index ab19c47..0000000 --- a/src/blogc-git-receiver/pre-receive.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * blogc: A blog compiler. - * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br> - * - * This program can be distributed under the terms of the BSD License. - * See the file LICENSE. - */ - -#ifndef _PRE_RECEIVE_H -#define _PRE_RECEIVE_H - -int bgr_pre_receive_hook(int argc, char *argv[]); - -#endif /* _PRE_RECEIVE_H */ diff --git a/src/blogc-git-receiver/settings.c b/src/blogc-git-receiver/settings.c deleted file mode 100644 index db29b18..0000000 --- a/src/blogc-git-receiver/settings.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * blogc: A blog compiler. - * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br> - * - * This program can be distributed under the terms of the BSD License. - * See the file LICENSE. - */ - -#include <stdio.h> -#include <libgen.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <stdbool.h> -#include "../common/utils.h" -#include "../common/config-parser.h" -#include "../common/error.h" -#include "../common/file.h" -#include "settings.h" - - -const char* -bgr_settings_get_base_dir(void) -{ - char *rv = getenv("BLOGC_GIT_RECEIVER_BASE_DIR"); - if (rv != NULL) { - return rv; - } - return getenv("HOME"); -} - - -char* -bgr_settings_get_builds_dir(void) -{ - char *rv = getenv("BLOGC_GIT_RECEIVER_BUILDS_DIR"); - if (rv != NULL) { - return bc_strdup(rv); - } - return bc_strdup_printf("%s/builds", bgr_settings_get_base_dir()); -} - - -char* -bgr_settings_get_section(bc_config_t *config, const char *repo_path) -{ - const char *bd = bgr_settings_get_base_dir(); - if (bd == NULL) { - return NULL; - } - char *rv = NULL; - char** sections = bc_config_list_sections(config); - for (size_t i = 0; sections[i] != NULL; i++) { - if (bc_str_starts_with(sections[i], "repo:")) { - char *tmp_repo = bc_strdup_printf("%s/repos/%s", bd, sections[i] + 5); - char *real_tmp_repo = realpath(tmp_repo, NULL); // maybe not needed - free(tmp_repo); - if (real_tmp_repo == NULL) - continue; - if (0 == strcmp(real_tmp_repo, repo_path)) { - rv = bc_strdup(sections[i]); - free(real_tmp_repo); - break; - } - free(real_tmp_repo); - } - } - bc_strv_free(sections); - return rv; -} - - -bc_config_t* -bgr_settings_parse(void) -{ - const char *bd = bgr_settings_get_base_dir(); - if (bd == NULL) { - return NULL; - } - char *config_file = bc_strdup_printf("%s/blogc-git-receiver.ini", bd); - if ((0 != access(config_file, F_OK))) { - free(config_file); - return NULL; - } - - size_t len; - bc_error_t *err = NULL; - char* config_content = bc_file_get_contents(config_file, true, &len, &err); - if (err != NULL) { - fprintf(stderr, "warning: failed to read configuration file (%s): %s\n", - config_file, err->msg); - bc_error_free(err); - free(config_file); - free(config_content); - return NULL; - } - - bc_config_t *config = bc_config_parse(config_content, len, NULL, &err); - free(config_content); - if (err != NULL) { - fprintf(stderr, "warning: failed to parse configuration file (%s): %s\n", - config_file, err->msg); - bc_error_free(err); - free(config_file); - return NULL; - } - free(config_file); - - return config; -} diff --git a/src/blogc-git-receiver/settings.h b/src/blogc-git-receiver/settings.h deleted file mode 100644 index 04c1a2b..0000000 --- a/src/blogc-git-receiver/settings.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * blogc: A blog compiler. - * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br> - * - * This program can be distributed under the terms of the BSD License. - * See the file LICENSE. - */ - -#ifndef _SETTINGS_H -#define _SETTINGS_H - -#include "../common/config-parser.h" - -const char* bgr_settings_get_base_dir(void); -char* bgr_settings_get_builds_dir(void); -char* bgr_settings_get_section(bc_config_t *config, const char *repo_path); -bc_config_t* bgr_settings_parse(void); - -#endif /* _SETTINGS_H */ diff --git a/src/blogc-git-receiver/shell-command-parser.c b/src/blogc-git-receiver/shell-command-parser.c deleted file mode 100644 index 0091e0b..0000000 --- a/src/blogc-git-receiver/shell-command-parser.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * blogc: A blog compiler. - * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br> - * - * This program can be distributed under the terms of the BSD License. - * See the file LICENSE. - */ - -#include <stdbool.h> -#include <stdlib.h> -#include <string.h> -#include "../common/utils.h" -#include "shell-command-parser.h" - -typedef enum { - START_COMMAND = 1, - START_REPO, - START_REPO2, - REPO, - START_ESCAPED, -} command_state_t; - - -char* -bgr_shell_command_parse(const char *command) -{ - command_state_t state = START_COMMAND; - size_t start = 0; - size_t command_len = strlen(command); - - bc_string_t *rv = bc_string_new(); - - for (size_t current = 0; current < command_len; current++) { - - char c = command[current]; - - switch (state) { - case START_COMMAND: - if (c == ' ') { - if (((current == 16) && - (0 == strncmp("git-receive-pack", command, 16))) || - ((current == 15) && - (0 == strncmp("git-upload-pack", command, 15))) || - ((current == 18) && - (0 == strncmp("git-upload-archive", command, 18)))) - { - state = START_REPO; - break; - } - goto error; - } - break; - - case START_REPO: - if (c == '\'') { // never saw git using double-quotes - state = START_REPO2; - break; - } - if (c == '\\') { // escaped ! or ' - state = START_ESCAPED; - break; - } - goto error; - - case START_REPO2: - if (c == '\'') { - state = START_REPO; - break; - } - start = current; - if (rv->len == 0 && c == '/') { // no absolute urls - start = current + 1; - } - state = REPO; - break; - - case START_ESCAPED: - if (c == '!' || c == '\'') { - bc_string_append_c(rv, c); - state = START_REPO; - break; - } - goto error; - - case REPO: - if (c == '\'') { - bc_string_append_len(rv, command + start, current - start); - state = START_REPO; - break; - } - break; - } - } - - if (rv->len > 0) - return bc_string_free(rv, false); - -error: - bc_string_free(rv, true); - return NULL; -} diff --git a/src/blogc-git-receiver/shell-command-parser.h b/src/blogc-git-receiver/shell-command-parser.h deleted file mode 100644 index 818d098..0000000 --- a/src/blogc-git-receiver/shell-command-parser.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * blogc: A blog compiler. - * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br> - * - * This program can be distributed under the terms of the BSD License. - * See the file LICENSE. - */ - -#ifndef _SHELL_COMMAND_PARSER_H -#define _SHELL_COMMAND_PARSER_H - -char* bgr_shell_command_parse(const char *command); - -#endif /* _SHELL_COMMAND_PARSER_H */ diff --git a/src/blogc-git-receiver/shell.c b/src/blogc-git-receiver/shell.c deleted file mode 100644 index a4c8a2d..0000000 --- a/src/blogc-git-receiver/shell.c +++ /dev/null @@ -1,190 +0,0 @@ -/* - * blogc: A blog compiler. - * Copyright (C) 2014-2020 Rafael G. Martins <rafael@rafaelmartins.eng.br> - * - * This program can be distributed under the terms of the BSD License. - * See the file LICENSE. - */ - -#include <stddef.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/stat.h> -#include <unistd.h> -#include <errno.h> -#include "../common/utils.h" -#include "settings.h" -#include "shell-command-parser.h" -#include "shell.h" - - -static bool -lexists(const char *pathname) -{ - struct stat b; - int tmp_errno = errno; - bool rv = lstat(pathname, &b) == 0; - errno = tmp_errno; - return rv; -} - - -int -bgr_shell(int argc, char *argv[]) -{ - int rv = 0; - - char *repo = NULL; - char *quoted_repo = NULL; - - // get shell path - char *self = getenv("SHELL"); - if (self == NULL) { - fprintf(stderr, "error: failed to find blogc-git-receiver path\n"); - rv = 1; - goto cleanup; - } - - // get base dir path - const char *bd = bgr_settings_get_base_dir(); - if (bd == NULL) { - fprintf(stderr, "error: failed to find base directory path\n"); - rv = 1; - goto cleanup; - } - - // validate command and extract git repository - char *tmp_repo = bgr_shell_command_parse(argv[2]); - if (tmp_repo == NULL) { - fprintf(stderr, "error: invalid git-shell command: %s\n", argv[2]); - rv = 1; - goto cleanup; - } - - repo = bc_strdup_printf("%s/repos/%s", bd, tmp_repo); - quoted_repo = bc_shell_quote(repo); - free(tmp_repo); - - if (0 == strncmp(argv[2], "git-upload-", 11)) // no need to check len here - goto git_exec; - - if (0 != access(repo, F_OK)) { - char *git_init_cmd = bc_strdup_printf( - "git init --bare %s > /dev/null", quoted_repo); - if (0 != system(git_init_cmd)) { - fprintf(stderr, "error: failed to create git repository: %s\n", - repo); - rv = 1; - free(git_init_cmd); - goto cleanup; - } - free(git_init_cmd); - } - - if (0 != chdir(repo)) { - fprintf(stderr, "error: failed to chdir (%s): %s\n", repo, - strerror(errno)); - rv = 1; - goto cleanup; - } - - if (0 != access("hooks", F_OK)) { - // openwrt git package won't install git templates, then the git - // repositories created with it won't have the hooks/ directory. - if (0 != mkdir("hooks", 0777)) { // mkdir honors umask for us. - fprintf(stderr, "error: failed to create directory (%s/hooks): " - "%s\n", repo, strerror(errno)); - rv = 1; - goto cleanup; - } - } - - if (0 != chdir("hooks")) { - fprintf(stderr, "error: failed to chdir (%s/hooks): %s\n", repo, - strerror(errno)); - rv = 1; - goto cleanup; - } - - if (lexists("pre-receive")) { - if (0 != unlink("pre-receive")) { - fprintf(stderr, "error: failed to remove old symlink " - "(%s/hooks/pre-receive): %s\n", repo, strerror(errno)); - rv = 1; - goto cleanup; - } - } - - if (0 != symlink(self, "pre-receive")) { - fprintf(stderr, "error: failed to create symlink " - "(%s/hooks/pre-receive): %s\n", repo, strerror(errno)); - rv = 1; - goto cleanup; - } - - if (lexists("post-receive")) { - if (0 != unlink("post-receive")) { - fprintf(stderr, "error: failed to remove old symlink " - "(%s/hooks/post-receive): %s\n", repo, strerror(errno)); - rv = 1; - goto cleanup; - } - } - - if (0 != symlink(self, "post-receive")) { - fprintf(stderr, "error: failed to create symlink " - "(%s/hooks/post-receive): %s\n", repo, strerror(errno)); - rv = 1; - goto cleanup; - } - -git_exec: - - if (0 != chdir(bd)) { - fprintf(stderr, "error: failed to chdir (%s): %s\n", bd, strerror(errno)); - rv = 1; - goto cleanup; - } - - // static allocation instead of bc_strdup_printf to avoid leaks - char buffer[4096]; - char *command = bc_strdup(argv[2]); - char *p; - for (p = command; *p != ' ' && *p != '\0'; p++); - if (*p == ' ') - *p = '\0'; - - if (sizeof(buffer) < (strlen(command) + strlen(quoted_repo) + 2)) { - fprintf(stderr, "error: git-shell command is too big\n"); - rv = 1; - goto cleanup; - } - - if (0 > snprintf(buffer, sizeof(buffer), "%s %s", command, quoted_repo)) { - fprintf(stderr, "error: failed to generate git-shell command\n"); - rv = 1; - goto cleanup; - } - - free(command); - free(repo); - free(quoted_repo); - - // this is a hack. no memory handling should be done inside this block - if (NULL == getenv("__VALGRIND_ENABLED")) { - execlp("git-shell", "git-shell", "-c", buffer, NULL); - - // execlp only returns on error, then something bad happened - fprintf(stderr, "error: failed to execute git-shell\n"); - return 1; - } - - printf("git-shell -c \"%s\"\n", buffer); // used by tests, ignore - return 0; - -cleanup: - free(repo); - free(quoted_repo); - return rv; -} diff --git a/src/blogc-git-receiver/shell.h b/src/blogc-git-receiver/shell.h deleted file mode 100644 index b59ff40..0000000 --- a/src/blogc-git-receiver/shell.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * blogc: A blog compiler. - * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br> - * - * This program can be distributed under the terms of the BSD License. - * See the file LICENSE. - */ - -#ifndef _SHELL_H -#define _SHELL_H - -char* bgr_shell_get_repo(const char *command); -int bgr_shell(int argc, char *argv[]); - -#endif /* _SHELL_H */ |