Subversion Repositories RepoView

Rev

Rev 15 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 nishi 1
/* $Id: util.c 29 2024-08-21 19:23:54Z nishi $ */
2
 
3
#include "rv_util.h"
4
 
5
#include "../config.h"
6
 
7
#include "rv_version.h"
5 nishi 8
#include "rv_db.h"
1 nishi 9
 
10
#include <stdio.h>
11
#include <stdlib.h>
12
#include <string.h>
15 nishi 13
#include <unistd.h>
14
#include <sys/wait.h>
1 nishi 15
 
3 nishi 16
char* rv_strcat(const char* a, const char* b) {
1 nishi 17
	char* str = malloc(strlen(a) + strlen(b) + 1);
18
	memcpy(str, a, strlen(a));
19
	memcpy(str + strlen(a), b, strlen(b));
20
	str[strlen(a) + strlen(b)] = 0;
21
	return str;
22
}
23
 
3 nishi 24
char* rv_strcat3(const char* a, const char* b, const char* c) {
1 nishi 25
	char* tmp = rv_strcat(a, b);
26
	char* str = rv_strcat(tmp, c);
27
	free(tmp);
28
	return str;
29
}
30
 
3 nishi 31
char* rv_strdup(const char* str) { return rv_strcat(str, ""); }
1 nishi 32
 
3 nishi 33
void rv_error_http(void) {
1 nishi 34
	printf("Content-Type: text/plain\r\n");
35
	printf("Status: 500 Internal Server Error\r\n");
36
	printf("\r\n");
37
	printf("This is RepoView version %s, named `%s`.\n", rv_get_version(), INSTANCE_NAME);
38
	printf("Unrecoverable error has occured.\n");
39
	printf("Admin contact: %s\n", INSTANCE_ADMIN);
40
	printf("Developer contact: Nishi <nishi@nishi.boats>\n");
41
	printf("-----\n");
42
}
43
 
3 nishi 44
int hex_to_num(char c) {
45
	if('0' <= c && c <= '9') {
1 nishi 46
		return c - '0';
3 nishi 47
	} else if('a' <= c && c <= 'f') {
1 nishi 48
		return c - 'a' + 10;
3 nishi 49
	} else if('A' <= c && c <= 'F') {
1 nishi 50
		return c - 'A' + 10;
51
	}
52
	return 0;
53
}
54
 
3 nishi 55
char* rv_url_decode(const char* str) {
1 nishi 56
	char* r = malloc(1);
57
	r[0] = 0;
58
	int i;
59
	char cbuf[2];
60
	cbuf[1] = 0;
3 nishi 61
	for(i = 0; str[i] != 0; i++) {
62
		if(str[i] == '%') {
1 nishi 63
			if(str[i + 1] == 0) break;
64
			if(str[i + 2] == 0) break;
65
			cbuf[0] = (hex_to_num(str[i + 1]) << 4) | hex_to_num(str[i + 2]);
66
			char* tmp = r;
67
			r = rv_strcat(tmp, cbuf);
68
			free(tmp);
69
			i += 2;
15 nishi 70
		} else if(str[i] == '+') {
71
			char* tmp = r;
72
			r = rv_strcat(tmp, " ");
73
			free(tmp);
3 nishi 74
		} else {
1 nishi 75
			cbuf[0] = str[i];
76
			char* tmp = r;
77
			r = rv_strcat(tmp, cbuf);
78
			free(tmp);
79
		}
80
	}
81
	return r;
82
}
5 nishi 83
 
84
char* rv_new_token(const char* username) {
85
	const char tokenstr[] = "0123456789abcdefghijklmnopqrstuvwxyz";
86
	char* token = malloc(17);
87
	token[16] = 0;
88
	int i;
29 nishi 89
	unsigned char uc;
90
	FILE* f = fopen("/dev/urandom", "rb");
5 nishi 91
regenerate:
92
	for(i = 0; i < 16; i++) {
29 nishi 93
		fread(&uc, 1, 1, f);
94
		token[i] = tokenstr[uc % strlen(tokenstr)];
5 nishi 95
	}
29 nishi 96
	fclose(f);
5 nishi 97
	if(rv_has_token(token)) goto regenerate;
98
	rv_save_token(username, token);
99
	return token;
100
}
15 nishi 101
 
102
void rv_add_auth(const char* username, const char* password) {
103
	pid_t pid = fork();
104
	if(pid == 0) {
105
		char* cmd[] = {"htpasswd", "-b", APACHE_PASSWD, (char*)username, (char*)password, NULL};
106
		execvp("htpasswd", cmd);
107
		_exit(0);
108
	} else {
109
		waitpid(pid, 0, 0);
110
	}
111
}