1
0
mirror of https://github.com/gophernicus/gophernicus.git synced 2024-12-04 14:46:37 -05:00

change indentation from tabs to spaces

This commit is contained in:
fosslinux 2019-08-03 18:30:05 +10:00
parent b0f8d60f93
commit b25c484c92
9 changed files with 2110 additions and 2121 deletions

81
bin2c.c
View File

@ -38,58 +38,57 @@
int main(int argc, char *argv[])
{
FILE *fp;
char *source = NULL;
char *name = NULL;
int first = 1;
int zero = 0;
int c;
int i;
FILE *fp;
char *source = NULL;
char *name = NULL;
int first = 1;
int zero = 0;
int c;
int i;
/* Parse args */
/* Parse args */
while ((c = getopt(argc, argv, "n:0")) != -1) {
switch(c) {
case 'n': name = optarg; break;
case '0': zero = 1; break;
case 'n': name = optarg; break;
case '0': zero = 1; break;
}
}
source = argv[optind];
if (!name) name = source;
source = argv[optind];
if (!name) name = source;
/* Check args */
if (!source) {
fprintf(stderr, "Usage: %s [-0] [-n <name>] <source>\n", argv[0]);
return 1;
}
/* Check args */
if (!source) {
fprintf(stderr, "Usage: %s [-0] [-n <name>] <source>\n", argv[0]);
return 1;
}
/* Try to open the source file */
if ((fp = fopen(source, "r")) == NULL) {
perror("Couldn't open source file");
return 1;
}
/* Try to open the source file */
if ((fp = fopen(source, "r")) == NULL) {
perror("Couldn't open source file");
return 1;
}
/* Convert */
printf("/* Automatically generated from %s */\n\n"
"#define %s { \\\n", source, name);
/* Convert */
printf("/* Automatically generated from %s */\n\n"
"#define %s { \\\n", source, name);
do {
for (i = 0; i < 16; i++) {
if ((c = fgetc(fp)) == EOF) {
if (zero--) c = '\0';
else break;
}
do {
for (i = 0; i < 16; i++) {
if ((c = fgetc(fp)) == EOF) {
if (zero--) c = '\0';
else break;
}
if (i == 0 && !first) printf(", \\\n");
if (i > 0) printf(", ");
if (i == 0 && !first) printf(", \\\n");
if (i > 0) printf(", ");
printf("0x%02x", c);
first = 0;
}
} while (c != EOF);
printf("0x%02x", c);
first = 0;
}
} while (c != EOF);
printf("}\n\n");
fclose(fp);
return 0;
printf("}\n\n");
fclose(fp);
return 0;
}

550
file.c
View File

