initial commit

This commit is contained in:
ston1th 2017-01-06 15:04:49 +01:00
commit 781006e83b
4 changed files with 161 additions and 0 deletions

4
build.sh Executable file
View file

@ -0,0 +1,4 @@
#!/bin/sh
cc -static -Wall -Werror -o ddns ddns.c
install -o www -g www -m 0500 ddns /var/www/ddns

137
ddns.c Normal file
View file

@ -0,0 +1,137 @@
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <sys/file.h>
#include <err.h>
#define SEP '='
#define IP_LEN 16
#define IP_FILE "ip.txt"
#define TOKEN "<empty>"
void free_arr(void *arr) {
uintptr_t *a = arr;
while(*a) {
free((void*)*a++);
}
free(arr);
}
char **parse(const char *str) {
const char *s = str;
char *qs, *token;
char **arr = NULL;
int c = 1;
qs = strdup(s);
while((token = strsep(&qs, "&")) != NULL) {
c++;
if(arr == NULL) {
arr = malloc(c*sizeof(char *));
if(arr == NULL)
break;
} else {
arr = realloc(arr, c*sizeof(char *));
if(arr == NULL)
break;
}
arr[c-1] = NULL;
arr[c-2] = strdup(token);
}
free(qs);
return(arr);
}
void header() {
puts("Status: 200 OK\r");
puts("Content-Type: text/html\r");
puts("\r");
}
int ctb(unsigned char a, unsigned char b) {
unsigned char c = ~(a ^ b);
c &= c >> 4;
c &= c >> 2;
c &= c >> 1;
return((int)c);
}
int ctc(const char *a, const char *b) {
if(strlen(a) != strlen(b)) {
return(0);
}
const char *x = a, *y = b;
char v = 0;
while(*x)
v |= *x++ ^ *y++;
return(ctb(v, 0));
}
int set_ip(char *env, int fd) {
char *ip, *token, *tmp;
int ret = -1, len = 0;
char **arg = parse(env);
char **arr = arg;
if(arg == NULL)
return(0);
for(; *arr; arr++) {
if(strncmp(*arr, "ip", 2) == 0) {
tmp = strchr(*arr, SEP);
if(++tmp == NULL)
continue;
ip = strdup(tmp);
} else if(strncmp(*arr, "token", 5) == 0) {
tmp = strchr(*arr, SEP);
if(++tmp == NULL)
continue;
token = strdup(tmp);
}
}
tmp = NULL;
free_arr(arg);
if(ctc(token, TOKEN) == 1) {
len = strlen(ip);
if(len >= IP_LEN-1)
len = IP_LEN-1;
write(fd, ip, len);
close(fd);
} else
ret = 1;
free(token);
free(ip);
return(ret);
}
char *err_msg[2] = {"wrong input", "wrong token"};
int main(void) {
char *env;
char ip[IP_LEN];
int errn = 0, len = 0;
int rfd = open(IP_FILE, O_RDONLY|O_SHLOCK);
if(read(rfd, &ip, IP_LEN) <= 0)
ip[0] = '\0';
close(rfd);
ip[IP_LEN] = '\0';
int wfd = open(IP_FILE, O_WRONLY|O_CREAT|O_TRUNC|O_EXLOCK);
if(pledge("stdio", NULL) == -1)
err(EXIT_FAILURE, "pledge");
env = getenv("QUERY_STRING");
header();
if(env != NULL) {
if((errn = set_ip(env, wfd)) >= 0)
puts(err_msg[errn]);
else
puts("ok");
} else {
len = strlen(ip);
write(wfd, ip, len);
close(wfd);
if(len > 1)
puts(ip);
else
puts("empty");
}
return(EXIT_SUCCESS);
}

7
httpd.conf Normal file
View file

@ -0,0 +1,7 @@
server "localhost" {
listen on * port 80
location "/ddns/*" {
fastcgi
root "/"
}
}

13
install.sh Executable file
View file

@ -0,0 +1,13 @@
#!/bin/sh
dir=/var/www/ddns
ip=ip.txt
ip_file=${dir}/${ip}
mkdir -p ${dir}
touch ${ip_file}
chmod 0600 ${ip_file}
chown www:www ${ip_file}
rcctl enable slowcgi
rcctl start slowcgi
rcctl enable httpd
rcctl start httpd