diff --git a/src/bin2c.c b/src/bin2c.c index e6c0c6c..38c1c3a 100644 --- a/src/bin2c.c +++ b/src/bin2c.c @@ -8,11 +8,11 @@ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -38,57 +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 */ - while ((c = getopt(argc, argv, "n:0")) != -1) { - switch(c) { - case 'n': name = optarg; break; - case '0': zero = 1; break; - } - } + /* Parse args */ + while ((c = getopt(argc, argv, "n:0")) != -1) { + switch(c) { + 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 ] \n", argv[0]); - return 1; - } + /* Check args */ + if (!source) { + fprintf(stderr, "Usage: %s [-0] [-n ] \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; } diff --git a/src/file.c b/src/file.c index f9bdaa6..c501f91 100644 --- a/src/file.c +++ b/src/file.c @@ -8,11 +8,11 @@ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -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("\n" - "\n\n" - " \n" - " \n" - " URL Redirect page\n" - "\n\n" - "Redirecting to %1$s\n" - "
\n", dest);
-    footer(st);
-    printf("
\n\n\n"); + /* Output HTML */ + printf("\n" + "\n\n" + " \n" + " \n" + " URL Redirect page\n" + "\n\n" + "Redirecting to %1$s\n" + "
\n", dest);
+	footer(st);
+	printf("
\n\n\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,44 +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); } diff --git a/src/gophernicus.c b/src/gophernicus.c index 460704d..1b6efb8 100644 --- a/src/gophernicus.c +++ b/src/gophernicus.c @@ -8,11 +8,11 @@ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -44,24 +44,24 @@ int deny_severity = LOG_ERR; */ void info(state *st, char *str, char type) { - char buf[BUFSIZE]; - char selector[16]; + char buf[BUFSIZE]; + char selector[16]; - /* Convert string to output charset */ - if (st->opt_iconv) sstrniconv(st->out_charset, buf, str); - else sstrlcpy(buf, str); + /* Convert string to output charset */ + if (st->opt_iconv) sstrniconv(st->out_charset, buf, str); + else sstrlcpy(buf, str); - /* Handle gopher title resources */ - strclear(selector); - if (type == TYPE_TITLE) { - sstrlcpy(selector, "TITLE"); - type = TYPE_INFO; - } + /* Handle gopher title resources */ + strclear(selector); + if (type == TYPE_TITLE) { + sstrlcpy(selector, "TITLE"); + type = TYPE_INFO; + } - /* Output info line */ - strcut(buf, st->out_width); - printf("%c%s\t%s\t%s" CRLF, - type, buf, selector, DUMMY_HOST); + /* Output info line */ + strcut(buf, st->out_width); + printf("%c%s\t%s\t%s" CRLF, + type, buf, selector, DUMMY_HOST); } @@ -70,40 +70,40 @@ void info(state *st, char *str, char type) */ void footer(state *st) { - char line[BUFSIZE]; - char buf[BUFSIZE]; - char msg[BUFSIZE]; + char line[BUFSIZE]; + char buf[BUFSIZE]; + char msg[BUFSIZE]; - if (!st->opt_footer) { + if (!st->opt_footer) { #ifndef ENABLE_STRICT_RFC1436 - if (st->req_filetype == TYPE_MENU || st->req_filetype == TYPE_QUERY) + if (st->req_filetype == TYPE_MENU || st->req_filetype == TYPE_QUERY) #endif - printf("." CRLF); - return; - } + printf("." CRLF); + return; + } - /* Create horizontal line */ - strrepeat(line, '_', st->out_width); + /* Create horizontal line */ + strrepeat(line, '_', st->out_width); - /* Create right-aligned footer message */ - snprintf(buf, sizeof(buf), FOOTER_FORMAT, st->server_platform); - snprintf(msg, sizeof(msg), "%*s", st->out_width - 1, buf); + /* Create right-aligned footer message */ + snprintf(buf, sizeof(buf), FOOTER_FORMAT, st->server_platform); + snprintf(msg, sizeof(msg), "%*s", st->out_width - 1, buf); - /* Menu footer? */ - if (st->req_filetype == TYPE_MENU || st->req_filetype == TYPE_QUERY) { - info(st, line, TYPE_INFO); - info(st, msg, TYPE_INFO); - printf("." CRLF); - } + /* Menu footer? */ + if (st->req_filetype == TYPE_MENU || st->req_filetype == TYPE_QUERY) { + info(st, line, TYPE_INFO); + info(st, msg, TYPE_INFO); + printf("." CRLF); + } - /* Plain text footer */ - else { - printf("%s" CRLF, line); - printf("%s" CRLF, msg); + /* Plain text footer */ + else { + printf("%s" CRLF, line); + printf("%s" CRLF, msg); #ifdef ENABLE_STRICT_RFC1436 - printf("." CRLF); + printf("." CRLF); #endif - } + } } @@ -112,51 +112,51 @@ void footer(state *st) */ void die(state *st, char *message, char *description) { - int en = errno; - static const char error_gif[] = ERROR_GIF; + int en = errno; + static const char error_gif[] = ERROR_GIF; - /* Handle NULL description */ - if (description == NULL) description = strerror(en); + /* Handle NULL description */ + if (description == NULL) description = strerror(en); - /* Log the error */ - if (st->opt_syslog) { - syslog(LOG_ERR, "error \"%s\" for request \"%s\" from %s", - description, st->req_selector, st->req_remote_addr); - } - log_combined(st, HTTP_404); + /* Log the error */ + if (st->opt_syslog) { + syslog(LOG_ERR, "error \"%s\" for request \"%s\" from %s", + description, st->req_selector, st->req_remote_addr); + } + log_combined(st, HTTP_404); - /* Handle menu errors */ - if (st->req_filetype == TYPE_MENU || st->req_filetype == TYPE_QUERY) { - printf("3" ERROR_PREFIX "%s\tTITLE\t" DUMMY_HOST CRLF, message); - footer(st); - } + /* Handle menu errors */ + if (st->req_filetype == TYPE_MENU || st->req_filetype == TYPE_QUERY) { + printf("3" ERROR_PREFIX "%s\tTITLE\t" DUMMY_HOST CRLF, message); + footer(st); + } - /* Handle image errors */ - else if (st->req_filetype == TYPE_GIF || st->req_filetype == TYPE_IMAGE) { - fwrite(error_gif, sizeof(error_gif), 1, stdout); - } + /* Handle image errors */ + else if (st->req_filetype == TYPE_GIF || st->req_filetype == TYPE_IMAGE) { + fwrite(error_gif, sizeof(error_gif), 1, stdout); + } - /* Handle HTML errors */ - else if (st->req_filetype == TYPE_HTML) { - printf("\n" - "\n\n" - " \n" - " " ERROR_PREFIX "%1$s\n" - "\n\n" - "" ERROR_PREFIX "%1$s\n" - "
\n", message);
-        footer(st);
-        printf("
\n\n\n"); - } + /* Handle HTML errors */ + else if (st->req_filetype == TYPE_HTML) { + printf("\n" + "\n\n" + " \n" + " " ERROR_PREFIX "%1$s\n" + "\n\n" + "" ERROR_PREFIX "%1$s\n" + "
\n", message);
+		footer(st);
+		printf("
\n\n\n"); + } - /* Use plain text error for other filetypes */ - else { - printf(ERROR_PREFIX "%s" CRLF, message); - footer(st); - } + /* Use plain text error for other filetypes */ + else { + printf(ERROR_PREFIX "%s" CRLF, message); + footer(st); + } - /* Quit */ - exit(EXIT_FAILURE); + /* Quit */ + exit(EXIT_FAILURE); } @@ -165,32 +165,32 @@ void die(state *st, char *message, char *description) */ void log_combined(state *st, int status) { - FILE *fp; - struct tm *ltime; - char timestr[64]; - time_t now; + FILE *fp; + struct tm *ltime; + char timestr[64]; + time_t now; - /* Try to open the logfile for appending */ - if (!*st->log_file) return; - if ((fp = fopen(st->log_file , "a")) == NULL) return; + /* Try to open the logfile for appending */ + if (!*st->log_file) return; + if ((fp = fopen(st->log_file , "a")) == NULL) return; - /* Format time */ - now = time(NULL); - ltime = localtime(&now); - strftime(timestr, sizeof(timestr), HTTP_DATE, ltime); + /* Format time */ + now = time(NULL); + ltime = localtime(&now); + strftime(timestr, sizeof(timestr), HTTP_DATE, ltime); - /* Generate log entry */ - fprintf(fp, "%s %s:%i - [%s] \"GET %c%s HTTP/1.0\" %i %li \"%s\" \"" HTTP_USERAGENT "\"\n", - st->req_remote_addr, - st->server_host, - st->server_port, - timestr, - st->req_filetype, - st->req_selector, - status, - (long) st->req_filesize, - st->req_referrer); - fclose(fp); + /* Generate log entry */ + fprintf(fp, "%s %s:%i - [%s] \"GET %c%s HTTP/1.0\" %i %li \"%s\" \"" HTTP_USERAGENT "\"\n", + st->req_remote_addr, + st->server_host, + st->server_port, + timestr, + st->req_filetype, + st->req_selector, + status, + (long) st->req_filesize, + st->req_referrer); + fclose(fp); } @@ -199,110 +199,110 @@ void log_combined(state *st, int status) */ void selector_to_path(state *st) { - DIR *dp; - struct dirent *dir; - struct stat file; + DIR *dp; + struct dirent *dir; + struct stat file; #ifdef HAVE_PASSWD - struct passwd *pwd; - char *path = EMPTY; - char *c; + struct passwd *pwd; + char *path = EMPTY; + char *c; #endif - char buf[BUFSIZE]; - int i; + char buf[BUFSIZE]; + int i; - /* Handle selector rewriting */ - for (i = 0; i < st->rewrite_count; i++) { + /* Handle selector rewriting */ + for (i = 0; i < st->rewrite_count; i++) { - /* Match found? */ - if (strstr(st->req_selector, st->rewrite[i].match) == st->req_selector) { + /* Match found? */ + if (strstr(st->req_selector, st->rewrite[i].match) == st->req_selector) { - /* Replace match with a new string */ - snprintf(buf, sizeof(buf), "%s%s", - st->rewrite[i].replace, - st->req_selector + strlen(st->rewrite[i].match)); + /* Replace match with a new string */ + snprintf(buf, sizeof(buf), "%s%s", + st->rewrite[i].replace, + st->req_selector + strlen(st->rewrite[i].match)); - if (st->debug) { - syslog(LOG_INFO, "rewriting selector \"%s\" -> \"%s\"", - st->req_selector, buf); - } + if (st->debug) { + syslog(LOG_INFO, "rewriting selector \"%s\" -> \"%s\"", + st->req_selector, buf); + } - sstrlcpy(st->req_selector, buf); - } - } + sstrlcpy(st->req_selector, buf); + } + } #ifdef HAVE_PASSWD - /* Virtual userdir (~user -> /home/user/public_gopher)? */ - if (st->opt_personal_spaces && *(st->user_dir) && - sstrncmp(st->req_selector, "/~") == MATCH) { + /* Virtual userdir (~user -> /home/user/public_gopher)? */ + if (st->opt_personal_spaces && *(st->user_dir) && + sstrncmp(st->req_selector, "/~") == MATCH) { - /* Parse userdir login name & path */; - sstrlcpy(buf, st->req_selector + 2); - if ((c = strchr(buf, '/'))) { - *c = '\0'; - path = c + 1; - } + /* Parse userdir login name & path */; + sstrlcpy(buf, st->req_selector + 2); + if ((c = strchr(buf, '/'))) { + *c = '\0'; + path = c + 1; + } - /* Check user validity */ - if ((pwd = getpwnam(buf)) == NULL) - die(st, ERR_NOTFOUND, "User not found"); - if (pwd->pw_uid < PASSWD_MIN_UID) - die(st, ERR_NOTFOUND, "User found but UID too low"); + /* Check user validity */ + if ((pwd = getpwnam(buf)) == NULL) + die(st, ERR_NOTFOUND, "User not found"); + if (pwd->pw_uid < PASSWD_MIN_UID) + die(st, ERR_NOTFOUND, "User found but UID too low"); - /* Generate absolute path to users own gopher root */ - snprintf(st->req_realpath, sizeof(st->req_realpath), - "%s/%s/%s", pwd->pw_dir, st->user_dir, path); + /* Generate absolute path to users own gopher root */ + snprintf(st->req_realpath, sizeof(st->req_realpath), + "%s/%s/%s", pwd->pw_dir, st->user_dir, path); - /* Check ~public_gopher access rights */ - if (stat(st->req_realpath, &file) == ERROR) - die(st, ERR_NOTFOUND, NULL); - if ((file.st_mode & S_IROTH) == 0) - die(st, ERR_ACCESS, "~/public_gopher not world-readable"); - if (file.st_uid != pwd->pw_uid) - die(st, ERR_ACCESS, "~/ and ~/public_gopher owned by different users"); + /* Check ~public_gopher access rights */ + if (stat(st->req_realpath, &file) == ERROR) + die(st, ERR_NOTFOUND, NULL); + if ((file.st_mode & S_IROTH) == 0) + die(st, ERR_ACCESS, "~/public_gopher not world-readable"); + if (file.st_uid != pwd->pw_uid) + die(st, ERR_ACCESS, "~/ and ~/public_gopher owned by different users"); - /* Userdirs always come from the default vhost */ - if (st->opt_vhost) - sstrlcpy(st->server_host, st->server_host_default); - return; - } + /* Userdirs always come from the default vhost */ + if (st->opt_vhost) + sstrlcpy(st->server_host, st->server_host_default); + return; + } #endif - /* Virtual hosting */ - if (st->opt_vhost) { + /* Virtual hosting */ + if (st->opt_vhost) { - /* Try looking for the selector from the current vhost */ - snprintf(st->req_realpath, sizeof(st->req_realpath), "%s/%s%s", - st->server_root, st->server_host, st->req_selector); - if (stat(st->req_realpath, &file) == OK) return; + /* Try looking for the selector from the current vhost */ + snprintf(st->req_realpath, sizeof(st->req_realpath), "%s/%s%s", + st->server_root, st->server_host, st->req_selector); + if (stat(st->req_realpath, &file) == OK) return; - /* Loop through all vhosts looking for the selector */ - if ((dp = opendir(st->server_root)) == NULL) die(st, ERR_NOTFOUND, NULL); - while ((dir = readdir(dp))) { + /* Loop through all vhosts looking for the selector */ + if ((dp = opendir(st->server_root)) == NULL) die(st, ERR_NOTFOUND, NULL); + while ((dir = readdir(dp))) { - /* Skip .hidden dirs and . & .. */ - if (dir->d_name[0] == '.') continue; + /* Skip .hidden dirs and . & .. */ + if (dir->d_name[0] == '.') continue; - /* Special case - skip lost+found (don't ask) */ - if (sstrncmp(dir->d_name, "lost+found") == MATCH) continue; + /* Special case - skip lost+found (don't ask) */ + if (sstrncmp(dir->d_name, "lost+found") == MATCH) continue; - /* Generate path to the found vhost */ - snprintf(st->req_realpath, sizeof(st->req_realpath), "%s/%s%s", - st->server_root, dir->d_name, st->req_selector); + /* Generate path to the found vhost */ + snprintf(st->req_realpath, sizeof(st->req_realpath), "%s/%s%s", + st->server_root, dir->d_name, st->req_selector); - /* Did we find the selector under this vhost? */ - if (stat(st->req_realpath, &file) == OK) { + /* Did we find the selector under this vhost? */ + if (stat(st->req_realpath, &file) == OK) { - /* Virtual host found - update state & return */ - sstrlcpy(st->server_host, dir->d_name); - return; - } - } - closedir(dp); - } + /* Virtual host found - update state & return */ + sstrlcpy(st->server_host, dir->d_name); + return; + } + } + closedir(dp); + } - /* Handle normal selectors */ - snprintf(st->req_realpath, sizeof(st->req_realpath), - "%s%s", st->server_root, st->req_selector); + /* Handle normal selectors */ + snprintf(st->req_realpath, sizeof(st->req_realpath), + "%s%s", st->server_root, st->req_selector); } @@ -312,38 +312,38 @@ void selector_to_path(state *st) char *get_local_address(void) { #ifdef HAVE_IPv4 - struct sockaddr_in addr; - socklen_t addrsize = sizeof(addr); + struct sockaddr_in addr; + socklen_t addrsize = sizeof(addr); #endif #ifdef HAVE_IPv6 - struct sockaddr_in6 addr6; - socklen_t addr6size = sizeof(addr6); - static char address[INET6_ADDRSTRLEN]; + struct sockaddr_in6 addr6; + socklen_t addr6size = sizeof(addr6); + static char address[INET6_ADDRSTRLEN]; #endif - char *c; + char *c; - /* Try IPv4 first */ + /* Try IPv4 first */ #ifdef HAVE_IPv4 - if (getsockname(0, (struct sockaddr *) &addr, &addrsize) == OK) { - c = inet_ntoa(addr.sin_addr); - if (strlen(c) > 0 && *c != '0') return c; - } + if (getsockname(0, (struct sockaddr *) &addr, &addrsize) == OK) { + c = inet_ntoa(addr.sin_addr); + if (strlen(c) > 0 && *c != '0') return c; + } #endif - /* IPv4 didn't work - try IPv6 */ + /* IPv4 didn't work - try IPv6 */ #ifdef HAVE_IPv6 - if (getsockname(0, (struct sockaddr *) &addr6, &addr6size) == OK) { - if (inet_ntop(AF_INET6, &addr6.sin6_addr, address, sizeof(address))) { + if (getsockname(0, (struct sockaddr *) &addr6, &addr6size) == OK) { + if (inet_ntop(AF_INET6, &addr6.sin6_addr, address, sizeof(address))) { - /* Strip ::ffff: IPv4-in-IPv6 prefix */ - if (sstrncmp(address, "::ffff:") == MATCH) return (address + 7); - else return address; - } - } + /* Strip ::ffff: IPv4-in-IPv6 prefix */ + if (sstrncmp(address, "::ffff:") == MATCH) return (address + 7); + else return address; + } + } #endif - /* Nothing works... I'm out of ideas */ - return UNKNOWN_ADDR; + /* Nothing works... I'm out of ideas */ + return UNKNOWN_ADDR; } @@ -353,42 +353,42 @@ char *get_local_address(void) char *get_peer_address(void) { #ifdef HAVE_IPv4 - struct sockaddr_in addr; - socklen_t addrsize = sizeof(addr); + struct sockaddr_in addr; + socklen_t addrsize = sizeof(addr); #endif #ifdef HAVE_IPv6 - struct sockaddr_in6 addr6; - socklen_t addr6size = sizeof(addr6); - static char address[INET6_ADDRSTRLEN]; + struct sockaddr_in6 addr6; + socklen_t addr6size = sizeof(addr6); + static char address[INET6_ADDRSTRLEN]; #endif - char *c; + char *c; - /* Are we a CGI script? */ - if ((c = getenv("REMOTE_ADDR"))) return c; - /* if ((c = getenv("REMOTE_HOST"))) return c; */ + /* Are we a CGI script? */ + if ((c = getenv("REMOTE_ADDR"))) return c; + /* if ((c = getenv("REMOTE_HOST"))) return c; */ - /* Try IPv4 first */ + /* Try IPv4 first */ #ifdef HAVE_IPv4 - if (getpeername(0, (struct sockaddr *) &addr, &addrsize) == OK) { - c = inet_ntoa(addr.sin_addr); - if (strlen(c) > 0 && *c != '0') return c; - } + if (getpeername(0, (struct sockaddr *) &addr, &addrsize) == OK) { + c = inet_ntoa(addr.sin_addr); + if (strlen(c) > 0 && *c != '0') return c; + } #endif - /* IPv4 didn't work - try IPv6 */ + /* IPv4 didn't work - try IPv6 */ #ifdef HAVE_IPv6 - if (getpeername(0, (struct sockaddr *) &addr6, &addr6size) == OK) { - if (inet_ntop(AF_INET6, &addr6.sin6_addr, address, sizeof(address))) { + if (getpeername(0, (struct sockaddr *) &addr6, &addr6size) == OK) { + if (inet_ntop(AF_INET6, &addr6.sin6_addr, address, sizeof(address))) { - /* Strip ::ffff: IPv4-in-IPv6 prefix */ - if (sstrncmp(address, "::ffff:") == MATCH) return (address + 7); - else return address; - } - } + /* Strip ::ffff: IPv4-in-IPv6 prefix */ + if (sstrncmp(address, "::ffff:") == MATCH) return (address + 7); + else return address; + } + } #endif - /* Nothing works... I'm out of ideas */ - return UNKNOWN_ADDR; + /* Nothing works... I'm out of ideas */ + return UNKNOWN_ADDR; } @@ -397,94 +397,94 @@ char *get_peer_address(void) */ void init_state(state *st) { - static const char *filetypes[] = { FILETYPES }; - char buf[BUFSIZE]; - char *c; - int i; + static const char *filetypes[] = { FILETYPES }; + char buf[BUFSIZE]; + char *c; + int i; - /* Request */ - strclear(st->req_selector); - strclear(st->req_realpath); - strclear(st->req_query_string); - strclear(st->req_search); - strclear(st->req_referrer); - sstrlcpy(st->req_local_addr, get_local_address()); - sstrlcpy(st->req_remote_addr, get_peer_address()); - /* strclear(st->req_remote_host); */ - st->req_filetype = DEFAULT_TYPE; - st->req_protocol = PROTO_GOPHER; - st->req_filesize = 0; + /* Request */ + strclear(st->req_selector); + strclear(st->req_realpath); + strclear(st->req_query_string); + strclear(st->req_search); + strclear(st->req_referrer); + sstrlcpy(st->req_local_addr, get_local_address()); + sstrlcpy(st->req_remote_addr, get_peer_address()); + /* strclear(st->req_remote_host); */ + st->req_filetype = DEFAULT_TYPE; + st->req_protocol = PROTO_GOPHER; + st->req_filesize = 0; - /* Output */ - st->out_width = DEFAULT_WIDTH; - st->out_charset = DEFAULT_CHARSET; + /* Output */ + st->out_width = DEFAULT_WIDTH; + st->out_charset = DEFAULT_CHARSET; - /* Settings */ - sstrlcpy(st->server_root, DEFAULT_ROOT); - sstrlcpy(st->server_host_default, DEFAULT_HOST); + /* Settings */ + sstrlcpy(st->server_root, DEFAULT_ROOT); + sstrlcpy(st->server_host_default, DEFAULT_HOST); - if ((c = getenv("HOSTNAME"))) - sstrlcpy(st->server_host, c); - else if ((gethostname(buf, sizeof(buf))) != ERROR) - sstrlcpy(st->server_host, buf); + if ((c = getenv("HOSTNAME"))) + sstrlcpy(st->server_host, c); + else if ((gethostname(buf, sizeof(buf))) != ERROR) + sstrlcpy(st->server_host, buf); - st->server_port = DEFAULT_PORT; - st->server_tls_port = DEFAULT_TLS_PORT; + st->server_port = DEFAULT_PORT; + st->server_tls_port = DEFAULT_TLS_PORT; - st->default_filetype = DEFAULT_TYPE; - sstrlcpy(st->map_file, DEFAULT_MAP); - sstrlcpy(st->tag_file, DEFAULT_TAG); - sstrlcpy(st->cgi_file, DEFAULT_CGI); - sstrlcpy(st->user_dir, DEFAULT_USERDIR); - strclear(st->log_file); + st->default_filetype = DEFAULT_TYPE; + sstrlcpy(st->map_file, DEFAULT_MAP); + sstrlcpy(st->tag_file, DEFAULT_TAG); + sstrlcpy(st->cgi_file, DEFAULT_CGI); + sstrlcpy(st->user_dir, DEFAULT_USERDIR); + strclear(st->log_file); - st->hidden_count = 0; - st->filetype_count = 0; - strclear(st->filter_dir); - st->rewrite_count = 0; + st->hidden_count = 0; + st->filetype_count = 0; + strclear(st->filter_dir); + st->rewrite_count = 0; - strclear(st->server_description); - strclear(st->server_location); - strclear(st->server_platform); - strclear(st->server_admin); + strclear(st->server_description); + strclear(st->server_location); + strclear(st->server_platform); + strclear(st->server_admin); #ifdef __OpenBSD__ st->extra_unveil_paths = NULL; #endif - /* Session */ - st->session_timeout = DEFAULT_SESSION_TIMEOUT; - st->session_max_kbytes = DEFAULT_SESSION_MAX_KBYTES; - st->session_max_hits = DEFAULT_SESSION_MAX_HITS; + /* Session */ + st->session_timeout = DEFAULT_SESSION_TIMEOUT; + st->session_max_kbytes = DEFAULT_SESSION_MAX_KBYTES; + st->session_max_hits = DEFAULT_SESSION_MAX_HITS; - /* Feature options */ - st->opt_vhost = TRUE; - st->opt_parent = TRUE; - st->opt_header = TRUE; - st->opt_footer = TRUE; - st->opt_date = TRUE; - st->opt_syslog = TRUE; - st->opt_magic = TRUE; - st->opt_iconv = TRUE; - st->opt_query = TRUE; - st->opt_caps = TRUE; - st->opt_status = TRUE; - st->opt_shm = TRUE; - st->opt_root = TRUE; - st->opt_proxy = TRUE; - st->opt_exec = TRUE; - st->opt_personal_spaces = TRUE; - st->debug = FALSE; + /* Feature options */ + st->opt_vhost = TRUE; + st->opt_parent = TRUE; + st->opt_header = TRUE; + st->opt_footer = TRUE; + st->opt_date = TRUE; + st->opt_syslog = TRUE; + st->opt_magic = TRUE; + st->opt_iconv = TRUE; + st->opt_query = TRUE; + st->opt_caps = TRUE; + st->opt_status = TRUE; + st->opt_shm = TRUE; + st->opt_root = TRUE; + st->opt_proxy = TRUE; + st->opt_exec = TRUE; + st->opt_personal_spaces = TRUE; + st->debug = FALSE; - /* Load default suffix -> filetype mappings */ - for (i = 0; filetypes[i]; i += 2) { - if (st->filetype_count < MAX_FILETYPES) { - sstrlcpy(st->filetype[st->filetype_count].suffix, filetypes[i]); - st->filetype[st->filetype_count].type = *filetypes[i + 1]; - st->filetype_count++; - } - } + /* Load default suffix -> filetype mappings */ + for (i = 0; filetypes[i]; i += 2) { + if (st->filetype_count < MAX_FILETYPES) { + sstrlcpy(st->filetype[st->filetype_count].suffix, filetypes[i]); + st->filetype[st->filetype_count].type = *filetypes[i + 1]; + st->filetype_count++; + } + } } @@ -493,395 +493,395 @@ void init_state(state *st) */ int main(int argc, char *argv[]) { - struct stat file; - state st; - char self[64]; - char selector[BUFSIZE]; - char buf[BUFSIZE]; - char *dest; - char *c; + struct stat file; + state st; + char self[64]; + char selector[BUFSIZE]; + char buf[BUFSIZE]; + char *dest; + char *c; #ifdef HAVE_SHMEM - struct shmid_ds shm_ds; - shm_state *shm; - int shmid = -1; + struct shmid_ds shm_ds; + shm_state *shm; + int shmid = -1; #endif #ifdef ENABLE_HAPROXY1 - char remote[BUFSIZE]; - char local[BUFSIZE]; - int dummy; + char remote[BUFSIZE]; + char local[BUFSIZE]; + int dummy; #endif #ifdef __OpenBSD__ char pledges[256]; char *extra_unveil; #endif - /* Get the name of this binary */ - if ((c = strrchr(argv[0], '/'))) sstrlcpy(self, c + 1); - else sstrlcpy(self, argv[0]); + /* Get the name of this binary */ + if ((c = strrchr(argv[0], '/'))) sstrlcpy(self, c + 1); + else sstrlcpy(self, argv[0]); - /* Initialize state */ + /* Initialize state */ #ifdef HAVE_LOCALES - setlocale(LC_TIME, DATE_LOCALE); + setlocale(LC_TIME, DATE_LOCALE); #endif - init_state(&st); - srand(time(NULL) / (getpid() + getppid())); + init_state(&st); + srand(time(NULL) / (getpid() + getppid())); - /* Handle command line arguments */ - parse_args(&st, argc, argv); + /* Handle command line arguments */ + parse_args(&st, argc, argv); - /* Open syslog() */ - if (st.opt_syslog) openlog(self, LOG_PID, LOG_DAEMON); + /* Open syslog() */ + if (st.opt_syslog) openlog(self, LOG_PID, LOG_DAEMON); #ifdef __OpenBSD__ - /* unveil(2) support. - * - * We only enable unveil(2) if the user isn't expecting to shell-out to - * arbitrary commands. - */ - if (st.opt_exec) { - if (st.extra_unveil_paths != NULL) { - die(&st, NULL, "-U and executable maps cannot co-exist"); - } - if (st.debug) - syslog(LOG_INFO, "executable gophermaps are enabled, no unveil(2)"); - } else { - if (unveil(st.server_root, "r") == -1) - die(&st, NULL, "unveil"); + /* unveil(2) support. + * + * We only enable unveil(2) if the user isn't expecting to shell-out to + * arbitrary commands. + */ + if (st.opt_exec) { + if (st.extra_unveil_paths != NULL) { + die(&st, NULL, "-U and executable maps cannot co-exist"); + } + if (st.debug) + syslog(LOG_INFO, "executable gophermaps are enabled, no unveil(2)"); + } else { + if (unveil(st.server_root, "r") == -1) + die(&st, NULL, "unveil"); - /* - * If we want personal gopherspaces, then we have to unveil(2) the user - * database. This isn't actually needed if pledge(2) is enabled, as the - * 'getpw' promise will ensure access to this file, but it doesn't hurt - * to unveil it anyway. - */ - if (st.opt_personal_spaces) { - if (st.debug) - syslog(LOG_INFO, "unveiling /etc/pwd.db"); - if (unveil("/etc/pwd.db", "r") == -1) - die(&st, NULL, "unveil"); - } + /* + * If we want personal gopherspaces, then we have to unveil(2) the user + * database. This isn't actually needed if pledge(2) is enabled, as the + * 'getpw' promise will ensure access to this file, but it doesn't hurt + * to unveil it anyway. + */ + if (st.opt_personal_spaces) { + if (st.debug) + syslog(LOG_INFO, "unveiling /etc/pwd.db"); + if (unveil("/etc/pwd.db", "r") == -1) + die(&st, NULL, "unveil"); + } - /* Any extra unveil paths that the user has specified */ - char *p = st.extra_unveil_paths; - while (p != NULL) { - extra_unveil = strsep(&p, ":"); - if (*extra_unveil == '\0') - continue; /* empty path */ + /* Any extra unveil paths that the user has specified */ + char *p = st.extra_unveil_paths; + while (p != NULL) { + extra_unveil = strsep(&p, ":"); + if (*extra_unveil == '\0') + continue; /* empty path */ - if (st.debug) - syslog(LOG_INFO, "unveiling extra path: %s\n", extra_unveil); - if (unveil(extra_unveil, "r") == -1) - die(&st, NULL, "unveil"); - } + if (st.debug) + syslog(LOG_INFO, "unveiling extra path: %s\n", extra_unveil); + if (unveil(extra_unveil, "r") == -1) + die(&st, NULL, "unveil"); + } - if (unveil(NULL, NULL) == -1) - die(&st, NULL, "unveil"); - } + if (unveil(NULL, NULL) == -1) + die(&st, NULL, "unveil"); + } - /* pledge(2) support */ - if (st.opt_shm) { - /* pledge(2) never allows shared memory */ - if (st.debug) - syslog(LOG_INFO, "shared-memory enabled, can't pledge(2)"); - } else { - strlcpy(pledges, - "stdio rpath inet sendfd recvfd proc", - sizeof(pledges)); + /* pledge(2) support */ + if (st.opt_shm) { + /* pledge(2) never allows shared memory */ + if (st.debug) + syslog(LOG_INFO, "shared-memory enabled, can't pledge(2)"); + } else { + strlcpy(pledges, + "stdio rpath inet sendfd recvfd proc", + sizeof(pledges)); - /* Executable maps shell-out using popen(3) */ - if (st.opt_exec) { - strlcat(pledges, " exec", sizeof(pledges)); - if (st.debug) { - syslog(LOG_INFO, - "executable gophermaps enabled, " - "adding 'exec' to pledge(2)"); - } - } + /* Executable maps shell-out using popen(3) */ + if (st.opt_exec) { + strlcat(pledges, " exec", sizeof(pledges)); + if (st.debug) { + syslog(LOG_INFO, + "executable gophermaps enabled, " + "adding 'exec' to pledge(2)"); + } + } - /* Personal spaces require getpwnam(3) and getpwent(3) */ - if (st.opt_personal_spaces) { - strlcat(pledges, " getpw", sizeof(pledges)); - if (st.debug) { - syslog(LOG_INFO, - "personal gopherspaces enabled, " - "adding 'getpw' to pledge(2)"); - } - } + /* Personal spaces require getpwnam(3) and getpwent(3) */ + if (st.opt_personal_spaces) { + strlcat(pledges, " getpw", sizeof(pledges)); + if (st.debug) { + syslog(LOG_INFO, + "personal gopherspaces enabled, " + "adding 'getpw' to pledge(2)"); + } + } - if (pledge(pledges, NULL) == -1) - die(&st, NULL, "pledge"); - } + if (pledge(pledges, NULL) == -1) + die(&st, NULL, "pledge"); + } #endif - /* Check if TCP wrappers have something to say about this connection */ + /* Check if TCP wrappers have something to say about this connection */ #ifdef HAVE_LIBWRAP - if (sstrncmp(st.req_remote_addr, UNKNOWN_ADDR) != MATCH && - hosts_ctl(self, STRING_UNKNOWN, st.req_remote_addr, STRING_UNKNOWN) == WRAP_DENIED) - die(&st, ERR_ACCESS, "Refused connection"); + if (sstrncmp(st.req_remote_addr, UNKNOWN_ADDR) != MATCH && + hosts_ctl(self, STRING_UNKNOWN, st.req_remote_addr, STRING_UNKNOWN) == WRAP_DENIED) + die(&st, ERR_ACCESS, "Refused connection"); #endif - /* Make sure the computer is turned on */ + /* Make sure the computer is turned on */ #ifdef __HAIKU__ - if (is_computer_on() != TRUE) - die(&st, ERR_ACCESS, "Please turn on the computer first"); + if (is_computer_on() != TRUE) + die(&st, ERR_ACCESS, "Please turn on the computer first"); #endif - /* Refuse to run as root */ + /* Refuse to run as root */ #ifdef HAVE_PASSWD - if (st.opt_root && getuid() == 0) - die(&st, ERR_ACCESS, "Cowardly refusing to run as root"); + if (st.opt_root && getuid() == 0) + die(&st, ERR_ACCESS, "Cowardly refusing to run as root"); #endif - /* Try to get shared memory */ + /* Try to get shared memory */ #ifdef HAVE_SHMEM - if (st.opt_shm) { - if ((shmid = shmget(SHM_KEY, sizeof(shm_state), IPC_CREAT | SHM_MODE)) == ERROR) { + if (st.opt_shm) { + if ((shmid = shmget(SHM_KEY, sizeof(shm_state), IPC_CREAT | SHM_MODE)) == ERROR) { - /* Getting memory failed -> delete the old allocation */ - shmctl(shmid, IPC_RMID, &shm_ds); - shm = NULL; - } - else { - /* Map shared memory */ - if ((shm = (shm_state *) shmat(shmid, (void *) 0, 0)) == (void *) ERROR) - shm = NULL; + /* Getting memory failed -> delete the old allocation */ + shmctl(shmid, IPC_RMID, &shm_ds); + shm = NULL; + } + else { + /* Map shared memory */ + if ((shm = (shm_state *) shmat(shmid, (void *) 0, 0)) == (void *) ERROR) + shm = NULL; - /* Initialize mapped shared memory */ - if (shm && shm->start_time == 0) { - shm->start_time = time(NULL); + /* Initialize mapped shared memory */ + if (shm && shm->start_time == 0) { + shm->start_time = time(NULL); - /* Keep server platform & description in shm */ - platform(&st); - sstrlcpy(shm->server_platform, st.server_platform); - sstrlcpy(shm->server_description, st.server_description); - } - } - } else { - shm = NULL; - } + /* Keep server platform & description in shm */ + platform(&st); + sstrlcpy(shm->server_platform, st.server_platform); + sstrlcpy(shm->server_description, st.server_description); + } + } + } else { + shm = NULL; + } - /* Get server platform and description */ - if (shm) { - sstrlcpy(st.server_platform, shm->server_platform); + /* Get server platform and description */ + if (shm) { + sstrlcpy(st.server_platform, shm->server_platform); - if (!*st.server_description) - sstrlcpy(st.server_description, shm->server_description); - } - else + if (!*st.server_description) + sstrlcpy(st.server_description, shm->server_description); + } + else #endif - platform(&st); + platform(&st); - /* Read selector */ + /* Read selector */ get_selector: - if (fgets(selector, sizeof(selector) - 1, stdin) == NULL) - strclear(selector); + if (fgets(selector, sizeof(selector) - 1, stdin) == NULL) + strclear(selector); - /* Remove trailing CRLF */ - chomp(selector); + /* Remove trailing CRLF */ + chomp(selector); - if (st.debug) syslog(LOG_INFO, "client sent us \"%s\"", selector); + if (st.debug) syslog(LOG_INFO, "client sent us \"%s\"", selector); - /* Handle HAproxy/Stunnel proxy protocol v1 */ + /* Handle HAproxy/Stunnel proxy protocol v1 */ #ifdef ENABLE_HAPROXY1 - if (sstrncmp(selector, "PROXY TCP") == MATCH && st.opt_proxy) { - if (st.debug) syslog(LOG_INFO, "got proxy protocol header \"%s\"", selector); + if (sstrncmp(selector, "PROXY TCP") == MATCH && st.opt_proxy) { + if (st.debug) syslog(LOG_INFO, "got proxy protocol header \"%s\"", selector); - sscanf(selector, "PROXY TCP%d %s %s %d %d", - &dummy, remote, local, &dummy, &st.server_port); + sscanf(selector, "PROXY TCP%d %s %s %d %d", + &dummy, remote, local, &dummy, &st.server_port); - /* Strip ::ffff: IPv4-in-IPv6 prefix and override old addresses */ - sstrlcpy(st.req_local_addr, local + ((sstrncmp(local, "::ffff:") == MATCH) ? 7 : 0)); - sstrlcpy(st.req_remote_addr, remote + ((sstrncmp(remote, "::ffff:") == MATCH) ? 7 : 0)); + /* Strip ::ffff: IPv4-in-IPv6 prefix and override old addresses */ + sstrlcpy(st.req_local_addr, local + ((sstrncmp(local, "::ffff:") == MATCH) ? 7 : 0)); + sstrlcpy(st.req_remote_addr, remote + ((sstrncmp(remote, "::ffff:") == MATCH) ? 7 : 0)); - /* My precious \o/ */ - goto get_selector; - } + /* My precious \o/ */ + goto get_selector; + } #endif - /* Handle hURL: redirect page */ - if (sstrncmp(selector, "URL:") == MATCH) { - st.req_filetype = TYPE_HTML; - sstrlcpy(st.req_selector, selector); - url_redirect(&st); - return OK; - } + /* Handle hURL: redirect page */ + if (sstrncmp(selector, "URL:") == MATCH) { + st.req_filetype = TYPE_HTML; + sstrlcpy(st.req_selector, selector); + url_redirect(&st); + return OK; + } - /* Handle gopher+ root requests (UMN gopher client is seriously borken) */ - if (sstrncmp(selector, "\t$") == MATCH) { - printf("+-1" CRLF); - printf("+INFO: 1Main menu\t\t%s\t%i" CRLF, - st.server_host, - st.server_port); - printf("+VIEWS:" CRLF " application/gopher+-menu: <512b>" CRLF); - printf("." CRLF); + /* Handle gopher+ root requests (UMN gopher client is seriously borken) */ + if (sstrncmp(selector, "\t$") == MATCH) { + printf("+-1" CRLF); + printf("+INFO: 1Main menu\t\t%s\t%i" CRLF, + st.server_host, + st.server_port); + printf("+VIEWS:" CRLF " application/gopher+-menu: <512b>" CRLF); + printf("." CRLF); - if (st.debug) syslog(LOG_INFO, "got a request for gopher+ root menu"); - return OK; - } + if (st.debug) syslog(LOG_INFO, "got a request for gopher+ root menu"); + return OK; + } - /* Convert HTTP request to gopher (respond using headerless HTTP/0.9) */ - if (sstrncmp(selector, "GET ") == MATCH || - sstrncmp(selector, "POST ") == MATCH ) { + /* Convert HTTP request to gopher (respond using headerless HTTP/0.9) */ + if (sstrncmp(selector, "GET ") == MATCH || + sstrncmp(selector, "POST ") == MATCH ) { - if ((c = strchr(selector, ' '))) sstrlcpy(selector, c + 1); - if ((c = strchr(selector, ' '))) *c = '\0'; + if ((c = strchr(selector, ' '))) sstrlcpy(selector, c + 1); + if ((c = strchr(selector, ' '))) *c = '\0'; - st.req_protocol = PROTO_HTTP; + st.req_protocol = PROTO_HTTP; - if (st.debug) syslog(LOG_INFO, "got HTTP request for \"%s\"", selector); - } + if (st.debug) syslog(LOG_INFO, "got HTTP request for \"%s\"", selector); + } - /* Save default server_host & fetch session data (including new server_host) */ - sstrlcpy(st.server_host_default, st.server_host); + /* Save default server_host & fetch session data (including new server_host) */ + sstrlcpy(st.server_host_default, st.server_host); #ifdef HAVE_SHMEM - if (shm) get_shm_session(&st, shm); + if (shm) get_shm_session(&st, shm); #endif - /* Parse search from selector */ - if ((c = strchr(selector, '\t'))) { - sstrlcpy(st.req_search, c + 1); - *c = '\0'; - } + /* Parse search from selector */ + if ((c = strchr(selector, '\t'))) { + sstrlcpy(st.req_search, c + 1); + *c = '\0'; + } - /* Parse ?query from selector */ - if (st.opt_query && (c = strchr(selector, '?'))) { - sstrlcpy(st.req_query_string, c + 1); - *c = '\0'; - } + /* Parse ?query from selector */ + if (st.opt_query && (c = strchr(selector, '?'))) { + sstrlcpy(st.req_query_string, c + 1); + *c = '\0'; + } - /* Parse ;vhost from selector */ - if (st.opt_vhost && (c = strchr(selector, ';'))) { - sstrlcpy(st.server_host, c + 1); - *c = '\0'; - } + /* Parse ;vhost from selector */ + if (st.opt_vhost && (c = strchr(selector, ';'))) { + sstrlcpy(st.server_host, c + 1); + *c = '\0'; + } - /* Loop through the selector, fix it & separate query_string */ - dest = st.req_selector; - if (selector[0] != '/') *dest++ = '/'; + /* Loop through the selector, fix it & separate query_string */ + dest = st.req_selector; + if (selector[0] != '/') *dest++ = '/'; - for (c = selector; *c;) { + for (c = selector; *c;) { - /* Skip duplicate slashes and /./ */ - while (*c == '/' && *(c + 1) == '/') c++; - if (*c == '/' && *(c + 1) == '.' && *(c + 2) == '/') c += 2; + /* Skip duplicate slashes and /./ */ + while (*c == '/' && *(c + 1) == '/') c++; + if (*c == '/' && *(c + 1) == '.' && *(c + 2) == '/') c += 2; - /* Copy valid char */ - *dest++ = *c++; - } - *dest = '\0'; + /* Copy valid char */ + *dest++ = *c++; + } + *dest = '\0'; - /* Main query parameters compatibility with older versions of Gophernicus */ - if (*st.req_query_string && !*st.req_search) sstrlcpy(st.req_search, st.req_query_string); - if (!*st.req_query_string && *st.req_search) sstrlcpy(st.req_query_string, st.req_search); + /* Main query parameters compatibility with older versions of Gophernicus */ + if (*st.req_query_string && !*st.req_search) sstrlcpy(st.req_search, st.req_query_string); + if (!*st.req_query_string && *st.req_search) sstrlcpy(st.req_query_string, st.req_search); - /* Remove encodings from selector */ - strndecode(st.req_selector, st.req_selector, sizeof(st.req_selector)); + /* Remove encodings from selector */ + strndecode(st.req_selector, st.req_selector, sizeof(st.req_selector)); - /* Deny requests for Slashdot and /../ hackers */ - if (strstr(st.req_selector, "/.")) - die(&st, ERR_ACCESS, "Refusing to serve out dotfiles"); + /* Deny requests for Slashdot and /../ hackers */ + if (strstr(st.req_selector, "/.")) + die(&st, ERR_ACCESS, "Refusing to serve out dotfiles"); - /* Handle /server-status requests */ + /* Handle /server-status requests */ #ifdef HAVE_SHMEM - if (st.opt_status && sstrncmp(st.req_selector, SERVER_STATUS) == MATCH) { - if (shm) server_status(&st, shm, shmid); - return OK; - } + if (st.opt_status && sstrncmp(st.req_selector, SERVER_STATUS) == MATCH) { + if (shm) server_status(&st, shm, shmid); + return OK; + } #endif - /* Remove possible extra cruft from server_host */ - if ((c = strchr(st.server_host, '\t'))) *c = '\0'; + /* Remove possible extra cruft from server_host */ + if ((c = strchr(st.server_host, '\t'))) *c = '\0'; - /* Guess request filetype so we can die() with style... */ - st.req_filetype = gopher_filetype(&st, st.req_selector, FALSE); + /* Guess request filetype so we can die() with style... */ + st.req_filetype = gopher_filetype(&st, st.req_selector, FALSE); - /* Convert seletor to path & stat() */ - selector_to_path(&st); - if (st.debug) syslog(LOG_INFO, "path to resource is \"%s\"", st.req_realpath); + /* Convert seletor to path & stat() */ + selector_to_path(&st); + if (st.debug) syslog(LOG_INFO, "path to resource is \"%s\"", st.req_realpath); - if (stat(st.req_realpath, &file) == ERROR) { + if (stat(st.req_realpath, &file) == ERROR) { - /* Handle virtual /caps.txt requests */ - if (st.opt_caps && sstrncmp(st.req_selector, CAPS_TXT) == MATCH) { + /* Handle virtual /caps.txt requests */ + if (st.opt_caps && sstrncmp(st.req_selector, CAPS_TXT) == MATCH) { #ifdef HAVE_SHMEM - caps_txt(&st, shm); + caps_txt(&st, shm); #else - caps_txt(&st, NULL); + caps_txt(&st, NULL); #endif - return OK; - } + return OK; + } - /* Requested file not found - die() */ - die(&st, ERR_NOTFOUND, NULL); - } + /* Requested file not found - die() */ + die(&st, ERR_NOTFOUND, NULL); + } - /* Fetch request filesize from stat() */ - st.req_filesize = file.st_size; + /* Fetch request filesize from stat() */ + st.req_filesize = file.st_size; - /* Everyone must have read access but no write access */ - if ((file.st_mode & S_IROTH) == 0) - die(&st, ERR_ACCESS, "File or directory not world-readable"); - if ((file.st_mode & S_IWOTH) != 0) - die(&st, ERR_ACCESS, "File or directory world-writeable"); + /* Everyone must have read access but no write access */ + if ((file.st_mode & S_IROTH) == 0) + die(&st, ERR_ACCESS, "File or directory not world-readable"); + if ((file.st_mode & S_IWOTH) != 0) + die(&st, ERR_ACCESS, "File or directory world-writeable"); - /* If stat said it was a dir then it's a menu */ - if ((file.st_mode & S_IFMT) == S_IFDIR) st.req_filetype = TYPE_MENU; + /* If stat said it was a dir then it's a menu */ + if ((file.st_mode & S_IFMT) == S_IFDIR) st.req_filetype = TYPE_MENU; - /* Not a dir - let's guess the filetype again... */ - else if ((file.st_mode & S_IFMT) == S_IFREG) - st.req_filetype = gopher_filetype(&st, st.req_realpath, st.opt_magic); + /* Not a dir - let's guess the filetype again... */ + else if ((file.st_mode & S_IFMT) == S_IFREG) + st.req_filetype = gopher_filetype(&st, st.req_realpath, st.opt_magic); - /* Menu selectors must end with a slash */ - if (st.req_filetype == TYPE_MENU && strlast(st.req_selector) != '/') - sstrlcat(st.req_selector, "/"); + /* Menu selectors must end with a slash */ + if (st.req_filetype == TYPE_MENU && strlast(st.req_selector) != '/') + sstrlcat(st.req_selector, "/"); - /* Change directory to wherever the resource was */ - sstrlcpy(buf, st.req_realpath); + /* Change directory to wherever the resource was */ + sstrlcpy(buf, st.req_realpath); - if ((file.st_mode & S_IFMT) != S_IFDIR) c = dirname(buf); - else c = buf; + if ((file.st_mode & S_IFMT) != S_IFDIR) c = dirname(buf); + else c = buf; - if (chdir(c) == ERROR) die(&st, ERR_ACCESS, NULL); + if (chdir(c) == ERROR) die(&st, ERR_ACCESS, NULL); - /* Keep count of hits and data transfer */ + /* Keep count of hits and data transfer */ #ifdef HAVE_SHMEM - if (shm) { - shm->hits++; - shm->kbytes += st.req_filesize / 1024; + if (shm) { + shm->hits++; + shm->kbytes += st.req_filesize / 1024; - /* Update user session */ - update_shm_session(&st, shm); - } + /* Update user session */ + update_shm_session(&st, shm); + } #endif - /* Log the request */ - if (st.opt_syslog) { - syslog(LOG_INFO, "request for \"gopher%s://%s:%i/%c%s\" from %s", - (st.server_port == st.server_tls_port ? "s" : ""), - st.server_host, - st.server_port, - st.req_filetype, - st.req_selector, - st.req_remote_addr); - } + /* Log the request */ + if (st.opt_syslog) { + syslog(LOG_INFO, "request for \"gopher%s://%s:%i/%c%s\" from %s", + (st.server_port == st.server_tls_port ? "s" : ""), + st.server_host, + st.server_port, + st.req_filetype, + st.req_selector, + st.req_remote_addr); + } - /* Check file type & act accordingly */ - switch (file.st_mode & S_IFMT) { - case S_IFDIR: - log_combined(&st, HTTP_OK); - gopher_menu(&st); - break; + /* Check file type & act accordingly */ + switch (file.st_mode & S_IFMT) { + case S_IFDIR: + log_combined(&st, HTTP_OK); + gopher_menu(&st); + break; - case S_IFREG: - log_combined(&st, HTTP_OK); - gopher_file(&st); - break; + case S_IFREG: + log_combined(&st, HTTP_OK); + gopher_file(&st); + break; - default: - die(&st, ERR_ACCESS, "Refusing to serve out special files"); - } + default: + die(&st, ERR_ACCESS, "Refusing to serve out special files"); + } - /* Clean exit */ - return OK; + /* Clean exit */ + return OK; } diff --git a/src/menu.c b/src/menu.c index df408d8..9e25716 100644 --- a/src/menu.c +++ b/src/menu.c @@ -8,11 +8,11 @@ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -35,16 +35,16 @@ */ int foldersort(const void *a, const void *b) { - mode_t amode; - mode_t bmode; + mode_t amode; + mode_t bmode; - amode = (*(sdirent *) a).mode & S_IFMT; - bmode = (*(sdirent *) b).mode & S_IFMT; + amode = (*(sdirent *) a).mode & S_IFMT; + bmode = (*(sdirent *) b).mode & S_IFMT; - if (amode == S_IFDIR && bmode != S_IFDIR) return -1; - if (amode != S_IFDIR && bmode == S_IFDIR) return 1; + if (amode == S_IFDIR && bmode != S_IFDIR) return -1; + if (amode != S_IFDIR && bmode == S_IFDIR) return 1; - return strcmp((*(sdirent *) a).name, (*(sdirent *) b).name); + return strcmp((*(sdirent *) a).name, (*(sdirent *) b).name); } @@ -53,40 +53,40 @@ int foldersort(const void *a, const void *b) */ int sortdir(char *path, sdirent *list, int max) { - DIR *dp; - struct dirent *d; - struct stat s; - char buf[BUFSIZE]; - int i; + DIR *dp; + struct dirent *d; + struct stat s; + char buf[BUFSIZE]; + int i; - /* Try to open the dir */ - if ((dp = opendir(path)) == NULL) return 0; - i = 0; + /* Try to open the dir */ + if ((dp = opendir(path)) == NULL) return 0; + i = 0; - /* Loop through the directory & stat() everything */ - while (max--) { - if ((d = readdir(dp)) == NULL) break; + /* Loop through the directory & stat() everything */ + while (max--) { + if ((d = readdir(dp)) == NULL) break; - snprintf(buf, sizeof(buf), "%s/%s", path, d->d_name); - if (stat(buf, &s) == ERROR) continue; + snprintf(buf, sizeof(buf), "%s/%s", path, d->d_name); + if (stat(buf, &s) == ERROR) continue; - if (strlen(d->d_name) > sizeof(list[i].name)) continue; - sstrlcpy(list[i].name, d->d_name); + if (strlen(d->d_name) > sizeof(list[i].name)) continue; + sstrlcpy(list[i].name, d->d_name); - list[i].mode = s.st_mode; - list[i].uid = s.st_uid; - list[i].gid = s.st_gid; - list[i].size = s.st_size; - list[i].mtime = s.st_mtime; - i++; - } - closedir(dp); + list[i].mode = s.st_mode; + list[i].uid = s.st_uid; + list[i].gid = s.st_gid; + list[i].size = s.st_size; + list[i].mtime = s.st_mtime; + i++; + } + closedir(dp); - /* Sort the entries */ - if (i > 1) qsort(list, i, sizeof(sdirent), foldersort); + /* Sort the entries */ + if (i > 1) qsort(list, i, sizeof(sdirent), foldersort); - /* Return number of entries found */ - return i; + /* Return number of entries found */ + return i; } @@ -96,47 +96,47 @@ int sortdir(char *path, sdirent *list, int max) #ifdef HAVE_PASSWD void userlist(state *st) { - struct passwd *pwd; - struct stat dir; - char buf[BUFSIZE]; - struct tm *ltime; - char timestr[20]; - int width; + struct passwd *pwd; + struct stat dir; + char buf[BUFSIZE]; + struct tm *ltime; + char timestr[20]; + int width; - /* Width of filenames for fancy listing */ - width = st->out_width - DATE_WIDTH - 15; + /* Width of filenames for fancy listing */ + width = st->out_width - DATE_WIDTH - 15; - /* Loop through all users */ - setpwent(); - while ((pwd = getpwent())) { + /* Loop through all users */ + setpwent(); + while ((pwd = getpwent())) { - /* Skip too small uids */ - if (pwd->pw_uid < PASSWD_MIN_UID) continue; + /* Skip too small uids */ + if (pwd->pw_uid < PASSWD_MIN_UID) continue; - /* Look for a world-readable user-owned ~/public_gopher */ - snprintf(buf, sizeof(buf), "%s/%s", pwd->pw_dir, st->user_dir); - if (stat(buf, &dir) == ERROR) continue; - if ((dir.st_mode & S_IROTH) == 0) continue; - if (dir.st_uid != pwd->pw_uid) continue; + /* Look for a world-readable user-owned ~/public_gopher */ + snprintf(buf, sizeof(buf), "%s/%s", pwd->pw_dir, st->user_dir); + if (stat(buf, &dir) == ERROR) continue; + if ((dir.st_mode & S_IROTH) == 0) continue; + if (dir.st_uid != pwd->pw_uid) continue; - /* Found one */ - snprintf(buf, sizeof(buf), USERDIR_FORMAT); + /* Found one */ + snprintf(buf, sizeof(buf), USERDIR_FORMAT); - if (st->opt_date) { - ltime = localtime(&dir.st_mtime); - strftime(timestr, sizeof(timestr), DATE_FORMAT, ltime); + if (st->opt_date) { + ltime = localtime(&dir.st_mtime); + strftime(timestr, sizeof(timestr), DATE_FORMAT, ltime); - printf("1%-*.*s %s - \t/~%s/\t%s\t%i" CRLF, - width, width, buf, timestr, pwd->pw_name, - st->server_host, st->server_port); - } - else { - printf("1%.*s\t/~%s/\t%s\t%i" CRLF, st->out_width, buf, - pwd->pw_name, st->server_host_default, st->server_port); - } - } + printf("1%-*.*s %s - \t/~%s/\t%s\t%i" CRLF, + width, width, buf, timestr, pwd->pw_name, + st->server_host, st->server_port); + } + else { + printf("1%.*s\t/~%s/\t%s\t%i" CRLF, st->out_width, buf, + pwd->pw_name, st->server_host_default, st->server_port); + } + } - endpwent(); + endpwent(); } #endif @@ -146,53 +146,53 @@ void userlist(state *st) */ void vhostlist(state *st) { - sdirent dir[MAX_SDIRENT]; - struct tm *ltime; - char timestr[20]; - char buf[BUFSIZE]; - int width; - int num; - int i; + sdirent dir[MAX_SDIRENT]; + struct tm *ltime; + char timestr[20]; + char buf[BUFSIZE]; + int width; + int num; + int i; - /* Scan the root dir for vhost dirs */ - num = sortdir(st->server_root, dir, MAX_SDIRENT); - if (num < 0) die(st, ERR_NOTFOUND, "WTF?"); + /* Scan the root dir for vhost dirs */ + num = sortdir(st->server_root, dir, MAX_SDIRENT); + if (num < 0) die(st, ERR_NOTFOUND, "WTF?"); - /* Width of filenames for fancy listing */ - width = st->out_width - DATE_WIDTH - 15; + /* Width of filenames for fancy listing */ + width = st->out_width - DATE_WIDTH - 15; - /* Loop through the directory entries */ - for (i = 0; i < num; i++) { + /* Loop through the directory entries */ + for (i = 0; i < num; i++) { - /* Skip dotfiles */ - if (dir[i].name[0] == '.') continue; + /* Skip dotfiles */ + if (dir[i].name[0] == '.') continue; - /* Require FQDN */ - if (!strchr(dir[i].name, '.')) continue; + /* Require FQDN */ + if (!strchr(dir[i].name, '.')) continue; - /* We only want world-readable directories */ - if ((dir[i].mode & S_IROTH) == 0) continue; - if ((dir[i].mode & S_IFMT) != S_IFDIR) continue; + /* We only want world-readable directories */ + if ((dir[i].mode & S_IROTH) == 0) continue; + if ((dir[i].mode & S_IFMT) != S_IFDIR) continue; - /* Generate display string for vhost */ - snprintf(buf, sizeof(buf), VHOST_FORMAT, dir[i].name); + /* Generate display string for vhost */ + snprintf(buf, sizeof(buf), VHOST_FORMAT, dir[i].name); - /* Fancy listing */ - if (st->opt_date) { - ltime = localtime(&dir[i].mtime); - strftime(timestr, sizeof(timestr), DATE_FORMAT, ltime); + /* Fancy listing */ + if (st->opt_date) { + ltime = localtime(&dir[i].mtime); + strftime(timestr, sizeof(timestr), DATE_FORMAT, ltime); - printf("1%-*.*s %s - \t/;%s\t%s\t%i" CRLF, - width, width, buf, timestr, dir[i].name, - dir[i].name, st->server_port); - } + printf("1%-*.*s %s - \t/;%s\t%s\t%i" CRLF, + width, width, buf, timestr, dir[i].name, + dir[i].name, st->server_port); + } - /* Teh boring version */ - else { - printf("1%.*s\t/;%s\t%s\t%i" CRLF, st->out_width, buf, - dir[i].name, dir[i].name, st->server_port); - } - } + /* Teh boring version */ + else { + printf("1%.*s\t/;%s\t%s\t%i" CRLF, st->out_width, buf, + dir[i].name, dir[i].name, st->server_port); + } + } } @@ -201,67 +201,67 @@ void vhostlist(state *st) */ char gopher_filetype(state *st, char *file, char magic) { - FILE *fp; - char buf[BUFSIZE]; - char *c; - int i; + FILE *fp; + char buf[BUFSIZE]; + char *c; + int i; - /* If it ends with an slash it's a menu */ - if (!*file) return st->default_filetype; - if (strlast(file) == '/') return TYPE_MENU; + /* If it ends with an slash it's a menu */ + if (!*file) return st->default_filetype; + if (strlast(file) == '/') return TYPE_MENU; - /* Get file suffix */ - if ((c = strrchr(file, '.'))) { - c++; + /* Get file suffix */ + if ((c = strrchr(file, '.'))) { + c++; - /* Loop through the filetype array looking for a match*/ - for (i = 0; i < st->filetype_count; i++) - if (strcasecmp(st->filetype[i].suffix, c) == MATCH) - return st->filetype[i].type; - } + /* Loop through the filetype array looking for a match*/ + for (i = 0; i < st->filetype_count; i++) + if (strcasecmp(st->filetype[i].suffix, c) == MATCH) + return st->filetype[i].type; + } - /* Are we allowed to look inside files? */ - if (!magic) return st->default_filetype; + /* Are we allowed to look inside files? */ + if (!magic) return st->default_filetype; - /* Read data from the file */ - if ((fp = fopen(file , "r")) == NULL) return st->default_filetype; - i = fread(buf, 1, sizeof(buf) - 1, fp); - buf[i] = '\0'; - fclose(fp); + /* Read data from the file */ + if ((fp = fopen(file , "r")) == NULL) return st->default_filetype; + i = fread(buf, 1, sizeof(buf) - 1, fp); + buf[i] = '\0'; + fclose(fp); - /* GIF images */ - if (sstrncmp(buf, "GIF89a") == MATCH || - sstrncmp(buf, "GIF87a") == MATCH) return TYPE_GIF; + /* GIF images */ + if (sstrncmp(buf, "GIF89a") == MATCH || + sstrncmp(buf, "GIF87a") == MATCH) return TYPE_GIF; - /* JPEG images */ - if (sstrncmp(buf, "\377\330\377\340") == MATCH) return TYPE_IMAGE; + /* JPEG images */ + if (sstrncmp(buf, "\377\330\377\340") == MATCH) return TYPE_IMAGE; - /* PNG images */ - if (sstrncmp(buf, "\211PNG") == MATCH) return TYPE_IMAGE; + /* PNG images */ + if (sstrncmp(buf, "\211PNG") == MATCH) return TYPE_IMAGE; - /* mbox */ - if (strstr(buf, "\nFrom: ") && - strstr(buf, "\nSubject: ")) return TYPE_MIME; + /* mbox */ + if (strstr(buf, "\nFrom: ") && + strstr(buf, "\nSubject: ")) return TYPE_MIME; - /* MIME */ - if (strstr(buf, "\nContent-Type: ")) return TYPE_MIME; + /* MIME */ + if (strstr(buf, "\nContent-Type: ")) return TYPE_MIME; - /* HTML files */ - if (buf[0] == '<' && - (strstr(buf, "default_filetype; + /* Unknown content - binary or text? */ + if (memchr(buf, '\0', i)) return TYPE_BINARY; + return st->default_filetype; } @@ -270,179 +270,179 @@ char gopher_filetype(state *st, char *file, char magic) */ int gophermap(state *st, char *mapfile, int depth) { - FILE *fp; - struct stat file; - char line[BUFSIZE]; + FILE *fp; + struct stat file; + char line[BUFSIZE]; #ifdef HAVE_POPEN - char command[BUFSIZE]; + char command[BUFSIZE]; #endif - char *selector; - char *name; - char *host; - char *c; - char type; - int port; - int exe; + char *selector; + char *name; + char *host; + char *c; + char type; + int port; + int exe; - /* Prevent include loops */ - if (depth > 4) return OK; + /* Prevent include loops */ + if (depth > 4) return OK; - /* Try to figure out whether the map is executable */ - if (stat(mapfile, &file) == OK) { - if ((file.st_mode & S_IXOTH)) { + /* Try to figure out whether the map is executable */ + if (stat(mapfile, &file) == OK) { + if ((file.st_mode & S_IXOTH)) { #ifdef HAVE_POPEN - /* Quote the command in case path has spaces */ - snprintf(command, sizeof(command), "'%s'", mapfile); + /* Quote the command in case path has spaces */ + snprintf(command, sizeof(command), "'%s'", mapfile); #endif - exe = TRUE; - } - else exe = FALSE; - } + exe = TRUE; + } + else exe = FALSE; + } - /* This must be a shell include */ - else { + /* This must be a shell include */ + else { #ifdef HAVE_POPEN - /* Let's assume the shell command runs as is without quoting */ - sstrlcpy(command, mapfile); + /* Let's assume the shell command runs as is without quoting */ + sstrlcpy(command, mapfile); #endif - exe = TRUE; - } + exe = TRUE; + } - /* Debug output */ - if (st->debug) { - if (exe) { - if (st->opt_exec) - syslog(LOG_INFO, "parsing executable gophermap \"%s\"", mapfile); - else - syslog(LOG_INFO, "parsing executable gophermap \"%s\" forbidden by -nx", mapfile); - } - else syslog(LOG_INFO, "parsing static gophermap \"%s\"", mapfile); - } + /* Debug output */ + if (st->debug) { + if (exe) { + if (st->opt_exec) + syslog(LOG_INFO, "parsing executable gophermap \"%s\"", mapfile); + else + syslog(LOG_INFO, "parsing executable gophermap \"%s\" forbidden by -nx", mapfile); + } + else syslog(LOG_INFO, "parsing static gophermap \"%s\"", mapfile); + } - /* Try to execute or open the mapfile */ - if (exe & st->opt_exec) { + /* Try to execute or open the mapfile */ + if (exe & st->opt_exec) { #ifdef HAVE_POPEN - setenv_cgi(st, mapfile); - if ((fp = popen(command, "r")) == NULL) return OK; + setenv_cgi(st, mapfile); + if ((fp = popen(command, "r")) == NULL) return OK; #else - return OK; + return OK; #endif - } - else - if ((fp = fopen(mapfile, "r")) == NULL) return OK; + } + else + if ((fp = fopen(mapfile, "r")) == NULL) return OK; - /* Read lines one by one */ - while (fgets(line, sizeof(line) - 1, fp)) { + /* Read lines one by one */ + while (fgets(line, sizeof(line) - 1, fp)) { - /* Parse type & name */ - chomp(line); - type = line[0]; - name = line + 1; + /* Parse type & name */ + chomp(line); + type = line[0]; + name = line + 1; - /* Ignore #comments */ - if (type == '#') continue; + /* Ignore #comments */ + if (type == '#') continue; - /* Stop handling gophermap? */ - if (type == '*') return OK; - if (type == '.') return QUIT; + /* Stop handling gophermap? */ + if (type == '*') return OK; + if (type == '.') return QUIT; - /* Print a list of users with public_gopher */ - if (type == '~' && st->opt_personal_spaces) { + /* Print a list of users with public_gopher */ + if (type == '~' && st->opt_personal_spaces) { #ifdef HAVE_PASSWD - userlist(st); + userlist(st); #endif - continue; - } + continue; + } - /* Print a list of available virtual hosts */ - if (type == '%') { - if (st->opt_vhost) vhostlist(st); - continue; - } + /* Print a list of available virtual hosts */ + if (type == '%') { + if (st->opt_vhost) vhostlist(st); + continue; + } - /* Hide files in menus */ - if (type == '-') { - if (st->hidden_count < MAX_HIDDEN) - sstrlcpy(st->hidden[st->hidden_count++], name); - continue; - } + /* Hide files in menus */ + if (type == '-') { + if (st->hidden_count < MAX_HIDDEN) + sstrlcpy(st->hidden[st->hidden_count++], name); + continue; + } - /* Override filetype mappings */ - if (type == ':') { - add_ftype_mapping(st, name); - continue; - } + /* Override filetype mappings */ + if (type == ':') { + add_ftype_mapping(st, name); + continue; + } - /* Include gophermap or shell exec */ - if (type == '=') { - gophermap(st, name, depth + 1); - continue; - } + /* Include gophermap or shell exec */ + if (type == '=') { + gophermap(st, name, depth + 1); + continue; + } - /* Title resource */ - if (type == TYPE_TITLE) { - info(st, name, TYPE_TITLE); - continue; - } + /* Title resource */ + if (type == TYPE_TITLE) { + info(st, name, TYPE_TITLE); + continue; + } - /* Print out non-resources as info text */ - if (!strchr(line, '\t')) { - info(st, line, TYPE_INFO); - continue; - } + /* Print out non-resources as info text */ + if (!strchr(line, '\t')) { + info(st, line, TYPE_INFO); + continue; + } - /* Parse selector */ - selector = EMPTY; - if ((c = strchr(name, '\t'))) { - *c = '\0'; - selector = c + 1; - } - if (!*selector) selector = name; + /* Parse selector */ + selector = EMPTY; + if ((c = strchr(name, '\t'))) { + *c = '\0'; + selector = c + 1; + } + if (!*selector) selector = name; - /* Parse host */ - host = st->server_host; - if ((c = strchr(selector, '\t'))) { - *c = '\0'; - host = c + 1; - } + /* Parse host */ + host = st->server_host; + if ((c = strchr(selector, '\t'))) { + *c = '\0'; + host = c + 1; + } - /* Parse port */ - port = st->server_port; - if ((c = strchr(host, '\t'))) { - *c = '\0'; - port = atoi(c + 1); - } + /* Parse port */ + port = st->server_port; + if ((c = strchr(host, '\t'))) { + *c = '\0'; + port = atoi(c + 1); + } - /* Handle remote, absolute and hURL gopher resources */ - if (sstrncmp(selector, "URL:") == MATCH || - selector[0] == '/' || - host != st->server_host) { + /* Handle remote, absolute and hURL gopher resources */ + if (sstrncmp(selector, "URL:") == MATCH || + selector[0] == '/' || + host != st->server_host) { - printf("%c%s\t%s\t%s\t%i" CRLF, type, name, - selector, host, port); - } + printf("%c%s\t%s\t%s\t%i" CRLF, type, name, + selector, host, port); + } - /* Handle relative resources */ - else { - printf("%c%s\t%s%s\t%s\t%i" CRLF, type, name, - st->req_selector, selector, host, port); + /* Handle relative resources */ + else { + printf("%c%s\t%s%s\t%s\t%i" CRLF, type, name, + st->req_selector, selector, host, port); - /* Automatically hide manually defined selectors */ + /* Automatically hide manually defined selectors */ #ifdef ENABLE_AUTOHIDING - if (st->hidden_count < MAX_HIDDEN) - sstrlcpy(st->hidden[st->hidden_count++], selector); + if (st->hidden_count < MAX_HIDDEN) + sstrlcpy(st->hidden[st->hidden_count++], selector); #endif - } - } + } + } - /* Clean up & return */ + /* Clean up & return */ #ifdef HAVE_POPEN - if (exe & st->opt_exec) pclose(fp); - else + if (exe & st->opt_exec) pclose(fp); + else #endif - fclose(fp); + fclose(fp); - return QUIT; + return QUIT; } @@ -451,241 +451,241 @@ int gophermap(state *st, char *mapfile, int depth) */ void gopher_menu(state *st) { - FILE *fp; - sdirent dir[MAX_SDIRENT]; - struct tm *ltime; - struct stat file; - char buf[BUFSIZE]; - char pathname[BUFSIZE]; - char displayname[BUFSIZE]; - char encodedname[BUFSIZE]; - char timestr[20]; - char sizestr[20]; - char *parent; - char *c; - char type; - int width; - int num; - int i; - int n; + FILE *fp; + sdirent dir[MAX_SDIRENT]; + struct tm *ltime; + struct stat file; + char buf[BUFSIZE]; + char pathname[BUFSIZE]; + char displayname[BUFSIZE]; + char encodedname[BUFSIZE]; + char timestr[20]; + char sizestr[20]; + char *parent; + char *c; + char type; + int width; + int num; + int i; + int n; - /* Check for a gophermap */ - snprintf(pathname, sizeof(pathname), "%s/%s", - st->req_realpath, st->map_file); + /* Check for a gophermap */ + snprintf(pathname, sizeof(pathname), "%s/%s", + st->req_realpath, st->map_file); - if (stat(pathname, &file) == OK && - (file.st_mode & S_IFMT) == S_IFREG) { + if (stat(pathname, &file) == OK && + (file.st_mode & S_IFMT) == S_IFREG) { - /* Parse gophermap */ - if (gophermap(st, pathname, 0) == QUIT) { - footer(st); - return; - } - } + /* Parse gophermap */ + if (gophermap(st, pathname, 0) == QUIT) { + footer(st); + return; + } + } - else { - /* Check for a gophertag */ - snprintf(pathname, sizeof(pathname), "%s/%s", - st->req_realpath, st->tag_file); + else { + /* Check for a gophertag */ + snprintf(pathname, sizeof(pathname), "%s/%s", + st->req_realpath, st->tag_file); - if (stat(pathname, &file) == OK && - (file.st_mode & S_IFMT) == S_IFREG) { + if (stat(pathname, &file) == OK && + (file.st_mode & S_IFMT) == S_IFREG) { - /* Read & output gophertag */ - if ((fp = fopen(pathname , "r"))) { + /* Read & output gophertag */ + if ((fp = fopen(pathname , "r"))) { - if (fgets(buf, sizeof(buf), fp) == NULL) strclear(buf); - chomp(buf); + if (fgets(buf, sizeof(buf), fp) == NULL) strclear(buf); + chomp(buf); - info(st, buf, TYPE_TITLE); - info(st, EMPTY, TYPE_INFO); - fclose(fp); - } - } + info(st, buf, TYPE_TITLE); + info(st, EMPTY, TYPE_INFO); + fclose(fp); + } + } - /* No gophermap or tag found - print default header */ - else if (st->opt_header) { + /* No gophermap or tag found - print default header */ + else if (st->opt_header) { - /* Use the selector as menu title */ - sstrlcpy(displayname, st->req_selector); + /* Use the selector as menu title */ + sstrlcpy(displayname, st->req_selector); - /* Shorten too long titles */ - while (strlen(displayname) > (st->out_width - sizeof(HEADER_FORMAT))) { - if ((c = strchr(displayname, '/')) == NULL) break; + /* Shorten too long titles */ + while (strlen(displayname) > (st->out_width - sizeof(HEADER_FORMAT))) { + if ((c = strchr(displayname, '/')) == NULL) break; - if (!*++c) break; - sstrlcpy(displayname, c); - } + if (!*++c) break; + sstrlcpy(displayname, c); + } - /* Output menu title */ - snprintf(buf, sizeof(buf), HEADER_FORMAT, displayname); - info(st, buf, TYPE_TITLE); - info(st, EMPTY, TYPE_INFO); - } - } + /* Output menu title */ + snprintf(buf, sizeof(buf), HEADER_FORMAT, displayname); + info(st, buf, TYPE_TITLE); + info(st, EMPTY, TYPE_INFO); + } + } - /* Scan the directory */ - num = sortdir(st->req_realpath, dir, MAX_SDIRENT); - if (num < 0) die(st, ERR_NOTFOUND, "WTF?"); + /* Scan the directory */ + num = sortdir(st->req_realpath, dir, MAX_SDIRENT); + if (num < 0) die(st, ERR_NOTFOUND, "WTF?"); - /* Create link to parent directory */ - if (st->opt_parent) { - sstrlcpy(buf, st->req_selector); - parent = dirname(buf); + /* Create link to parent directory */ + if (st->opt_parent) { + sstrlcpy(buf, st->req_selector); + parent = dirname(buf); - /* Root has no parent */ - if (strcmp(st->req_selector, ROOT) != MATCH) { + /* Root has no parent */ + if (strcmp(st->req_selector, ROOT) != MATCH) { - /* Prevent double-slash */ - if (strcmp(parent, ROOT) == MATCH) parent++; + /* Prevent double-slash */ + if (strcmp(parent, ROOT) == MATCH) parent++; - /* Print link */ - printf("1%-*s\t%s/\t%s\t%i" CRLF, - st->opt_date ? (st->out_width - 1) : (int) strlen(PARENT), - PARENT, parent, st->server_host, st->server_port); - } - } + /* Print link */ + printf("1%-*s\t%s/\t%s\t%i" CRLF, + st->opt_date ? (st->out_width - 1) : (int) strlen(PARENT), + PARENT, parent, st->server_host, st->server_port); + } + } - /* Width of filenames for fancy listing */ - width = st->out_width - DATE_WIDTH - 15; + /* Width of filenames for fancy listing */ + width = st->out_width - DATE_WIDTH - 15; - /* Loop through the directory entries */ - for (i = 0; i < num; i++) { + /* Loop through the directory entries */ + for (i = 0; i < num; i++) { - /* Get full path+name */ - snprintf(pathname, sizeof(pathname), "%s/%s", - st->req_realpath, dir[i].name); + /* Get full path+name */ + snprintf(pathname, sizeof(pathname), "%s/%s", + st->req_realpath, dir[i].name); - /* Skip dotfiles and non world-readables */ - if (dir[i].name[0] == '.') continue; - if ((dir[i].mode & S_IROTH) == 0) continue; + /* Skip dotfiles and non world-readables */ + if (dir[i].name[0] == '.') continue; + if ((dir[i].mode & S_IROTH) == 0) continue; - /* Skip gophermaps and tags (but not dirs) */ - if ((dir[i].mode & S_IFMT) != S_IFDIR) { - if (strcmp(dir[i].name, st->map_file) == MATCH) continue; - if (strcmp(dir[i].name, st->tag_file) == MATCH) continue; - } + /* Skip gophermaps and tags (but not dirs) */ + if ((dir[i].mode & S_IFMT) != S_IFDIR) { + if (strcmp(dir[i].name, st->map_file) == MATCH) continue; + if (strcmp(dir[i].name, st->tag_file) == MATCH) continue; + } - /* Skip files marked for hiding */ - for (n = 0; n < st->hidden_count; n++) - if (strcmp(dir[i].name, st->hidden[n]) == MATCH) break; - if (n < st->hidden_count) continue; /* Cruel hack... */ + /* Skip files marked for hiding */ + for (n = 0; n < st->hidden_count; n++) + if (strcmp(dir[i].name, st->hidden[n]) == MATCH) break; + if (n < st->hidden_count) continue; /* Cruel hack... */ - /* Generate display name with correct output charset */ - if (st->opt_iconv) - sstrniconv(st->out_charset, displayname, dir[i].name); - else - sstrlcpy(displayname, dir[i].name); + /* Generate display name with correct output charset */ + if (st->opt_iconv) + sstrniconv(st->out_charset, displayname, dir[i].name); + else + sstrlcpy(displayname, dir[i].name); - /* #OCT-encode filename */ - strnencode(encodedname, dir[i].name, sizeof(encodedname)); + /* #OCT-encode filename */ + strnencode(encodedname, dir[i].name, sizeof(encodedname)); - /* Handle inline .gophermap */ - if (strstr(displayname, st->map_file) > displayname) { - gophermap(st, pathname, 0); - continue; - } + /* Handle inline .gophermap */ + if (strstr(displayname, st->map_file) > displayname) { + gophermap(st, pathname, 0); + continue; + } - /* Handle directories */ - if ((dir[i].mode & S_IFMT) == S_IFDIR) { + /* Handle directories */ + if ((dir[i].mode & S_IFMT) == S_IFDIR) { - /* Check for a gophertag */ - snprintf(buf, sizeof(buf), "%s/%s", - pathname, st->tag_file); + /* Check for a gophertag */ + snprintf(buf, sizeof(buf), "%s/%s", + pathname, st->tag_file); - if (stat(buf, &file) == OK && - (file.st_mode & S_IFMT) == S_IFREG) { + if (stat(buf, &file) == OK && + (file.st_mode & S_IFMT) == S_IFREG) { - /* Use the gophertag as displayname */ - if ((fp = fopen(buf , "r"))) { + /* Use the gophertag as displayname */ + if ((fp = fopen(buf , "r"))) { - if (fgets(buf, sizeof(buf), fp) == NULL) strclear(buf); - chomp(buf); - fclose(fp); + if (fgets(buf, sizeof(buf), fp) == NULL) strclear(buf); + chomp(buf); + fclose(fp); - /* Skip empty gophertags */ - if (*buf) { + /* Skip empty gophertags */ + if (*buf) { - /* Convert to output charset */ - if (st->opt_iconv) sstrniconv(st->out_charset, displayname, buf); - else sstrlcpy(displayname, buf); - } + /* Convert to output charset */ + if (st->opt_iconv) sstrniconv(st->out_charset, displayname, buf); + else sstrlcpy(displayname, buf); + } - } - } + } + } - /* Dir listing with dates */ - if (st->opt_date) { - ltime = localtime(&dir[i].mtime); - strftime(timestr, sizeof(timestr), DATE_FORMAT, ltime); + /* Dir listing with dates */ + if (st->opt_date) { + ltime = localtime(&dir[i].mtime); + strftime(timestr, sizeof(timestr), DATE_FORMAT, ltime); - /* Hack to get around UTF-8 byte != char */ - n = width - strcut(displayname, width); - strrepeat(buf, ' ', n); + /* Hack to get around UTF-8 byte != char */ + n = width - strcut(displayname, width); + strrepeat(buf, ' ', n); - printf("1%s%s %s - \t%s%s/\t%s\t%i" CRLF, - displayname, - buf, - timestr, - st->req_selector, - encodedname, - st->server_host, - st->server_port); - } + printf("1%s%s %s - \t%s%s/\t%s\t%i" CRLF, + displayname, + buf, + timestr, + st->req_selector, + encodedname, + st->server_host, + st->server_port); + } - /* Regular dir listing */ - else { - strcut(displayname, st->out_width); - printf("1%s\t%s%s/\t%s\t%i" CRLF, - displayname, - st->req_selector, - encodedname, - st->server_host, - st->server_port); - } + /* Regular dir listing */ + else { + strcut(displayname, st->out_width); + printf("1%s\t%s%s/\t%s\t%i" CRLF, + displayname, + st->req_selector, + encodedname, + st->server_host, + st->server_port); + } - continue; - } + continue; + } - /* Skip special files (sockets, fifos etc) */ - if ((dir[i].mode & S_IFMT) != S_IFREG) continue; + /* Skip special files (sockets, fifos etc) */ + if ((dir[i].mode & S_IFMT) != S_IFREG) continue; - /* Get file type */ - type = gopher_filetype(st, pathname, st->opt_magic); + /* Get file type */ + type = gopher_filetype(st, pathname, st->opt_magic); - /* File listing with dates & sizes */ - if (st->opt_date) { - ltime = localtime(&dir[i].mtime); - strftime(timestr, sizeof(timestr), DATE_FORMAT, ltime); - strfsize(sizestr, dir[i].size, sizeof(sizestr)); + /* File listing with dates & sizes */ + if (st->opt_date) { + ltime = localtime(&dir[i].mtime); + strftime(timestr, sizeof(timestr), DATE_FORMAT, ltime); + strfsize(sizestr, dir[i].size, sizeof(sizestr)); - /* Hack to get around UTF-8 byte != char */ - n = width - strcut(displayname, width); - strrepeat(buf, ' ', n); + /* Hack to get around UTF-8 byte != char */ + n = width - strcut(displayname, width); + strrepeat(buf, ' ', n); - printf("%c%s%s %s %s\t%s%s\t%s\t%i" CRLF, type, - displayname, - buf, - timestr, - sizestr, - st->req_selector, - encodedname, - st->server_host, - st->server_port); - } + printf("%c%s%s %s %s\t%s%s\t%s\t%i" CRLF, type, + displayname, + buf, + timestr, + sizestr, + st->req_selector, + encodedname, + st->server_host, + st->server_port); + } - /* Regular file listing */ - else { - strcut(displayname, st->out_width); - printf("%c%s\t%s%s\t%s\t%i" CRLF, type, - displayname, - st->req_selector, - encodedname, - st->server_host, - st->server_port); - } - } + /* Regular file listing */ + else { + strcut(displayname, st->out_width); + printf("%c%s\t%s%s\t%s\t%i" CRLF, type, + displayname, + st->req_selector, + encodedname, + st->server_host, + st->server_port); + } + } - /* Print footer */ - footer(st); + /* Print footer */ + footer(st); } diff --git a/src/options.c b/src/options.c index c107de7..f82adf1 100644 --- a/src/options.c +++ b/src/options.c @@ -8,11 +8,11 @@ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -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,118 +93,118 @@ 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, + /* Parse args */ + while ((opt = getopt(argc, argv, #ifdef __OpenBSD__ - "U:" /* extra unveil(2) paths are OpenBSD only */ + "U:" /* extra unveil(2) paths are OpenBSD only */ #endif - "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; + "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, "US-ASCII") == MATCH) st->out_charset = US_ASCII; - 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, "US-ASCII") == MATCH) st->out_charset = US_ASCII; + 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; #ifdef __OpenBSD__ - case 'U': st->extra_unveil_paths = optarg; break; + case 'U': st->extra_unveil_paths = optarg; break; #endif - 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); + } } diff --git a/src/platform.c b/src/platform.c index 7b45c65..53f7c47 100644 --- a/src/platform.c +++ b/src/platform.c @@ -8,11 +8,11 @@ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -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,32 +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 } diff --git a/src/session.c b/src/session.c index f555792..dab6261 100644 --- a/src/session.c +++ b/src/session.c @@ -8,11 +8,11 @@ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -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,72 +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 diff --git a/src/string.c b/src/string.c index f334799..027a863 100644 --- a/src/string.c +++ b/src/string.c @@ -8,11 +8,11 @@ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -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