@ -35,29 +35,29 @@
*/
void send_binary_file(state *st)
{
/* Faster sendfile() version */
/* Faster sendfile() version */
#ifdef HAVE_SENDFILE
int fd;
off_t offset = 0;
int fd;
off_t offset = 0;
if (st->debug) syslog(LOG_INFO, "outputting binary file \"%s\"", st->req_realpath);
if (st->debug) syslog(LOG_INFO, "outputting binary file \"%s\"", st->req_realpath);
if ((fd = open(st->req_realpath, O_RDONLY)) == ERROR) return;
sendfile(1, fd, &offset, st->req_filesize);
close(fd);
if ((fd = open(st->req_realpath, O_RDONLY)) == ERROR) return;
sendfile(1, fd, &offset, st->req_filesize);
close(fd);
/* More compatible POSIX fread()/fwrite() version */
/* More compatible POSIX fread()/fwrite() version */
#else
FILE *fp;
char buf[BUFSIZE];
int bytes;
FILE *fp;
char buf[BUFSIZE];
int bytes;
if (st->debug) syslog(LOG_INFO, "outputting binary file \"%s\"", st->req_realpath);
if (st->debug) syslog(LOG_INFO, "outputting binary file \"%s\"", st->req_realpath);
if ((fp = fopen(st->req_realpath , "r")) == NULL) return;
while ((bytes = fread(buf, 1, sizeof(buf), fp)) > 0)
fwrite(buf, bytes, 1, stdout);
fclose(fp);
if ((fp = fopen(st->req_realpath , "r")) == NULL) return;
while ((bytes = fread(buf, 1, sizeof(buf), fp)) > 0)
fwrite(buf, bytes, 1, stdout);
fclose(fp);
#endif
}
@ -67,37 +67,37 @@ void send_binary_file(state *st)
*/
void send_text_file(state *st)
{
FILE *fp;
char in[BUFSIZE];
char out[BUFSIZE];
int line;
FILE *fp;
char in[BUFSIZE];
char out[BUFSIZE];
int line;
if (st->debug) syslog(LOG_INFO, "outputting text file \"%s\"", st->req_realpath);
if ((fp = fopen(st->req_realpath , "r")) == NULL) return;
if (st->debug) syslog(LOG_INFO, "outputting text file \"%s\"", st->req_realpath);
if ((fp = fopen(st->req_realpath , "r")) == NULL) return;
/* Loop through the file line by line */
line = 0;
/* Loop through the file line by line */
line = 0;
while (fgets(in, sizeof(in), fp)) {
while (fgets(in, sizeof(in), fp)) {
/* Covert to output charset & print */
if (st->opt_iconv) sstrniconv(st->out_charset, out, in);
else sstrlcpy(out, in);
/* Covert to output charset & print */
if (st->opt_iconv) sstrniconv(st->out_charset, out, in);
else sstrlcpy(out, in);
chomp(out);
chomp(out);
#ifdef ENABLE_STRICT_RFC1436
if (strcmp(out, ".") == MATCH) printf(".." CRLF);
else
if (strcmp(out, ".") == MATCH) printf(".." CRLF);
else
#endif
printf("%s" CRLF, out);
line++;
}
printf("%s" CRLF, out);
line++;
}
#ifdef ENABLE_STRICT_RFC1436
printf("." CRLF);
printf("." CRLF);
#endif
fclose(fp);
fclose(fp);
}
@ -106,40 +106,40 @@ void send_text_file(state *st)
*/
void url_redirect(state *st)
{
char dest[BUFSIZE];
char dest[BUFSIZE];
/* Basic security checking */
sstrlcpy(dest, st->req_selector + 4);
/* Basic security checking */
sstrlcpy(dest, st->req_selector + 4);
if (sstrncmp(dest, "http://") != MATCH &&
sstrncmp(dest, "https://") != MATCH &&
sstrncmp(dest, "ftp://") != MATCH &&
sstrncmp(dest, "irc://") != MATCH &&
sstrncmp(dest, "mailto:") != MATCH)
die(st, ERR_ACCESS, "Refusing to HTTP redirect unsafe protocols");
if (sstrncmp(dest, "http://") != MATCH &&
sstrncmp(dest, "https://") != MATCH &&
sstrncmp(dest, "ftp://") != MATCH &&
sstrncmp(dest, "irc://") != MATCH &&
sstrncmp(dest, "mailto:") != MATCH)
die(st, ERR_ACCESS, "Refusing to HTTP redirect unsafe protocols");
/* Log the redirect */
if (st->opt_syslog) {
syslog(LOG_INFO, "request for \"gopher%s://%s:%i/h%s\" from %s",
(st->server_port == st->server_tls_port ? "s" : ""),
st->server_host,
st->server_port,
st->req_selector,
st->req_remote_addr);
}
log_combined(st, HTTP_OK);
/* Log the redirect */
if (st->opt_syslog) {
syslog(LOG_INFO, "request for \"gopher%s://%s:%i/h%s\" from %s",
(st->server_port == st->server_tls_port ? "s" : ""),
st->server_host,
st->server_port,
st->req_selector,
st->req_remote_addr);
}
log_combined(st, HTTP_OK);
/* Output HTML */
printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n"
"<HTML>\n<HEAD>\n"
" <META HTTP-EQUIV=\"Refresh\" content=\"1;URL=%1$s\">\n"
" <META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html;charset=iso-8859-1\">\n"
" <TITLE>URL Redirect page</TITLE>\n"
"</HEAD>\n<BODY>\n"
"<STRONG>Redirecting to <A HREF=\"%1$s\">%1$s</A></STRONG>\n"
"<PRE>\n", dest);
footer(st);
printf("</PRE>\n</BODY>\n</HTML>\n");
/* Output HTML */
printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n"
"<HTML>\n<HEAD>\n"
" <META HTTP-EQUIV=\"Refresh\" content=\"1;URL=%1$s\">\n"
" <META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html;charset=iso-8859-1\">\n"
" <TITLE>URL Redirect page</TITLE>\n"
"</HEAD>\n<BODY>\n"
"<STRONG>Redirecting to <A HREF=\"%1$s\">%1$s</A></STRONG>\n"
"<PRE>\n", dest);
footer(st);
printf("</PRE>\n</BODY>\n</HTML>\n");
}
@ -149,78 +149,78 @@ void url_redirect(state *st)
#ifdef HAVE_SHMEM
void server_status(state *st, shm_state *shm, int shmid)
{
struct shmid_ds shm_ds;
time_t now;
time_t uptime;
int sessions;
int i;
struct shmid_ds shm_ds;
time_t now;
time_t uptime;
int sessions;
int i;
/* Log the request */
if (st->opt_syslog) {
syslog(LOG_INFO, "request for \"gopher%s://%s:%i/0" SERVER_STATUS "\" from %s",
(st->server_port == st->server_tls_port ? "s" : ""),
st->server_host,
st->server_port,
st->req_remote_addr);
}
log_combined(st, HTTP_OK);
/* Log the request */
if (st->opt_syslog) {
syslog(LOG_INFO, "request for \"gopher%s://%s:%i/0" SERVER_STATUS "\" from %s",
(st->server_port == st->server_tls_port ? "s" : ""),
st->server_host,
st->server_port,
st->req_remote_addr);
}
log_combined(st, HTTP_OK);
/* Quit if shared memory isn't initialized yet */
if (!shm) return;
/* Quit if shared memory isn't initialized yet */
if (!shm) return;
/* Update counters */
shm->hits++;
shm->kbytes += 1;
/* Update counters */
shm->hits++;
shm->kbytes += 1;
/* Get server uptime */
now = time(NULL);
uptime = (now - shm->start_time) + 1;
/* Get server uptime */
now = time(NULL);
uptime = (now - shm->start_time) + 1;
/* Get shared memory info */
shmctl(shmid, IPC_STAT, &shm_ds);
/* Get shared memory info */
shmctl(shmid, IPC_STAT, &shm_ds);
/* Print statistics */
printf("Total Accesses: %li" CRLF
"Total kBytes: %li" CRLF
"Uptime: %i" CRLF
"ReqPerSec: %.3f" CRLF
"BytesPerSec: %li" CRLF
"BytesPerReq: %li" CRLF
"BusyServers: %i" CRLF
"IdleServers: 0" CRLF
"CPULoad: %.2f" CRLF,
shm->hits,
shm->kbytes,
(int) uptime,
(float) shm->hits / (float) uptime,
shm->kbytes * 1024 / (int) uptime,
shm->kbytes * 1024 / (shm->hits + 1),
(int) shm_ds.shm_nattch,
loadavg());
/* Print statistics */
printf("Total Accesses: %li" CRLF
"Total kBytes: %li" CRLF
"Uptime: %i" CRLF
"ReqPerSec: %.3f" CRLF
"BytesPerSec: %li" CRLF
"BytesPerReq: %li" CRLF
"BusyServers: %i" CRLF
"IdleServers: 0" CRLF
"CPULoad: %.2f" CRLF,
shm->hits,
shm->kbytes,
(int) uptime,
(float) shm->hits / (float) uptime,
shm->kbytes * 1024 / (int) uptime,
shm->kbytes * 1024 / (shm->hits + 1),
(int) shm_ds.shm_nattch,
loadavg());
/* Print active sessions */
sessions = 0;
/* Print active sessions */
sessions = 0;
for (i = 0; i < SHM_SESSIONS; i++) {
if ((now - shm->session[i].req_atime) < st->session_timeout) {
sessions++;
for (i = 0; i < SHM_SESSIONS; i++) {
if ((now - shm->session[i].req_atime) < st->session_timeout) {
sessions++;
if (st->debug) {
printf("Session: %-4i %-40s %-4li %-7li gopher%s://%s:%i/%c%s" CRLF,
(int) (now - shm->session[i].req_atime),
shm->session[i].req_remote_addr,
shm->session[i].hits,
shm->session[i].kbytes,
(shm->session[i].server_port == st->server_tls_port ? "s" : ""),
shm->session[i].server_host,
shm->session[i].server_port,
shm->session[i].req_filetype,
shm->session[i].req_selector);
}
}
}
if (st->debug) {
printf("Session: %-4i %-40s %-4li %-7li gopher%s://%s:%i/%c%s" CRLF,
(int) (now - shm->session[i].req_atime),
shm->session[i].req_remote_addr,
shm->session[i].hits,
shm->session[i].kbytes,
(shm->session[i].server_port == st->server_tls_port ? "s" : ""),
shm->session[i].server_host,
shm->session[i].server_port,
shm->session[i].req_filetype,
shm->session[i].req_selector);
}
}
}
printf("Total Sessions: %i" CRLF, sessions);
printf("Total Sessions: %i" CRLF, sessions);
}
#endif
@ -230,62 +230,62 @@ void server_status(state *st, shm_state *shm, int shmid)
*/
void caps_txt(state *st, shm_state *shm)
{
/* Log the request */
if (st->opt_syslog) {
syslog(LOG_INFO, "request for \"gopher%s://%s:%i/0" CAPS_TXT "\" from %s",
(st->server_port == st->server_tls_port ? "s" : ""),
st->server_host,
st->server_port,
st->req_remote_addr);
}
log_combined(st, HTTP_OK);
/* Log the request */
if (st->opt_syslog) {
syslog(LOG_INFO, "request for \"gopher%s://%s:%i/0" CAPS_TXT "\" from %s",
(st->server_port == st->server_tls_port ? "s" : ""),
st->server_host,
st->server_port,
st->req_remote_addr);
}
log_combined(st, HTTP_OK);
/* Update counters */
/* Update counters */
#ifdef HAVE_SHMEM
if (shm) {
shm->hits++;
shm->kbytes += 1;
if (shm) {
shm->hits++;
shm->kbytes += 1;
/* Update session data */
st->req_filesize += 1024;
update_shm_session(st, shm);
}
/* Update session data */
st->req_filesize += 1024;
update_shm_session(st, shm);
}
#endif
/* Standard caps.txt stuff */
printf("CAPS" CRLF
CRLF
"##" CRLF
"## This is an automatically generated caps file." CRLF
"##" CRLF
CRLF
"CapsVersion=1" CRLF
"ExpireCapsAfter=%i" CRLF
CRLF
"PathDelimeter=/" CRLF
"PathIdentity=." CRLF
"PathParent=.." CRLF
"PathParentDouble=FALSE" CRLF
"PathKeepPreDelimeter=FALSE" CRLF
"ServerSupportsStdinScripts=TRUE" CRLF
"ServerDefaultEncoding=%s" CRLF
"ServerTLSPort=%i" CRLF
CRLF
"ServerSoftware=" SERVER_SOFTWARE CRLF
"ServerSoftwareVersion=" VERSION " \"" CODENAME "\"" CRLF
"ServerArchitecture=%s" CRLF,
st->session_timeout,
strcharset(st->out_charset),
st->server_tls_port,
st->server_platform);
/* Standard caps.txt stuff */
printf("CAPS" CRLF
CRLF
"##" CRLF
"## This is an automatically generated caps file." CRLF
"##" CRLF
CRLF
"CapsVersion=1" CRLF
"ExpireCapsAfter=%i" CRLF
CRLF
"PathDelimeter=/" CRLF
"PathIdentity=." CRLF
"PathParent=.." CRLF
"PathParentDouble=FALSE" CRLF
"PathKeepPreDelimeter=FALSE" CRLF
"ServerSupportsStdinScripts=TRUE" CRLF
"ServerDefaultEncoding=%s" CRLF
"ServerTLSPort=%i" CRLF
CRLF
"ServerSoftware=" SERVER_SOFTWARE CRLF
"ServerSoftwareVersion=" VERSION " \"" CODENAME "\"" CRLF
"ServerArchitecture=%s" CRLF,
st->session_timeout,
strcharset(st->out_charset),
st->server_tls_port,
st->server_platform);
/* Optional keys */
if (*st->server_description)
printf("ServerDescription=%s" CRLF, st->server_description);
if (*st->server_location)
printf("ServerGeolocationString=%s" CRLF, st->server_location);
if (*st->server_admin)
printf("ServerAdmin=%s" CRLF, st->server_admin);
/* Optional keys */
if (*st->server_description)
printf("ServerDescription=%s" CRLF, st->server_description);
if (*st->server_location)
printf("ServerGeolocationString=%s" CRLF, st->server_location);
if (*st->server_admin)
printf("ServerAdmin=%s" CRLF, st->server_admin);
}
@ -294,71 +294,71 @@ void caps_txt(state *st, shm_state *shm)
*/
void setenv_cgi(state *st, char *script)
{
char buf[BUFSIZE];
char buf[BUFSIZE];
/* Security */
setenv("PATH", SAFE_PATH, 1);
/* Security */
setenv("PATH", SAFE_PATH, 1);
/* Set up the environment as per CGI spec */
setenv("GATEWAY_INTERFACE", "CGI/1.1", 1);
setenv("CONTENT_LENGTH", "0", 1);
setenv("QUERY_STRING", st->req_query_string, 1);
snprintf(buf, sizeof(buf), SERVER_SOFTWARE_FULL, st->server_platform);
setenv("SERVER_SOFTWARE", buf, 1);
setenv("SERVER_ARCH", st->server_platform, 1);
setenv("SERVER_DESCRIPTION", st->server_description, 1);
snprintf(buf, sizeof(buf), SERVER_SOFTWARE "/" VERSION);
setenv("SERVER_VERSION", buf, 1);
/* Set up the environment as per CGI spec */
setenv("GATEWAY_INTERFACE", "CGI/1.1", 1);
setenv("CONTENT_LENGTH", "0", 1);
setenv("QUERY_STRING", st->req_query_string, 1);
snprintf(buf, sizeof(buf), SERVER_SOFTWARE_FULL, st->server_platform);
setenv("SERVER_SOFTWARE", buf, 1);
setenv("SERVER_ARCH", st->server_platform, 1);
setenv("SERVER_DESCRIPTION", st->server_description, 1);
snprintf(buf, sizeof(buf), SERVER_SOFTWARE "/" VERSION);
setenv("SERVER_VERSION", buf, 1);
if (st->req_protocol == PROTO_HTTP)
setenv("SERVER_PROTOCOL", "HTTP/0.9", 1);
else
setenv("SERVER_PROTOCOL", "RFC1436", 1);
if (st->req_protocol == PROTO_HTTP)
setenv("SERVER_PROTOCOL", "HTTP/0.9", 1);
else
setenv("SERVER_PROTOCOL", "RFC1436", 1);
if (st->server_port == st->server_tls_port) {
setenv("HTTPS", "on", 1);
setenv("TLS", "on", 1);
}
if (st->server_port == st->server_tls_port) {
setenv("HTTPS", "on", 1);
setenv("TLS", "on", 1);
}
setenv("SERVER_NAME", st->server_host, 1);
snprintf(buf, sizeof(buf), "%i", st->server_port);
setenv("SERVER_PORT", buf, 1);
snprintf(buf, sizeof(buf), "%i", st->server_tls_port);
setenv("SERVER_TLS_PORT", buf, 1);
setenv("REQUEST_METHOD", "GET", 1);
setenv("DOCUMENT_ROOT", st->server_root, 1);
setenv("SCRIPT_NAME", st->req_selector, 1);
setenv("SCRIPT_FILENAME", script, 1);
setenv("LOCAL_ADDR", st->req_local_addr, 1);
setenv("REMOTE_ADDR", st->req_remote_addr, 1);
setenv("HTTP_REFERER", st->req_referrer, 1);
setenv("SERVER_NAME", st->server_host, 1);
snprintf(buf, sizeof(buf), "%i", st->server_port);
setenv("SERVER_PORT", buf, 1);
snprintf(buf, sizeof(buf), "%i", st->server_tls_port);
setenv("SERVER_TLS_PORT", buf, 1);
setenv("REQUEST_METHOD", "GET", 1);
setenv("DOCUMENT_ROOT", st->server_root, 1);
setenv("SCRIPT_NAME", st->req_selector, 1);
setenv("SCRIPT_FILENAME", script, 1);
setenv("LOCAL_ADDR", st->req_local_addr, 1);
setenv("REMOTE_ADDR", st->req_remote_addr, 1);
setenv("HTTP_REFERER", st->req_referrer, 1);
#ifdef HAVE_SHMEM
snprintf(buf, sizeof(buf), "%x", st->session_id);
setenv("SESSION_ID", buf, 1);
snprintf(buf, sizeof(buf), "%x", st->session_id);
setenv("SESSION_ID", buf, 1);
#endif
setenv("HTTP_ACCEPT_CHARSET", strcharset(st->out_charset), 1);
setenv("HTTP_ACCEPT_CHARSET", strcharset(st->out_charset), 1);
/* Gophernicus extras */
snprintf(buf, sizeof(buf), "%c", st->req_filetype);
setenv("GOPHER_FILETYPE", buf, 1);
setenv("GOPHER_CHARSET", strcharset(st->out_charset), 1);
setenv("GOPHER_REFERER", st->req_referrer, 1);
snprintf(buf, sizeof(buf), "%i", st->out_width);
setenv("COLUMNS", buf, 1);
snprintf(buf, sizeof(buf), CODENAME);
setenv("SERVER_CODENAME", buf, 1);
/* Gophernicus extras */
snprintf(buf, sizeof(buf), "%c", st->req_filetype);
setenv("GOPHER_FILETYPE", buf, 1);
setenv("GOPHER_CHARSET", strcharset(st->out_charset), 1);
setenv("GOPHER_REFERER", st->req_referrer, 1);
snprintf(buf, sizeof(buf), "%i", st->out_width);
setenv("COLUMNS", buf, 1);
snprintf(buf, sizeof(buf), CODENAME);
setenv("SERVER_CODENAME", buf, 1);
/* Bucktooth extras */
if (*st->req_query_string) {
snprintf(buf, sizeof(buf), "%s?%s",
st->req_selector, st->req_query_string);
setenv("SELECTOR", buf, 1);
}
else setenv("SELECTOR", st->req_selector, 1);
/* Bucktooth extras */
if (*st->req_query_string) {
snprintf(buf, sizeof(buf), "%s?%s",
st->req_selector, st->req_query_string);
setenv("SELECTOR", buf, 1);
}
else setenv("SELECTOR", st->req_selector, 1);
setenv("SERVER_HOST", st->server_host, 1);
setenv("REQUEST", st->req_selector, 1);
setenv("SEARCHREQUEST", st->req_search, 1);
setenv("SERVER_HOST", st->server_host, 1);
setenv("REQUEST", st->req_selector, 1);
setenv("SEARCHREQUEST", st->req_search, 1);
}
@ -367,18 +367,18 @@ void setenv_cgi(state *st, char *script)
*/
void run_cgi(state *st, char *script, char *arg)
{
if (st->opt_exec) {
if (st->opt_exec) {
/* Setup environment & execute the binary */
if (st->debug) syslog(LOG_INFO, "executing script \"%s\"", script);
/* Setup environment & execute the binary */
if (st->debug) syslog(LOG_INFO, "executing script \"%s\"", script);
setenv_cgi(st, script);
execl(script, script, arg, NULL);
}
else if (st->debug) syslog(LOG_INFO, "script \"%s\" was blocked by -nx", script);
setenv_cgi(st, script);
execl(script, script, arg, NULL);
}
else if (st->debug) syslog(LOG_INFO, "script \"%s\" was blocked by -nx", script);
/* Didn't work - die */
die(st, ERR_ACCESS, NULL);
/* Didn't work - die */
die(st, ERR_ACCESS, NULL);
}
@ -387,46 +387,44 @@ void run_cgi(state *st, char *script, char *arg)
*/
void gopher_file(state *st)
{
struct stat file;
char buf[BUFSIZE];
char *c;
struct stat file;
char buf[BUFSIZE];
char *c;
/* Refuse to serve out gophermaps/tags */
if ((c = strrchr(st->req_realpath, '/'))) c++;
else c = st->req_realpath;
/* Refuse to serve out gophermaps/tags */
if ((c = strrchr(st->req_realpath, '/'))) c++;
else c = st->req_realpath;
if (strcmp(c, st->map_file) == MATCH)
die(st, ERR_ACCESS, "Refusing to serve out a gophermap file");
if (strcmp(c, st->tag_file) == MATCH)
die(st, ERR_ACCESS, "Refusing to serve out a gophertag file");
if (strcmp(c, st->map_file) == MATCH)
die(st, ERR_ACCESS, "Refusing to serve out a gophermap file");
if (strcmp(c, st->tag_file) == MATCH)
die(st, ERR_ACCESS, "Refusing to serve out a gophertag file");
/* Check for & run CGI and query scripts */
if (strstr(st->req_realpath, st->cgi_file) || st->req_filetype == TYPE_QUERY)
run_cgi(st, st->req_realpath, NULL);
/* Check for & run CGI and query scripts */
if (strstr(st->req_realpath, st->cgi_file) || st->req_filetype == TYPE_QUERY)
run_cgi(st, st->req_realpath, NULL);
/* Check for a file suffix filter */
if (*st->filter_dir && (c = strrchr(st->req_realpath, '.'))) {
snprintf(buf, sizeof(buf), "%s/%s", st->filter_dir, c + 1);
/* Check for a file suffix filter */
if (*st->filter_dir && (c = strrchr(st->req_realpath, '.'))) {
snprintf(buf, sizeof(buf), "%s/%s", st->filter_dir, c + 1);
/* Filter file through the script */
if (stat(buf, &file) == OK && (file.st_mode & S_IXOTH))
run_cgi(st, buf, st->req_realpath);
}
/* Filter file through the script */
if (stat(buf, &file) == OK && (file.st_mode & S_IXOTH))
run_cgi(st, buf, st->req_realpath);
}
/* Check for a filetype filter */
if (*st->filter_dir) {
snprintf(buf, sizeof(buf), "%s/%c", st->filter_dir, st->req_filetype);
/* Check for a filetype filter */
if (*st->filter_dir) {
snprintf(buf, sizeof(buf), "%s/%c", st->filter_dir, st->req_filetype);
/* Filter file through the script */
if (stat(buf, &file) == OK && (file.st_mode & S_IXOTH))
run_cgi(st, buf, st->req_realpath);
}
/* Filter file through the script */
if (stat(buf, &file) == OK && (file.st_mode & S_IXOTH))
run_cgi(st, buf, st->req_realpath);
}
/* Output regular files */
if (st->req_filetype == TYPE_TEXT || st->req_filetype == TYPE_MIME)
send_text_file(st);
else
send_binary_file(st);
/* Output regular files */
if (st->req_filetype == TYPE_TEXT || st->req_filetype == TYPE_MIME)
send_text_file(st);
else
send_binary_file(st);
}

