sgw | Static git web (fork of stagit) |
| download: https://git.y1.nz/archives/sgw.tar.gz | |
| README | Files | Log | Refs | LICENSE |
repo.c
1 #include <git2.h>
2 #include <stdio.h>
3 #include <limits.h> /* for PATH_MAX */
4 #include <string.h> /* for strcspn */ // TODO remove this dep
5 #include <err.h> /* for err */
6
7 #include "config.h" /* for LICENSE_FILES and README_FILES */
8 #include "files.h" /* for check_file_error */
9 #include "repo.h"
10
11 #define LENGTH(s) (sizeof(s)/sizeof(*s))
12 #define URL_SIZE 255
13 #define DESCRIPTION_SIZE 1024
14 #define OWNER_SIZE 255
15
16 static const char *license_files[] = { LICENSE_FILES };
17 static const char *readme_files[] = { README_FILES };
18
19 /* helper for find_readme, find_url, find_license, etc. */
20 FILE *
21 git_fopen(RepoData *data, char *path, int path_size, const char *file)
22 {
23 FILE *ret;
24
25 /* Try dir/<whatever> (the +5 removes the leading '.git/') */
26 join_path(path, path_size, data->dir, file + 5);
27 if ((ret = fopen(path, "r"))) return ret;
28
29 /* then try dir/.git/<whatever. */
30 join_path(path, path_size, data->dir, file);
31 return fopen(path, "r");
32 }
33
34 void
35 find_head(RepoData *data)
36 {
37 data->head = NULL;
38 git_object *obj = NULL;
39 if (!git_revparse_single(&obj, data->repo, "HEAD"))
40 data->head = git_object_id(obj);
41 git_object_free(obj);
42 }
43
44 void
45 find_submodules(RepoData *data)
46 {
47 git_object *obj = NULL;
48 data->submodules = NULL;
49 if (
50 !git_revparse_single(&obj, data->repo, "HEAD:.gitmodules") &&
51 git_object_type(obj) == GIT_OBJ_BLOB
52 )
53 data->submodules = ".gitmodules";
54 git_object_free(obj);
55 }
56
57 void
58 find_description(RepoData *data)
59 {
60 char path[PATH_MAX];
61 FILE *fp;
62 data->description = malloc(DESCRIPTION_SIZE * sizeof(char));
63 data->description[0] = '\0';
64
65 if (!(fp = git_fopen(data, path, sizeof(path), ".git/description")))
66 return;
67
68 if (!fgets(data->description, DESCRIPTION_SIZE, fp))
69 data->description[0] = '\0';
70
71 check_file_error(fp, path, 'r');
72 fclose(fp);
73 }
74
75 void
76 find_url(RepoData *data)
77 {
78 char path[PATH_MAX];
79 FILE *fp;
80
81 data->url = malloc(URL_SIZE * sizeof(char));
82 data->url[0] = '\0';
83
84 if (!(fp = git_fopen(data, path, sizeof(path), ".git/url")))
85 return;
86
87 if (!fgets(data->url, URL_SIZE, fp))
88 data->url[0] = '\0';
89
90 check_file_error(fp, path, 'r');
91 fclose(fp);
92
93 // TODO ???
94 data->url[strcspn(data->url, "\n")] = '\0';
95 }
96
97 void
98 find_repo_name(RepoData *data)
99 {
100 char abs_dir[PATH_MAX + 1];
101 char *p;
102
103 data->name = data->repo_name = "";
104
105 /* set abs_dir */
106 if (!realpath(data->dir, abs_dir))
107 err(1, "realpath");
108
109 if ((data->name = strrchr(abs_dir, '/'))) data->name++;
110 else data->name = "";
111
112 if (!(data->repo_name = strdup(data->name))) err(1, "strdup");
113 if ((p = strrchr(data->repo_name, '.')))
114 if (!strcmp(p, ".git"))
115 *p = '\0';
116
117 if (data->repo_name[0] == '\0')
118 data->repo_name = "untitled";
119 }
120
121 void
122 find_license(RepoData *data)
123 {
124 git_object *obj = NULL;
125 int i;
126 data->license = NULL;
127 for (i = 0; i < LENGTH(license_files) && data->license == NULL; i++) {
128 if (
129 !git_revparse_single(&obj, data->repo, license_files[i]) &&
130 git_object_type(obj) == GIT_OBJ_BLOB
131 )
132 data->license = license_files[i] + strlen("HEAD:");
133 git_object_free(obj);
134 }
135 }
136
137 void
138 find_readme(RepoData *data)
139 {
140 git_object *obj = NULL;
141 int i;
142 data->readme = NULL;
143 for (i = 0; i < LENGTH(readme_files) && data->readme == NULL; i++) {
144 if (
145 !git_revparse_single(&obj, data->repo, readme_files[i]) &&
146 git_object_type(obj) == GIT_OBJ_BLOB
147 )
148 data->readme = readme_files[i] + strlen("HEAD:");
149 git_object_free(obj);
150 }
151 }
152
153 void
154 find_owner(RepoData *data)
155 {
156 FILE *fp;
157 char path[PATH_MAX];
158
159 data->owner = malloc(OWNER_SIZE * sizeof(char));
160 data->owner[0] = '\0';
161
162 fp = git_fopen(data, path, sizeof(path), ".git/owner");
163
164 if (!fp) return;
165
166 if (!fgets(data->owner, OWNER_SIZE, fp))
167 data->owner[0] = '\0';
168 check_file_error(fp, path, 'r');
169 fclose(fp);
170 data->owner[strcspn(data->owner, "\n")] = '\0';
171 }
172
173 RepoData *
174 alloc_repo_data(const char *dir)
175 {
176 RepoData *data = malloc(sizeof(RepoData));
177
178 data->dir = dir;
179
180 #ifdef __OpenBSD__
181 if (unveil(data->dir, "r") == -1) err(1, "unveil: %s", data->dir);
182 if (unveil(".", "rwc") == -1) err(1, "unveil: .");
183
184 /*
185 if (cachefile) {
186 if (unveil(cachefile, "rwc") == -1) err(1, "unveil: %s", cachefile);
187 if (pledge("stdio rpath wpath cpath fattr", NULL) == -1) err(1, "pledge");
188 } else {
189 if (pledge("stdio rpath wpath cpath", NULL) == -1) err(1, "pledge");
190 }
191 */
192 #endif
193
194 /* open the git repo */
195 int result = git_repository_open_ext(
196 &(data->repo), data->dir, GIT_REPOSITORY_OPEN_NO_SEARCH, NULL
197 );
198 if (result < 0) {
199 fprintf(stderr, "fatal: cannot open repository '%s'" "\n", dir);
200 return NULL;
201 }
202
203 find_head(data);
204 find_repo_name(data);
205 find_description(data);
206 find_url(data);
207 find_license(data);
208 find_readme(data);
209 find_submodules(data);
210 find_owner(data);
211
212 return data;
213 }
214
215 void
216 free_repo_data(RepoData *data)
217 {
218 git_repository_free(data->repo);
219 free(data->url);
220 free(data->owner);
221 free(data->description);
222 free(data);
223 }
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.