aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/configfile.c
blob: 4908058ce994d546b3280d1f0c300686a8b55fd7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
/* configfile.c: parsing of config files
 *
 * Copyright (C) 2008 Lars Hjemli
 *
 * Licensed under GNU General Public License v2
 *   (see COPYING for full license text)
 */

#include <ctype.h>
#include <stdio.h>
#include "configfile.h"

int next_char(FILE *f)
{
	int c = fgetc(f);
	if (c=='\r') {
		c = fgetc(f);
		if (c!='\n') {
			ungetc(c, f);
			c = '\r';
		}
	}
	return c;
}

void skip_line(FILE *f)
{
	int c;

	while((c=next_char(f)) && c!='\n' && c!=EOF)
		;
}

int read_config_line(FILE *f, char *line, const char **value, int bufsize)
{
	int i = 0, isname = 0;

	*value = NULL;
	while(i<bufsize-1) {
		int c = next_char(f);
		if (!isname && (c=='#' || c==';')) {
			skip_line(f);
			continue;
		}
		if (!isname && isspace(c))
			continue;

		if (c=='=' && !*value) {
			line[i] = 0;
			*value = &line[i+1];
		} else if (c=='\n' && !isname) {
			i = 0;
			continue;
		} else if (c=='\n' || c==EOF) {
			line[i] = 0;
			break;
		} else {
			line[i]=c;
		}
		isname = 1;
		i++;
	}
	line[i+1] = 0;
	return i;
}