File diff suppressed because it is too large Load Diff

View File

@ -41,9 +41,9 @@
/*
* Features
*/
#undef ENABLE_STRICT_RFC1436 /* Follow RFC1436 to the letter */
#undef ENABLE_AUTOHIDING /* Hide manually listed resources from generated menus */
#define ENABLE_HAPROXY1 /* Autodetect HAproxy/Stunnel proxy protocol v1 */
#undef ENABLE_STRICT_RFC1436 /* Follow RFC1436 to the letter */
#undef ENABLE_AUTOHIDING /* Hide manually listed resources from generated menus */
#define ENABLE_HAPROXY1 /* Autodetect HAproxy/Stunnel proxy protocol v1 */
/*
@ -51,17 +51,17 @@
*/
/* Defaults should fit standard POSIX systems */
#define HAVE_IPv4 /* IPv4 should work anywhere */
#define HAVE_IPv6 /* Requires modern POSIX */
#define HAVE_PASSWD /* For systems with passwd-like userdb */
#define PASSWD_MIN_UID 100 /* Minimum allowed UID for ~userdirs */
#define HAVE_LOCALES /* setlocale() and friends */
#define HAVE_SHMEM /* Shared memory support */
#define HAVE_UNAME /* uname() */
#define HAVE_POPEN /* popen() */
#undef HAVE_STRLCPY /* strlcpy() from OpenBSD */
#undef HAVE_SENDFILE /* sendfile() in Linux & others */
/* #undef HAVE_LIBWRAP autodetected, don't enable here */
#define HAVE_IPv4 /* IPv4 should work anywhere */
#define HAVE_IPv6 /* Requires modern POSIX */
#define HAVE_PASSWD /* For systems with passwd-like userdb */
#define PASSWD_MIN_UID 100 /* Minimum allowed UID for ~userdirs */
#define HAVE_LOCALES /* setlocale() and friends */
#define HAVE_SHMEM /* Shared memory support */
#define HAVE_UNAME /* uname() */
#define HAVE_POPEN /* popen() */
#undef HAVE_STRLCPY /* strlcpy() from OpenBSD */
#undef HAVE_SENDFILE /* sendfile() in Linux & others */
/* #undef HAVE_LIBWRAP autodetected, don't enable here */
/* Linux */
#ifdef __linux
@ -158,278 +158,278 @@ size_t strlcat(char *dst, const char *src, size_t siz);
*/
/* Common stuff */
#define CRLF "\r\n"
#define EMPTY ""
#define PARENT ".."
#define ROOT "/"
#define CRLF "\r\n"
#define EMPTY ""
#define PARENT ".."
#define ROOT "/"
#define FALSE 0
#define TRUE 1
#define FALSE 0
#define TRUE 1
#define QUIT 1
#define OK 0
#define ERROR -1
#define QUIT 1
#define OK 0
#define ERROR -1
#define MATCH 0
#define WRAP_DENIED 0
#define MATCH 0
#define WRAP_DENIED 0
/* Gopher filetypes */
#define TYPE_TEXT '0'
#define TYPE_MENU '1'
#define TYPE_ERROR '3'
#define TYPE_GZIP '5'
#define TYPE_QUERY '7'
#define TYPE_BINARY '9'
#define TYPE_GIF 'g'
#define TYPE_HTML 'h'
#define TYPE_INFO 'i'
#define TYPE_IMAGE 'I'
#define TYPE_MIME 'M'
#define TYPE_DOC 'd'
#define TYPE_TITLE '!'
#define TYPE_TEXT '0'
#define TYPE_MENU '1'
#define TYPE_ERROR '3'
#define TYPE_GZIP '5'
#define TYPE_QUERY '7'
#define TYPE_BINARY '9'
#define TYPE_GIF 'g'
#define TYPE_HTML 'h'
#define TYPE_INFO 'i'
#define TYPE_IMAGE 'I'
#define TYPE_MIME 'M'
#define TYPE_DOC 'd'
#define TYPE_TITLE '!'
/* Protocols */
#define PROTO_GOPHER 'g'
#define PROTO_HTTP 'h'
#define PROTO_GOPHER 'g'
#define PROTO_HTTP 'h'
/* Charsets */
#define AUTO 0
#define US_ASCII 1
#define ISO_8859_1 2
#define UTF_8 3
#define AUTO 0
#define US_ASCII 1
#define ISO_8859_1 2
#define UTF_8 3
/* HTTP protocol stuff for logging */
#define HTTP_OK 200
#define HTTP_404 404
#define HTTP_DATE "%d/%b/%Y:%T %z"
#define HTTP_USERAGENT "Unknown gopher client"
#define HTTP_OK 200
#define HTTP_404 404
#define HTTP_DATE "%d/%b/%Y:%T %z"
#define HTTP_USERAGENT "Unknown gopher client"
/* Defaults for settings */
#define DEFAULT_HOST "localhost"
#define DEFAULT_PORT 70
#define DEFAULT_TLS_PORT 0
#define DEFAULT_TYPE TYPE_TEXT
#define DEFAULT_MAP "gophermap"
#define DEFAULT_TAG "gophertag"
#define DEFAULT_CGI "/cgi-bin/"
#define DEFAULT_USERDIR "public_gopher"
#define DEFAULT_WIDTH 76
#define DEFAULT_CHARSET US_ASCII
#define MIN_WIDTH 33
#define MAX_WIDTH 200
#define UNKNOWN_ADDR "unknown"
#define DEFAULT_HOST "localhost"
#define DEFAULT_PORT 70
#define DEFAULT_TLS_PORT 0
#define DEFAULT_TYPE TYPE_TEXT
#define DEFAULT_MAP "gophermap"
#define DEFAULT_TAG "gophertag"
#define DEFAULT_CGI "/cgi-bin/"
#define DEFAULT_USERDIR "public_gopher"
#define DEFAULT_WIDTH 76
#define DEFAULT_CHARSET US_ASCII
#define MIN_WIDTH 33
#define MAX_WIDTH 200
#define UNKNOWN_ADDR "unknown"
/* Session defaults */
#define DEFAULT_SESSION_TIMEOUT 1800
#define DEFAULT_SESSION_MAX_KBYTES 4194304
#define DEFAULT_SESSION_MAX_HITS 4096
#define DEFAULT_SESSION_TIMEOUT 1800
#define DEFAULT_SESSION_MAX_KBYTES 4194304
#define DEFAULT_SESSION_MAX_HITS 4096
/* Dummy values for gopher protocol */
#define DUMMY_SELECTOR "null"
#define DUMMY_HOST "null.host\t1"
#define DUMMY_SELECTOR "null"
#define DUMMY_HOST "null.host\t1"
/* Safe $PATH for exec() */
#ifdef __HAIKU__
#define SAFE_PATH "/boot/common/bin:/bin"
#define SAFE_PATH "/boot/common/bin:/bin"
#else
#define SAFE_PATH "/usr/bin:/bin"
#define SAFE_PATH "/usr/bin:/bin"
#endif
/* Special requests */
#define SERVER_STATUS "/server-status"
#define CAPS_TXT "/caps.txt"
#define SERVER_STATUS "/server-status"
#define CAPS_TXT "/caps.txt"
/* Error messages */
#define ERR_ACCESS "Access denied!"
#define ERR_NOTFOUND "File or directory not found!"
#define ERR_ACCESS "Access denied!"
#define ERR_NOTFOUND "File or directory not found!"
#define ERROR_HOST "error.host\t1"
#define ERROR_PREFIX "Error: "
#define ERROR_HOST "error.host\t1"
#define ERROR_PREFIX "Error: "
/* Strings */
#define SERVER_SOFTWARE "Gophernicus"
#define SERVER_SOFTWARE "Gophernicus"
#define SERVER_SOFTWARE_FULL SERVER_SOFTWARE "/" VERSION " (%s)"
#define HEADER_FORMAT "[%s]"
#define FOOTER_FORMAT "Gophered by Gophernicus/" VERSION " on %s"
#define HEADER_FORMAT "[%s]"
#define FOOTER_FORMAT "Gophered by Gophernicus/" VERSION " on %s"
#define UNITS "KB", "MB", "GB", "TB", "PB", NULL
#define DATE_FORMAT "%Y-%b-%d %H:%M" /* See man 3 strftime */
#define DATE_WIDTH 17
#define DATE_LOCALE "POSIX"
#define UNITS "KB", "MB", "GB", "TB", "PB", NULL
#define DATE_FORMAT "%Y-%b-%d %H:%M" /* See man 3 strftime */
#define DATE_WIDTH 17
#define DATE_LOCALE "POSIX"
#define USERDIR_FORMAT "~%s", pwd->pw_name /* See man 3 getpwent */
#define VHOST_FORMAT "gopher://%s/"
#define USERDIR_FORMAT "~%s", pwd->pw_name /* See man 3 getpwent */
#define VHOST_FORMAT "gopher://%s/"
/* ISO-8859-1 to US-ASCII look-alike conversion table */
#define ASCII \
"E?,f..++^%S<??Z?" \
"?''\"\"*--~?s>??zY" \
" !c_*Y|$\"C?<?-R-" \
"??23'u?*,1?>????" \
"AAAAAAACEEEEIIII" \
"DNOOOOO*OUUUUYTB" \
"aaaaaaaceeeeiiii" \
"dnooooo/ouuuuyty"
"E?,f..++^%S<??Z?" \
"?''\"\"*--~?s>??zY" \
" !c_*Y|$\"C?<?-R-" \
"??23'u?*,1?>????" \
"AAAAAAACEEEEIIII" \
"DNOOOOO*OUUUUYTB" \
"aaaaaaaceeeeiiii" \
"dnooooo/ouuuuyty"
#define UNKNOWN '?'
/* Sizes & maximums */
#define BUFSIZE 1024 /* Default size for string buffers */
#define MAX_HIDDEN 32 /* Maximum number of hidden files */
#define MAX_FILETYPES 128 /* Maximum number of suffix to filetype mappings */
#define MAX_FILTERS 16 /* Maximum number of file filters */
#define MAX_SDIRENT 1024 /* Maximum number of files per directory to handle */
#define MAX_REWRITE 32 /* Maximum number of selector rewrite options */
#define BUFSIZE 1024 /* Default size for string buffers */
#define MAX_HIDDEN 32 /* Maximum number of hidden files */
#define MAX_FILETYPES 128 /* Maximum number of suffix to filetype mappings */
#define MAX_FILTERS 16 /* Maximum number of file filters */
#define MAX_SDIRENT 1024 /* Maximum number of files per directory to handle */
#define MAX_REWRITE 32 /* Maximum number of selector rewrite options */
/* Struct for file suffix -> gopher filetype mapping */
typedef struct {
char suffix[15];
char type;
char suffix[15];
char type;
} ftype;
/* Struct for selector rewriting */
typedef struct {
char match[BUFSIZE];
char replace[BUFSIZE];
char match[BUFSIZE];
char replace[BUFSIZE];
} srewrite;
/* Struct for keeping the current options & state */
typedef struct {
/* Request */
char req_selector[BUFSIZE];
char req_realpath[BUFSIZE];
char req_query_string[BUFSIZE];
char req_search[BUFSIZE];
char req_referrer[BUFSIZE];
char req_local_addr[64];
char req_remote_addr[64];
char req_filetype;
char req_protocol;
off_t req_filesize;
/* Request */
char req_selector[BUFSIZE];
char req_realpath[BUFSIZE];
char req_query_string[BUFSIZE];
char req_search[BUFSIZE];
char req_referrer[BUFSIZE];
char req_local_addr[64];
char req_remote_addr[64];
char req_filetype;
char req_protocol;
off_t req_filesize;
/* Output */
int out_width;
int out_charset;
/* Output */
int out_width;
int out_charset;
/* Settings */
char server_description[64];
char server_location[64];
char server_platform[64];
char server_admin[64];
char server_root[256];
char server_host_default[64];
char server_host[64];
int server_port;
int server_tls_port;
/* Settings */
char server_description[64];
char server_location[64];
char server_platform[64];
char server_admin[64];
char server_root[256];
char server_host_default[64];
char server_host[64];
int server_port;
int server_tls_port;
char default_filetype;
char map_file[64];
char tag_file[64];
char cgi_file[64];
char user_dir[64];
char log_file[256];
char default_filetype;
char map_file[64];
char tag_file[64];
char cgi_file[64];
char user_dir[64];
char log_file[256];
char hidden[MAX_HIDDEN][256];
int hidden_count;
char hidden[MAX_HIDDEN][256];
int hidden_count;
ftype filetype[MAX_FILETYPES];
int filetype_count;
char filter_dir[64];
ftype filetype[MAX_FILETYPES];
int filetype_count;
char filter_dir[64];
srewrite rewrite[MAX_REWRITE];
int rewrite_count;
srewrite rewrite[MAX_REWRITE];
int rewrite_count;
/* Session */
int session_timeout;
int session_max_kbytes;
int session_max_hits;
int session_id;
/* Session */
int session_timeout;
int session_max_kbytes;
int session_max_hits;
int session_id;
/* Feature options */
char opt_parent;
char opt_header;
char opt_footer;
char opt_date;
char opt_syslog;
char opt_magic;
char opt_iconv;
char opt_vhost;
char opt_query;
char opt_caps;
char opt_status;
char opt_shm;
char opt_root;
char opt_proxy;
char opt_exec;
char opt_personal_spaces;
char debug;
/* Feature options */
char opt_parent;
char opt_header;
char opt_footer;
char opt_date;
char opt_syslog;
char opt_magic;
char opt_iconv;
char opt_vhost;
char opt_query;
char opt_caps;
char opt_status;
char opt_shm;
char opt_root;
char opt_proxy;
char opt_exec;
char opt_personal_spaces;
char debug;
} state;
/* Shared memory for session & accounting data */
#ifdef HAVE_SHMEM
#define SHM_KEY 0xbeeb0008 /* Unique identifier + struct version */
#define SHM_MODE 0600 /* Access mode for the shared memory */
#define SHM_SESSIONS 256 /* Max amount of user sessions to track */
#define SHM_KEY 0xbeeb0008 /* Unique identifier + struct version */
#define SHM_MODE 0600 /* Access mode for the shared memory */
#define SHM_SESSIONS 256 /* Max amount of user sessions to track */
typedef struct {
long hits;
long kbytes;
long hits;
long kbytes;
time_t req_atime;
char req_selector[128];
char req_remote_addr[64];
char req_filetype;
int session_id;
time_t req_atime;
char req_selector[128];
char req_remote_addr[64];
char req_filetype;
int session_id;
char server_host[64];
int server_port;
char server_host[64];
int server_port;
} shm_session;
typedef struct {
time_t start_time;
long hits;
long kbytes;
char server_platform[64];
char server_description[64];
shm_session session[SHM_SESSIONS];
time_t start_time;
long hits;
long kbytes;
char server_platform[64];
char server_description[64];
shm_session session[SHM_SESSIONS];
} shm_state;
#endif
/* Struct for directory sorting */
typedef struct {
char name[128]; /* Should be 256 but we're saving stack space */
mode_t mode;
uid_t uid;
gid_t gid;
off_t size;
time_t mtime;
char name[128]; /* Should be 256 but we're saving stack space */
mode_t mode;
uid_t uid;
gid_t gid;
off_t size;
time_t mtime;
} sdirent;
/* File suffix to gopher filetype mappings */
#define FILETYPES \
"txt","0","pl","0","py","0","sh","0","tcl","0","c","0","cpp","0", "h","0","log","0", \
"conf","0","php","0","php3","0", \
"map","1","menu","1", \
"hqx","4", \
"Z","5","gz","5","tgz","5","tar","5","zip","5","bz2","5","rar","5","sea","5", \
"q","7","qry","7", \
"iso","9","so","9","o","9","rtf","9","ttf","9","bin","9", \
"ics","c","ical","c", \
"gif","g", \
"html","h","htm","h","xhtml","h","css","h","swf","h","rdf","h","rss","h","xml","h", \
"jpg","I","jpeg","I","png","I","bmp","I","svg","I","tif","I","tiff","I", \
"ico","I","xbm","I","xpm","I","pcx","I", \
"mbox","M", \
"pdf","d","ps","d","doc","d","ppt","d","xls","d","xlsx","d","docx","d","pptx","d", \
"mp3","s","wav","s","mid","s","wma","s","flac","s","ogg","s","aiff","s","aac","s", \
"avi",";","mp4",";","mpg",";","mov",";","qt",";","asf",";","mpv",";","m4v",";","webm",";","ogv",";", \
NULL, NULL
"txt","0","pl","0","py","0","sh","0","tcl","0","c","0","cpp","0", "h","0","log","0", \
"conf","0","php","0","php3","0", \
"map","1","menu","1", \
"hqx","4", \
"Z","5","gz","5","tgz","5","tar","5","zip","5","bz2","5","rar","5","sea","5", \
"q","7","qry","7", \
"iso","9","so","9","o","9","rtf","9","ttf","9","bin","9", \
"ics","c","ical","c", \
"gif","g", \
"html","h","htm","h","xhtml","h","css","h","swf","h","rdf","h","rss","h","xml","h", \
"jpg","I","jpeg","I","png","I","bmp","I","svg","I","tif","I","tiff","I", \
"ico","I","xbm","I","xpm","I","pcx","I", \
"mbox","M", \
"pdf","d","ps","d","doc","d","ppt","d","xls","d","xlsx","d","docx","d","pptx","d", \
"mp3","s","wav","s","mid","s","wma","s","flac","s","ogg","s","aiff","s","aac","s", \
"avi",";","mp4",";","mpg",";","mov",";","qt",";","asf",";","mpv",";","m4v",";","webm",";","ogv",";", \
NULL, NULL
/*
* Useful macros
@ -450,5 +450,3 @@ typedef struct {
#include "files.h"
#endif

949
menu.c

File diff suppressed because it is too large Load Diff

249
options.c
View File

@ -35,33 +35,33 @@
*/
void add_ftype_mapping(state *st, char *suffix)
{
char *type;
int i;
char *type;
int i;
/* Let's not do anything stupid */
if (!*suffix) return;
if (!(type = strchr(suffix, '='))) return;
/* Let's not do anything stupid */
if (!*suffix) return;
if (!(type = strchr(suffix, '='))) return;
/* Extract type from the suffix=X string */
*type++ = '\0';
if (!*type) return;
/* Extract type from the suffix=X string */
*type++ = '\0';
if (!*type) return;
/* Loop through the filetype array */
for (i = 0; i < st->filetype_count; i++) {
/* Loop through the filetype array */
for (i = 0; i < st->filetype_count; i++) {
/* Old entry found? */
if (strcasecmp(st->filetype[i].suffix, suffix) == MATCH) {
st->filetype[i].type = *type;
return;
}
}
/* Old entry found? */
if (strcasecmp(st->filetype[i].suffix, suffix) == MATCH) {
st->filetype[i].type = *type;
return;
}
}
/* No old entry found - add new entry */
if (i < MAX_FILETYPES) {
sstrlcpy(st->filetype[i].suffix, suffix);
st->filetype[i].type = *type;
st->filetype_count++;
}
/* No old entry found - add new entry */
if (i < MAX_FILETYPES) {
sstrlcpy(st->filetype[i].suffix, suffix);
st->filetype[i].type = *type;
st->filetype_count++;
}
}
@ -70,21 +70,21 @@ void add_ftype_mapping(state *st, char *suffix)
*/
void add_rewrite_mapping(state *st, char *match)
{
char *replace;
char *replace;
/* Check input and split it into match & replace */
if (!*match) return;
if (!(replace = strchr(match, '='))) return;
/* Check input and split it into match & replace */
if (!*match) return;
if (!(replace = strchr(match, '='))) return;
*replace++ = '\0';
if (!*replace) return;
*replace++ = '\0';
if (!*replace) return;
/* Insert match/replace values into the array */
if (st->rewrite_count < MAX_REWRITE) {
sstrlcpy(st->rewrite[st->rewrite_count].match, match);
sstrlcpy(st->rewrite[st->rewrite_count].replace, replace);
st->rewrite_count++;
}
/* Insert match/replace values into the array */
if (st->rewrite_count < MAX_REWRITE) {
sstrlcpy(st->rewrite[st->rewrite_count].match, match);
sstrlcpy(st->rewrite[st->rewrite_count].replace, replace);
st->rewrite_count++;
}
}
@ -93,112 +93,111 @@ void add_rewrite_mapping(state *st, char *match)
*/
void parse_args(state *st, int argc, char *argv[])
{
FILE *fp;
static const char readme[] = README;
static const char license[] = LICENSE;
struct stat file;
char buf[BUFSIZE];
int opt;
FILE *fp;
static const char readme[] = README;
static const char license[] = LICENSE;
struct stat file;
char buf[BUFSIZE];
int opt;
/* Parse args */
while ((opt = getopt(argc, argv, "h:p:T:r:t:g:a:c:u:m:l:w:o:s:i:k:f:e:R:D:L:A:P:n:dbv?-")) != ERROR) {
switch(opt) {
case 'h': sstrlcpy(st->server_host, optarg); break;
case 'p': st->server_port = atoi(optarg); break;
case 'T': st->server_tls_port = atoi(optarg); break;
case 'r': sstrlcpy(st->server_root, optarg); break;
case 't': st->default_filetype = *optarg; break;
case 'g': sstrlcpy(st->map_file, optarg); break;
case 'a': sstrlcpy(st->map_file, optarg); break;
case 'c': sstrlcpy(st->cgi_file, optarg); break;
case 'u': sstrlcpy(st->user_dir, optarg); break;
case 'm': /* obsolete, replaced by -l */
case 'l': sstrlcpy(st->log_file, optarg); break;
/* Parse args */
while ((opt = getopt(argc, argv, "h:p:T:r:t:g:a:c:u:m:l:w:o:s:i:k:f:e:R:D:L:A:P:n:dbv?-")) != ERROR) {
switch(opt) {
case 'h': sstrlcpy(st->server_host, optarg); break;
case 'p': st->server_port = atoi(optarg); break;
case 'T': st->server_tls_port = atoi(optarg); break;
case 'r': sstrlcpy(st->server_root, optarg); break;
case 't': st->default_filetype = *optarg; break;
case 'g': sstrlcpy(st->map_file, optarg); break;
case 'a': sstrlcpy(st->map_file, optarg); break;
case 'c': sstrlcpy(st->cgi_file, optarg); break;
case 'u': sstrlcpy(st->user_dir, optarg); break;
case 'm': /* obsolete, replaced by -l */
case 'l': sstrlcpy(st->log_file, optarg); break;
case 'w': st->out_width = atoi(optarg); break;
case 'o':
if (sstrncasecmp(optarg, "UTF-8") == MATCH) st->out_charset = UTF_8;
if (sstrncasecmp(optarg, "ISO-8859-1") == MATCH) st->out_charset = ISO_8859_1;
break;
case 'w': st->out_width = atoi(optarg); break;
case 'o':
if (sstrncasecmp(optarg, "UTF-8") == MATCH) st->out_charset = UTF_8;
if (sstrncasecmp(optarg, "ISO-8859-1") == MATCH) st->out_charset = ISO_8859_1;
break;
case 's': st->session_timeout = atoi(optarg); break;
case 'i': st->session_max_kbytes = abs(atoi(optarg)); break;
case 'k': st->session_max_hits = abs(atoi(optarg)); break;
case 's': st->session_timeout = atoi(optarg); break;
case 'i': st->session_max_kbytes = abs(atoi(optarg)); break;
case 'k': st->session_max_hits = abs(atoi(optarg)); break;
case 'f': sstrlcpy(st->filter_dir, optarg); break;
case 'e': add_ftype_mapping(st, optarg); break;
case 'f': sstrlcpy(st->filter_dir, optarg); break;
case 'e': add_ftype_mapping(st, optarg); break;
case 'R': add_rewrite_mapping(st, optarg); break;
case 'D': sstrlcpy(st->server_description, optarg); break;
case 'L': sstrlcpy(st->server_location, optarg); break;
case 'A': sstrlcpy(st->server_admin, optarg); break;
case 'R': add_rewrite_mapping(st, optarg); break;
case 'D': sstrlcpy(st->server_description, optarg); break;
case 'L': sstrlcpy(st->server_location, optarg); break;
case 'A': sstrlcpy(st->server_admin, optarg); break;
case 'n':
if (*optarg == 'v') { st->opt_vhost = FALSE; break; }
if (*optarg == 'l') { st->opt_parent = FALSE; break; }
if (*optarg == 'h') { st->opt_header = FALSE; break; }
if (*optarg == 'f') { st->opt_footer = FALSE; break; }
if (*optarg == 'd') { st->opt_date = FALSE; break; }
if (*optarg == 'c') { st->opt_magic = FALSE; break; }
if (*optarg == 'o') { st->opt_iconv = FALSE; break; }
if (*optarg == 'q') { st->opt_query = FALSE; break; }
if (*optarg == 's') { st->opt_syslog = FALSE; break; }
if (*optarg == 'a') { st->opt_caps = FALSE; break; }
if (*optarg == 't') { st->opt_status = FALSE; break; }
if (*optarg == 'm') { st->opt_shm = FALSE; break; }
if (*optarg == 'r') { st->opt_root = FALSE; break; }
if (*optarg == 'p') { st->opt_proxy = FALSE; break; }
if (*optarg == 'x') { st->opt_exec = FALSE; break; }
if (*optarg == 'u') { st->opt_personal_spaces = FALSE; break; }
break;
case 'n':
if (*optarg == 'v') { st->opt_vhost = FALSE; break; }
if (*optarg == 'l') { st->opt_parent = FALSE; break; }
if (*optarg == 'h') { st->opt_header = FALSE; break; }
if (*optarg == 'f') { st->opt_footer = FALSE; break; }
if (*optarg == 'd') { st->opt_date = FALSE; break; }
if (*optarg == 'c') { st->opt_magic = FALSE; break; }
if (*optarg == 'o') { st->opt_iconv = FALSE; break; }
if (*optarg == 'q') { st->opt_query = FALSE; break; }
if (*optarg == 's') { st->opt_syslog = FALSE; break; }
if (*optarg == 'a') { st->opt_caps = FALSE; break; }
if (*optarg == 't') { st->opt_status = FALSE; break; }
if (*optarg == 'm') { st->opt_shm = FALSE; break; }
if (*optarg == 'r') { st->opt_root = FALSE; break; }
if (*optarg == 'p') { st->opt_proxy = FALSE; break; }
if (*optarg == 'x') { st->opt_exec = FALSE; break; }
if (*optarg == 'u') { st->opt_personal_spaces = FALSE; break; }
break;
case 'd': st->debug = TRUE; break;
case 'b': puts(license); exit(EXIT_SUCCESS);
case 'd': st->debug = TRUE; break;
case 'b': puts(license); exit(EXIT_SUCCESS);
case 'v':
printf("%s/%s \"%s\" (built %s)\n", SERVER_SOFTWARE, VERSION, CODENAME, __DATE__);
exit(EXIT_SUCCESS);
case 'v':
printf("%s/%s \"%s\" (built %s)\n", SERVER_SOFTWARE, VERSION, CODENAME, __DATE__);
exit(EXIT_SUCCESS);
default : puts(readme); exit(EXIT_SUCCESS);
}
}
default : puts(readme); exit(EXIT_SUCCESS);
}
}
/* Sanitize options */
if (st->out_width > MAX_WIDTH) st->out_width = MAX_WIDTH;
if (st->out_width < MIN_WIDTH) st->out_width = MIN_WIDTH;
if (st->out_width < MIN_WIDTH + DATE_WIDTH) st->opt_date = FALSE;
if (!st->opt_syslog) st->debug = FALSE;
/* Sanitize options */
if (st->out_width > MAX_WIDTH) st->out_width = MAX_WIDTH;
if (st->out_width < MIN_WIDTH) st->out_width = MIN_WIDTH;
if (st->out_width < MIN_WIDTH + DATE_WIDTH) st->opt_date = FALSE;
if (!st->opt_syslog) st->debug = FALSE;
/* Primary vhost directory must exist or we disable vhosting */
if (st->opt_vhost) {
snprintf(buf, sizeof(buf), "%s/%s", st->server_root, st->server_host);
if (stat(buf, &file) == ERROR) st->opt_vhost = FALSE;
}
/* Primary vhost directory must exist or we disable vhosting */
if (st->opt_vhost) {
snprintf(buf, sizeof(buf), "%s/%s", st->server_root, st->server_host);
if (stat(buf, &file) == ERROR) st->opt_vhost = FALSE;
}
/* If -D arg looks like a file load the file contents */
if (*st->server_description == '/') {
/* If -D arg looks like a file load the file contents */
if (*st->server_description == '/') {
if ((fp = fopen(st->server_description , "r"))) {
if (fgets(st->server_description, sizeof(st->server_description), fp) == NULL)
strclear(st->server_description);
if ((fp = fopen(st->server_description , "r"))) {
if (fgets(st->server_description, sizeof(st->server_description), fp) == NULL)
strclear(st->server_description);
chomp(st->server_description);
fclose(fp);
}
else strclear(st->server_description);
}
chomp(st->server_description);
fclose(fp);
}
else strclear(st->server_description);
}
/* If -L arg looks like a file load the file contents */
if (*st->server_location == '/') {
/* If -L arg looks like a file load the file contents */
if (*st->server_location == '/') {
if ((fp = fopen(st->server_location , "r"))) {
if (fgets(st->server_location, sizeof(st->server_location), fp) == NULL)
strclear(st->server_description);
if ((fp = fopen(st->server_location , "r"))) {
if (fgets(st->server_location, sizeof(st->server_location), fp) == NULL)
strclear(st->server_description);
chomp(st->server_location);
fclose(fp);
}
else strclear(st->server_location);
}
chomp(st->server_location);
fclose(fp);
}
else strclear(st->server_location);
}
}

