Subversion Repositories RepoView

Rev

Rev 10 | Rev 12 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 10 Rev 11
Line 1... Line 1...
1
/* $Id: repo.c 10 2024-08-21 02:13:48Z nishi $ */
1
/* $Id: repo.c 11 2024-08-21 04:31:55Z nishi $ */
2
 
2
 
3
#include "rv_repo.h"
3
#include "rv_repo.h"
-
 
4
 
-
 
5
#include "../config.h"
-
 
6
 
-
 
7
#include "rv_util.h"
-
 
8
 
-
 
9
#include <stdbool.h>
-
 
10
#include <unistd.h>
-
 
11
#include <stdlib.h>
-
 
12
#include <dirent.h>
-
 
13
#include <stdio.h>
-
 
14
#include <string.h>
-
 
15
#include <fcntl.h>
-
 
16
#include <sys/stat.h>
-
 
17
#include <sys/wait.h>
-
 
18
 
-
 
19
char* rv_construct_repouser(const char* reponame, const char* username) {
-
 
20
	char cbuf[2];
-
 
21
	cbuf[0] = REPO_USER_DELIM;
-
 
22
	cbuf[1] = 0;
-
 
23
	return rv_strcat3(reponame, cbuf, username);
-
 
24
}
-
 
25
 
-
 
26
bool rv_repo_exists(const char* repouser) {
-
 
27
	char* path = rv_strcat3(SVN_ROOT, "/", repouser);
-
 
28
	if(access(path, F_OK) == 0) {
-
 
29
		free(path);
-
 
30
		return true;
-
 
31
	}
-
 
32
	return false;
-
 
33
}
-
 
34
 
-
 
35
void rv_repo_list(const char* username, void (*handler)(const char* name, const char* rev)) {
-
 
36
	struct dirent** nl;
-
 
37
	int n = scandir(SVN_ROOT, &nl, NULL, alphasort);
-
 
38
	if(n < 0) return;
-
 
39
	int i;
-
 
40
	for(i = 0; i < n; i++) {
-
 
41
		if(strcmp(nl[i]->d_name, "..") != 0 && strcmp(nl[i]->d_name, ".") != 0) {
-
 
42
			char* tmp = rv_strcat3(SVN_ROOT, "/", nl[i]->d_name);
-
 
43
			char* path = rv_strcat(tmp, "/db/current");
-
 
44
			free(tmp);
-
 
45
			char* str = rv_strdup(nl[i]->d_name);
-
 
46
			int j;
-
 
47
			for(j = 0; str[j] != 0; j++) {
-
 
48
				if(str[j] == REPO_USER_DELIM) {
-
 
49
					str[j] = 0;
-
 
50
					if(strcmp(str + j + 1, username) == 0) {
-
 
51
						struct stat s;
-
 
52
						char* rev = rv_strdup("???");
-
 
53
						if(stat(path, &s) == 0) {
-
 
54
							free(rev);
-
 
55
							rev = malloc(s.st_size + 1);
-
 
56
							FILE* f = fopen(path, "r");
-
 
57
							fread(rev, 1, s.st_size, f);
-
 
58
							fclose(f);
-
 
59
							rev[s.st_size] = 0;
-
 
60
						}
-
 
61
						handler(str, rev);
-
 
62
						free(rev);
-
 
63
					}
-
 
64
					break;
-
 
65
				}
-
 
66
			}
-
 
67
			free(path);
-
 
68
			free(str);
-
 
69
		}
-
 
70
		free(nl[i]);
-
 
71
	}
-
 
72
	free(nl);
-
 
73
}
-
 
74
 
-
 
75
void null_exec(char** cmd) {
-
 
76
	pid_t pid = fork();
-
 
77
	if(pid == 0) {
-
 
78
		int null = open("/dev/null", O_RDWR);
-
 
79
		dup2(STDOUT_FILENO, null);
-
 
80
		execvp(cmd[0], cmd);
-
 
81
		_exit(0);
-
 
82
	} else {
-
 
83
		waitpid(pid, 0, 0);
-
 
84
	}
-
 
85
}
-
 
86
 
-
 
