1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#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) {
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();
}
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;
}
|