View File

@ -37,258 +37,258 @@ void platform(state *st)
{
#ifdef HAVE_UNAME
#if defined(_AIX) || defined(__linux) || defined(__APPLE__)
FILE *fp;
FILE *fp;
#endif
#if defined(__linux) || defined(__APPLE__)
char buf[BUFSIZE];
char buf[BUFSIZE];
#endif
#ifdef __linux
struct stat file;
struct stat file;
#endif
struct utsname name;
char sysname[64];
char release[64];
char machine[64];
char *c;
struct utsname name;
char sysname[64];
char release[64];
char machine[64];
char *c;
/* Fetch system information */
uname(&name);
/* Fetch system information */
uname(&name);
strclear(sysname);
strclear(release);
strclear(machine);
strclear(sysname);
strclear(release);
strclear(machine);
/* AIX-specific */
/* AIX-specific */
#ifdef _AIX
/* Fix uname() results */
sstrlcpy(machine, "powerpc");
snprintf(release, sizeof(release), "%s.%s",
name.version,
name.release);
/* Fix uname() results */
sstrlcpy(machine, "powerpc");
snprintf(release, sizeof(release), "%s.%s",
name.version,
name.release);
/* Get CPU type */
if ((fp = popen("/usr/sbin/getsystype -i", "r"))) {
if (fgets(machine, sizeof(machine), fp) != NULL)
strreplace(machine, ' ', '_');
pclose(fp);
}
/* Get CPU type */
if ((fp = popen("/usr/sbin/getsystype -i", "r"))) {
if (fgets(machine, sizeof(machine), fp) != NULL)
strreplace(machine, ' ', '_');
pclose(fp);
}
/* Get hardware name using shell uname */
if (!*st->server_description &&
(fp = popen("/usr/bin/uname -M", "r"))) {
/* Get hardware name using shell uname */
if (!*st->server_description &&
(fp = popen("/usr/bin/uname -M", "r"))) {
if (fgets(st->server_description, sizeof(st->server_description), fp) != NULL) {
strreplace(st->server_description, ',', ' ');
chomp(st->server_description);
}
pclose(fp);
}
if (fgets(st->server_description, sizeof(st->server_description), fp) != NULL) {
strreplace(st->server_description, ',', ' ');
chomp(st->server_description);
}
pclose(fp);
}
#endif
/* Mac OS X, just like Unix but totally different... */
/* Mac OS X, just like Unix but totally different... */
#ifdef __APPLE__
/* Hardcode OS name */
sstrlcpy(sysname, "MacOSX");
/* Hardcode OS name */
sstrlcpy(sysname, "MacOSX");
/* Get OS X version */
if ((fp = popen("/usr/bin/sw_vers -productVersion", "r"))) {
if (fgets(release, sizeof(release), fp) == NULL) strclear(release);
pclose(fp);
}
/* Get OS X version */
if ((fp = popen("/usr/bin/sw_vers -productVersion", "r"))) {
if (fgets(release, sizeof(release), fp) == NULL) strclear(release);
pclose(fp);
}
/* Get hardware name */
if (!*st->server_description &&
(fp = popen("/usr/sbin/sysctl -n hw.model", "r"))) {
/* Get hardware name */
if (!*st->server_description &&
(fp = popen("/usr/sbin/sysctl -n hw.model", "r"))) {
/* Read hardware name */
if (fgets(buf, sizeof(buf), fp) != NULL) {
/* Read hardware name */
if (fgets(buf, sizeof(buf), fp) != NULL) {
/* Clones are gone now so we'll hardcode the manufacturer */
sstrlcpy(st->server_description, "Apple ");
sstrlcat(st->server_description, buf);
/* Clones are gone now so we'll hardcode the manufacturer */
sstrlcpy(st->server_description, "Apple ");
sstrlcat(st->server_description, buf);
/* Remove hardware revision */
for (c = st->server_description; *c; c++)
if (*c >= '0' && *c <= '9') { *c = '\0'; break; }
}
pclose(fp);
}
/* Remove hardware revision */
for (c = st->server_description; *c; c++)
if (*c >= '0' && *c <= '9') { *c = '\0'; break; }
}
pclose(fp);
}
#endif
/* Linux uname() just says Linux/kernelversion - let's dig deeper... */
/* Linux uname() just says Linux/kernelversion - let's dig deeper... */
#ifdef __linux
/* Most Linux ARM/MIPS boards have hardware name in /proc/cpuinfo */
/* Most Linux ARM/MIPS boards have hardware name in /proc/cpuinfo */
#if defined(__arm__) || defined(__mips__)
if (!*st->server_description && (fp = fopen("/proc/cpuinfo" , "r"))) {
if (!*st->server_description && (fp = fopen("/proc/cpuinfo" , "r"))) {
while (fgets(buf, sizeof(buf), fp)) {
while (fgets(buf, sizeof(buf), fp)) {
#ifdef __arm__
if ((c = strkey(buf, "Hardware"))) {
if ((c = strkey(buf, "Hardware"))) {
#else
if ((c = strkey(buf, "machine"))) {
if ((c = strkey(buf, "machine"))) {
#endif
sstrlcpy(st->server_description, c);
chomp(st->server_description);
break;
}
}
fclose(fp);
}
sstrlcpy(st->server_description, c);
chomp(st->server_description);
break;
}
}
fclose(fp);
}
#endif
/* Get hardware type from DMI data */
if (!*st->server_description && (fp = fopen("/sys/class/dmi/id/board_vendor" , "r"))) {
if (fgets(buf, sizeof(buf), fp) != NULL) {
sstrlcpy(st->server_description, buf);
chomp(st->server_description);
}
fclose(fp);
/* Get hardware type from DMI data */
if (!*st->server_description && (fp = fopen("/sys/class/dmi/id/board_vendor" , "r"))) {
if (fgets(buf, sizeof(buf), fp) != NULL) {
sstrlcpy(st->server_description, buf);
chomp(st->server_description);
}
fclose(fp);
if ((fp = fopen("/sys/class/dmi/id/board_name" , "r"))) {
if (fgets(buf, sizeof(buf), fp) != NULL) {
if (*st->server_description) sstrlcat(st->server_description, " ");
sstrlcat(st->server_description, buf);
chomp(st->server_description);
}
if ((fp = fopen("/sys/class/dmi/id/board_name" , "r"))) {
if (fgets(buf, sizeof(buf), fp) != NULL) {
if (*st->server_description) sstrlcat(st->server_description, " ");
sstrlcat(st->server_description, buf);
chomp(st->server_description);
}
fclose(fp);
}
}
fclose(fp);
}
}
/* No DMI? Get possible hypervisor name */
if (!*st->server_description && (fp = fopen("/sys/hypervisor/type" , "r"))) {
if (fgets(buf, sizeof(buf), fp) != NULL) {
chomp(buf);
if (*buf) snprintf(st->server_description, sizeof(st->server_description), "%s virtual machine", buf);
}
fclose(fp);
}
/* No DMI? Get possible hypervisor name */
if (!*st->server_description && (fp = fopen("/sys/hypervisor/type" , "r"))) {
if (fgets(buf, sizeof(buf), fp) != NULL) {
chomp(buf);
if (*buf) snprintf(st->server_description, sizeof(st->server_description), "%s virtual machine", buf);
}
fclose(fp);
}
/* Identify Gentoo */
if (!*sysname && (fp = fopen("/etc/gentoo-release", "r"))) {
if (fgets(sysname, sizeof(sysname), fp) != NULL) {
if ((c = strstr(sysname, "release "))) sstrlcpy(release, c + 8);
if ((c = strchr(release, ' '))) *c = '\0';
if ((c = strchr(sysname, ' '))) *c = '\0';
}
fclose(fp);
}
/* Identify Gentoo */
if (!*sysname && (fp = fopen("/etc/gentoo-release", "r"))) {
if (fgets(sysname, sizeof(sysname), fp) != NULL) {
if ((c = strstr(sysname, "release "))) sstrlcpy(release, c + 8);
if ((c = strchr(release, ' '))) *c = '\0';
if ((c = strchr(sysname, ' '))) *c = '\0';
}
fclose(fp);
}
/* Identify RedHat */
if (!*sysname && (fp = fopen("/etc/redhat-release", "r"))) {
if (fgets(sysname, sizeof(sysname), fp) != NULL) {
if ((c = strstr(sysname, "release "))) sstrlcpy(release, c + 8);
if ((c = strchr(release, ' '))) *c = '\0';
if ((c = strchr(sysname, ' '))) *c = '\0';
/* Identify RedHat */
if (!*sysname && (fp = fopen("/etc/redhat-release", "r"))) {
if (fgets(sysname, sizeof(sysname), fp) != NULL) {
if ((c = strstr(sysname, "release "))) sstrlcpy(release, c + 8);
if ((c = strchr(release, ' '))) *c = '\0';
if ((c = strchr(sysname, ' '))) *c = '\0';
if (strcmp(sysname, "Red") == MATCH) sstrlcpy(sysname, "RedHat");
}
fclose(fp);
}
if (strcmp(sysname, "Red") == MATCH) sstrlcpy(sysname, "RedHat");
}
fclose(fp);
}
/* Identify Slackware */
if (!*sysname && (fp = fopen("/etc/slackware-version", "r"))) {
if (fgets(sysname, sizeof(sysname), fp) != NULL) {
/* Identify Slackware */
if (!*sysname && (fp = fopen("/etc/slackware-version", "r"))) {
if (fgets(sysname, sizeof(sysname), fp) != NULL) {
if ((c = strchr(sysname, ' '))) {
sstrlcpy(release, c + 1);
*c = '\0';
}
if ((c = strchr(sysname, ' '))) {
sstrlcpy(release, c + 1);
*c = '\0';
}
if ((c = strchr(sysname, '-'))) *c = '\0';
}
fclose(fp);
}
if ((c = strchr(sysname, '-'))) *c = '\0';
}
fclose(fp);
}
/* Identify CRUX */
if (!*sysname && stat("/usr/bin/crux", &file) == OK && (file.st_mode & S_IXOTH)) {
/* Identify CRUX */
if (!*sysname && stat("/usr/bin/crux", &file) == OK && (file.st_mode & S_IXOTH)) {
sstrlcpy(sysname, "CRUX");
sstrlcpy(sysname, "CRUX");
if ((fp = popen("/usr/bin/crux", "r"))) {
if (fgets(buf, sizeof(buf), fp) != NULL &&
(c = strchr(buf, ' ')) &&
(c = strchr(c + 1, ' '))) sstrlcpy(release, c + 1);
pclose(fp);
}
}
if ((fp = popen("/usr/bin/crux", "r"))) {
if (fgets(buf, sizeof(buf), fp) != NULL &&
(c = strchr(buf, ' ')) &&
(c = strchr(c + 1, ' '))) sstrlcpy(release, c + 1);
pclose(fp);
}
}
/* Uh-oh.... how about a standard Linux with lsb_release? */
if (stat("/usr/bin/lsb_release", &file) == OK && (file.st_mode & S_IXOTH)) {
/* Uh-oh.... how about a standard Linux with lsb_release? */
if (stat("/usr/bin/lsb_release", &file) == OK && (file.st_mode & S_IXOTH)) {
if (!*sysname && (fp = popen("/usr/bin/lsb_release -i -s", "r"))) {
if (fgets(sysname, sizeof(sysname), fp) == NULL) strclear(sysname);
pclose(fp);
}
if (!*sysname && (fp = popen("/usr/bin/lsb_release -i -s", "r"))) {
if (fgets(sysname, sizeof(sysname), fp) == NULL) strclear(sysname);
pclose(fp);
}
if (!*release && (fp = popen("/usr/bin/lsb_release -r -s", "r"))) {
if (fgets(release, sizeof(release), fp) == NULL) strclear(release);
pclose(fp);
}
}
if (!*release && (fp = popen("/usr/bin/lsb_release -r -s", "r"))) {
if (fgets(release, sizeof(release), fp) == NULL) strclear(release);
pclose(fp);
}
}
/* OK, nothing worked - let's try /etc/issue for sysname */
if (!*sysname && (fp = fopen("/etc/issue", "r"))) {
if (fgets(sysname, sizeof(sysname), fp) != NULL) {
if ((c = strchr(sysname, ' '))) *c = '\0';
if ((c = strchr(sysname, '\\'))) *c = '\0';
}
fclose(fp);
}
/* OK, nothing worked - let's try /etc/issue for sysname */
if (!*sysname && (fp = fopen("/etc/issue", "r"))) {
if (fgets(sysname, sizeof(sysname), fp) != NULL) {
if ((c = strchr(sysname, ' '))) *c = '\0';
if ((c = strchr(sysname, '\\'))) *c = '\0';
}
fclose(fp);
}
/* Debian version should be in /etc/debian_version */
if (!*release && (fp = fopen("/etc/debian_version", "r"))) {
if (fgets (release, sizeof(release), fp) != NULL)
if ((c = strchr(release, '/'))) *c = '\0';
fclose(fp);
}
/* Debian version should be in /etc/debian_version */
if (!*release && (fp = fopen("/etc/debian_version", "r"))) {
if (fgets (release, sizeof(release), fp) != NULL)
if ((c = strchr(release, '/'))) *c = '\0';
fclose(fp);
}
#endif
/* Haiku OS */
/* Haiku OS */
#ifdef __HAIKU__
/* Fix release name */
snprintf(release, sizeof(release), "R%s", name.release);
/* Fix release name */
snprintf(release, sizeof(release), "R%s", name.release);
#endif
/* Fill in the blanks using uname() data */
if (!*sysname) sstrlcpy(sysname, name.sysname);
if (!*release) sstrlcpy(release, name.release);
if (!*machine) sstrlcpy(machine, name.machine);
/* Fill in the blanks using uname() data */
if (!*sysname) sstrlcpy(sysname, name.sysname);
if (!*release) sstrlcpy(release, name.release);
if (!*machine) sstrlcpy(machine, name.machine);
/* I always liked weird Perl-only functions */
chomp(sysname);
chomp(release);
chomp(machine);
/* I always liked weird Perl-only functions */
chomp(sysname);
chomp(release);
chomp(machine);
/* We're only interested in major.minor version */
if ((c = strchr(release, '.'))) if ((c = strchr(c + 1, '.'))) *c = '\0';
if ((c = strchr(release, '-'))) *c = '\0';
if ((c = strchr(release, '/'))) *c = '\0';
/* We're only interested in major.minor version */
if ((c = strchr(release, '.'))) if ((c = strchr(c + 1, '.'))) *c = '\0';
if ((c = strchr(release, '-'))) *c = '\0';
if ((c = strchr(release, '/'))) *c = '\0';
/* Create a nicely formatted platform string */
snprintf(st->server_platform, sizeof(st->server_platform), "%s/%s %s",
sysname,
/* Create a nicely formatted platform string */
snprintf(st->server_platform, sizeof(st->server_platform), "%s/%s %s",
sysname,
#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__)
machine,
release);
machine,
release);
#else
release,
machine);
release,
machine);
#endif
/* Debug */
if (st->debug) {
syslog(LOG_INFO, "generated platform string \"%s\"",
st->server_platform);
}
/* Debug */
if (st->debug) {
syslog(LOG_INFO, "generated platform string \"%s\"",
st->server_platform);
}
#else
/* Fallback reply */
sstrlcpy(st->server_platform, "Unknown computer-like system");
/* Fallback reply */
sstrlcpy(st->server_platform, "Unknown computer-like system");
#endif
}
@ -298,34 +298,32 @@ void platform(state *st)
*/
float loadavg(void)
{
FILE *fp;
char buf[BUFSIZE];
FILE *fp;
char buf[BUFSIZE];
/* Faster Linux version */
/* Faster Linux version */
#ifdef __linux
if ((fp = fopen("/proc/loadavg" , "r")) == NULL) return 0;
if (fgets(buf, sizeof(buf), fp) == NULL) strclear(buf);
fclose(fp);
if ((fp = fopen("/proc/loadavg" , "r")) == NULL) return 0;
if (fgets(buf, sizeof(buf), fp) == NULL) strclear(buf);
fclose(fp);
return (float) atof(buf);
return (float) atof(buf);
/* Generic slow version - parse the output of uptime */
/* Generic slow version - parse the output of uptime */
#else
#ifdef HAVE_POPEN
char *c;
char *c;
if ((fp = popen("/usr/bin/uptime", "r"))) {
if (fgets(buf, sizeof(buf), fp) == NULL) strclear(buf);
pclose(fp);
if ((fp = popen("/usr/bin/uptime", "r"))) {
if (fgets(buf, sizeof(buf), fp) == NULL) strclear(buf);
pclose(fp);
if ((c = strstr(buf, "average: ")) || (c = strstr(buf, "averages: ")))
return (float) atof(c + 9);
}
if ((c = strstr(buf, "average: ")) || (c = strstr(buf, "averages: ")))
return (float) atof(c + 9);
}
#endif
/* Fallback reply */
return 0;
/* Fallback reply */
return 0;
#endif
}

