so://phie

soso

My pretty neat website
git clone git://soophie.de/soso

blob: 999bb061114d2b29de055d0f8c1222eaec4bb815 (3858 bytes)[raw]

1#include <dirent.h>

2#include "git_list.h"

3

4#include "../templ/duc_git_list.h"

5

6static 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}

13

14static 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}

19

20static 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}

32

33static 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}

39

40static 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}

49

50static 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}

81

82static 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}

85

86static 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}

100

101const 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};