87
void rv_create_repo(const char* repouser) {
-
 
88
	char* user = rv_strdup(repouser);
-
 
89
	int i;
-
 
90
	for(i = 0; user[i] != 0; i++) {
-
 
91
		if(user[i] == REPO_USER_DELIM) {
-
 
92
			user[i] = 0;
-
 
93
			break;
-
 
94
		}
-
 
95
	}
-
 
96
	char* path = rv_strcat3(SVN_ROOT, "/", repouser);
-
 
97
	char* cmd[] = {"svnadmin", "create", path, NULL};
-
 
98
	null_exec(cmd);
-
 
99
	free(path);
-
 
100
	FILE* f = fopen(APACHE_AUTHZ, "r+");
-
 
101
	lockf(fileno(f), F_LOCK, 0);
-
 
102
 
-
 
103
	fseek(f, 0, SEEK_END);
-
 
104
 
-
 
105
	fprintf(f, "#%%START %s\n", repouser);
-
 
106
	fprintf(f, "* = r\n");
-
 
107
	fprintf(f, "%s = r\n", user);
-
 
108
	fprintf(f, "#%%END\n");
-
 
109
 
-
 
110
	lockf(fileno(f), F_ULOCK, 0);
-
 
111
	free(user);
-
 
112
}
-
 
113
 
-
 
114
char* rv_get_readme(const char* repouser) {
-
 
115
	char* tmp = rv_strcat3(SVN_ROOT, "/", repouser);
-
 
116
	char* path = rv_strcat(tmp, "/README.txt");
-
 
117
	free(tmp);
-
 
118
	struct stat s;
-
 
119
	if(stat(path, &s) == 0) {
-
 
120
		FILE* f = fopen(path, "r");
-
 
121
		char* buf = malloc(s.st_size + 1);
-
 
122
		fread(buf, 1, s.st_size, f);
-
 
123
		fclose(f);
-
 
124
		buf[s.st_size] = 0;
-
 
125
		return buf;
-
 
126
	}
-
 
127
	return NULL;
-
 
128
}
-
 
129
 
-
 
130
long long rv_get_filesize(const char* repouser, const char* path) {
-
 
131
	char* svnpath = rv_strcat3(SVN_ROOT, "/", repouser);
-
 
132
	int pipes[2];
-
 
133
	pipe(pipes);
-
 
134
	pid_t pid = fork();
-
 
135
	if(pid == 0) {
-
 
136
		close(pipes[0]);
-
 
137
		dup2(pipes[1], STDOUT_FILENO);
-
 
138
		char* cmd[] = {"svnlook", "filesize", svnpath, (char*)path, NULL};
-
 
139
		execvp("svnlook", cmd);
-
 
140
		_exit(0);
-
 
141
	} else {
-
 
142
		close(pipes[1]);
-
 
143
		char cbuf[2];
-
 
144
		cbuf[1] = 0;
-
 
145
		char* d = malloc(1);
-
 
146
		d[0] = 0;
-
 
147
		while(1) {
-
 
148
			int n = read(pipes[0], cbuf, 1);
-
 
149
			if(n == 0) break;
-
 
150
			char* tmp = d;
-
 
151
			d = rv_strcat(tmp, cbuf);
-
 
152
			free(tmp);
-
 
153
		}
-
 
154
		int status;
-
 
155
		waitpid(pid, &status, 0);
-
 
156
		if(WEXITSTATUS(status) != 0) {
-
 
157
			free(d);
-
 
158
			free(svnpath);
-
 
159
			return -1;
-
 
160
		}
-
 
161
		long long sz = atoll(d);
-
 
162
		free(svnpath);
-
 
163
		free(d);
-
 
164
		return sz;
-
 
165
	}
-
 
166
}
-
 
167
 
-
 