145
session.c
View File

@ -36,21 +36,21 @@
#ifdef HAVE_SHMEM
int get_shm_session_id(state *st, shm_state *shm)
{
time_t now;
int i;
time_t now;
int i;
/* Get current time */
now = time(NULL);
/* Get current time */
now = time(NULL);
/* Locate user's old session using remote_addr */
for (i = 0; i < SHM_SESSIONS; i++) {
if (strcmp(st->req_remote_addr, shm->session[i].req_remote_addr) == MATCH &&
(now - shm->session[i].req_atime) < st->session_timeout) break;
}
/* Locate user's old session using remote_addr */
for (i = 0; i < SHM_SESSIONS; i++) {
if (strcmp(st->req_remote_addr, shm->session[i].req_remote_addr) == MATCH &&
(now - shm->session[i].req_atime) < st->session_timeout) break;
}
/* Return -1 on error */
if (i == SHM_SESSIONS) return ERROR;
else return i;
/* Return -1 on error */
if (i == SHM_SESSIONS) return ERROR;
else return i;
}
#endif
@ -61,15 +61,15 @@ int get_shm_session_id(state *st, shm_state *shm)
#ifdef HAVE_SHMEM
void get_shm_session(state *st, shm_state *shm)
{
int i;
int i;
/* Get session id */
if ((i = get_shm_session_id(st, shm)) == ERROR) return;
/* Get session id */
if ((i = get_shm_session_id(st, shm)) == ERROR) return;
/* Get session data */
if (st->opt_vhost) {
sstrlcpy(st->server_host, shm->session[i].server_host);
}
/* Get session data */
if (st->opt_vhost) {
sstrlcpy(st->server_host, shm->session[i].server_host);
}
}
#endif
@ -80,73 +80,72 @@ void get_shm_session(state *st, shm_state *shm)
#ifdef HAVE_SHMEM
void update_shm_session(state *st, shm_state *shm)
{
time_t now;
char buf[BUFSIZE];
int delay;
int i;
time_t now;
char buf[BUFSIZE];
int delay;
int i;
/* Get current time */
now = time(NULL);
/* Get current time */
now = time(NULL);
/* No existing session found? */
if ((i = get_shm_session_id(st, shm)) == ERROR) {
/* No existing session found? */
if ((i = get_shm_session_id(st, shm)) == ERROR) {
/* Look for an empty/expired session slot */
for (i = 0; i < SHM_SESSIONS; i++) {
/* Look for an empty/expired session slot */
for (i = 0; i < SHM_SESSIONS; i++) {
if ((now - shm->session[i].req_atime) > st->session_timeout) {
if ((now - shm->session[i].req_atime) > st->session_timeout) {
/* Found slot -> initialize it */
sstrlcpy(shm->session[i].req_remote_addr, st->req_remote_addr);
shm->session[i].hits = 0;
shm->session[i].kbytes = 0;
shm->session[i].session_id = rand();
break;
}
}
}
/* Found slot -> initialize it */
sstrlcpy(shm->session[i].req_remote_addr, st->req_remote_addr);
shm->session[i].hits = 0;
shm->session[i].kbytes = 0;
shm->session[i].session_id = rand();
break;
}
}
}
/* No available session slot found? */
if (i == SHM_SESSIONS) return;
/* No available session slot found? */
if (i == SHM_SESSIONS) return;
/* Get referrer from old session data */
if (*shm->session[i].server_host) {
snprintf(buf, sizeof(buf), "gopher%s://%s:%i/%c%s",
(shm->session[i].server_port == st->server_tls_port ? "s" : ""),
shm->session[i].server_host,
shm->session[i].server_port,
shm->session[i].req_filetype,
shm->session[i].req_selector);
sstrlcpy(st->req_referrer, buf);
}
/* Get referrer from old session data */
if (*shm->session[i].server_host) {
snprintf(buf, sizeof(buf), "gopher%s://%s:%i/%c%s",
(shm->session[i].server_port == st->server_tls_port ? "s" : ""),
shm->session[i].server_host,
shm->session[i].server_port,
shm->session[i].req_filetype,
shm->session[i].req_selector);
sstrlcpy(st->req_referrer, buf);
}
/* Get public session id */
st->session_id = shm->session[i].session_id;
/* Get public session id */
st->session_id = shm->session[i].session_id;
/* Update session data */
sstrlcpy(shm->session[i].server_host, st->server_host);
shm->session[i].server_port = st->server_port;
/* Update session data */
sstrlcpy(shm->session[i].server_host, st->server_host);
shm->session[i].server_port = st->server_port;
sstrlcpy(shm->session[i].req_selector, st->req_selector);
shm->session[i].req_filetype = st->req_filetype;
shm->session[i].req_atime = now;
sstrlcpy(shm->session[i].req_selector, st->req_selector);
shm->session[i].req_filetype = st->req_filetype;
shm->session[i].req_atime = now;
shm->session[i].hits++;
shm->session[i].kbytes += st->req_filesize / 1024;
shm->session[i].hits++;
shm->session[i].kbytes += st->req_filesize / 1024;
/* Transfer limits exceeded? */
if ((st->session_max_kbytes && shm->session[i].kbytes > st->session_max_kbytes) ||
(st->session_max_hits && shm->session[i].hits > st->session_max_hits)) {
/* Transfer limits exceeded? */
if ((st->session_max_kbytes && shm->session[i].kbytes > st->session_max_kbytes) ||
(st->session_max_hits && shm->session[i].hits > st->session_max_hits)) {
/* Calculate throttle delay */
delay = max(shm->session[i].kbytes / st->session_max_kbytes,
shm->session[i].hits / st->session_max_hits);
/* Calculate throttle delay */
delay = max(shm->session[i].kbytes / st->session_max_kbytes,
shm->session[i].hits / st->session_max_hits);
/* Throttle user */
syslog(LOG_INFO, "throttling user from %s for %i seconds",
st->req_remote_addr, delay);
sleep(delay);
}
/* Throttle user */
syslog(LOG_INFO, "throttling user from %s for %i seconds",
st->req_remote_addr, delay);
sleep(delay);
}
}
#endif

