summaryrefslogtreecommitdiffstats
path: root/src/blogc-git-receiver/shell.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/blogc-git-receiver/shell.c')
-rw-r--r--src/blogc-git-receiver/shell.c190
1 files changed, 0 insertions, 190 deletions
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;
-}