#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <stdarg.h>
#include <pthread.h>
#include <string.h>
#include <netdb.h>
#include <dirent.h>
#include <time.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pwd.h>
Data Structures | |
struct | longLine |
struct | multi_fd |
struct | ta |
Defines | |
#define | MAXBUF 1024 |
#define | LISTENQ 1024 |
Typedefs | |
typedef void | Sigfunc (int) |
Functions | |
int | sizeOfLongLine (struct longLine *llPtr) |
void | my_perror (char *msg) |
static void | err_doit (int errnoflag, const char *fmt, va_list ap) |
void | err_sys (const char *fmt,...) |
void | err_quit (const char *fmt,...) |
void | write_std (int fd, void *ptr, size_t nbytes) |
static void | log_doit (int fd, const char *fmt, va_list ap) |
void | log_generic (int fd, const char *fmt,...) |
char * | joinLongLine (struct longLine *llPtr) |
int | multi_read (struct multi_fd my_fd, char *cptr, size_t size) |
char * | read_long_line_until (struct multi_fd my_fd, char *delimeter) |
short int | isDir (char *path) |
char * | make_message (const char *fmt,...) |
void | log_ssl_error (void) |
int | multi_write (struct multi_fd my_fd, char *str, int size) |
int | my_ls_generic (struct multi_fd my_fd, char *path) |
int | checkPerms (char *path) |
void * | Calloc (size_t n, size_t size) |
char * | getFilenameFromRequest (char *req, char *delimeter) |
int | my_send_file_generic (struct multi_fd my_fd, char *filename, char *http_version) |
char * | get_http_version_from_request (char *request) |
int | handle_client_generic (struct multi_fd my_fd, char *prefix, char *kind) |
void | ssl_err (void) |
int | handle_client_ssl (int fd, char *prefix) |
int | handle_client (int fd, char *prefix) |
int | Accept (int fd, struct sockaddr *sa, socklen_t *salenptr) |
void | Close (int fd) |
void * | thread_main_generic (void *arg, char *kind, int(*handlerFunc)(int, char *prefix), int sock) |
void * | thread_main (void *arg) |
void * | thread_main_ssl (void *arg) |
void | Pthread_create (pthread_t *tid, const pthread_attr_t *attr, void *(*func)(void *), void *arg) |
void | thread_make_generic (int numer_procesu, int me, void *(*func)(void *)) |
void | thread_make (int numer_procesu, int me) |
void | thread_make_ssl (int numer_procesu, int me) |
pid_t | Fork (void) |
void | child_main_generic (int numer_procesu, char *kind, void(*func)(int, int)) |
Sigfunc * | signal (int signo, Sigfunc *func) |
Sigfunc * | set_signal (int signo, Sigfunc *func) |
void | handle_sigpipe (int signum) |
void | make_child (int numer_procesu, char *rodzaj, void(*func)(int, int), pid_t *array) |
int | Open (const char *pathname, int oflag, mode_t mode) |
void | sig_int (int signo) |
void | Setsockopt (int fd, int level, int optname, const void *optval, socklen_t optlen) |
void | Listen (int fd, int backlog) |
int | tcp_listen (const char *serv) |
uid_t | get_uid (char *name) |
int | open_log_file (char *path) |
void | log_files_init (void) |
void | usage () |
void | ssl_initialize (void) |
void | make_children (void(*sub_func)(int, int), char *rodzaj, pid_t *array) |
void | write_pid (void) |
void | handle_sigchld (int signum) |
int | get_table_index_by_pid (pid_t pid, pid_t *table) |
void | recreate_specific_process (int index, char *table_name, char *kind, void(*thread_func)(int, int), pid_t *pids_array) |
void | recreate_process_by_dead_pid (pid_t dead_pid) |
void | recreate_children (void) |
void | check_for_sigchld (void) |
int | main (int argc, char **argv) |
Variables | |
static pid_t * | pids |
static pid_t * | pids_ssl |
pid_t | my_pid |
int | forks = 3 |
int | threads = 4 |
int | listenfd |
int | listenfd_ssl |
int | log_access_fd |
int | log_debug_fd |
int | log_main_fd |
short int | debug = 0 |
short int | received_sigchld = 0 |
pthread_t * | tptr |
socklen_t | addrlen |
char * | port_default = "80" |
char * | port_default_ssl = "443" |
char * | my_name = "my_httpd" |
SSL_CTX * | my_ssl_ctx |
#define LISTENQ 1024 |
#define MAXBUF 1024 |
typedef void Sigfunc(int) |
int Accept | ( | int | fd, | |
struct sockaddr * | sa, | |||
socklen_t * | salenptr | |||
) |
Funkcja opakowująca accept().
void* Calloc | ( | size_t | n, | |
size_t | size | |||
) |
Funkcja opakowująca calloc(). Kończy działanie programu w razie napotkania błędu.
void check_for_sigchld | ( | void | ) |
Sprawdza czy zmienna-flaga received_sigchld została ustawiona (ma wartość 1). Zmienna ta jest ustawiona przez funkcję obsługującą sygnał SIGCHLD. Jeśli tak, to na miejsce zabitych potomków tworzymy nowe.
int checkPerms | ( | char * | path | ) |
Katalog musi mieć ustawione R oraz X dla innych. Plik musi mieć ustawione R dla innych.
void child_main_generic | ( | int | numer_procesu, | |
char * | kind, | |||
void(*)(int, int) | func | |||
) |
Ogólna wersja głównej pętli procesu. Tworzy wątki obsługujące połączenia.
void Close | ( | int | fd | ) |
Funkcja opakowująca close(). W razie występienia błędu wyświetla komunikat i kończy działanie programu.
static void err_doit | ( | int | errnoflag, | |
const char * | fmt, | |||
va_list | ap | |||
) | [static] |
Analizuje podane argumenty jako sformatowany tekst i wyświetla go na standardowym wyjściu błędu. Jeśli errnoflag jest ustawione na 1, to również wyświetla komunikat błędu na podstawie wartości zmiennej errno.
void err_quit | ( | const char * | fmt, | |
... | ||||
) |
Pobiera listę argumentów o zmiennej długości, która jest komunikatem w stylu printf() do wyświetlenia.
fmt | Napis podany w formacie jak do printf(). |
void err_sys | ( | const char * | fmt, | |
... | ||||
) |
Wypisuje na standardowe wyjście błędu komunikat podany jako argument, potem komunikat błędu na podstawie zmiennej errno. Kończy działanie programu ze stanem błedu.
pid_t Fork | ( | void | ) |
Wywołuje fork(), jeśli wystąpił błąd, to wyświetla komunikat błędu i kończy pracę programu z kodem błędu.
char* get_http_version_from_request | ( | char * | request | ) |
Analizuje żądanie podane jako argument i zwraca wskaźnik do tablicy zawierającej wersję protokołu HTTP, którą posłużył się klient.
int get_table_index_by_pid | ( | pid_t | pid, | |
pid_t * | table | |||
) |
Zwraca indeks pozycji na której znajduje się ten numer PID (jeśli został znaleziony). W razie niepowodzenia zwraca -1.
uid_t get_uid | ( | char * | name | ) |
Pobiera login użytkownika jako argument i zwraca jego UID jeśli istnieje.
char* getFilenameFromRequest | ( | char * | req, | |
char * | delimeter | |||
) |
Zwraca wskaźnik na tablicę zawierającą nazwę pliku.
int handle_client | ( | int | fd, | |
char * | prefix | |||
) |
Obsługuje klienta nieszyfrowanego. Wykorzystuje funkcję handle_client_generic().
int handle_client_generic | ( | struct multi_fd | my_fd, | |
char * | prefix, | |||
char * | kind | |||
) |
Uniwersalna funkcja obsługująca pojedyńcze żadanie klienta (zarówno szyfrowane jak i nieszyfrowane).
int handle_client_ssl | ( | int | fd, | |
char * | prefix | |||
) |
Obsługuje klienta nieszyfrowanego. Wykorzystuje funkcję handle_client_generic().
void handle_sigchld | ( | int | signum | ) |
Funkcja obsługująca sygnał SIGCHLD. Ustawia wartość zmiennej received_sigchld na 1.
void handle_sigpipe | ( | int | signum | ) |
Funkcja obsługująca sygnal SIGPIPE. Loguje tylko informację o otrzmaniu sygnału.
short int isDir | ( | char * | path | ) |
Sprawdza czy podana ścieżka jest katalogiem.
char* joinLongLine | ( | struct longLine * | llPtr | ) |
Alokuje nową, ciągłą przestrzeń na docelową tablicę, kopiuje tam zawartość buforów z kolejnych struktur i zwraca adres tak utworzonej tablicy.
void Listen | ( | int | fd, | |
int | backlog | |||
) |
Wywołuje listen() z podanymi argumentami i kończy pracę programu jeśli wystąpił błąd.
static void log_doit | ( | int | fd, | |
const char * | fmt, | |||
va_list | ap | |||
) | [static] |
Przyjmuje jako argument deskryptor z otwartym plikiem logu. Zapisuje do niego komunikat podany jako kolejne argumenty. Komunikat poprzedza aktualną datą i czasem.
void log_files_init | ( | void | ) |
Otwiera wszystkie pliki z logami.
void log_generic | ( | int | fd, | |
const char * | fmt, | |||
... | ||||
) |
Jeśli podany deskryptor jest logiem debug, to wykonuje logowanie tylko jeśli zmienna debug jest włączona.
void log_ssl_error | ( | void | ) |
Zapisuje w głównym logu komunikaty błędów SSL.
int main | ( | int | argc, | |
char ** | argv | |||
) |
Główna funkcja programu. Przyjmuje standardowe argumenty.
void make_child | ( | int | numer_procesu, | |
char * | rodzaj, | |||
void(*)(int, int) | func, | |||
pid_t * | array | |||
) |
Wykonuje Fork() i tworzy proces potomny na podstawie podanych argumentów.
void make_children | ( | void(*)(int, int) | sub_func, | |
char * | rodzaj, | |||
pid_t * | array | |||
) |
Tworzy odpowiedni rodzaj potomków (szyfrowane bądź nie) zgodnie z podanymi argumentami.
char* make_message | ( | const char * | fmt, | |
... | ||||
) |
Alokuje sukcesywnie coraz większe tablice i zapisuje w nich napis podany jako argument. Jeśli napis sie zmieści, to zwraca adres tablicy.
int multi_read | ( | struct multi_fd | my_fd, | |
char * | cptr, | |||
size_t | size | |||
) |
Zależnie od zawartości uniwersalnego deskryptora używa read() bądź SSL_read() do odczytania danych. W razie napotkania błędu kończy działanie.
int multi_write | ( | struct multi_fd | my_fd, | |
char * | str, | |||
int | size | |||
) |
Zależnie od zawartości uniwersalnego deskryptora używa write() bądź SSL_write() do zapisania danych. W razie napotkania błędu kończy działanie.
int my_ls_generic | ( | struct multi_fd | my_fd, | |
char * | path | |||
) |
Wypisuje do uniwersalengo deskryptora podanego jako pierwszy argument zawartość katalogu podanego jako drugi argument.
void my_perror | ( | char * | msg | ) |
Wywołuje perror() i wychodzi z programu.
int my_send_file_generic | ( | struct multi_fd | my_fd, | |
char * | filename, | |||
char * | http_version | |||
) |
Funkcja przyjmuje jako pierwszy argument uniwersalny deskryptor. Zapisuje do niego plik do którego ścieżka podana jest jako drugi argument.
int Open | ( | const char * | pathname, | |
int | oflag, | |||
mode_t | mode | |||
) |
Wywołuje open() z podanymi argymentami. Jeśli wystąpił błąd, to wyświetla komunikat i kończy pracę.
int open_log_file | ( | char * | path | ) |
Funkcja opakowująca do otwierania pliku z logiem.
void Pthread_create | ( | pthread_t * | tid, | |
const pthread_attr_t * | attr, | |||
void *(*)(void *) | func, | |||
void * | arg | |||
) |
Wywołuje pthread_create() z podanymi argumentami. Jeśli wystąpił błąd, wyświetla odpowiedni komunikat i kończy działanie programu.
char* read_long_line_until | ( | struct multi_fd | my_fd, | |
char * | delimeter | |||
) |
Czyta dane z deskryptora i zapisuje je do struktur długiej linii. Użytkownik wpisać podać teoretycznie dowolną ilość danych. Kończy w momencie napotkania separatora podanego jako drugi argument.
void recreate_children | ( | void | ) |
Za pomocą funkcji waitpid() sprawdza które z procesów potomnych zmieniły swój stan (zostaly zabite). Następnie je odtwarza.
void recreate_process_by_dead_pid | ( | pid_t | dead_pid | ) |
Pobiera numer PID zabitego procesu, przegląda listę zarejestrowanych procesów potomnych i na miejsce martwego potomka tworzy nowego.
void recreate_specific_process | ( | int | index, | |
char * | table_name, | |||
char * | kind, | |||
void(*)(int, int) | thread_func, | |||
pid_t * | pids_array | |||
) |
Odtwarza potomka nieszyfrowanego lub szyfrowanego w zależności od podanych argumentów.
Funkcja opakowująca do ustawiania funkcji obsługującej dany sygnał.
void Setsockopt | ( | int | fd, | |
int | level, | |||
int | optname, | |||
const void * | optval, | |||
socklen_t | optlen | |||
) |
Wywołuje setsockopt() z podanymi argumentami i kończy pracę programu jeśli wystąpił błąd.
void sig_int | ( | int | signo | ) |
Obsługa sygnału INT ([Ctrl]+[C] na klawiaturze).
int sizeOfLongLine | ( | struct longLine * | llPtr | ) |
Pobiera wskaźnik do struktury longLine i oblicza długość całej długiej linii.
void ssl_err | ( | void | ) |
Wyswietla komunikat bledu OpenSSL i wychodzi z programu z kodem bledu.
void ssl_initialize | ( | void | ) |
Przygotowuje do użycia bibliotekę OpenSSL.
int tcp_listen | ( | const char * | serv | ) |
Funkcja opakowująca. Tworzy gniazdo nasłuchujące na porcie usługi podanej jako argument w postaci napisu.
void* thread_main | ( | void * | arg | ) |
Wywołuje thread_main_generic() z argumentami charakterystycznymi dla wątku nieszyfrowanego.
void* thread_main_generic | ( | void * | arg, | |
char * | kind, | |||
int(*)(int, char *prefix) | handlerFunc, | |||
int | sock | |||
) |
Ogólna wersja głównej funkcji wątku (dla serwera obsługującego połączenia szyfrowane oraz dla serwera obsługującego połączenia nieszyfrowane).
void* thread_main_ssl | ( | void * | arg | ) |
Wywołuje thread_main_generic() z argumentami charakterystycznymi dla wątku SSL.
void thread_make | ( | int | numer_procesu, | |
int | me | |||
) |
Wywołuje thread_make_generic() z argumentami odpowiednimi dla wątku obsługującego połączenia nieszyfrowane.
void thread_make_generic | ( | int | numer_procesu, | |
int | me, | |||
void *(*)(void *) | func | |||
) |
Przyjmuje jako jeden z argumentów wskaźnik do funkcji, którą ma wykonywać utworzony wątek.
void thread_make_ssl | ( | int | numer_procesu, | |
int | me | |||
) |
Wywołuje thread_make_generic() z argumentami odpowiednimi dla wątku obsługującego połączenia SSL.
void usage | ( | ) |
Wyświetla instrukcję użycia programu i kończy działanie programu z kodem błędu.
void write_pid | ( | void | ) |
Zapisuje PID serwera w pliku na dysku.
void write_std | ( | int | fd, | |
void * | ptr, | |||
size_t | nbytes | |||
) |
Przyjmuje takie same argumenty jak write(). Wywołuje z nimi write() i w razie napotkania błędu kończy działanie programu wyświetlając odpowiedni komunikat.
socklen_t addrlen |
short int debug = 0 |
int forks = 3 |
int listenfd |
Deskryptory plików oraz gniazd.
int listenfd_ssl |
int log_access_fd |
int log_debug_fd |
int log_main_fd |
char * my_name = "my_httpd" |
pid_t my_pid |
PID bieżącego procesu.
SSL_CTX* my_ssl_ctx |
Kontekst SSL.
pid_t* pids [static] |
Tablice na PID-y potomków szyfrowanych i nie szyfrowanych.
pid_t * pids_ssl [static] |
char* port_default = "80" |
char * port_default_ssl = "443" |
short int received_sigchld = 0 |
int threads = 4 |
Ilość potomków i wątków.
pthread_t* tptr |