410
string.c
View File

@ -35,8 +35,8 @@
*/
void strrepeat(char *dest, char c, size_t num)
{
memset(dest, c, num);
dest[num] = '\0';
memset(dest, c, num);
dest[num] = '\0';
}
@ -45,10 +45,10 @@ void strrepeat(char *dest, char c, size_t num)
*/
void strreplace(char *str, char from, char to)
{
while (*str) {
if (*str == from) *str = to;
str++;
}
while (*str) {
if (*str == from) *str = to;
str++;
}
}
@ -57,26 +57,26 @@ void strreplace(char *str, char from, char to)
*/
size_t strcut(char *str, size_t width)
{
unsigned char c = '\0';
int w = 0;
int i;
unsigned char c = '\0';
int w = 0;
int i;
while (width-- && (c = *str++)) {
if (c >= 0x80 && (*str & 0xc0) == 0x80) {
i = 0;
while (width-- && (c = *str++)) {
if (c >= 0x80 && (*str & 0xc0) == 0x80) {
i = 0;
if ((c & 0xf8) == 0xf0) i = 3;
else if ((c & 0xf0) == 0xe0) i = 2;
else if ((c & 0xe0) == 0xc0) i = 1;
if ((c & 0xf8) == 0xf0) i = 3;
else if ((c & 0xf0) == 0xe0) i = 2;
else if ((c & 0xe0) == 0xc0) i = 1;
while (i--) if (!*str++) break;
}
while (i--) if (!*str++) break;
}
w++;
}
w++;
}
if (c) *str = '\0';
return w;
if (c) *str = '\0';
return w;
}
@ -85,22 +85,22 @@ size_t strcut(char *str, size_t width)
*/
char *strkey(char *header, char *key)
{
char *c;
size_t len;
char *c;
size_t len;
if ((len = strlen(key)) == 0) return NULL;
if ((len = strlen(key)) == 0) return NULL;
if (strncasecmp(header, key, len) == MATCH) {
c = header + len;
do { c++; } while (*c == ' ' || *c == '\t');
if (strncasecmp(header, key, len) == MATCH) {
c = header + len;
do { c++; } while (*c == ' ' || *c == '\t');
if (*c != ':') return NULL;
if (*c != ':') return NULL;
do { c++; } while (*c == ' ' || *c == '\t');
return c;
}
do { c++; } while (*c == ' ' || *c == '\t');
return c;
}
return NULL;
return NULL;
}
@ -109,10 +109,10 @@ char *strkey(char *header, char *key)
*/
char strlast(char *str)
{
int len;
int len;
if ((len = (int)strlen(str) - 1) >= 0) return str[len];
else return 0;
if ((len = (int)strlen(str) - 1) >= 0) return str[len];
else return 0;
}
@ -121,10 +121,10 @@ char strlast(char *str)
*/
void chomp(char *str)
{
char *c;
char *c;
if ((c = strrchr(str, '\n'))) *c = '\0';
if ((c = strrchr(str, '\r'))) *c = '\0';
if ((c = strrchr(str, '\n'))) *c = '\0';
if ((c = strrchr(str, '\r'))) *c = '\0';
}
@ -133,12 +133,12 @@ void chomp(char *str)
*/
char *strcharset(int charset)
{
if (charset == AUTO) return "auto";
if (charset == US_ASCII) return "US-ASCII";
if (charset == ISO_8859_1) return "ISO-8859-1";
if (charset == UTF_8) return "UTF-8";
if (charset == AUTO) return "auto";
if (charset == US_ASCII) return "US-ASCII";
if (charset == ISO_8859_1) return "ISO-8859-1";
if (charset == UTF_8) return "UTF-8";
return "(unknown)";
return "(unknown)";
}
@ -147,93 +147,93 @@ char *strcharset(int charset)
*/
void strniconv(int charset, char *out, char *in, size_t outsize)
{
char ascii[] = ASCII;
unsigned long c;
size_t len;
int i;
char ascii[] = ASCII;
unsigned long c;
size_t len;
int i;
/* Loop through the input string */
len = strlen(in);
while (--outsize && len > 0) {
/* Loop through the input string */
len = strlen(in);
while (--outsize && len > 0) {
/* Get one input char */
c = (unsigned char) *in++;
len--;
/* Get one input char */
c = (unsigned char) *in++;
len--;
/* 7-bit chars are the same in all three charsets */
if (c < 0x80) {
*out++ = (unsigned char) c;
continue;
}
/* 7-bit chars are the same in all three charsets */
if (c < 0x80) {
*out++ = (unsigned char) c;
continue;
}
/* Assume ISO-8859-1 which requires 0 extra bytes */
i = 0;
/* Assume ISO-8859-1 which requires 0 extra bytes */
i = 0;
/* UTF-8? (We'll actually check the next char here, not current) */
if ((*in & 0xc0) == 0x80) {
/* UTF-8? (We'll actually check the next char here, not current) */
if ((*in & 0xc0) == 0x80) {
/* Four-byte UTF-8? */
if ((c & 0xf8) == 0xf0 && len >= 3) { c &= 0x07; i = 3; }
/* Four-byte UTF-8? */
if ((c & 0xf8) == 0xf0 && len >= 3) { c &= 0x07; i = 3; }
/* Three-byte UTF-8? */
else if ((c & 0xf0) == 0xe0 && len >= 2) { c &= 0x0f; i = 2; }
/* Three-byte UTF-8? */
else if ((c & 0xf0) == 0xe0 && len >= 2) { c &= 0x0f; i = 2; }
/* Two-byte UTF-8? */
else if ((c & 0xe0) == 0xc0 && len >= 1) { c &= 0x1f; i = 1; }
/* Two-byte UTF-8? */
else if ((c & 0xe0) == 0xc0 && len >= 1) { c &= 0x1f; i = 1; }
/* Parse rest of the UTF-8 bytes */
while (i--) {
c <<= 6;
c |= *in++ & 0x3f;
len--;
}
}
/* Parse rest of the UTF-8 bytes */
while (i--) {
c <<= 6;
c |= *in++ & 0x3f;
len--;
}
}
/*
* At this point we've got one 32bit UTF character in c and
* we're ready to convert it to the specified output charset
*/
/*
* At this point we've got one 32bit UTF character in c and
* we're ready to convert it to the specified output charset
*/
/* Handle UTF-8 */
if (charset == UTF_8) {
i = 0;
/* Handle UTF-8 */
if (charset == UTF_8) {
i = 0;
/* Two-byte encoding? */
if (c < 0x800 && outsize > 2) { *out++ = (c >> 6) | 0xc0; i = 1; }
/* Two-byte encoding? */
if (c < 0x800 && outsize > 2) { *out++ = (c >> 6) | 0xc0; i = 1; }
/* Three-byte encoding? */
else if (c < 0x10000 && outsize > 3) { *out++ = (c >> 12) | 0xe0; i = 2; }
/* Three-byte encoding? */
else if (c < 0x10000 && outsize > 3) { *out++ = (c >> 12) | 0xe0; i = 2; }
/* Four-byte encoding? */
else if (c < 0x110000 && outsize > 4) { *out++ = (c >> 18) | 0xf0; i = 3; }
/* Four-byte encoding? */
else if (c < 0x110000 && outsize > 4) { *out++ = (c >> 18) | 0xf0; i = 3; }
/* Encode rest of the UTF-8 bytes */
while (i--) {
*out++ = ((c >> (i * 6)) & 0x3f) | 0x80;
outsize--;
}
continue;
}
/* Encode rest of the UTF-8 bytes */
while (i--) {
*out++ = ((c >> (i * 6)) & 0x3f) | 0x80;
outsize--;
}
continue;
}
/* Handle ISO-8859-1 */
if (charset == ISO_8859_1) {
/* Handle ISO-8859-1 */
if (charset == ISO_8859_1) {
if (c >= 0xa0 && c <= 0xff)
*out++ = (unsigned char) c;
else
*out++ = UNKNOWN;
continue;
}
if (c >= 0xa0 && c <= 0xff)
*out++ = (unsigned char) c;
else
*out++ = UNKNOWN;
continue;
}
/* Handle all other charsets as 7-bit US-ASCII */
if (c >= 0x80 && c <= 0xff)
*out++ = ascii[c - 0x80];
else
*out++ = UNKNOWN;
}
/* Handle all other charsets as 7-bit US-ASCII */
if (c >= 0x80 && c <= 0xff)
*out++ = ascii[c - 0x80];
else
*out++ = UNKNOWN;
}
/* Zero-terminate output */
*out = '\0';
/* Zero-terminate output */
*out = '\0';
}
@ -242,31 +242,31 @@ void strniconv(int charset, char *out, char *in, size_t outsize)
*/
void strnencode(char *out, const char *in, size_t outsize)
{
unsigned char c;
unsigned char c;
/* Loop through the input string */
while (--outsize) {
/* Loop through the input string */
while (--outsize) {
/* End of source? */
if (!(c = *in++)) break;
/* End of source? */
if (!(c = *in++)) break;
/* Need to encode the char? */
if (c < '+' || c > '~') {
/* Need to encode the char? */
if (c < '+' || c > '~') {
/* Can we fit the encoded version into outbuffer? */
if (outsize < 5) break;
/* Can we fit the encoded version into outbuffer? */
if (outsize < 5) break;
/* Output encoded char */
snprintf(out, outsize, "#%.3o", c);
out += 4;
}
/* Output encoded char */
snprintf(out, outsize, "#%.3o", c);
out += 4;
}
/* Copy regular chars */
else *out++ = c;
}
/* Copy regular chars */
else *out++ = c;
}
/* Zero-terminate output */
*out = '\0';
/* Zero-terminate output */
*out = '\0';
}
@ -275,37 +275,37 @@ void strnencode(char *out, const char *in, size_t outsize)
*/
void strndecode(char *out, char *in, size_t outsize)
{
unsigned char c;
unsigned int i;
unsigned char c;
unsigned int i;
/* Loop through the input string */
while (--outsize) {
/* Loop through the input string */
while (--outsize) {
/* End of source? */
if (!(c = *in++)) break;
/* End of source? */
if (!(c = *in++)) break;
/* Parse %hex encoding */
if (c == '%' && strlen(in) >= 2) {
sscanf(in, "%2x", &i);
*out++ = i;
in += 2;
continue;
}
/* Parse %hex encoding */
if (c == '%' && strlen(in) >= 2) {
sscanf(in, "%2x", &i);
*out++ = i;
in += 2;
continue;
}
/* Parse #octal encoding */
if (c == '#' && strlen(in) >= 3) {
sscanf(in, "%3o", &i);
*out++ = i;
in += 3;
continue;
}
/* Parse #octal encoding */
if (c == '#' && strlen(in) >= 3) {
sscanf(in, "%3o", &i);
*out++ = i;
in += 3;
continue;
}
/* Copy non-encoded chars */
*out++ = c;
}
/* Copy non-encoded chars */
*out++ = c;
}
/* Zero-terminate output */
*out = '\0';
/* Zero-terminate output */
*out = '\0';
}
@ -314,22 +314,22 @@ void strndecode(char *out, char *in, size_t outsize)
*/
void strfsize(char *out, off_t size, size_t outsize)
{
static char *unit[] = { UNITS };
int u;
float s;
static char *unit[] = { UNITS };
int u;
float s;
/* Start with kilobytes */
s = ((float) size) / 1024;
u = 0;
/* Start with kilobytes */
s = ((float) size) / 1024;
u = 0;
/* Loop through the units until the size is small enough */
while (s >= 1000 && unit[(u + 1)]) {
s = s / 1024;
u++;
}
/* Loop through the units until the size is small enough */
while (s >= 1000 && unit[(u + 1)]) {
s = s / 1024;
u++;
}
/* Format size */
snprintf(out, outsize, "%7.1f %s", s, unit[u]);
/* Format size */
snprintf(out, outsize, "%7.1f %s", s, unit[u]);
}
@ -360,27 +360,27 @@ void strfsize(char *out, off_t size, size_t outsize)
*/
size_t strlcpy(char *dst, const char *src, size_t siz)
{
char *d = dst;
const char *s = src;
size_t n = siz;
char *d = dst;
const char *s = src;
size_t n = siz;
/* Copy as many bytes as will fit */
if (n != 0) {
while (--n != 0) {
if ((*d++ = *s++) == '\0')
break;
}
}
/* Copy as many bytes as will fit */
if (n != 0) {
while (--n != 0) {
if ((*d++ = *s++) == '\0')
break;
}
}
/* Not enough room in dst, add NUL and traverse rest of src */
if (n == 0) {
if (siz != 0)
*d = '\0'; /* NUL-terminate dst */
while (*s++)
;
}
/* Not enough room in dst, add NUL and traverse rest of src */
if (n == 0) {
if (siz != 0)
*d = '\0'; /* NUL-terminate dst */
while (*s++)
;
}
return(s - src - 1); /* count does not include NUL */
return(s - src - 1); /* count does not include NUL */
}
/*
@ -392,29 +392,29 @@ size_t strlcpy(char *dst, const char *src, size_t siz)
*/
size_t strlcat(char *dst, const char *src, size_t siz)
{
char *d = dst;
const char *s = src;
size_t n = siz;
size_t dlen;
char *d = dst;
const char *s = src;
size_t n = siz;
size_t dlen;
/* Find the end of dst and adjust bytes left but don't go past end */
while (n-- != 0 && *d != '\0')
d++;
dlen = d - dst;
n = siz - dlen;
/* Find the end of dst and adjust bytes left but don't go past end */
while (n-- != 0 && *d != '\0')
d++;
dlen = d - dst;
n = siz - dlen;
if (n == 0)
return(dlen + strlen(s));
while (*s != '\0') {
if (n != 1) {
*d++ = *s;
n--;
}
s++;
}
*d = '\0';
if (n == 0)
return(dlen + strlen(s));
while (*s != '\0') {
if (n != 1) {
*d++ = *s;
n--;
}
s++;
}
*d = '\0';
return(dlen + (s - src)); /* count does not include NUL */
return(dlen + (s - src)); /* count does not include NUL */
}
#endif