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 if (
75 data->description[0] == 'U' && data->description[1] == 'n' &&
76 data->description[2] == 'n' && data->description[3] == 'a' &&
77 data->description[4] == 'm' && data->description[5] == 'e' &&
78 data->description[6] == 'd' && data->description[7] == ' ' &&
79 data->description[8] == 'r'
80 ) fprintf(stderr, "Warning: empty description: %s" "\n", data->repo_name);
81 }
82
83 void
84 find_url(RepoData *data)
85 {
86 char path[PATH_MAX];
87 FILE *fp;
88
89 data->url = malloc(URL_SIZE * sizeof(char));
90 data->url[0] = '\0';
91
92 if ((fp = git_fopen(data, path, sizeof(path), ".git/url"))) {
93 if (!fgets(data->url, URL_SIZE, fp))
94 data->url[0] = '\0';
95
96 check_file_error(fp, path, 'r');
97 fclose(fp);
98
99 data->url[strcspn(data->url, "\n")] = '\0';
100 }
101
102 if (!data->url[0])
103 fprintf(stderr, "Warning: empty url: %s" "\n", data->repo_name);
104 }
105
106 void
107 find_repo_name(RepoData *data)
108 {
109 char abs_dir[PATH_MAX + 1];
110 char *p;
111
112 data->name = data->repo_name = "";
113
114 /* set abs_dir */
115 if (!realpath(data->dir, abs_dir))
116 err(1, "realpath");
117
118 if ((data->name = strrchr(abs_dir, '/'))) data->name++;
119 else data->name = "";
120
121 if (!(data->repo_name = strdup(data->name))) err(1, "strdup");
122 if ((p = strrchr(data->repo_name, '.')))
123 if (!strcmp(p, ".git"))
124 *p = '\0';
125
126 if (data->repo_name[0] == '\0') {
127 data->repo_name = "untitled";
128 fprintf(stderr, "Warning: untitled repostory: %s" "\n", abs_dir);
129 }
130 }
131
132 void
133 find_license(RepoData *data)
134 {
135 git_object *obj = NULL;
136 int i;
137 data->license = NULL;
138 for (i = 0; i < LENGTH(license_files) && data->license == NULL; i++) {
139 if (
140 !git_revparse_single(&obj, data->repo, license_files[i]) &&
141 git_object_type(obj) == GIT_OBJ_BLOB
142 )
143 data->license = license_files[i] + strlen("HEAD:");
144 git_object_free(obj);
145 }
146 }
147
148 void
149 find_readme(RepoData *data)
150 {
151 git_object *obj = NULL;
152 int i;
153 data->readme = NULL;
154 for (i = 0; i < LENGTH(readme_files) && data->readme == NULL; i++) {
155 if (
156 !git_revparse_single(&obj, data->repo, readme_files[i]) &&
157 git_object_type(obj) == GIT_OBJ_BLOB
158 )
159 data->readme = readme_files[i] + strlen("HEAD:");
160 git_object_free(obj);
161 }
162 }
163
164 void
165 find_owner(RepoData *data)
166 {
167 FILE *fp;
168 char path[PATH_MAX];
169
170 data->owner = malloc(OWNER_SIZE * sizeof(char));
171 data->owner[0] = '\0';
172
173 fp = git_fopen(data, path, sizeof(path), ".git/owner");
174
175 if (!fp) return;
176
177 if (!fgets(data->owner, OWNER_SIZE, fp))
178 data->owner[0] = '\0';
179 check_file_error(fp, path, 'r');
180 fclose(fp);
181 data->owner[strcspn(data->owner, "\n")] = '\0';
182 }
183
184 RepoData *
185 alloc_repo_data(const char *dir)
186 {
187 RepoData *data = malloc(sizeof(RepoData));
188
189 data->dir = dir;
190
191 #ifdef __OpenBSD__
192 if (unveil(data->dir, "r") == -1) err(1, "unveil: %s", data->dir);
193 if (unveil(".", "rwc") == -1) err(1, "unveil: .");
194
195 /*
196 if (cachefile) {
197 if (unveil(cachefile, "rwc") == -1) err(1, "unveil: %s", cachefile);
198 if (pledge("stdio rpath wpath cpath fattr", NULL) == -1) err(1, "pledge");
199 } else {
200 if (pledge("stdio rpath wpath cpath", NULL) == -1) err(1, "pledge");
201 }
202 */
203 #endif
204
205 /* open the git repo */
206 int result = git_repository_open_ext(
207 &(data->repo), data->dir, GIT_REPOSITORY_OPEN_NO_SEARCH, NULL
208 );
209 if (result < 0) {
210 fprintf(stderr, "fatal: cannot open repository '%s'" "\n", dir);
211 return NULL;
212 }
213
214 find_head(data);
215 find_repo_name(data);
216 find_description(data);
217 find_url(data);
218 find_license(data);
219 find_readme(data);
220 find_submodules(data);
221 find_owner(data);
222
223 return data;
224 }
225
226 void
227 free_repo_data(RepoData *data)
228 {
229 git_repository_free(data->repo);
230 free(data->url);
231 free(data->owner);
232 free(data->description);
233 free(data);
234 }
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.