gemini server written in C used with inetd
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
vger/main.c

97 lines
2.5 KiB

#include "vger.c"
int
main(int argc, char **argv)
{
char request[GEMINI_REQUEST_MAX] = {'\0'};
char user[_SC_LOGIN_NAME_MAX] = {'\0'};
char hostname[GEMINI_REQUEST_MAX] = {'\0'};
char path[GEMINI_REQUEST_MAX] = {'\0'};
char query[GEMINI_REQUEST_MAX] = {'\0'};
char cgi_dir[PATH_MAX] = {'\0'};
char rel_cgi_dir[PATH_MAX] = {'\0'};
char chroot_dir[PATH_MAX] = DEFAULT_CHROOT;
char tmp[PATH_MAX] = {'\0'};
int option = 0;
int virtualhost = 0;
/*
* request : contain the whole request from client : gemini://...\r\n
* user : username, used in drop_privileges()
* hostname : extracted from hostname. used with virtualhosts and cgi SERVER_NAME
* query : after a ? in cgi : gemini://...?query
*/
while ((option = getopt(argc, argv, ":d:l:m:u:c:vi")) != -1) {
switch (option) {
case 'd':
esnprintf(chroot_dir, sizeof(chroot_dir), "%s", optarg);
break;
case 'l':
esnprintf(lang, sizeof(lang), "lang=%s", optarg);
break;
case 'm':
esnprintf(default_mime, sizeof(default_mime), "%s", optarg);
break;
case 'u':
esnprintf(user, sizeof(user), "%s", optarg);
break;
case 'c':
esnprintf(rel_cgi_dir, sizeof(rel_cgi_dir), "%s", optarg);
/* remove leading / */
while (*rel_cgi_dir == '/')
memmove(rel_cgi_dir, rel_cgi_dir+1,
strlen(rel_cgi_dir)); // strlen +1-1
break;
case 'v':
virtualhost = 1;
break;
case 'i':
doautoidx = 1;
break;
}
}
read_request(request);
split_request(request, hostname, path, query);
/* do chroot if an user is supplied */
if (*user)
drop_privileges(user);
/* set actual chroot_dir */
if (virtualhost) {
esnprintf(tmp, sizeof(tmp), "%s/%s", chroot_dir, hostname);
esnprintf(chroot_dir, sizeof(chroot_dir), "%s", tmp);
}
/* cgi_dir is in chroot_dir */
if (*rel_cgi_dir)
esnprintf(cgi_dir, sizeof(cgi_dir),
"%s/%s", chroot_dir, rel_cgi_dir);
set_rootdir(chroot_dir, cgi_dir, user);
if (strlen(path) == 0) { /* this is root dir */
esnprintf(path, sizeof(path), "./");
} else {
uridecode(path);
remove_double_dot(path);
}
uridecode(query);
/* is it cgi ? */
if (*cgi_dir)
if (do_cgi(rel_cgi_dir, path, hostname, query) == 0)
stop(EXIT_SUCCESS, NULL);
/* *** from here, cgi didn't run *** */
/* check if path available */
check_path(path, sizeof(path));
/* regular file to stdout */
display_file(path);
stop(EXIT_SUCCESS, NULL);
}