iEntirely rewritten fiche - fiche - A pastebin adjusted for gopher use Err vernunftzentrum.de 70 hgit clone git://vernunftzentrum.de/fiche.git URL:git://vernunftzentrum.de/fiche.git vernunftzentrum.de 70 1Log /ckeen/repos/fiche/log.gph vernunftzentrum.de 70 1Files /ckeen/repos/fiche/files.gph vernunftzentrum.de 70 1Refs /ckeen/repos/fiche/refs.gph vernunftzentrum.de 70 1LICENSE /ckeen/repos/fiche/file/LICENSE.gph vernunftzentrum.de 70 i--- Err vernunftzentrum.de 70 1commit 8ff08a04093e51dfdbde0b6a4f8f3e58dcbe43be /ckeen/repos/fiche/commit/8ff08a04093e51dfdbde0b6a4f8f3e58dcbe43be.gph vernunftzentrum.de 70 1parent c054f8dc20c193c6354fe7e636255758b06fc6f7 /ckeen/repos/fiche/commit/c054f8dc20c193c6354fe7e636255758b06fc6f7.gph vernunftzentrum.de 70 hAuthor: solusipse URL:mailto:solus1ps3@gmail.com vernunftzentrum.de 70 iDate: Sat, 2 Sep 2017 17:51:43 +0200 Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 iEntirely rewritten fiche Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 iDiffstat: Err vernunftzentrum.de 70 i .gitignore | 6 ++++++ Err vernunftzentrum.de 70 i Makefile | 12 ++++-------- Err vernunftzentrum.de 70 i fiche.c | 1056 ++++++++++++++++++------------- Err vernunftzentrum.de 70 i fiche.h | 169 ++++++++++++++----------------- Err vernunftzentrum.de 70 i main.c | 133 +++++++++++++++++++++++++++++++ Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i5 files changed, 826 insertions(+), 550 deletions(-) Err vernunftzentrum.de 70 i--- Err vernunftzentrum.de 70 1diff --git a/.gitignore b/.gitignore /ckeen/repos/fiche/file/.gitignore.gph vernunftzentrum.de 70 i@@ -1,2 +1,8 @@ Err vernunftzentrum.de 70 i # ignore binaries Err vernunftzentrum.de 70 i /fiche Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+# ignore default outpit dir Err vernunftzentrum.de 70 i+code/ Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+# ignore log files Err vernunftzentrum.de 70 i+*.log Err vernunftzentrum.de 70 1diff --git a/Makefile b/Makefile /ckeen/repos/fiche/file/Makefile.gph vernunftzentrum.de 70 i@@ -1,13 +1,9 @@ Err vernunftzentrum.de 70 i-# ----------------------------------- Err vernunftzentrum.de 70 i-# Fiche MAKEFILE Err vernunftzentrum.de 70 i-# https://github.com/solusipse/fiche Err vernunftzentrum.de 70 i-# solusipse.net Err vernunftzentrum.de 70 i-# ----------------------------------- Err vernunftzentrum.de 70 i- Err vernunftzentrum.de 70 i-CFLAGS+=-pthread -O2 Err vernunftzentrum.de 70 i+# for debug add -g -O0 to line below Err vernunftzentrum.de 70 i+CFLAGS+=-pthread -O2 -Wall -Wextra -Wpedantic -Wstrict-overflow -fno-strict-aliasing -std=gnu11 -g -O0 Err vernunftzentrum.de 70 i prefix=/usr/local Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i-all: fiche Err vernunftzentrum.de 70 i+all: Err vernunftzentrum.de 70 i+ ${CC} main.c fiche.c $(CFLAGS) -o fiche Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i install: fiche Err vernunftzentrum.de 70 i install -m 0755 fiche $(prefix)/bin Err vernunftzentrum.de 70 1diff --git a/fiche.c b/fiche.c /ckeen/repos/fiche/file/fiche.c.gph vernunftzentrum.de 70 i@@ -5,7 +5,7 @@ Fiche - Command line pastebin for sharing terminal output. Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i License: MIT (http://www.opensource.org/licenses/mit-license.php) Err vernunftzentrum.de 70 i Repository: https://github.com/solusipse/fiche/ Err vernunftzentrum.de 70 i-Live example: http://code.solusipse.net/ Err vernunftzentrum.de 70 i+Live example: http://termbin.com Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i ------------------------------------------------------------------------------- Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i@@ -13,566 +13,720 @@ usage: fiche [-DepbsdolBuw]. Err vernunftzentrum.de 70 i [-D] [-e] [-d domain] [-p port] [-s slug size] Err vernunftzentrum.de 70 i [-o output directory] [-B buffer size] [-u user name] Err vernunftzentrum.de 70 i [-l log file] [-b banlist] [-w whitelist] Err vernunftzentrum.de 70 i- Err vernunftzentrum.de 70 i -D option is for daemonizing fiche Err vernunftzentrum.de 70 i- Err vernunftzentrum.de 70 i -e option is for using an extended character set for the URL Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i Compile with Makefile or manually with -O2 and -pthread flags. Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i To install use `make install` command. Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i Use netcat to push text - example: Err vernunftzentrum.de 70 i- Err vernunftzentrum.de 70 i $ cat fiche.c | nc localhost 9999 Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i ------------------------------------------------------------------------------- Err vernunftzentrum.de 70 i */ Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i-#include Err vernunftzentrum.de 70 i #include "fiche.h" Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i-int main(int argc, char **argv) Err vernunftzentrum.de 70 i-{ Err vernunftzentrum.de 70 i- time_seed = time(0); Err vernunftzentrum.de 70 i+#include Err vernunftzentrum.de 70 i+#include Err vernunftzentrum.de 70 i+#include Err vernunftzentrum.de 70 i+#include Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+#include Err vernunftzentrum.de 70 i+#include Err vernunftzentrum.de 70 i+#include Err vernunftzentrum.de 70 i+#include Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+#include Err vernunftzentrum.de 70 i+#include Err vernunftzentrum.de 70 i+#include Err vernunftzentrum.de 70 i+#include Err vernunftzentrum.de 70 i+#include Err vernunftzentrum.de 70 i+#include Err vernunftzentrum.de 70 i+#include Err vernunftzentrum.de 70 i+#include Err vernunftzentrum.de 70 i+#include Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+/****************************************************************************** Err vernunftzentrum.de 70 i+ * Various declarations Err vernunftzentrum.de 70 i+ */ Err vernunftzentrum.de 70 i+const char *Fiche_Symbols = "abcdefghijklmnopqrstuvwxyz0123456789"; Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i- parse_parameters(argc, argv); Err vernunftzentrum.de 70 i- set_domain_name(); Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i- if (getuid() == 0) Err vernunftzentrum.de 70 i- { Err vernunftzentrum.de 70 i- if (UID == -1) Err vernunftzentrum.de 70 i- error("user not set"); Err vernunftzentrum.de 70 i- if (setgid(GID) != 0) Err vernunftzentrum.de 70 i- error("Unable to drop group privileges"); Err vernunftzentrum.de 70 i- if (setuid(UID) != 0) Err vernunftzentrum.de 70 i- error("Unable to drop user privileges"); Err vernunftzentrum.de 70 i- } Err vernunftzentrum.de 70 i+/****************************************************************************** Err vernunftzentrum.de 70 i+ * Inner structs Err vernunftzentrum.de 70 i+ */ Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+struct fiche_connection { Err vernunftzentrum.de 70 i+ int socket; Err vernunftzentrum.de 70 i+ struct sockaddr_in address; Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ Fiche_Settings *settings; Err vernunftzentrum.de 70 i+}; Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+/****************************************************************************** Err vernunftzentrum.de 70 i+ * Static function declarations Err vernunftzentrum.de 70 i+ */ Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+// Settings-related Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+/** Err vernunftzentrum.de 70 i+ * @brief Sets domain name Err vernunftzentrum.de 70 i+ * @warning settings.domain has to be freed after using this function! Err vernunftzentrum.de 70 i+ */ Err vernunftzentrum.de 70 i+static int set_domain_name(Fiche_Settings *settings); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+/** Err vernunftzentrum.de 70 i+ * @brief Changes user running this program to requested one Err vernunftzentrum.de 70 i+ * @warning Application has to be run as root to use this function Err vernunftzentrum.de 70 i+ */ Err vernunftzentrum.de 70 i+static int perform_user_change(const Fiche_Settings *settings); Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i- if (BASEDIR == NULL) Err vernunftzentrum.de 70 i- set_basedir(); Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i- startup_message(); Err vernunftzentrum.de 70 i+// Server-related Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i- int listen_socket, optval = 1; Err vernunftzentrum.de 70 i- struct sockaddr_in server_address; Err vernunftzentrum.de 70 i+/** Err vernunftzentrum.de 70 i+ * @brief Starts server with settings provided in Fiche_Settings struct Err vernunftzentrum.de 70 i+ */ Err vernunftzentrum.de 70 i+static int start_server(Fiche_Settings *settings); Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i- listen_socket = create_socket(); Err vernunftzentrum.de 70 i- setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, (const void *)&optval , sizeof(int)); Err vernunftzentrum.de 70 i+/** Err vernunftzentrum.de 70 i+ * @brief Dispatches incoming connections by spawning threads Err vernunftzentrum.de 70 i+ */ Err vernunftzentrum.de 70 i+static void dispatch_connection(int socket, Fiche_Settings *settings); Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i-#if (HAVE_INET6) Err vernunftzentrum.de 70 i- struct sockaddr_in6 server_address6; Err vernunftzentrum.de 70 i- if (IPv6) Err vernunftzentrum.de 70 i+/** Err vernunftzentrum.de 70 i+ * @brief Handles connections Err vernunftzentrum.de 70 i+ * @remarks Is being run by dispatch_connection in separate threads Err vernunftzentrum.de 70 i+ * @arg args Struct fiche_connection containing connection details Err vernunftzentrum.de 70 i+ */ Err vernunftzentrum.de 70 i+static void *handle_connection(void *args); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+// Server-related utils Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+/** Err vernunftzentrum.de 70 i+ * @brief Generates a slug that will be used for paste creation Err vernunftzentrum.de 70 i+ * @warning output has to be freed after using! Err vernunftzentrum.de 70 i+ * Err vernunftzentrum.de 70 i+ * @arg output pointer to output string containing full path to directory Err vernunftzentrum.de 70 i+ * @arg length default or user-requested length of a slug Err vernunftzentrum.de 70 i+ * @arg extra_length additional length that was added to speed-up the Err vernunftzentrum.de 70 i+ * generation process Err vernunftzentrum.de 70 i+ * Err vernunftzentrum.de 70 i+ * This function is used in connection with create_directory function Err vernunftzentrum.de 70 i+ * It generates strings that are used to create a directory for Err vernunftzentrum.de 70 i+ * user-provided data. If directory already exists, we ask this function Err vernunftzentrum.de 70 i+ * to generate another slug with increased size. Err vernunftzentrum.de 70 i+ */ Err vernunftzentrum.de 70 i+static void generate_slug(char **output, uint8_t length, uint8_t extra_length); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+/** Err vernunftzentrum.de 70 i+ * @brief Creates a directory at requested path using requested slug Err vernunftzentrum.de 70 i+ * @returns 0 if succeded, 1 if failed or dir already existed Err vernunftzentrum.de 70 i+ * Err vernunftzentrum.de 70 i+ * @arg output_dir root directory for all pastes Err vernunftzentrum.de 70 i+ * @arg slug directory name for a particular paste Err vernunftzentrum.de 70 i+ */ Err vernunftzentrum.de 70 i+static int create_directory(char *output_dir, char *slug); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+/** Err vernunftzentrum.de 70 i+ * @brief Saves data to file at requested path Err vernunftzentrum.de 70 i+ * Err vernunftzentrum.de 70 i+ * @arg data Buffer with data received from the user Err vernunftzentrum.de 70 i+ * @arg path Path at which file containing data from the buffer will be created Err vernunftzentrum.de 70 i+ */ Err vernunftzentrum.de 70 i+static int save_to_file(uint8_t *data, char *output_dir, char *path); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+// Logging-related Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+/** Err vernunftzentrum.de 70 i+ * @brief Displays error messages Err vernunftzentrum.de 70 i+ */ Err vernunftzentrum.de 70 i+static void print_error(const char *format, ...); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+/** Err vernunftzentrum.de 70 i+ * @brief Displays status messages Err vernunftzentrum.de 70 i+ */ Err vernunftzentrum.de 70 i+static void print_status(const char *format, ...); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+/** Err vernunftzentrum.de 70 i+ * @brief Displays horizontal line Err vernunftzentrum.de 70 i+ */ Err vernunftzentrum.de 70 i+static void print_separator(); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+/** Err vernunftzentrum.de 70 i+ * @brief Saves connection entry to the logfile Err vernunftzentrum.de 70 i+ */ Err vernunftzentrum.de 70 i+static void log_entry(const Fiche_Settings *s, const char *ip, Err vernunftzentrum.de 70 i+ const char *hostname, const char *slug); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+/** Err vernunftzentrum.de 70 i+ * @brief Returns string containing current date Err vernunftzentrum.de 70 i+ * @warning Output has to be freed! Err vernunftzentrum.de 70 i+ */ Err vernunftzentrum.de 70 i+static char *get_date(); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+/** Err vernunftzentrum.de 70 i+ * @brief Time seed Err vernunftzentrum.de 70 i+ */ Err vernunftzentrum.de 70 i+unsigned int seed; Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+/****************************************************************************** Err vernunftzentrum.de 70 i+ * Public fiche functions Err vernunftzentrum.de 70 i+ */ Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+void fiche_init(Fiche_Settings *settings) { Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // Initialize everything to default values Err vernunftzentrum.de 70 i+ // or to NULL in case of pointers Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ struct Fiche_Settings def = { Err vernunftzentrum.de 70 i+ // domain Err vernunftzentrum.de 70 i+ "example.com", Err vernunftzentrum.de 70 i+ // output dir Err vernunftzentrum.de 70 i+ "code", Err vernunftzentrum.de 70 i+ // port Err vernunftzentrum.de 70 i+ 9999, Err vernunftzentrum.de 70 i+ // slug length Err vernunftzentrum.de 70 i+ 4, Err vernunftzentrum.de 70 i+ // buffer length Err vernunftzentrum.de 70 i+ 32768, Err vernunftzentrum.de 70 i+ // user name Err vernunftzentrum.de 70 i+ NULL, Err vernunftzentrum.de 70 i+ // path to log file Err vernunftzentrum.de 70 i+ NULL, Err vernunftzentrum.de 70 i+ // path to banlist Err vernunftzentrum.de 70 i+ NULL, Err vernunftzentrum.de 70 i+ // path to whitelist Err vernunftzentrum.de 70 i+ NULL Err vernunftzentrum.de 70 i+ }; Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // Copy default settings to provided instance Err vernunftzentrum.de 70 i+ *settings = def; Err vernunftzentrum.de 70 i+} Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+int fiche_run(Fiche_Settings settings) { Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ seed = time(NULL); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // Display welcome message Err vernunftzentrum.de 70 i { Err vernunftzentrum.de 70 i- server_address6 = set_address6(server_address6); Err vernunftzentrum.de 70 i- bind_to_port6(listen_socket, server_address6); Err vernunftzentrum.de 70 i+ char *date = get_date(); Err vernunftzentrum.de 70 i+ print_status("Starting fiche on %s...", date); Err vernunftzentrum.de 70 i+ free(date); Err vernunftzentrum.de 70 i } Err vernunftzentrum.de 70 i- else Err vernunftzentrum.de 70 i- { Err vernunftzentrum.de 70 i-#else Err vernunftzentrum.de 70 i- if (1) { Err vernunftzentrum.de 70 i-#endif Err vernunftzentrum.de 70 i- server_address = set_address(server_address); Err vernunftzentrum.de 70 i- bind_to_port(listen_socket, server_address); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // Try to set requested user Err vernunftzentrum.de 70 i+ if ( perform_user_change(&settings) != 0) { Err vernunftzentrum.de 70 i+ print_error("Was not able to change the user!"); Err vernunftzentrum.de 70 i+ return -1; Err vernunftzentrum.de 70 i } Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i- if (DAEMON) Err vernunftzentrum.de 70 i+ // Check if output directory is writable Err vernunftzentrum.de 70 i+ // - First we try to create it Err vernunftzentrum.de 70 i { Err vernunftzentrum.de 70 i- pid_t pid; Err vernunftzentrum.de 70 i+ mkdir( Err vernunftzentrum.de 70 i+ settings.output_dir_path, Err vernunftzentrum.de 70 i+ S_IRWXU | S_IRGRP | S_IROTH | S_IXOTH | S_IXGRP Err vernunftzentrum.de 70 i+ ); Err vernunftzentrum.de 70 i+ // - Then we check if we can write there Err vernunftzentrum.de 70 i+ if ( access(settings.output_dir_path, W_OK) != 0 ) { Err vernunftzentrum.de 70 i+ print_error("Output directory not writable!"); Err vernunftzentrum.de 70 i+ return -1; Err vernunftzentrum.de 70 i+ } Err vernunftzentrum.de 70 i+ } Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // Check if log file is writable (if set) Err vernunftzentrum.de 70 i+ if ( settings.log_file_path ) { Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // Create log file if it doesn't exist Err vernunftzentrum.de 70 i+ creat(settings.log_file_path, S_IRWXU); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // Then check if it's accessible Err vernunftzentrum.de 70 i+ if ( access(settings.log_file_path, W_OK) != 0 ) { Err vernunftzentrum.de 70 i+ print_error("Log file not writable!"); Err vernunftzentrum.de 70 i+ return -1; Err vernunftzentrum.de 70 i+ } Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i- pid = fork(); Err vernunftzentrum.de 70 i- if (pid == -1) Err vernunftzentrum.de 70 i- error("Failed to fork"); Err vernunftzentrum.de 70 i- if (pid == 0) Err vernunftzentrum.de 70 i- while (1) perform_connection(listen_socket); Err vernunftzentrum.de 70 i } Err vernunftzentrum.de 70 i- else Err vernunftzentrum.de 70 i- while (1) perform_connection(listen_socket); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // Try to set domain name Err vernunftzentrum.de 70 i+ if ( set_domain_name(&settings) != 0 ) { Err vernunftzentrum.de 70 i+ print_error("Was not able to set domain name!"); Err vernunftzentrum.de 70 i+ return -1; Err vernunftzentrum.de 70 i+ } Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // Main loop in this method Err vernunftzentrum.de 70 i+ start_server(&settings); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // Perform final cleanup Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // This is allways allocated on the heap Err vernunftzentrum.de 70 i+ free(settings.domain); Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i return 0; Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+} Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+/****************************************************************************** Err vernunftzentrum.de 70 i+ * Static functions below Err vernunftzentrum.de 70 i+ */ Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+static void print_error(const char *format, ...) { Err vernunftzentrum.de 70 i+ va_list args; Err vernunftzentrum.de 70 i+ va_start(args, format); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ printf("[Fiche][ERROR] "); Err vernunftzentrum.de 70 i+ vprintf(format, args); Err vernunftzentrum.de 70 i+ printf("\n"); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ va_end(args); Err vernunftzentrum.de 70 i } Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i-void *thread_connection(void *args) Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+static void print_status(const char *format, ...) { Err vernunftzentrum.de 70 i+ va_list args; Err vernunftzentrum.de 70 i+ va_start(args, format); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ printf("[Fiche][STATUS] "); Err vernunftzentrum.de 70 i+ vprintf(format, args); Err vernunftzentrum.de 70 i+ printf("\n"); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ va_end(args); Err vernunftzentrum.de 70 i+} Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+static void print_separator() { Err vernunftzentrum.de 70 i+ printf("============================================================\n"); Err vernunftzentrum.de 70 i+} Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+static void log_entry(const Fiche_Settings *s, const char *ip, Err vernunftzentrum.de 70 i+ const char *hostname, const char *slug) Err vernunftzentrum.de 70 i { Err vernunftzentrum.de 70 i- int connection_socket = ((struct thread_arguments *) args ) -> connection_socket; Err vernunftzentrum.de 70 i- struct sockaddr_in client_address; Err vernunftzentrum.de 70 i- struct client_data data; Err vernunftzentrum.de 70 i-#if (HAVE_INET6) Err vernunftzentrum.de 70 i- struct sockaddr_in6 client_address6; Err vernunftzentrum.de 70 i- if (IPv6) Err vernunftzentrum.de 70 i- { Err vernunftzentrum.de 70 i- client_address6 = ((struct thread_arguments *) args ) -> client_address6; Err vernunftzentrum.de 70 i- data = get_client_address6(client_address6); Err vernunftzentrum.de 70 i+ // Logging to file not enabled, finish here Err vernunftzentrum.de 70 i+ if (!s->log_file_path) { Err vernunftzentrum.de 70 i+ return; Err vernunftzentrum.de 70 i } Err vernunftzentrum.de 70 i- else Err vernunftzentrum.de 70 i- { Err vernunftzentrum.de 70 i-#else Err vernunftzentrum.de 70 i- if (1) { Err vernunftzentrum.de 70 i-#endif Err vernunftzentrum.de 70 i- client_address = ((struct thread_arguments *) args ) -> client_address; Err vernunftzentrum.de 70 i- data = get_client_address(client_address); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ FILE *f = fopen(s->log_file_path, "a"); Err vernunftzentrum.de 70 i+ if (!f) { Err vernunftzentrum.de 70 i+ print_status("Was not able to save entry to the log!"); Err vernunftzentrum.de 70 i+ return; Err vernunftzentrum.de 70 i } Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i- char buffer[BUFSIZE]; Err vernunftzentrum.de 70 i- bzero(buffer, BUFSIZE); Err vernunftzentrum.de 70 i- int status = recv(connection_socket, buffer, BUFSIZE, MSG_WAITALL); Err vernunftzentrum.de 70 i+ char *date = get_date(); Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i- if (WHITELIST != NULL && check_whitelist(data.ip_address) == NULL) Err vernunftzentrum.de 70 i- { Err vernunftzentrum.de 70 i- display_info(data, NULL, "Rejected connection from unknown user."); Err vernunftzentrum.de 70 i- save_log(NULL, data.ip_address, data.hostname); Err vernunftzentrum.de 70 i- if (write(connection_socket, "You are not whitelisted!\n", 26) < 0) Err vernunftzentrum.de 70 i- printf("Error writing on stream socket\n"); Err vernunftzentrum.de 70 i- close(connection_socket); Err vernunftzentrum.de 70 i- pthread_exit(NULL); Err vernunftzentrum.de 70 i- } Err vernunftzentrum.de 70 i+ // Write entry to file Err vernunftzentrum.de 70 i+ fprintf(f, "%s -- %s -- %s (%s)\n", slug, date, ip, hostname); Err vernunftzentrum.de 70 i+ fclose(f); Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i- if (BANLIST != NULL && check_banlist(data.ip_address) != NULL) Err vernunftzentrum.de 70 i- { Err vernunftzentrum.de 70 i- display_info(data, NULL, "Rejected connection from banned user."); Err vernunftzentrum.de 70 i- save_log(NULL, data.ip_address, data.hostname); Err vernunftzentrum.de 70 i- if (write(connection_socket, "You are banned!\n", 17) < 0) Err vernunftzentrum.de 70 i- printf("Error writing on stream socket\n"); Err vernunftzentrum.de 70 i- close(connection_socket); Err vernunftzentrum.de 70 i- pthread_exit(NULL); Err vernunftzentrum.de 70 i- } Err vernunftzentrum.de 70 i+ free(date); Err vernunftzentrum.de 70 i+} Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i- if (check_protocol(buffer) == 1) Err vernunftzentrum.de 70 i- status = -1; Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i- if (status != -1) Err vernunftzentrum.de 70 i- { Err vernunftzentrum.de 70 i- char slug[SLUG_SIZE+8]; Err vernunftzentrum.de 70 i- generate_url(buffer, slug, SLUG_SIZE+8, data); Err vernunftzentrum.de 70 i- save_log(slug, data.ip_address, data.hostname); Err vernunftzentrum.de 70 i- char response[strlen(slug) + strlen(DOMAIN) + 2]; Err vernunftzentrum.de 70 i- snprintf(response, sizeof response, "%s%s\n", DOMAIN, slug); Err vernunftzentrum.de 70 i- if (write(connection_socket, response, strlen(response)) < 0) Err vernunftzentrum.de 70 i- printf("Error writing on stream socket\n"); Err vernunftzentrum.de 70 i- } Err vernunftzentrum.de 70 i- else Err vernunftzentrum.de 70 i- { Err vernunftzentrum.de 70 i- display_info(data, NULL, "Invalid connection."); Err vernunftzentrum.de 70 i- save_log(NULL, data.ip_address, data.hostname); Err vernunftzentrum.de 70 i- if (write(connection_socket, "Use netcat.\n", 12) < 0) Err vernunftzentrum.de 70 i- printf("Error writing on stream socket\n"); Err vernunftzentrum.de 70 i- } Err vernunftzentrum.de 70 i+static char *get_date() { Err vernunftzentrum.de 70 i+ struct tm curtime; Err vernunftzentrum.de 70 i+ time_t ltime; Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i- close(connection_socket); Err vernunftzentrum.de 70 i- pthread_exit(NULL); Err vernunftzentrum.de 70 i+ ltime=time(<ime); Err vernunftzentrum.de 70 i+ localtime_r(<ime, &curtime); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // Much more than required, date string is usually about 25 chars Err vernunftzentrum.de 70 i+ char buf[128]; Err vernunftzentrum.de 70 i+ asctime_r(&curtime, buf); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ char *out = malloc(strlen(buf) + 1); Err vernunftzentrum.de 70 i+ strcpy(out, buf); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // Remove newline char Err vernunftzentrum.de 70 i+ out[strlen(buf)-1] = 0; Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ return out; Err vernunftzentrum.de 70 i } Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i-void perform_connection(int listen_socket) Err vernunftzentrum.de 70 i-{ Err vernunftzentrum.de 70 i- pthread_t thread_id; Err vernunftzentrum.de 70 i- struct sockaddr_in client_address; Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i- int address_length; Err vernunftzentrum.de 70 i- int connection_socket; Err vernunftzentrum.de 70 i+static int set_domain_name(Fiche_Settings *settings) { Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i-#if (HAVE_INET6) Err vernunftzentrum.de 70 i- struct sockaddr_in6 client_address6; Err vernunftzentrum.de 70 i- if (IPv6) Err vernunftzentrum.de 70 i- { Err vernunftzentrum.de 70 i- address_length = sizeof(client_address6); Err vernunftzentrum.de 70 i- connection_socket = accept(listen_socket, (struct sockaddr *) &client_address6, (void *) &address_length); Err vernunftzentrum.de 70 i+ const char *prefix = "http://"; Err vernunftzentrum.de 70 i+ const int len = strlen(settings->domain) + strlen(prefix) + 1; Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ char *b = malloc(len); Err vernunftzentrum.de 70 i+ if (b == NULL) { Err vernunftzentrum.de 70 i+ return -1; Err vernunftzentrum.de 70 i } Err vernunftzentrum.de 70 i- else Err vernunftzentrum.de 70 i- { Err vernunftzentrum.de 70 i-#else Err vernunftzentrum.de 70 i- if (1) { Err vernunftzentrum.de 70 i-#endif Err vernunftzentrum.de 70 i- address_length = sizeof(client_address); Err vernunftzentrum.de 70 i- connection_socket = accept(listen_socket, (struct sockaddr *) &client_address, (void *) &address_length); Err vernunftzentrum.de 70 i- } Err vernunftzentrum.de 70 i- Err vernunftzentrum.de 70 i- struct timeval timeout; Err vernunftzentrum.de 70 i- timeout.tv_sec = 5; Err vernunftzentrum.de 70 i- timeout.tv_usec = 0; Err vernunftzentrum.de 70 i- Err vernunftzentrum.de 70 i- if (setsockopt (connection_socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)) < 0) Err vernunftzentrum.de 70 i- error("while setting setsockopt timeout"); Err vernunftzentrum.de 70 i- if (setsockopt (connection_socket, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)) < 0) Err vernunftzentrum.de 70 i- error("while setting setsockopt timeout"); Err vernunftzentrum.de 70 i- Err vernunftzentrum.de 70 i- struct thread_arguments arguments; Err vernunftzentrum.de 70 i- arguments.connection_socket = connection_socket; Err vernunftzentrum.de 70 i-#if (HAVE_INET6) Err vernunftzentrum.de 70 i- if (IPv6) Err vernunftzentrum.de 70 i- arguments.client_address6 = client_address6; Err vernunftzentrum.de 70 i- else Err vernunftzentrum.de 70 i-#endif Err vernunftzentrum.de 70 i- arguments.client_address = client_address; Err vernunftzentrum.de 70 i- Err vernunftzentrum.de 70 i- if (pthread_create(&thread_id, NULL, &thread_connection, &arguments) != 0) Err vernunftzentrum.de 70 i- error("on thread creation"); Err vernunftzentrum.de 70 i- else Err vernunftzentrum.de 70 i- pthread_detach(thread_id); Err vernunftzentrum.de 70 i-} Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i-char *get_date() Err vernunftzentrum.de 70 i-{ Err vernunftzentrum.de 70 i- time_t rawtime; Err vernunftzentrum.de 70 i- struct tm *timeinfo; Err vernunftzentrum.de 70 i- char *timechar; Err vernunftzentrum.de 70 i+ strcpy(b, prefix); Err vernunftzentrum.de 70 i+ strcat(b, settings->domain); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ settings->domain = b; Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i- time(&rawtime); Err vernunftzentrum.de 70 i- timeinfo = localtime(&rawtime); Err vernunftzentrum.de 70 i- timechar = asctime(timeinfo); Err vernunftzentrum.de 70 i- timechar[strlen(timechar)-1] = 0; Err vernunftzentrum.de 70 i+ print_status("Domain set to: %s.", settings->domain); Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i- return timechar; Err vernunftzentrum.de 70 i+ return 0; Err vernunftzentrum.de 70 i } Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i-struct client_data get_client_address(struct sockaddr_in client_address) Err vernunftzentrum.de 70 i-{ Err vernunftzentrum.de 70 i- struct hostent *hostp; Err vernunftzentrum.de 70 i- struct client_data data; Err vernunftzentrum.de 70 i- char *hostaddrp; Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i- hostp = gethostbyaddr((const char *)&client_address.sin_addr.s_addr, sizeof(client_address.sin_addr.s_addr), AF_INET); Err vernunftzentrum.de 70 i- if (hostp == NULL) Err vernunftzentrum.de 70 i- { Err vernunftzentrum.de 70 i- printf("WARNING: Couldn't obtain client's hostname\n"); Err vernunftzentrum.de 70 i- data.hostname = "n/a"; Err vernunftzentrum.de 70 i+static int perform_user_change(const Fiche_Settings *settings) { Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // User change wasn't requested, finish here Err vernunftzentrum.de 70 i+ if (settings->user_name == NULL) { Err vernunftzentrum.de 70 i+ return 0; Err vernunftzentrum.de 70 i } Err vernunftzentrum.de 70 i- else Err vernunftzentrum.de 70 i- data.hostname = hostp->h_name; Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i- hostaddrp = inet_ntoa(client_address.sin_addr); Err vernunftzentrum.de 70 i- if (hostaddrp == NULL) Err vernunftzentrum.de 70 i- { Err vernunftzentrum.de 70 i- printf("WARNING: Couldn't obtain client's address\n"); Err vernunftzentrum.de 70 i- data.ip_address = "n/a"; Err vernunftzentrum.de 70 i+ // Check if root, if not - finish here Err vernunftzentrum.de 70 i+ if (getuid() != 0) { Err vernunftzentrum.de 70 i+ print_error("Run as root if you want to change the user!"); Err vernunftzentrum.de 70 i+ return -1; Err vernunftzentrum.de 70 i } Err vernunftzentrum.de 70 i- else Err vernunftzentrum.de 70 i- data.ip_address = hostaddrp; Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i- return data; Err vernunftzentrum.de 70 i-} Err vernunftzentrum.de 70 i+ // Get user details Err vernunftzentrum.de 70 i+ const struct passwd *userdata = getpwnam(settings->user_name); Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i-#if (HAVE_INET6) Err vernunftzentrum.de 70 i-struct client_data get_client_address6(struct sockaddr_in6 client_address6) Err vernunftzentrum.de 70 i-{ Err vernunftzentrum.de 70 i- struct hostent *hostp; Err vernunftzentrum.de 70 i- struct client_data data; Err vernunftzentrum.de 70 i- static char hostaddrp[INET6_ADDRSTRLEN]; Err vernunftzentrum.de 70 i+ const int uid = userdata->pw_uid; Err vernunftzentrum.de 70 i+ const int gid = userdata->pw_gid; Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i- hostp = gethostbyaddr((const char *)&client_address6.sin6_addr, sizeof(client_address6.sin6_addr), AF_INET6); Err vernunftzentrum.de 70 i- if (hostp == NULL) Err vernunftzentrum.de 70 i- { Err vernunftzentrum.de 70 i- printf("WARNING: Couldn't obtain client's hostname\n"); Err vernunftzentrum.de 70 i- data.hostname = "n/a"; Err vernunftzentrum.de 70 i+ if (uid == -1 || gid == -1) { Err vernunftzentrum.de 70 i+ print_error("Could find requested user: %s!", settings->user_name); Err vernunftzentrum.de 70 i+ return -1; Err vernunftzentrum.de 70 i } Err vernunftzentrum.de 70 i- else Err vernunftzentrum.de 70 i- data.hostname = hostp->h_name; Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i- inet_ntop(AF_INET6, &(client_address6.sin6_addr), hostaddrp, Err vernunftzentrum.de 70 i- INET6_ADDRSTRLEN); Err vernunftzentrum.de 70 i- if (hostaddrp == NULL) Err vernunftzentrum.de 70 i- { Err vernunftzentrum.de 70 i- printf("WARNING: Couldn't obtain client's address\n"); Err vernunftzentrum.de 70 i- data.ip_address = "n/a"; Err vernunftzentrum.de 70 i+ if (setgid(gid) != 0) { Err vernunftzentrum.de 70 i+ print_error("Couldn't switch to requested user: %s!", settings->user_name); Err vernunftzentrum.de 70 i } Err vernunftzentrum.de 70 i- else Err vernunftzentrum.de 70 i- data.ip_address = hostaddrp; Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i- return data; Err vernunftzentrum.de 70 i+ if (setuid(uid) != 0) { Err vernunftzentrum.de 70 i+ print_error("Couldn't switch to requested user: %s!", settings->user_name); Err vernunftzentrum.de 70 i+ } Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ print_status("User changed to: %s.", settings->user_name); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ return 0; Err vernunftzentrum.de 70 i } Err vernunftzentrum.de 70 i-#endif Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i-void save_log(char *slug, char *hostaddrp, char *h_name) Err vernunftzentrum.de 70 i-{ Err vernunftzentrum.de 70 i- if (LOG != NULL) Err vernunftzentrum.de 70 i- { Err vernunftzentrum.de 70 i- char contents[256]; Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i- if (slug != NULL) Err vernunftzentrum.de 70 i- snprintf(contents, sizeof contents, "%s -- %s -- %s (%s)\n", slug, get_date(), hostaddrp, h_name); Err vernunftzentrum.de 70 i- else Err vernunftzentrum.de 70 i- snprintf(contents, sizeof contents, "%s -- %s -- %s (%s)\n", "rej", get_date(), hostaddrp, h_name); Err vernunftzentrum.de 70 i+static int start_server(Fiche_Settings *settings) { Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // Perform socket creation Err vernunftzentrum.de 70 i+ int s = socket(AF_INET, SOCK_STREAM, 0); Err vernunftzentrum.de 70 i+ if (s < 0) { Err vernunftzentrum.de 70 i+ print_error("Couldn't create a socket!"); Err vernunftzentrum.de 70 i+ return -1; Err vernunftzentrum.de 70 i+ } Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // Set socket settings Err vernunftzentrum.de 70 i+ if ( setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &(int){ 1 } , sizeof(int)) != 0 ) { Err vernunftzentrum.de 70 i+ print_error("Couldn't prepare the socket!"); Err vernunftzentrum.de 70 i+ return -1; Err vernunftzentrum.de 70 i+ } Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // Prepare address and port handler Err vernunftzentrum.de 70 i+ struct sockaddr_in address; Err vernunftzentrum.de 70 i+ address.sin_family = AF_INET; Err vernunftzentrum.de 70 i+ address.sin_addr.s_addr = INADDR_ANY; Err vernunftzentrum.de 70 i+ address.sin_port = htons(settings->port); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // Bind to port Err vernunftzentrum.de 70 i+ if ( bind(s, (struct sockaddr *) &address, sizeof(address)) != 0) { Err vernunftzentrum.de 70 i+ print_error("Couldn't bind to the port: %d!", settings->port); Err vernunftzentrum.de 70 i+ return -1; Err vernunftzentrum.de 70 i+ } Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i- FILE *fp; Err vernunftzentrum.de 70 i- fp = fopen(LOG, "a"); Err vernunftzentrum.de 70 i- fprintf(fp, "%s", contents); Err vernunftzentrum.de 70 i- fclose(fp); Err vernunftzentrum.de 70 i+ // Start listening Err vernunftzentrum.de 70 i+ if ( listen(s, 128) != 0 ) { Err vernunftzentrum.de 70 i+ print_error("Couldn't start listening on the socket!"); Err vernunftzentrum.de 70 i+ return -1; Err vernunftzentrum.de 70 i } Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ print_status("Server started listening on port: %d.", settings->port); Err vernunftzentrum.de 70 i+ print_separator(); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // Run dispatching loop Err vernunftzentrum.de 70 i+ while (1) { Err vernunftzentrum.de 70 i+ dispatch_connection(s, settings); Err vernunftzentrum.de 70 i+ } Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // Give some time for all threads to finish Err vernunftzentrum.de 70 i+ // NOTE: this code is reached only in testing environment Err vernunftzentrum.de 70 i+ // There is currently no way to kill the main thread from any thread Err vernunftzentrum.de 70 i+ // Something like this can be done for testing purpouses: Err vernunftzentrum.de 70 i+ // int i = 0; Err vernunftzentrum.de 70 i+ // while (i < 3) { Err vernunftzentrum.de 70 i+ // dispatch_connection(s, settings); Err vernunftzentrum.de 70 i+ // i++; Err vernunftzentrum.de 70 i+ // } Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ sleep(5); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ return 0; Err vernunftzentrum.de 70 i } Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i-void display_info(struct client_data data, char *slug, char *message) Err vernunftzentrum.de 70 i-{ Err vernunftzentrum.de 70 i- if (DAEMON) Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+static void dispatch_connection(int socket, Fiche_Settings *settings) { Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // Create address structs for this socket Err vernunftzentrum.de 70 i+ struct sockaddr_in address; Err vernunftzentrum.de 70 i+ socklen_t addlen = sizeof(address); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // Accept a connection and get a new socket id Err vernunftzentrum.de 70 i+ const int s = accept(socket, (struct sockaddr *) &address, &addlen); Err vernunftzentrum.de 70 i+ if (s < 0 ) { Err vernunftzentrum.de 70 i+ print_error("Error on accepting connection!"); Err vernunftzentrum.de 70 i return; Err vernunftzentrum.de 70 i+ } Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i- if (slug == NULL) Err vernunftzentrum.de 70 i- printf("%s\n", message); Err vernunftzentrum.de 70 i- else Err vernunftzentrum.de 70 i- printf("Saved to: %s\n", slug); Err vernunftzentrum.de 70 i+ // Set timeout for accepted socket Err vernunftzentrum.de 70 i+ const struct timeval timeout = { 5, 0 }; Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i- printf("%s\n", get_date()); Err vernunftzentrum.de 70 i- printf("Client: %s (%s)\n", data.ip_address, data.hostname); Err vernunftzentrum.de 70 i- printf("====================================\n"); Err vernunftzentrum.de 70 i-} Err vernunftzentrum.de 70 i+ if ( setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) != 0 ) { Err vernunftzentrum.de 70 i+ print_error("Couldn't set a timeout!"); Err vernunftzentrum.de 70 i+ } Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i-char *check_banlist(char *ip_address) Err vernunftzentrum.de 70 i-{ Err vernunftzentrum.de 70 i- load_list(BANFILE, 0); Err vernunftzentrum.de 70 i- return strstr(BANLIST, ip_address); Err vernunftzentrum.de 70 i-} Err vernunftzentrum.de 70 i+ if ( setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)) != 0 ) { Err vernunftzentrum.de 70 i+ print_error("Couldn't set a timeout!"); Err vernunftzentrum.de 70 i+ } Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i-char *check_whitelist(char *ip_address) Err vernunftzentrum.de 70 i-{ Err vernunftzentrum.de 70 i- load_list(WHITEFILE, 1); Err vernunftzentrum.de 70 i- return strstr(WHITELIST, ip_address); Err vernunftzentrum.de 70 i-} Err vernunftzentrum.de 70 i+ // Create an argument for the thread function Err vernunftzentrum.de 70 i+ //struct fiche_connection c = { s, address, settings }; Err vernunftzentrum.de 70 i+ struct fiche_connection *c = malloc(sizeof(*c)); Err vernunftzentrum.de 70 i+ if (!c) { Err vernunftzentrum.de 70 i+ print_error("Couldn't allocate memory!"); Err vernunftzentrum.de 70 i+ return; Err vernunftzentrum.de 70 i+ } Err vernunftzentrum.de 70 i+ c->socket = s; Err vernunftzentrum.de 70 i+ c->address = address; Err vernunftzentrum.de 70 i+ c->settings = settings; Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i-void load_list(char *file_path, int type) Err vernunftzentrum.de 70 i-{ Err vernunftzentrum.de 70 i- FILE *fp; Err vernunftzentrum.de 70 i- Err vernunftzentrum.de 70 i- if (( fp = fopen(file_path, "r")) == NULL ) Err vernunftzentrum.de 70 i- error("cannot load list"); Err vernunftzentrum.de 70 i- Err vernunftzentrum.de 70 i- fseek(fp, 0, SEEK_END); Err vernunftzentrum.de 70 i- long fsize = ftell(fp); Err vernunftzentrum.de 70 i- fseek(fp, 0, SEEK_SET); Err vernunftzentrum.de 70 i- Err vernunftzentrum.de 70 i- char *buffer = malloc(fsize + 1); Err vernunftzentrum.de 70 i- if (fread(buffer, fsize, 1, fp) != fsize) Err vernunftzentrum.de 70 i- error("reading list failed"); Err vernunftzentrum.de 70 i- fclose(fp); Err vernunftzentrum.de 70 i- Err vernunftzentrum.de 70 i- buffer[fsize] = 0; Err vernunftzentrum.de 70 i- Err vernunftzentrum.de 70 i- if (type == 0) Err vernunftzentrum.de 70 i- BANLIST = buffer; Err vernunftzentrum.de 70 i- else Err vernunftzentrum.de 70 i- WHITELIST = buffer; Err vernunftzentrum.de 70 i- Err vernunftzentrum.de 70 i- free(buffer); Err vernunftzentrum.de 70 i-} Err vernunftzentrum.de 70 i+ // Spawn a new thread to handle this connection Err vernunftzentrum.de 70 i+ pthread_t id; Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i-int create_socket() Err vernunftzentrum.de 70 i-{ Err vernunftzentrum.de 70 i- int lsocket; Err vernunftzentrum.de 70 i-#if (HAVE_INET6) Err vernunftzentrum.de 70 i- if (IPv6) Err vernunftzentrum.de 70 i- lsocket = socket(AF_INET6, SOCK_STREAM, 0); Err vernunftzentrum.de 70 i- else Err vernunftzentrum.de 70 i-#endif Err vernunftzentrum.de 70 i- lsocket = socket(AF_INET, SOCK_STREAM, 0); Err vernunftzentrum.de 70 i- Err vernunftzentrum.de 70 i- if (lsocket < 0) Err vernunftzentrum.de 70 i- error("Couldn't open socket"); Err vernunftzentrum.de 70 i- Err vernunftzentrum.de 70 i- return lsocket; Err vernunftzentrum.de 70 i-} Err vernunftzentrum.de 70 i+ if ( pthread_create(&id, NULL, &handle_connection, c) != 0 ) { Err vernunftzentrum.de 70 i+ print_error("Couldn't spawn a thread!"); Err vernunftzentrum.de 70 i+ return; Err vernunftzentrum.de 70 i+ } Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i-struct sockaddr_in set_address(struct sockaddr_in server_address) Err vernunftzentrum.de 70 i-{ Err vernunftzentrum.de 70 i- bzero((char *) &server_address, sizeof(server_address)); Err vernunftzentrum.de 70 i- server_address.sin_family = AF_INET; Err vernunftzentrum.de 70 i- server_address.sin_addr.s_addr = htonl(INADDR_ANY); Err vernunftzentrum.de 70 i- server_address.sin_port = htons((unsigned short)PORT); Err vernunftzentrum.de 70 i- return server_address; Err vernunftzentrum.de 70 i-} Err vernunftzentrum.de 70 i+ // Detach thread if created succesfully Err vernunftzentrum.de 70 i+ // TODO: consider using pthread_tryjoin_np Err vernunftzentrum.de 70 i+ pthread_detach(id); Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i-#if (HAVE_INET6) Err vernunftzentrum.de 70 i-struct sockaddr_in6 set_address6(struct sockaddr_in6 server_address6) Err vernunftzentrum.de 70 i-{ Err vernunftzentrum.de 70 i- bzero((char *) &server_address6, sizeof(server_address6)); Err vernunftzentrum.de 70 i- server_address6.sin6_family = AF_INET6; Err vernunftzentrum.de 70 i- server_address6.sin6_addr = in6addr_any; Err vernunftzentrum.de 70 i- server_address6.sin6_port = htons((unsigned short)PORT); Err vernunftzentrum.de 70 i- return server_address6; Err vernunftzentrum.de 70 i } Err vernunftzentrum.de 70 i-#endif Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i-void bind_to_port(int listen_socket, struct sockaddr_in server_address) Err vernunftzentrum.de 70 i-{ Err vernunftzentrum.de 70 i- if (bind(listen_socket, (struct sockaddr *) &server_address, sizeof(server_address)) < 0) Err vernunftzentrum.de 70 i- error("while binding to port"); Err vernunftzentrum.de 70 i- if (listen(listen_socket, QUEUE_SIZE) < 0) Err vernunftzentrum.de 70 i- error("while starting listening"); Err vernunftzentrum.de 70 i-} Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i-#if (HAVE_INET6) Err vernunftzentrum.de 70 i-void bind_to_port6(int listen_socket, struct sockaddr_in6 server_address6) Err vernunftzentrum.de 70 i-{ Err vernunftzentrum.de 70 i- if (bind(listen_socket, (struct sockaddr *) &server_address6, sizeof(server_address6)) < 0) Err vernunftzentrum.de 70 i- error("while binding to port"); Err vernunftzentrum.de 70 i- if (listen(listen_socket, QUEUE_SIZE) < 0) Err vernunftzentrum.de 70 i- error("while starting listening"); Err vernunftzentrum.de 70 i-} Err vernunftzentrum.de 70 i-#endif Err vernunftzentrum.de 70 i+static void *handle_connection(void *args) { Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i-void generate_url(char *buffer, char *slug, size_t slug_length, struct client_data data) Err vernunftzentrum.de 70 i-{ Err vernunftzentrum.de 70 i- int i; Err vernunftzentrum.de 70 i- memset(slug, '\0', slug_length); Err vernunftzentrum.de 70 i+ // Cast args to it's previous type Err vernunftzentrum.de 70 i+ struct fiche_connection *c = (struct fiche_connection *) args; Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // Get client's IP Err vernunftzentrum.de 70 i+ const char *ip = inet_ntoa(c->address.sin_addr); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // Get client's hostname Err vernunftzentrum.de 70 i+ char hostname[1024]; Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ if (getnameinfo((struct sockaddr *)&c->address, sizeof(c->address), Err vernunftzentrum.de 70 i+ hostname, sizeof(hostname), NULL, 0, 0) != 0 ) { Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i- for (i = 0; i <= SLUG_SIZE - 1; i++) Err vernunftzentrum.de 70 i+ // Couldn't resolve a hostname Err vernunftzentrum.de 70 i+ strcpy(hostname, "n/a"); Err vernunftzentrum.de 70 i+ } Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // Print status on this connection Err vernunftzentrum.de 70 i { Err vernunftzentrum.de 70 i-#if defined(BSD) Err vernunftzentrum.de 70 i- int symbol_id = arc4random() % strlen(symbols); Err vernunftzentrum.de 70 i-#else Err vernunftzentrum.de 70 i- int symbol_id = rand_r(&time_seed) % strlen(symbols); Err vernunftzentrum.de 70 i-#endif Err vernunftzentrum.de 70 i- slug[i] = symbols[symbol_id]; Err vernunftzentrum.de 70 i+ char *date = get_date(); Err vernunftzentrum.de 70 i+ print_status("%s", date); Err vernunftzentrum.de 70 i+ free(date); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ print_status("Incoming connection from: %s (%s).", ip, hostname); Err vernunftzentrum.de 70 i+ } Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // Create a buffer Err vernunftzentrum.de 70 i+ uint8_t buffer[c->settings->buffer_len]; Err vernunftzentrum.de 70 i+ memset(buffer, 0, c->settings->buffer_len); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ const int r = recv(c->socket, buffer, sizeof(buffer), MSG_WAITALL); Err vernunftzentrum.de 70 i+ if (r <= 0) { Err vernunftzentrum.de 70 i+ print_error("No data received from the client!"); Err vernunftzentrum.de 70 i+ print_separator(); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // Close the socket Err vernunftzentrum.de 70 i+ close(c->socket); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // Cleanup Err vernunftzentrum.de 70 i+ free(c); Err vernunftzentrum.de 70 i+ pthread_exit(NULL); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ return 0; Err vernunftzentrum.de 70 i+ } Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // - Check if request was performed with a known protocol Err vernunftzentrum.de 70 i+ // TODO Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // - Check if on whitelist Err vernunftzentrum.de 70 i+ // TODO Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // - Check if on banlist Err vernunftzentrum.de 70 i+ // TODO Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // Generate slug and use it to create an url Err vernunftzentrum.de 70 i+ char *slug; Err vernunftzentrum.de 70 i+ uint8_t extra = 0; Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ do { Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // Generate slugs until it's possible to create a directory Err vernunftzentrum.de 70 i+ // with generated slug on disk Err vernunftzentrum.de 70 i+ generate_slug(&slug, c->settings->slug_len, extra); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // Increment counter for additional letters needed Err vernunftzentrum.de 70 i+ ++extra; Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // If i was incremented more than 128 times, something Err vernunftzentrum.de 70 i+ // for sure went wrong. We are closing connection and Err vernunftzentrum.de 70 i+ // killing this thread in such case Err vernunftzentrum.de 70 i+ if (extra > 128) { Err vernunftzentrum.de 70 i+ print_error("Couldn't generate a valid slug!"); Err vernunftzentrum.de 70 i+ print_separator(); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // Cleanup Err vernunftzentrum.de 70 i+ free(c); Err vernunftzentrum.de 70 i+ free(slug); Err vernunftzentrum.de 70 i+ close(c->socket); Err vernunftzentrum.de 70 i+ pthread_exit(NULL); Err vernunftzentrum.de 70 i+ return NULL; Err vernunftzentrum.de 70 i+ } Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ } Err vernunftzentrum.de 70 i+ while(create_directory(c->settings->output_dir_path, slug) != 0); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ if ( save_to_file(buffer, c->settings->output_dir_path, slug) != 0 ) { Err vernunftzentrum.de 70 i+ print_error("Couldn't save a file!"); Err vernunftzentrum.de 70 i+ print_separator(); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // Cleanup Err vernunftzentrum.de 70 i+ free(c); Err vernunftzentrum.de 70 i+ free(slug); Err vernunftzentrum.de 70 i+ close(c->socket); Err vernunftzentrum.de 70 i+ pthread_exit(NULL); Err vernunftzentrum.de 70 i+ return NULL; Err vernunftzentrum.de 70 i } Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i- while (create_directory(slug) == -1) Err vernunftzentrum.de 70 i+ // Write a response to the user Err vernunftzentrum.de 70 i { Err vernunftzentrum.de 70 i-#if defined(BSD) Err vernunftzentrum.de 70 i- int symbol_id = arc4random() % strlen(symbols); Err vernunftzentrum.de 70 i-#else Err vernunftzentrum.de 70 i- int symbol_id = rand_r(&time_seed) % strlen(symbols); Err vernunftzentrum.de 70 i-#endif Err vernunftzentrum.de 70 i- slug[strlen(slug)] = symbols[symbol_id]; Err vernunftzentrum.de 70 i+ // Create an url (additional byte for slash and one for new line) Err vernunftzentrum.de 70 i+ const size_t len = strlen(c->settings->domain) + strlen(slug) + 3; Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ char url[len]; Err vernunftzentrum.de 70 i+ snprintf(url, len, "%s%s%s%s", c->settings->domain, "/", slug, "\n"); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // Send the response Err vernunftzentrum.de 70 i+ write(c->socket, url, len); Err vernunftzentrum.de 70 i } Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i- save_to_file(slug, buffer, data); Err vernunftzentrum.de 70 i-} Err vernunftzentrum.de 70 i+ print_status("Received %d bytes, saved to: %s.", r, slug); Err vernunftzentrum.de 70 i+ print_separator(); Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i-int create_directory(char *slug) Err vernunftzentrum.de 70 i-{ Err vernunftzentrum.de 70 i- char *directory = malloc(strlen(BASEDIR) + strlen(slug) + sizeof(char) + 1); Err vernunftzentrum.de 70 i+ // Log connection Err vernunftzentrum.de 70 i+ // TODO: log unsuccessful and rejected connections Err vernunftzentrum.de 70 i+ log_entry(c->settings, ip, hostname, slug); Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i- snprintf(directory, strlen(BASEDIR) + strlen(slug) + sizeof(char) + 1, "%s%s%s", BASEDIR, "/", slug); Err vernunftzentrum.de 70 i+ // Close the connection Err vernunftzentrum.de 70 i+ close(c->socket); Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i- mkdir(BASEDIR, S_IRWXU | S_IRGRP | S_IROTH | S_IXOTH | S_IXGRP); Err vernunftzentrum.de 70 i- int result = mkdir(directory, S_IRWXU | S_IRGRP | S_IROTH | S_IXOTH | S_IXGRP); Err vernunftzentrum.de 70 i+ // Perform cleanup of values used in this thread Err vernunftzentrum.de 70 i+ free(slug); Err vernunftzentrum.de 70 i+ free(c); Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i- free(directory); Err vernunftzentrum.de 70 i+ pthread_exit(NULL); Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i- return result; Err vernunftzentrum.de 70 i+ return NULL; Err vernunftzentrum.de 70 i } Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i-void save_to_file(char *slug, char *buffer, struct client_data data) Err vernunftzentrum.de 70 i-{ Err vernunftzentrum.de 70 i- char *directory = malloc(strlen(BASEDIR) + strlen(slug) + 11 * sizeof(char) + 1 ); Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i- snprintf(directory, strlen(BASEDIR) + strlen(slug) + 11 * sizeof(char) + 1, "%s%s%s%s", BASEDIR , "/", slug, "/index.txt"); Err vernunftzentrum.de 70 i+static void generate_slug(char **output, uint8_t length, uint8_t extra_length) { Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i- FILE *fp; Err vernunftzentrum.de 70 i- fp = fopen(directory, "w"); Err vernunftzentrum.de 70 i- fprintf(fp, "%s", buffer); Err vernunftzentrum.de 70 i- fclose(fp); Err vernunftzentrum.de 70 i+ // Realloc buffer for slug when we want it to be bigger Err vernunftzentrum.de 70 i+ // This happens in case when directory with this name already Err vernunftzentrum.de 70 i+ // exists. To save time, we don't generate new slugs until Err vernunftzentrum.de 70 i+ // we spot an available one. We add another letter instead. Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i- display_info(data, directory, ""); Err vernunftzentrum.de 70 i+ if (extra_length > 0) { Err vernunftzentrum.de 70 i+ free(*output); Err vernunftzentrum.de 70 i+ } Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i- free(directory); Err vernunftzentrum.de 70 i-} Err vernunftzentrum.de 70 i+ // Create a buffer for slug with extra_length if any Err vernunftzentrum.de 70 i+ *output = calloc(length + 1 + extra_length, sizeof(char)); Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i-void set_uid_gid(char *username) Err vernunftzentrum.de 70 i-{ Err vernunftzentrum.de 70 i- struct passwd *userdata = getpwnam(username); Err vernunftzentrum.de 70 i- if (userdata == NULL) Err vernunftzentrum.de 70 i- error("Provided user doesn't exist"); Err vernunftzentrum.de 70 i+ if (*output == NULL) { Err vernunftzentrum.de 70 i+ // TODO Err vernunftzentrum.de 70 i+ } Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i- UID = userdata->pw_uid; Err vernunftzentrum.de 70 i- GID = userdata->pw_gid; Err vernunftzentrum.de 70 i-} Err vernunftzentrum.de 70 i+ // Take n-th symbol from symbol table and use it for slug generation Err vernunftzentrum.de 70 i+ for (int i = 0; i < length + extra_length; i++) { Err vernunftzentrum.de 70 i+ int n = rand_r(&seed) % strlen(Fiche_Symbols); Err vernunftzentrum.de 70 i+ *(output[0] + sizeof(char) * i) = Fiche_Symbols[n]; Err vernunftzentrum.de 70 i+ } Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i-int check_protocol(char *buffer) Err vernunftzentrum.de 70 i-{ Err vernunftzentrum.de 70 i- if (strlen(buffer) < 3) Err vernunftzentrum.de 70 i- return 1; Err vernunftzentrum.de 70 i- if ((strncmp(buffer, "GET", 3) == 0)||(strncmp(buffer, "POST", 4) == 0)) Err vernunftzentrum.de 70 i- if (strstr(buffer, "HTTP/1.")) Err vernunftzentrum.de 70 i- return 1; Err vernunftzentrum.de 70 i- return 0; Err vernunftzentrum.de 70 i } Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i-void set_basedir() Err vernunftzentrum.de 70 i-{ Err vernunftzentrum.de 70 i- BASEDIR = getenv("HOME"); Err vernunftzentrum.de 70 i- strncat(BASEDIR, "/code", 5 * sizeof(char)); Err vernunftzentrum.de 70 i-} Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i-void startup_message() Err vernunftzentrum.de 70 i-{ Err vernunftzentrum.de 70 i- if (DAEMON) Err vernunftzentrum.de 70 i- return; Err vernunftzentrum.de 70 i+static int create_directory(char *output_dir, char *slug) { Err vernunftzentrum.de 70 i+ // Additional byte is for the slash Err vernunftzentrum.de 70 i+ size_t len = strlen(output_dir) + strlen(slug) + 2; Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i- printf("====================================\n"); Err vernunftzentrum.de 70 i- printf("Domain name: %s\n", DOMAIN); Err vernunftzentrum.de 70 i- printf("Saving files to: %s\n", BASEDIR); Err vernunftzentrum.de 70 i- printf("Fiche started listening on port %d.\n", PORT); Err vernunftzentrum.de 70 i- printf("Buffer size set to: %d.\n", BUFSIZE); Err vernunftzentrum.de 70 i- printf("Slug size set to: %d.\n", SLUG_SIZE); Err vernunftzentrum.de 70 i- printf("Log file: %s\n", LOG); Err vernunftzentrum.de 70 i- printf("====================================\n"); Err vernunftzentrum.de 70 i-} Err vernunftzentrum.de 70 i+ // Generate a path Err vernunftzentrum.de 70 i+ char *path = malloc(len); Err vernunftzentrum.de 70 i+ snprintf(path, len, "%s%s%s", output_dir, "/", slug); Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i-void error(char *buffer) Err vernunftzentrum.de 70 i-{ Err vernunftzentrum.de 70 i- printf("Error: %s\n", buffer); Err vernunftzentrum.de 70 i- exit(1); Err vernunftzentrum.de 70 i-} Err vernunftzentrum.de 70 i+ // Create output directory, just in case Err vernunftzentrum.de 70 i+ mkdir(output_dir, S_IRWXU | S_IRGRP | S_IROTH | S_IXOTH | S_IXGRP); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // Create slug directory Err vernunftzentrum.de 70 i+ const int r = mkdir( Err vernunftzentrum.de 70 i+ path, Err vernunftzentrum.de 70 i+ S_IRWXU | S_IRGRP | S_IROTH | S_IXOTH | S_IXGRP Err vernunftzentrum.de 70 i+ ); Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i-void set_domain_name() { Err vernunftzentrum.de 70 i- char b[128]; Err vernunftzentrum.de 70 i- memcpy(b, DOMAIN, sizeof DOMAIN); Err vernunftzentrum.de 70 i+ free(path); Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i- if (HTTPS) Err vernunftzentrum.de 70 i- snprintf(DOMAIN, sizeof DOMAIN, "%s%s", "https://", b); Err vernunftzentrum.de 70 i- else Err vernunftzentrum.de 70 i- snprintf(DOMAIN, sizeof DOMAIN, "%s%s", "http://", b); Err vernunftzentrum.de 70 i+ return r; Err vernunftzentrum.de 70 i } Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i-void parse_parameters(int argc, char **argv) Err vernunftzentrum.de 70 i-{ Err vernunftzentrum.de 70 i- int c; Err vernunftzentrum.de 70 i- Err vernunftzentrum.de 70 i- while ((c = getopt (argc, argv, "D6eSp:b:s:d:o:l:B:u:w:")) != -1) Err vernunftzentrum.de 70 i- switch (c) Err vernunftzentrum.de 70 i- { Err vernunftzentrum.de 70 i- case 'D': Err vernunftzentrum.de 70 i- DAEMON = 1; Err vernunftzentrum.de 70 i- break; Err vernunftzentrum.de 70 i- case '6': Err vernunftzentrum.de 70 i- IPv6 = 1; Err vernunftzentrum.de 70 i- break; Err vernunftzentrum.de 70 i- case 'e': Err vernunftzentrum.de 70 i- snprintf(symbols, sizeof symbols, "%s", "abcdefghijklmnopqrstuvwxyz0123456789-+_=.ABCDEFGHIJKLMNOPQRSTUVWXYZ"); Err vernunftzentrum.de 70 i- break; Err vernunftzentrum.de 70 i- case 'S': Err vernunftzentrum.de 70 i- HTTPS = 1; Err vernunftzentrum.de 70 i- break; Err vernunftzentrum.de 70 i- case 'd': Err vernunftzentrum.de 70 i- snprintf(DOMAIN, sizeof DOMAIN, "%s%s", optarg, "/"); Err vernunftzentrum.de 70 i- break; Err vernunftzentrum.de 70 i- case 'p': Err vernunftzentrum.de 70 i- PORT = atoi(optarg); Err vernunftzentrum.de 70 i- break; Err vernunftzentrum.de 70 i- case 'B': Err vernunftzentrum.de 70 i- BUFSIZE = atoi(optarg); Err vernunftzentrum.de 70 i- break; Err vernunftzentrum.de 70 i- case 'b': Err vernunftzentrum.de 70 i- BANFILE = optarg; Err vernunftzentrum.de 70 i- load_list(BANFILE, 0); Err vernunftzentrum.de 70 i- break; Err vernunftzentrum.de 70 i- case 's': Err vernunftzentrum.de 70 i- SLUG_SIZE = atoi(optarg); Err vernunftzentrum.de 70 i- break; Err vernunftzentrum.de 70 i- case 'o': Err vernunftzentrum.de 70 i- BASEDIR = optarg; Err vernunftzentrum.de 70 i- break; Err vernunftzentrum.de 70 i- case 'l': Err vernunftzentrum.de 70 i- LOG = optarg; Err vernunftzentrum.de 70 i- break; Err vernunftzentrum.de 70 i- case 'u': Err vernunftzentrum.de 70 i- set_uid_gid(optarg); Err vernunftzentrum.de 70 i- break; Err vernunftzentrum.de 70 i- case 'w': Err vernunftzentrum.de 70 i- WHITEFILE = optarg; Err vernunftzentrum.de 70 i- load_list(WHITEFILE, 1); Err vernunftzentrum.de 70 i- break; Err vernunftzentrum.de 70 i- default: Err vernunftzentrum.de 70 i- printf("usage: fiche [-D6epbsdSolBuw].\n"); Err vernunftzentrum.de 70 i- printf(" [-d domain] [-p port] [-s slug_size]\n"); Err vernunftzentrum.de 70 i- printf(" [-o output directory] [-B buffer_size] [-u user name]\n"); Err vernunftzentrum.de 70 i- printf(" [-l log file] [-b banlist] [-w whitelist]\n"); Err vernunftzentrum.de 70 i- exit(1); Err vernunftzentrum.de 70 i- } Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+static int save_to_file(uint8_t *data, char *output_dir, char *slug) { Err vernunftzentrum.de 70 i+ char *file_name = "index.txt"; Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // Additional 2 bytes are for 2 slashes Err vernunftzentrum.de 70 i+ size_t len = strlen(output_dir) + strlen(slug) + strlen(file_name) + 3; Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // Generate a path Err vernunftzentrum.de 70 i+ char *path = malloc(len); Err vernunftzentrum.de 70 i+ snprintf(path, len, "%s%s%s%s%s", output_dir, "/", slug, "/", file_name); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // Attempt file saving Err vernunftzentrum.de 70 i+ FILE *f = fopen(path, "w"); Err vernunftzentrum.de 70 i+ if (!f) { Err vernunftzentrum.de 70 i+ return -1; Err vernunftzentrum.de 70 i+ } Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ if ( fprintf(f, "%s", data) < 0 ) { Err vernunftzentrum.de 70 i+ return -1; Err vernunftzentrum.de 70 i+ } Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ fclose(f); Err vernunftzentrum.de 70 i+ free(path); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ return 0; Err vernunftzentrum.de 70 i } Err vernunftzentrum.de 70 1diff --git a/fiche.h b/fiche.h /ckeen/repos/fiche/file/fiche.h.gph vernunftzentrum.de 70 i@@ -5,7 +5,7 @@ Fiche - Command line pastebin for sharing terminal output. Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i License: MIT (http://www.opensource.org/licenses/mit-license.php) Err vernunftzentrum.de 70 i Repository: https://github.com/solusipse/fiche/ Err vernunftzentrum.de 70 i-Live example: http://code.solusipse.net/ Err vernunftzentrum.de 70 i+Live example: http://termbin.com Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i ------------------------------------------------------------------------------- Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i@@ -14,15 +14,7 @@ usage: fiche [-DepbsdolBuw]. Err vernunftzentrum.de 70 i [-o output directory] [-B buffer size] [-u user name] Err vernunftzentrum.de 70 i [-l log file] [-b banlist] [-w whitelist] Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i--D option is for daemonizing fiche Err vernunftzentrum.de 70 i- Err vernunftzentrum.de 70 i--e option is for using an extended character set for the URL Err vernunftzentrum.de 70 i- Err vernunftzentrum.de 70 i-Compile with Makefile or manually with -O2 and -pthread flags. Err vernunftzentrum.de 70 i-To install use `make install` command. Err vernunftzentrum.de 70 i- Err vernunftzentrum.de 70 i Use netcat to push text - example: Err vernunftzentrum.de 70 i- Err vernunftzentrum.de 70 i $ cat fiche.c | nc localhost 9999 Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i ------------------------------------------------------------------------------- Err vernunftzentrum.de 70 i@@ -31,91 +23,86 @@ $ cat fiche.c | nc localhost 9999 Err vernunftzentrum.de 70 i #ifndef FICHE_H Err vernunftzentrum.de 70 i #define FICHE_H Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i-#ifndef HAVE_INET6 Err vernunftzentrum.de 70 i-#define HAVE_INET6 1 Err vernunftzentrum.de 70 i-#endif Err vernunftzentrum.de 70 i+#include Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i-#include Err vernunftzentrum.de 70 i-#include Err vernunftzentrum.de 70 i-#include Err vernunftzentrum.de 70 i-#include Err vernunftzentrum.de 70 i-#include Err vernunftzentrum.de 70 i-#include Err vernunftzentrum.de 70 i-#include Err vernunftzentrum.de 70 i-#include Err vernunftzentrum.de 70 i-#include Err vernunftzentrum.de 70 i-#include Err vernunftzentrum.de 70 i-#include Err vernunftzentrum.de 70 i-#include Err vernunftzentrum.de 70 i-#include Err vernunftzentrum.de 70 i- Err vernunftzentrum.de 70 i-int UID = -1; Err vernunftzentrum.de 70 i-int GID = -1; Err vernunftzentrum.de 70 i-char *LOG; Err vernunftzentrum.de 70 i-char *BASEDIR; Err vernunftzentrum.de 70 i-char *BANLIST; Err vernunftzentrum.de 70 i-char *BANFILE; Err vernunftzentrum.de 70 i-char *WHITEFILE; Err vernunftzentrum.de 70 i-char *WHITELIST; Err vernunftzentrum.de 70 i-int DAEMON = 0; Err vernunftzentrum.de 70 i-int HTTPS = 0; Err vernunftzentrum.de 70 i-int PORT = 9999; Err vernunftzentrum.de 70 i-int IPv6 = 0; Err vernunftzentrum.de 70 i-int SLUG_SIZE = 4; Err vernunftzentrum.de 70 i-int BUFSIZE = 32768; Err vernunftzentrum.de 70 i-int QUEUE_SIZE = 500; Err vernunftzentrum.de 70 i-char DOMAIN[128] = "localhost/"; Err vernunftzentrum.de 70 i-char symbols[67] = "abcdefghijklmnopqrstuvwxyz0123456789"; Err vernunftzentrum.de 70 i- Err vernunftzentrum.de 70 i-unsigned int time_seed; Err vernunftzentrum.de 70 i- Err vernunftzentrum.de 70 i-struct thread_arguments Err vernunftzentrum.de 70 i-{ Err vernunftzentrum.de 70 i- int connection_socket; Err vernunftzentrum.de 70 i- struct sockaddr_in client_address; Err vernunftzentrum.de 70 i-#if (HAVE_INET6) Err vernunftzentrum.de 70 i- struct sockaddr_in6 client_address6; Err vernunftzentrum.de 70 i-#endif Err vernunftzentrum.de 70 i-}; Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i-struct client_data Err vernunftzentrum.de 70 i-{ Err vernunftzentrum.de 70 i- char *ip_address; Err vernunftzentrum.de 70 i- char *hostname; Err vernunftzentrum.de 70 i-}; Err vernunftzentrum.de 70 i+/** Err vernunftzentrum.de 70 i+ * @brief Used as a container for fiche settings. Create before Err vernunftzentrum.de 70 i+ * the initialization Err vernunftzentrum.de 70 i+ * Err vernunftzentrum.de 70 i+ */ Err vernunftzentrum.de 70 i+typedef struct Fiche_Settings { Err vernunftzentrum.de 70 i+ /** Err vernunftzentrum.de 70 i+ * @brief Domain used in output links Err vernunftzentrum.de 70 i+ */ Err vernunftzentrum.de 70 i+ char *domain; Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i-int create_socket(); Err vernunftzentrum.de 70 i-int create_directory(char *slug); Err vernunftzentrum.de 70 i-int check_protocol(char *buffer); Err vernunftzentrum.de 70 i+ /** Err vernunftzentrum.de 70 i+ * @brief Path to directory used for storing uploaded pastes Err vernunftzentrum.de 70 i+ */ Err vernunftzentrum.de 70 i+ char *output_dir_path; Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ /** Err vernunftzentrum.de 70 i+ * @brief Port on which fiche is waiting for connections Err vernunftzentrum.de 70 i+ */ Err vernunftzentrum.de 70 i+ uint16_t port; Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ /** Err vernunftzentrum.de 70 i+ * @brief Length of a paste's name Err vernunftzentrum.de 70 i+ */ Err vernunftzentrum.de 70 i+ uint8_t slug_len; Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ /** Err vernunftzentrum.de 70 i+ * @brief Connection buffer length Err vernunftzentrum.de 70 i+ * Err vernunftzentrum.de 70 i+ * @remarks Length of this buffer limits max size of uploaded files Err vernunftzentrum.de 70 i+ */ Err vernunftzentrum.de 70 i+ uint32_t buffer_len; Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ /** Err vernunftzentrum.de 70 i+ * @brief Name of the user that runs fiche process Err vernunftzentrum.de 70 i+ */ Err vernunftzentrum.de 70 i+ char *user_name; Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ /** Err vernunftzentrum.de 70 i+ * @brief Path to the log file Err vernunftzentrum.de 70 i+ */ Err vernunftzentrum.de 70 i+ char *log_file_path; Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ /** Err vernunftzentrum.de 70 i+ * @brief Path to the file with banned IPs Err vernunftzentrum.de 70 i+ */ Err vernunftzentrum.de 70 i+ char *banlist_path; Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ /** Err vernunftzentrum.de 70 i+ * @brief Path to the file with whitelisted IPs Err vernunftzentrum.de 70 i+ */ Err vernunftzentrum.de 70 i+ char *whitelist_path; Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+} Fiche_Settings; Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+/** Err vernunftzentrum.de 70 i+ * @brief Initializes Fiche_Settings instance Err vernunftzentrum.de 70 i+ */ Err vernunftzentrum.de 70 i+void fiche_init(Fiche_Settings *settings); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+/** Err vernunftzentrum.de 70 i+ * @brief Runs fiche server Err vernunftzentrum.de 70 i+ * Err vernunftzentrum.de 70 i+ * @return 0 if it was able to start, any other value otherwise Err vernunftzentrum.de 70 i+ */ Err vernunftzentrum.de 70 i+int fiche_run(Fiche_Settings settings); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+/** Err vernunftzentrum.de 70 i+ * @brief array of symbols used in slug generation Err vernunftzentrum.de 70 i+ * @remarks defined in fiche.c Err vernunftzentrum.de 70 i+ */ Err vernunftzentrum.de 70 i+extern const char *Fiche_Symbols; Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i-void bind_to_port(int listen_socket, struct sockaddr_in serveraddr); Err vernunftzentrum.de 70 i-#if (HAVE_INET6) Err vernunftzentrum.de 70 i-void bind_to_port6(int listen_socket, struct sockaddr_in6 serveraddr6); Err vernunftzentrum.de 70 i-#endif Err vernunftzentrum.de 70 i-void error(char *buffer); Err vernunftzentrum.de 70 i-void perform_connection(int listen_socket); Err vernunftzentrum.de 70 i-void generate_url(char *buffer, char *slug, size_t slug_length, struct client_data data); Err vernunftzentrum.de 70 i-void save_to_file(char *buffer, char *slug, struct client_data data); Err vernunftzentrum.de 70 i-void display_info(struct client_data data, char *slug, char *message); Err vernunftzentrum.de 70 i-void startup_message(); Err vernunftzentrum.de 70 i-void set_basedir(); Err vernunftzentrum.de 70 i-void set_domain_name(); Err vernunftzentrum.de 70 i-void load_list(char *file_path, int type); Err vernunftzentrum.de 70 i-void parse_parameters(int argc, char **argv); Err vernunftzentrum.de 70 i-void save_log(char *slug, char *hostaddrp, char *h_name); Err vernunftzentrum.de 70 i-void set_uid_gid(); Err vernunftzentrum.de 70 i- Err vernunftzentrum.de 70 i-char *check_banlist(char *ip_address); Err vernunftzentrum.de 70 i-char *check_whitelist(char *ip_address); Err vernunftzentrum.de 70 i-char *get_date(); Err vernunftzentrum.de 70 i- Err vernunftzentrum.de 70 i-struct sockaddr_in set_address(struct sockaddr_in serveraddr); Err vernunftzentrum.de 70 i-#if (HAVE_INET6) Err vernunftzentrum.de 70 i-struct sockaddr_in6 set_address6(struct sockaddr_in6 serveraddr6); Err vernunftzentrum.de 70 i-#endif Err vernunftzentrum.de 70 i-struct client_data get_client_address(struct sockaddr_in client_address); Err vernunftzentrum.de 70 i-#if (HAVE_INET6) Err vernunftzentrum.de 70 i-struct client_data get_client_address6(struct sockaddr_in6 client_address6); Err vernunftzentrum.de 70 i-#endif Err vernunftzentrum.de 70 i Err vernunftzentrum.de 70 i #endif Err vernunftzentrum.de 70 1diff --git a/main.c b/main.c /ckeen/repos/fiche/file/main.c.gph vernunftzentrum.de 70 i@@ -0,0 +1,133 @@ Err vernunftzentrum.de 70 i+/* Err vernunftzentrum.de 70 i+Fiche - Command line pastebin for sharing terminal output. Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+------------------------------------------------------------------------------- Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+License: MIT (http://www.opensource.org/licenses/mit-license.php) Err vernunftzentrum.de 70 i+Repository: https://github.com/solusipse/fiche/ Err vernunftzentrum.de 70 i+Live example: http://termbin.com Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+------------------------------------------------------------------------------- Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+usage: fiche [-DepbsdolBuw]. Err vernunftzentrum.de 70 i+ [-D] [-e] [-d domain] [-p port] [-s slug size] Err vernunftzentrum.de 70 i+ [-o output directory] [-B buffer size] [-u user name] Err vernunftzentrum.de 70 i+ [-l log file] [-b banlist] [-w whitelist] Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+Use netcat to push text - example: Err vernunftzentrum.de 70 i+$ cat fiche.c | nc localhost 9999 Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+------------------------------------------------------------------------------- Err vernunftzentrum.de 70 i+*/ Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+#include "fiche.h" Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+#include Err vernunftzentrum.de 70 i+#include Err vernunftzentrum.de 70 i+#include Err vernunftzentrum.de 70 i+#include Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+int main(int argc, char **argv) { Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // Fiche settings instance Err vernunftzentrum.de 70 i+ Fiche_Settings fs; Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // Initialize settings instance to default values Err vernunftzentrum.de 70 i+ fiche_init(&fs); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // Note: fiche_run is responsible for checking if these values Err vernunftzentrum.de 70 i+ // were set correctly Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // Note: according to getopt documentation, we don't need to Err vernunftzentrum.de 70 i+ // copy strings, so we decided to go with pointer approach for these Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // Parse input arguments Err vernunftzentrum.de 70 i+ int c; Err vernunftzentrum.de 70 i+ while ((c = getopt(argc, argv, "D6eSp:b:s:d:o:l:B:u:w:")) != -1) { Err vernunftzentrum.de 70 i+ switch (c) { Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // domain Err vernunftzentrum.de 70 i+ case 'd': Err vernunftzentrum.de 70 i+ { Err vernunftzentrum.de 70 i+ fs.domain = optarg; Err vernunftzentrum.de 70 i+ } Err vernunftzentrum.de 70 i+ break; Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // port Err vernunftzentrum.de 70 i+ case 'p': Err vernunftzentrum.de 70 i+ { Err vernunftzentrum.de 70 i+ fs.port = atoi(optarg); Err vernunftzentrum.de 70 i+ } Err vernunftzentrum.de 70 i+ break; Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // slug size Err vernunftzentrum.de 70 i+ case 's': Err vernunftzentrum.de 70 i+ { Err vernunftzentrum.de 70 i+ fs.slug_len = atoi(optarg); Err vernunftzentrum.de 70 i+ } Err vernunftzentrum.de 70 i+ break; Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // output directory path Err vernunftzentrum.de 70 i+ case 'o': Err vernunftzentrum.de 70 i+ { Err vernunftzentrum.de 70 i+ fs.output_dir_path = optarg; Err vernunftzentrum.de 70 i+ } Err vernunftzentrum.de 70 i+ break; Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // buffer size Err vernunftzentrum.de 70 i+ case 'B': Err vernunftzentrum.de 70 i+ { Err vernunftzentrum.de 70 i+ fs.buffer_len = atoi(optarg); Err vernunftzentrum.de 70 i+ } Err vernunftzentrum.de 70 i+ break; Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // user name Err vernunftzentrum.de 70 i+ case 'u': Err vernunftzentrum.de 70 i+ { Err vernunftzentrum.de 70 i+ fs.user_name = optarg; Err vernunftzentrum.de 70 i+ } Err vernunftzentrum.de 70 i+ break; Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // log file path Err vernunftzentrum.de 70 i+ case 'l': Err vernunftzentrum.de 70 i+ { Err vernunftzentrum.de 70 i+ fs.log_file_path = optarg; Err vernunftzentrum.de 70 i+ } Err vernunftzentrum.de 70 i+ break; Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // banlist file path Err vernunftzentrum.de 70 i+ case 'b': Err vernunftzentrum.de 70 i+ { Err vernunftzentrum.de 70 i+ fs.banlist_path = optarg; Err vernunftzentrum.de 70 i+ } Err vernunftzentrum.de 70 i+ break; Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // whitelist file path Err vernunftzentrum.de 70 i+ case 'w': Err vernunftzentrum.de 70 i+ { Err vernunftzentrum.de 70 i+ fs.whitelist_path = optarg; Err vernunftzentrum.de 70 i+ } Err vernunftzentrum.de 70 i+ break; Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ // Display help in case of any unsupported argument Err vernunftzentrum.de 70 i+ default: Err vernunftzentrum.de 70 i+ { Err vernunftzentrum.de 70 i+ printf("usage: fiche [-dpsoBulbw].\n"); Err vernunftzentrum.de 70 i+ printf(" [-d domain] [-p port] [-s slug size]\n"); Err vernunftzentrum.de 70 i+ printf(" [-o output directory] [-B buffer size] [-u user name]\n"); Err vernunftzentrum.de 70 i+ printf(" [-l log file] [-b banlist] [-w whitelist]\n"); Err vernunftzentrum.de 70 i+ return 0; Err vernunftzentrum.de 70 i+ } Err vernunftzentrum.de 70 i+ break; Err vernunftzentrum.de 70 i+ } Err vernunftzentrum.de 70 i+ } Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ fiche_run(fs); Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ return 0; Err vernunftzentrum.de 70 i+} Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 i+ Err vernunftzentrum.de 70 .