168
bool rv_get_list(const char* repouser, const char* path, void (*handler)(const char* pathname), int* isdir) {
-
 
169
	char* svnpath = rv_strcat3(SVN_ROOT, "/", repouser);
-
 
170
	int pipes[2];
-
 
171
	*isdir = 0;
-
 
172
	pipe(pipes);
-
 
173
	pid_t pid = fork();
-
 
174
	if(pid == 0) {
-
 
175
		close(pipes[0]);
-
 
176
		dup2(pipes[1], STDOUT_FILENO);
-
 
177
		char* cmd[] = {"svnlook", "-N", "tree", svnpath, (char*)path, NULL};
-
 
178
		execvp("svnlook", cmd);
-
 
179
		_exit(0);
-
 
180
	} else {
-
 
181
		close(pipes[1]);
-
 
182
		char cbuf[2];
-
 
183
		cbuf[1] = 0;
-
 
184
		char* d = malloc(1);
-
 
185
		d[0] = 0;
-
 
186
		while(1) {
-
 
187
			int n = read(pipes[0], cbuf, 1);
-
 
188
			if(n == 0) break;
-
 
189
			char* tmp = d;
-
 
190
			d = rv_strcat(tmp, cbuf);
-
 
191
			free(tmp);
-
 
192
		}
-
 
193
		int status;
-
 
194
		waitpid(pid, &status, 0);
-
 
195
		if(WEXITSTATUS(status) != 0) {
-
 
196
			free(d);
-
 
197
			free(svnpath);
-
 
198
			return false;
-
 
199
		}
-
 
200
		int count = 0;
-
 
201
		int incr = 0;
-
 
202
		int i;
-
 
203
		int phase = 0;
-
 
204
	repeat:
-
 
205
		for(i = 0;; i++) {
-
 
206
			if(d[i] == '\r') {
-
 
207
				d[i] = 0;
-
 
208
			} else if(d[i] == '\n' || d[i] == 0) {
-
 
209
				char oldc = d[i];
-
 
210
				d[i] = 0;
-
 
211
				count++;
-
 
212
				if(count > 1 && strlen(d + incr + 1) > 0 && d[incr] != 0) {
-
 
213
					char* pathname = d + incr + 1;
-
 
214
					if(phase == 0 && pathname[strlen(pathname) - 1] == '/') {
-
 
215
						handler(d + incr + 1);
-
 
216
					} else if(phase == 1 && pathname[strlen(pathname) - 1] != '/') {
-
 
217
						handler(d + incr + 1);
-
 
218
					}
-
 
219
				} else {
-
 
220
					char* pathname = d + incr;
-
 
221
					if(pathname[strlen(pathname) - 1] == '/') *isdir = 1;
-
 
222
				}
-
 
223
				d[i] = oldc;
-
 
224
				incr = i + 1;
-
 
225
				if(oldc == 0) break;
-
 
226
			}
-
 
227
		}
-
 
228
		phase++;
-
 
229
		if(phase == 1) goto repeat;
-
 
230
		free(d);
-
 
231
	}
-
 
232
	free(svnpath);
-
 
233
	return true;
-
 
234
}
-
 
235
 
-
 
236
char* rv_read_file(const char* repouser, char* path) {
-
 
237
	char* svnpath = rv_strcat3(SVN_ROOT, "/", repouser);
-
 
238
	int pipes[2];
-
 
239
	pipe(pipes);
-
 
240
	pid_t pid = fork();
-
 
241
	if(pid == 0) {
-
 
242
		close(pipes[0]);
-
 
243
		dup2(pipes[1], STDOUT_FILENO);
-
 
244
		char* cmd[] = {"svnlook", "cat", svnpath, (char*)path, NULL};
-
 
245
		execvp("svnlook", cmd);
-
 
246
		_exit(0);
-
 
247
	} else {
-
 
248
		close(pipes[1]);
-
 
249
		char cbuf[2];
-
 
250
		cbuf[1] = 0;
-
 
251
		char* d = malloc(1);
-
 
252
		d[0] = 0;
-
 
253
		while(1) {
-
 
254
			int n = read(pipes[0], cbuf, 1);
-
 
255
			if(n == 0) break;
-
 
256
			char* tmp = d;
-
 
257
			d = rv_strcat(tmp, cbuf);
-
 
258
			free(tmp);
-
 
259
		}
-
 
260
		int status;
-
 
261
		waitpid(pid, &status, 0);
-
 
262
		if(WEXITSTATUS(status) != 0) {
-
 
263
			free(d);
-
 
264
			free(svnpath);
-
 
265
			return NULL;
-
 
266
		}
-
 
267
		return d;
-
 
268
	}
-
 
269
}