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 	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.