My pretty neat website
git clone git://soophie.de/soso
blob: 999bb061114d2b29de055d0f8c1222eaec4bb815 (3858 bytes)[raw]
1
#include <dirent.h>2
#include "git_list.h"4
#include "../templ/duc_git_list.h"6
static orb_rc_t init(orb_module_t *self) {7
duc_git_list_t *data = self->data;8
(void) data;9
git_list_param_list_t *param_list = self->param_list;10
(void) param_list;11
return ORB_OK;12
}14
static int _fetch_repo_meta_sort(const void *a, const void *b) {15
const git_repo_meta_t *repo_meta_a = a;16
const git_repo_meta_t *repo_meta_b = b;17
return strcmp(repo_meta_a->name, repo_meta_b->name);18
}20
static int _fetch_read_text_file(char *filename, char **content) {21
FILE *fd = fopen(filename, "r");22
if (fd == NULL) return 1;23
fseek(fd, 0, SEEK_END);24
size_t len = ftell(fd);25
fseek(fd, 0, SEEK_SET);26
*content = calloc(1, sizeof(char) * (len + 1));27
fread(*content, sizeof(char), len, fd);28
(*content)[len] = '\0';29
fclose(fd);30
return 0;31
}33
static int _fetch_read_git_file(char *repo_path, char *filename, char **content) {34
size_t file_path_len = strlen(repo_path) + strlen(filename) + 2;35
char file_path[file_path_len];36
snprintf(file_path, file_path_len, "%s/%s", repo_path, filename);37
return _fetch_read_text_file(file_path, content);38
}40
static bool _fetch_git_file_exists(char *repo_path, char *filename) {41
size_t file_path_len = strlen(repo_path) + strlen(filename) + 2;42
char file_path[file_path_len];43
snprintf(file_path, file_path_len, "%s/%s", repo_path, filename);44
FILE *fp = fopen(file_path, "r");45
if (!fp) return false;46
fclose(fp);47
return true;48
}50
static orb_rc_t fetch(orb_module_t *self) {51
duc_git_list_t *data = self->data;52
git_list_param_list_t *param_list = self->param_list;53
if (!param_list->path) return ORB_FATAL(1);54
DIR *dir = opendir(param_list->path);55
if (dir == NULL) return ORB_FATAL(2);56
struct dirent *entry;57
while ((entry = readdir(dir)) != NULL) {58
if (entry->d_type != DT_DIR) continue;59
if (strcmp(entry->d_name, ".") == 0) continue;60
if (strcmp(entry->d_name, "..") == 0) continue;61
size_t repo_path_len = strlen(param_list->path) + strlen(entry->d_name) + 2;62
char repo_path[repo_path_len];63
snprintf(repo_path, repo_path_len, "%s/%s", param_list->path, entry->d_name);64
bool is_public = _fetch_git_file_exists(repo_path, "git-daemon-export-ok");65
if (!is_public) continue;66
data->repo_meta_list = realloc(data->repo_meta_list, sizeof(git_repo_meta_t) * (data->repo_meta_list_len + 1));67
git_repo_meta_t *repo_meta = &data->repo_meta_list[data->repo_meta_list_len];68
memset(repo_meta, 0, sizeof(git_repo_meta_t));69
repo_meta->name = strdup(entry->d_name);70
_fetch_read_git_file(repo_path, "description", &repo_meta->description);71
_fetch_read_git_file(repo_path, "owner", &repo_meta->owner);72
repo_meta->is_public = is_public;73
repo_meta->is_archive = _fetch_git_file_exists(repo_path, ".archive");74
repo_meta->is_fork = _fetch_git_file_exists(repo_path, ".fork");75
data->repo_meta_list_len++;76
}77
closedir(dir);78
qsort(data->repo_meta_list, data->repo_meta_list_len, sizeof(git_repo_meta_t), _fetch_repo_meta_sort);79
return ORB_OK;80
}82
static orb_rc_t render(orb_module_t *self, void *out) {83
return ORB_ERR(duc_git_list_render(out, (duc_git_list_t *) self->data));84
}86
static void cleanup(orb_module_t *self) {87
duc_git_list_t *data = self->data;88
if (data->repo_meta_list && data->repo_meta_list_len > 0) {89
for (size_t i = 0; i < data->repo_meta_list_len; i++) {90
git_repo_meta_t *repo_meta = &data->repo_meta_list[i];91
free(repo_meta->name);92
if (repo_meta->description) free(repo_meta->description);93
if (repo_meta->owner) free(repo_meta->owner);94
}95
free(data->repo_meta_list);96
data->repo_meta_list = NULL;97
data->repo_meta_list_len = 0;98
}99
}101
const orb_module_type_t GIT_LIST_TYPE = {102
.size = sizeof(duc_git_list_t),103
.init = init,104
.fetch = fetch,105
.render = render,106
.cleanup = cleanup,107
};