int parse_configfile(const char *filename, configfile_value_fn fn)
{
	static int nesting;
	int len;
	char line[256];
	const char *value;
	FILE *f;

	/* cancel deeply nested include-commands */
	if (nesting > 8)
		return -1;
	if (!(f = fopen(filename, "r")))
		return -1;
	nesting++;
	while((len = read_config_line(f, line, &value, sizeof(line))) > 0)
		fn(line, value);
	nesting--;
	fclose(f);
	return 0;
}
o">= NULL; char *cgit_query_page = NULL; char *cgit_query_head = NULL; char *cgit_query_search = NULL; char *cgit_query_sha1 = NULL; char *cgit_query_sha2 = NULL; char *cgit_query_path = NULL; char *cgit_query_name = NULL; int cgit_query_ofs = 0; int htmlfd = 0; int chk_zero(int result, char *msg) { if (result != 0) die("%s: %s", msg, strerror(errno)); return result; } int chk_positive(int result, char *msg) { if (result <= 0) die("%s: %s", msg, strerror(errno)); return result; } struct repoinfo *add_repo(const char *url) { struct repoinfo *ret; if (++cgit_repolist.count > cgit_repolist.length) { if (cgit_repolist.length == 0) cgit_repolist.length = 8; else cgit_repolist.length *= 2; cgit_repolist.repos = xrealloc(cgit_repolist.repos, cgit_repolist.length * sizeof(struct repoinfo)); } ret = &cgit_repolist.repos[cgit_repolist.count-1]; ret->url = xstrdup(url); ret->name = ret->url; ret->path = NULL; ret->desc = NULL; ret->owner = NULL; ret->snapshots = cgit_snapshots; ret->module_link = cgit_module_link; return ret; } void cgit_global_config_cb(const char *name, const char *value) { if (!strcmp(name, "root-title")) cgit_root_title = xstrdup(value); else if (!strcmp(name, "css")) cgit_css = xstrdup(value); else if (!strcmp(name, "logo")) cgit_logo = xstrdup(value); else if (!strcmp(name, "logo-link")) cgit_logo_link = xstrdup(value); else if (!strcmp(name, "module-link")) cgit_module_link = xstrdup(value); else if (!strcmp(name, "virtual-root")) cgit_virtual_root = xstrdup(value); else if (!strcmp(name, "nocache")) cgit_nocache = atoi(value); else if (!strcmp(name, "snapshots")) cgit_snapshots = atoi(value); else if (!strcmp(name, "cache-root")) cgit_cache_root = xstrdup(value); else if (!strcmp(name, "cache-root-ttl")) cgit_cache_root_ttl = atoi(value); else if (!strcmp(name, "cache-repo-ttl")) cgit_cache_repo_ttl = atoi(value); else if (!strcmp(name, "cache-static-ttl")) cgit_cache_static_ttl = atoi(value); else if (!strcmp(name, "cache-dynamic-ttl")) cgit_cache_dynamic_ttl = atoi(value); else if (!strcmp(name, "max-message-length")) cgit_max_msg_len = atoi(value); else if (!strcmp(name, "max-commit-count")) cgit_max_commit_count = atoi(value); else if (!strcmp(name, "repo.url")) cgit_repo = add_repo(value); else if (!strcmp(name, "repo.name")) cgit_repo->name = xstrdup(value); else if (cgit_repo && !strcmp(name, "repo.path")) cgit_repo->path = xstrdup(value); else if (cgit_repo && !strcmp(name, "repo.desc")) cgit_repo->desc = xstrdup(value); else if (cgit_repo && !strcmp(name, "repo.owner")) cgit_repo->owner = xstrdup(value); else if (cgit_repo && !strcmp(name, "repo.snapshots")) cgit_repo->snapshots = atoi(value); else if (cgit_repo && !strcmp(name, "repo.module-link")) cgit_repo->module_link= xstrdup(value); } void cgit_repo_config_cb(const char *name, const char *value) { if (!strcmp(name, "name")) cgit_repo_name = xstrdup(value); else if (!strcmp(name, "desc")) cgit_repo_desc = xstrdup(value); else if (!strcmp(name, "owner")) cgit_repo_owner = xstrdup(value); } void cgit_querystring_cb(const char *name, const char *value) { if (!strcmp(name,"r")) { cgit_query_repo = xstrdup(value); } else if (!strcmp(name, "p")) { cgit_query_page = xstrdup(value); } else if (!strcmp(name, "q")) { cgit_query_search = xstrdup(value); } else if (!strcmp(name, "h")) { cgit_query_head = xstrdup(value); cgit_query_has_symref = 1; } else if (!strcmp(name, "id")) { cgit_query_sha1 = xstrdup(value); cgit_query_has_sha1 = 1; } else if (!strcmp(name, "id2")) { cgit_query_sha2 = xstrdup(value); cgit_query_has_sha1 = 1; } else if (!strcmp(name, "ofs")) { cgit_query_ofs = atoi(value); } else if (!strcmp(name, "path")) { cgit_query_path = xstrdup(value); } else if (!strcmp(name, "name")) { cgit_query_name = xstrdup(value); } } void *cgit_free_commitinfo(struct commitinfo *info) { free(info->author); free(info->author_email); free(info->committer); free(info->committer_email); free(info->subject); free(info); return NULL; } int hextoint(char c) { if (c >= 'a' && c <= 'f') return 10 + c - 'a'; else if (c >= 'A' && c <= 'F') return 10 + c - 'A'; else if (c >= '0' && c <= '9') return c - '0'; else return -1; } void cgit_diff_tree_cb(struct diff_queue_struct *q, struct diff_options *options, void *data) { int i; for (i = 0; i < q->nr; i++) { if (q->queue[i]->status == 'U') continue; ((filepair_fn)data)(q->queue[i]); } } static int load_mmfile(mmfile_t *file, const unsigned char *sha1) { enum object_type type; if (is_null_sha1(sha1)) { file->ptr = (char *)""; file->size = 0; } else { file->ptr = read_sha1_file(sha1, &type, &file->size); } return 1; } /* * Receive diff-buffers from xdiff and concatenate them as * needed across multiple callbacks. * * This is basically a copy of xdiff-interface.c/xdiff_outf(), * ripped from git and modified to use globals instead of * a special callback-struct. */ char *diffbuf = NULL; int buflen = 0; int filediff_cb(void *priv, mmbuffer_t *mb, int nbuf) { int i; for (i = 0; i < nbuf; i++) { if (mb[i].ptr[mb[i].size-1] != '\n') { /* Incomplete line */ diffbuf = xrealloc(diffbuf, buflen + mb[i].size); memcpy(diffbuf + buflen, mb[i].ptr, mb[i].size); buflen += mb[i].size; continue; } /* we have a complete line */ if (!diffbuf) { ((linediff_fn)priv)(mb[i].ptr, mb[i].size); continue; } diffbuf = xrealloc(diffbuf, buflen + mb[i].size); memcpy(diffbuf + buflen, mb[i].ptr, mb[i].size); ((linediff_fn)priv)(diffbuf, buflen + mb[i].size); free(diffbuf); diffbuf = NULL; buflen = 0; } if (diffbuf) { ((linediff_fn)priv)(diffbuf, buflen); free(diffbuf); diffbuf = NULL; buflen = 0; } return 0; } int cgit_diff_files(const unsigned char *old_sha1, const unsigned char *new_sha1, linediff_fn fn) { mmfile_t file1, file2; xpparam_t diff_params; xdemitconf_t emit_params; xdemitcb_t emit_cb; if (!load_mmfile(&file1, old_sha1) || !load_mmfile(&file2, new_sha1)) return 1; diff_params.flags = XDF_NEED_MINIMAL; emit_params.ctxlen = 3; emit_params.flags = XDL_EMIT_FUNCNAMES; emit_cb.outf = filediff_cb; emit_cb.priv = fn; xdl_diff(&file1, &file2, &diff_params, &emit_params, &emit_cb); return 0; } void cgit_diff_tree(const unsigned char *old_sha1, const unsigned char *new_sha1, filepair_fn fn) { struct diff_options opt; int ret; diff_setup(&opt); opt.output_format = DIFF_FORMAT_CALLBACK; opt.detect_rename = 1; opt.recursive = 1; opt.format_callback = cgit_diff_tree_cb; opt.format_callback_data = fn; diff_setup_done(&opt); if (old_sha1) ret = diff_tree_sha1(old_sha1, new_sha1, "", &opt); else ret = diff_root_tree_sha1(new_sha1, "", &opt); diffcore_std(&opt); diff_flush(&opt); } void cgit_diff_commit(struct commit *commit, filepair_fn fn) { unsigned char *old_sha1 = NULL; if (commit->parents) old_sha1 = commit->parents->item->object.sha1; cgit_diff_tree(old_sha1, commit->object.sha1, fn); }