#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <syslog.h>
#include <unistd.h>
#include "config.h"
#include "git.h"
#include "macros.h"
#include "misc.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) {
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;
free(repo);
}
}
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);
}
void cleanup_git(git_repository **repos) {
cleanup_git_repos(repos);
git_libgit2_shutdown();
}
pull_request *get_pull_request(int id, const char *root) {
}
int create_pull_request_dir(pull_request *pr, const char *root) {
int id = 0;
int is_num = 0;
DIR *dir = opendir(root);
struct dirent entry, *result;
while (readdir_r(dir, &entry, &result) == 0 && result != NULL) {
if (entry.d_type == DT_DIR) {
char *tmp = entry.d_name;
if (*tmp == '\0') {
continue;
}
for (is_num = 1; *tmp && is_num; is_num = isdigit(*tmp++));
if (is_num) {
int val = strtol(entry.d_name, NULL, 0);
id = (id < val) ? val : id;
}
}
}
if (id > 0) {
struct stat st;
file **commits = (pr->pr_type) ? get_branch_commits(pr->branch) : pr->patches;
int len = snprintf(NULL, 0, "%s/%i", root, id);
char *pr_dir = calloc(len+1, sizeof(char));
sprintf(pr_dir, "%s/%i", root, id);
if (stat(pr_dir, &st) < -1) {
mkdir(pr_dir, 0755);
}
for (int i = 0; commits[i] != NULL; i++) {
FILE *fp;
if (access(commits[i]->name, F_OK) == 0) {
long size = 0;
char *buf = read_file(commits[i]->name, &size);
if (buf != NULL) {
if (strcmp(commits[i]->buf, buf) == 0) {
free(buf);
continue;
}
free(buf);
} else {
continue;
}
}
fp = fopen(commits[i]->name, "w");
fwrite(commits[i]->buf, sizeof(char), strlen(commits[i]->buf), fp);
fclose(fp);
}
TODO
}
return id;
}
git_repository **init_git(config *cfg) {
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);
while (readdir_r(root, &entry, &result) == 0 && result != NULL) {
if (entry.d_type == DT_DIR) {
if (strcmp(entry.d_name, ".") && strcmp(entry.d_name, "..")) {
char *repo_dir = calloc(strlen(cfg->git_root) + strlen(entry.d_name) + 2, sizeof(char));
sprintf(repo_dir, "%s/%s", cfg->git_root, entry.d_name);
if (!find_ignore_file(repo_dir)) {
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);
}
}
}
if (repo_count) {
log(LOG_INFO, "Found, and opened %i repositories.", repo_count);
repos = calloc(repo_count+1, sizeof(git_repository *));
int i = 0;
for (git_repo *r = first; r != NULL; 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;
}