summaryrefslogtreecommitdiff
path: root/git.c
diff options
context:
space:
mode:
authormrb0nk500 <b0nk@b0nk.xyz>2021-06-13 15:45:12 -0400
committermrb0nk500 <b0nk@b0nk.xyz>2021-06-13 15:45:12 -0400
commit6c244ade251499eea92be4dff8bd3793bcc27817 (patch)
treedb5c9601620076bb813ee754ec8d26592bd9a63c /git.c
parent4ac6ebfa301c6a6eff1b2c27cd6539c25f3d529a (diff)
Finished the git initialization code.
Diffstat (limited to 'git.c')
-rw-r--r--git.c106
1 files changed, 103 insertions, 3 deletions
diff --git a/git.c b/git.c
index 61ab0c0..fbeb0e9 100644
--- a/git.c
+++ b/git.c
@@ -1,7 +1,7 @@
+#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <git2.h>
-#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -10,13 +10,113 @@
#include <syslog.h>
#include <unistd.h>
#include "config.h"
+#include "git.h"
#include "macros.h"
+git_repo *add_repo(git_repository *repo, git_repo **first, git_repo **last) {
+ git_repo *new_repo = calloc(1, sizeof(git_repo));
+ (*last != NULL) ? ((*last)->next = new_repo) : (*first = new_repo);
+
+ new_repo->repo = repo;
+
+ *last = new_repo;
+
+ return new_repo;
+}
+
+int find_ignore_file(const char *path) {
+ DIR *root = opendir(path);
+ struct dirent entry, *result;
+
+ while (readdir_r(root, &entry, &result) == 0 && result != NULL) {
+ /* Is this entry a regular file, and is it the ignore file? */
+ if (entry.d_type == DT_REG && strcasecmp(entry.d_name, "pullreqd-ignore") == 0) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+void cleanup_linked_list(git_repo *root) {
+ if (root != NULL) {
+ git_repo *repo = root;
+ cleanup_linked_list(root->next);
+ repo->repo = NULL;
+ repo->next = NULL;
+ }
+}
+
+void cleanup_git_repos(git_repository **repos) {
+ for (int i = 0; repos[i] != NULL; i++) {
+ git_repository_free(repos[i]);
+ repos[i] = NULL;
+ }
+ free(repos);
+}
+
git_repository **init_git(config *cfg) {
- git_repository **repos;
- git_repository *repo;
+ git_repository **repos = NULL;
+ git_repository *repo = NULL;
+ git_repo *first = NULL, *last = NULL, *current = NULL;
+ DIR *root = opendir(cfg->git_root);
+ struct dirent entry, *result;
+ int repo_count = 0;
+
+ log(LOG_INFO, "Initializing libgit2.");
+ int ret = git_libgit2_init();
+
+ log(LOG_INFO, "Searching \"%s\" for repositories.", cfg->git_root);
+ /* Find all git repos in the git root. */
+ while (readdir_r(root, &entry, &result) == 0 && result != NULL) {
+ log(LOG_DEBUG, "entry.d_name %s, result->d_name: %s", entry.d_name, result->d_name);
+ /* Is this entry a directory? */
+ if (entry.d_type == DT_DIR) {
+ /* Is the entry neither ".", nor ".."? */
+ if (strcmp(entry.d_name, ".") && strcmp(entry.d_name, "..")) {
+ char *repo_dir = calloc(strlen(cfg->git_root) + strlen(entry.d_name) + 1, sizeof(char));
+
+ /* Append the directory name to the git root. */
+ /* Could also do this:
+ * memcpy(repo_dir, cfg->git_root, strlen(cfg->git_repo));
+ * strcat(repo_dir, entry.d_name);
+ */
+ sprintf(repo_dir, "%s%s", cfg->git_root, entry.d_name);
+ /* Was no ignore file found? */
+ if (!find_ignore_file(repo_dir)) {
+ /* Did we fail to open the git repo? */
+ if (git_repository_open(&repo, repo_dir)) {
+ log(LOG_ERR, "Failed to open git repository %s, ignoring.", entry.d_name);
+ } else {
+ log(LOG_INFO, "Successfully opened git repository %s", entry.d_name);
+ current = add_repo(repo, &first, &last);
+ repo_count++;
+ }
+ }
+ free(repo_dir);
+ }
+ }
+ }
+ /* Did we find any repos? */
+ if (repo_count) {
+ log(LOG_INFO, "Found, and opened %i repositories.", repo_count);
+ /* Allocate repo_count + 1 git repos, since we need a NULL entry to denote the end. */
+ repos = calloc(repo_count+1, sizeof(git_repository *));
+ /* Add the repos to the array. */
+ int i = 0;
+ for (git_repo *r = first; r != NULL; /*repos[i] = r->repo,*/ r = r->next, i++) {
+ repos[i] = r->repo;
+ }
+ cleanup_linked_list(first);
+ first = NULL;
+ last = NULL;
+ current = NULL;
+ } else {
+ log(LOG_ERR, "Couldn't find, and/or open any repositories.");
+ }
+ return repos;
}