git.y1.nz

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.