From 8d914c1238078e57052f87f05b01f704d29974cf Mon Sep 17 00:00:00 2001 From: Trouverecc <129832000+Trouverecc@users.noreply.github.com> Date: Mon, 8 Jul 2024 15:22:36 +0800 Subject: [PATCH] Add files via upload --- DockerFile | 9 + Log.txt | 113 ++ Makefile | 46 + README.md | 2 - access_log | 2 + cgi/README | 2 + cgi/cgi.tar.gz | Bin 0 -> 20480 bytes cgi/daemonize.c | 82 ++ echo_client | Bin 0 -> 17232 bytes echo_server | Bin 0 -> 58072 bytes example | Bin 0 -> 56432 bytes include/parse.h | 29 + liso_client | Bin 0 -> 17200 bytes liso_server | Bin 0 -> 65000 bytes samples/request_get | 9 + samples/request_head | 9 + samples/request_pipeline | 82 ++ samples/request_post | 9 + samples/sample_400 | 8 + samples/sample_404 | 7 + samples/sample_501 | 4 + samples/sample_505 | 7 + samples/sample_error1 | 7 + samples/sample_error2 | 7 + samples/sample_error3 | 7 + samples/sample_error4 | 7 + samples/sample_request_example | 4 + samples/sample_request_realistic | 9 + samples/try_week3 | 179 +++ src/example.c | 40 + src/lex.yy.c | 2018 ++++++++++++++++++++++++++++ src/lexer.l | 263 ++++ src/liso_client.c | 91 ++ src/liso_server.c | 234 ++++ src/parse.c | 77 ++ src/parser.y | 241 ++++ src/y.tab.c | 1669 +++++++++++++++++++++++ src/y.tab.h | 99 ++ static_site/images/liso_header.png | Bin 0 -> 17431 bytes static_site/index.html | 20 + static_site/style.css | 8 + 41 files changed, 5398 insertions(+), 2 deletions(-) create mode 100644 DockerFile create mode 100644 Log.txt create mode 100644 Makefile create mode 100644 access_log create mode 100644 cgi/README create mode 100644 cgi/cgi.tar.gz create mode 100644 cgi/daemonize.c create mode 100644 echo_client create mode 100644 echo_server create mode 100644 example create mode 100644 include/parse.h create mode 100644 liso_client create mode 100644 liso_server create mode 100644 samples/request_get create mode 100644 samples/request_head create mode 100644 samples/request_pipeline create mode 100644 samples/request_post create mode 100644 samples/sample_400 create mode 100644 samples/sample_404 create mode 100644 samples/sample_501 create mode 100644 samples/sample_505 create mode 100644 samples/sample_error1 create mode 100644 samples/sample_error2 create mode 100644 samples/sample_error3 create mode 100644 samples/sample_error4 create mode 100644 samples/sample_request_example create mode 100644 samples/sample_request_realistic create mode 100644 samples/try_week3 create mode 100644 src/example.c create mode 100644 src/lex.yy.c create mode 100644 src/lexer.l create mode 100644 src/liso_client.c create mode 100644 src/liso_server.c create mode 100644 src/parse.c create mode 100644 src/parser.y create mode 100644 src/y.tab.c create mode 100644 src/y.tab.h create mode 100644 static_site/images/liso_header.png create mode 100644 static_site/index.html create mode 100644 static_site/style.css diff --git a/DockerFile b/DockerFile new file mode 100644 index 0000000..da7f358 --- /dev/null +++ b/DockerFile @@ -0,0 +1,9 @@ +# base image from gradescope +FROM gradescope/auto-builds:ubuntu-18.04 +# make necessary directories +RUN apt-get update &&\ + apt-get -y install gcc flex bison build-essential siege apache2-utils libssl-dev &&\ + # change ApacheBench request HTTP version to 1.1 + perl -pi -e 's/HTTP\/1.0/HTTP\/1.1/g' /usr/bin/ab + +WORKDIR /home diff --git a/Log.txt b/Log.txt new file mode 100644 index 0000000..1761598 --- /dev/null +++ b/Log.txt @@ -0,0 +1,113 @@ +[Date: Mon, 03 Jun 2024 15:09:30 UTC][client: 127.0.0.1:38636]HTTP/1.1 501 Not Implemented +[Date: Mon, 03 Jun 2024 15:09:30 UTC][client: 127.0.0.1:38636]200 OK, responded for request GET +[Date: Mon, 03 Jun 2024 15:09:30 UTC][client: 127.0.0.1:38636]HTTP/1.1 505 HTTP Version Not Supported +[Date: Mon, 03 Jun 2024 15:09:30 UTC][client: 127.0.0.1:38636]HTTP/1.1 505 HTTP Version Not Supported +[Date: Mon, 03 Jun 2024 15:09:30 UTC][client: 127.0.0.1:38636]HTTP/1.1 501 Not Implemented +[Date: Mon, 03 Jun 2024 15:09:30 UTC][client: 127.0.0.1:38636]HTTP/1.1 501 Not Implemented +[Date: Mon, 03 Jun 2024 15:09:30 UTC][client: 127.0.0.1:38636]HTTP/1.1 400 Bad request +[Date: Mon, 03 Jun 2024 15:18:08 UTC][client: 127.0.0.1:38636]HTTP/1.1 501 Not Implemented +[Date: Mon, 03 Jun 2024 15:18:08 UTC][client: 127.0.0.1:38636]200 OK, responded for request GET +[Date: Mon, 03 Jun 2024 15:18:08 UTC][client: 127.0.0.1:38636]HTTP/1.1 505 HTTP Version Not Supported +[Date: Mon, 03 Jun 2024 15:18:08 UTC][client: 127.0.0.1:38636]HTTP/1.1 505 HTTP Version Not Supported +[Date: Mon, 03 Jun 2024 15:18:08 UTC][client: 127.0.0.1:38636]HTTP/1.1 501 Not Implemented +[Date: Mon, 03 Jun 2024 15:18:08 UTC][client: 127.0.0.1:38636]HTTP/1.1 501 Not Implemented +[Date: Mon, 03 Jun 2024 15:18:08 UTC][client: 127.0.0.1:38636]HTTP/1.1 400 Bad request +[Date: Mon, 03 Jun 2024 15:30:21 UTC][client: 127.0.0.1:38636]HTTP/1.1 501 Not Implemented +[Date: Mon, 03 Jun 2024 15:30:21 UTC][client: 127.0.0.1:38636]200 OK, responded for request GET +[Date: Mon, 03 Jun 2024 15:30:21 UTC][client: 127.0.0.1:38636]HTTP/1.1 505 HTTP Version Not Supported +[Date: Mon, 03 Jun 2024 15:30:21 UTC][client: 127.0.0.1:38636]HTTP/1.1 505 HTTP Version Not Supported +[Date: Mon, 03 Jun 2024 15:30:21 UTC][client: 127.0.0.1:38636]HTTP/1.1 501 Not Implemented +[Date: Mon, 03 Jun 2024 15:30:21 UTC][client: 127.0.0.1:38636]HTTP/1.1 501 Not Implemented +[Date: Mon, 03 Jun 2024 15:30:21 UTC][client: 127.0.0.1:38636]HTTP/1.1 400 Bad request +[Date: Wed, 05 Jun 2024 12:48:26 UTC][client: 127.0.0.1:38636]HTTP/1.1 501 Not Implemented +[Date: Wed, 05 Jun 2024 12:48:26 UTC][client: 127.0.0.1:38636]200 OK, responded for request GET +[Date: Wed, 05 Jun 2024 12:48:26 UTC][client: 127.0.0.1:38636]HTTP/1.1 505 HTTP Version Not Supported +[Date: Wed, 05 Jun 2024 12:48:26 UTC][client: 127.0.0.1:38636]HTTP/1.1 505 HTTP Version Not Supported +[Date: Wed, 05 Jun 2024 12:48:26 UTC][client: 127.0.0.1:38636]HTTP/1.1 501 Not Implemented +[Date: Wed, 05 Jun 2024 12:48:26 UTC][client: 127.0.0.1:38636]HTTP/1.1 501 Not Implemented +[Date: Wed, 05 Jun 2024 12:48:26 UTC][client: 127.0.0.1:38636]HTTP/1.1 400 Bad request +[Date: Wed, 05 Jun 2024 12:48:26 UTC][client: 127.0.0.1:38636]HTTP/1.1 400 Bad request +[Date: Wed, 05 Jun 2024 12:48:26 UTC][client: 127.0.0.1:38636]200 OK, responded for request GET +[Date: Wed, 05 Jun 2024 12:48:26 UTC][client: 127.0.0.1:38636]HTTP/1.1 505 HTTP Version Not Supported +[Date: Wed, 05 Jun 2024 12:48:26 UTC][client: 127.0.0.1:38636]HTTP/1.1 505 HTTP Version Not Supported +[Date: Wed, 05 Jun 2024 12:48:26 UTC][client: 127.0.0.1:38636]HTTP/1.1 501 Not Implemented +[Date: Wed, 05 Jun 2024 12:48:26 UTC][client: 127.0.0.1:38636]HTTP/1.1 501 Not Implemented +[Date: Wed, 05 Jun 2024 12:48:26 UTC][client: 127.0.0.1:38636]HTTP/1.1 400 Bad request +[Date: Wed, 05 Jun 2024 12:48:26 UTC][client: 127.0.0.1:38636]HTTP/1.1 501 Not Implemented +[Date: Wed, 05 Jun 2024 12:48:26 UTC][client: 127.0.0.1:38636]200 OK, responded for request GET +[Date: Wed, 05 Jun 2024 12:55:35 UTC][client: 127.0.0.1:38636]HTTP/1.1 501 Not Implemented +[Date: Wed, 05 Jun 2024 12:55:35 UTC][client: 127.0.0.1:38636]200 OK, responded for request GET +[Date: Wed, 05 Jun 2024 12:55:35 UTC][client: 127.0.0.1:38636]HTTP/1.1 505 HTTP Version Not Supported +[Date: Wed, 05 Jun 2024 12:55:35 UTC][client: 127.0.0.1:38636]HTTP/1.1 505 HTTP Version Not Supported +[Date: Wed, 05 Jun 2024 12:55:35 UTC][client: 127.0.0.1:38636]HTTP/1.1 501 Not Implemented +[Date: Wed, 05 Jun 2024 12:55:35 UTC][client: 127.0.0.1:38636]HTTP/1.1 501 Not Implemented +[Date: Wed, 05 Jun 2024 12:55:35 UTC][client: 127.0.0.1:38636]HTTP/1.1 400 Bad request +[Date: Wed, 05 Jun 2024 12:55:35 UTC][client: 127.0.0.1:38636]HTTP/1.1 400 Bad request +[Date: Wed, 05 Jun 2024 12:55:35 UTC][client: 127.0.0.1:38636]200 OK, responded for request GET +[Date: Wed, 05 Jun 2024 12:55:35 UTC][client: 127.0.0.1:38636]HTTP/1.1 505 HTTP Version Not Supported +[Date: Wed, 05 Jun 2024 12:55:35 UTC][client: 127.0.0.1:38636]HTTP/1.1 505 HTTP Version Not Supported +[Date: Wed, 05 Jun 2024 12:55:35 UTC][client: 127.0.0.1:38636]HTTP/1.1 501 Not Implemented +[Date: Wed, 05 Jun 2024 12:55:35 UTC][client: 127.0.0.1:38636]HTTP/1.1 501 Not Implemented +[Date: Wed, 05 Jun 2024 12:55:35 UTC][client: 127.0.0.1:38636]HTTP/1.1 400 Bad request +[Date: Wed, 05 Jun 2024 12:55:35 UTC][client: 127.0.0.1:38636]HTTP/1.1 400 Bad request +[Date: Wed, 05 Jun 2024 12:55:35 UTC][client: 127.0.0.1:38636]HTTP/1.1 501 Not Implemented +[Date: Wed, 05 Jun 2024 12:55:35 UTC][client: 127.0.0.1:38636]200 OK, responded for request GET +[Date: Wed, 05 Jun 2024 12:58:09 UTC][client: 127.0.0.1:38636]HTTP/1.1 501 Not Implemented +[Date: Wed, 05 Jun 2024 12:58:09 UTC][client: 127.0.0.1:38636]200 OK, responded for request GET +[Date: Wed, 05 Jun 2024 12:58:09 UTC][client: 127.0.0.1:38636]HTTP/1.1 505 HTTP Version Not Supported +[Date: Wed, 05 Jun 2024 12:58:09 UTC][client: 127.0.0.1:38636]HTTP/1.1 505 HTTP Version Not Supported +[Date: Wed, 05 Jun 2024 12:58:09 UTC][client: 127.0.0.1:38636]HTTP/1.1 501 Not Implemented +[Date: Wed, 05 Jun 2024 12:58:09 UTC][client: 127.0.0.1:38636]HTTP/1.1 501 Not Implemented +[Date: Wed, 05 Jun 2024 12:58:09 UTC][client: 127.0.0.1:38636]HTTP/1.1 400 Bad request +[Date: Wed, 05 Jun 2024 12:58:09 UTC][client: 127.0.0.1:38636]HTTP/1.1 400 Bad request +[Date: Wed, 05 Jun 2024 12:58:09 UTC][client: 127.0.0.1:38636]200 OK, responded for request GET +[Date: Wed, 05 Jun 2024 12:58:09 UTC][client: 127.0.0.1:38636]HTTP/1.1 505 HTTP Version Not Supported +[Date: Wed, 05 Jun 2024 12:58:09 UTC][client: 127.0.0.1:38636]HTTP/1.1 505 HTTP Version Not Supported +[Date: Wed, 05 Jun 2024 12:58:09 UTC][client: 127.0.0.1:38636]HTTP/1.1 501 Not Implemented +[Date: Wed, 05 Jun 2024 12:58:09 UTC][client: 127.0.0.1:38636]HTTP/1.1 501 Not Implemented +[Date: Wed, 05 Jun 2024 12:58:09 UTC][client: 127.0.0.1:38636]HTTP/1.1 400 Bad request +[Date: Wed, 05 Jun 2024 12:59:09 UTC][client: 127.0.0.1:38636]HTTP/1.1 501 Not Implemented +[Date: Wed, 05 Jun 2024 12:59:09 UTC][client: 127.0.0.1:38636]200 OK, responded for request GET +[Date: Wed, 05 Jun 2024 12:59:09 UTC][client: 127.0.0.1:38636]HTTP/1.1 505 HTTP Version Not Supported +[Date: Wed, 05 Jun 2024 12:59:09 UTC][client: 127.0.0.1:38636]HTTP/1.1 505 HTTP Version Not Supported +[Date: Wed, 05 Jun 2024 12:59:09 UTC][client: 127.0.0.1:38636]HTTP/1.1 501 Not Implemented +[Date: Wed, 05 Jun 2024 12:59:09 UTC][client: 127.0.0.1:38636]HTTP/1.1 501 Not Implemented +[Date: Wed, 05 Jun 2024 12:59:09 UTC][client: 127.0.0.1:38636]HTTP/1.1 400 Bad request +[Date: Wed, 05 Jun 2024 12:59:09 UTC][client: 127.0.0.1:38636]HTTP/1.1 400 Bad request +[Date: Wed, 05 Jun 2024 12:59:09 UTC][client: 127.0.0.1:38636]200 OK, responded for request GET +[Date: Wed, 05 Jun 2024 12:59:09 UTC][client: 127.0.0.1:38636]HTTP/1.1 505 HTTP Version Not Supported +[Date: Wed, 05 Jun 2024 12:59:09 UTC][client: 127.0.0.1:38636]HTTP/1.1 505 HTTP Version Not Supported +[Date: Wed, 05 Jun 2024 12:59:09 UTC][client: 127.0.0.1:38636]HTTP/1.1 501 Not Implemented +[Date: Wed, 05 Jun 2024 12:59:09 UTC][client: 127.0.0.1:38636]HTTP/1.1 501 Not Implemented +[Date: Wed, 05 Jun 2024 12:59:09 UTC][client: 127.0.0.1:38636]HTTP/1.1 400 Bad request +[Date: Wed, 05 Jun 2024 13:00:40 UTC][client: 127.0.0.1:38636]HTTP/1.1 501 Not Implemented +[Date: Wed, 05 Jun 2024 13:00:40 UTC][client: 127.0.0.1:38636]200 OK, responded for request GET +[Date: Wed, 05 Jun 2024 13:00:40 UTC][client: 127.0.0.1:38636]HTTP/1.1 505 HTTP Version Not Supported +[Date: Wed, 05 Jun 2024 13:00:40 UTC][client: 127.0.0.1:38636]HTTP/1.1 505 HTTP Version Not Supported +[Date: Wed, 05 Jun 2024 13:00:40 UTC][client: 127.0.0.1:38636]HTTP/1.1 501 Not Implemented +[Date: Wed, 05 Jun 2024 13:00:40 UTC][client: 127.0.0.1:38636]HTTP/1.1 501 Not Implemented +[Date: Wed, 05 Jun 2024 13:00:40 UTC][client: 127.0.0.1:38636]HTTP/1.1 400 Bad request +[Date: Wed, 05 Jun 2024 13:00:40 UTC][client: 127.0.0.1:38636]HTTP/1.1 400 Bad request +[Date: Wed, 05 Jun 2024 13:00:40 UTC][client: 127.0.0.1:38636]200 OK, responded for request GET +[Date: Wed, 05 Jun 2024 13:00:40 UTC][client: 127.0.0.1:38636]HTTP/1.1 505 HTTP Version Not Supported +[Date: Wed, 05 Jun 2024 13:00:40 UTC][client: 127.0.0.1:38636]HTTP/1.1 505 HTTP Version Not Supported +[Date: Wed, 05 Jun 2024 13:00:40 UTC][client: 127.0.0.1:38636]HTTP/1.1 501 Not Implemented +[Date: Wed, 05 Jun 2024 13:00:40 UTC][client: 127.0.0.1:38636]HTTP/1.1 501 Not Implemented +[Date: Wed, 05 Jun 2024 13:00:40 UTC][client: 127.0.0.1:38636]HTTP/1.1 400 Bad request +[Date: Wed, 05 Jun 2024 13:00:40 UTC][client: 127.0.0.1:38636]HTTP/1.1 400 Bad request +[Date: Wed, 05 Jun 2024 13:00:40 UTC][client: 127.0.0.1:38636]HTTP/1.1 501 Not Implemented +[Date: Wed, 05 Jun 2024 13:01:20 UTC][client: 127.0.0.1:38636]HTTP/1.1 501 Not Implemented +[Date: Wed, 05 Jun 2024 13:01:20 UTC][client: 127.0.0.1:38636]200 OK, responded for request GET +[Date: Wed, 05 Jun 2024 13:01:20 UTC][client: 127.0.0.1:38636]HTTP/1.1 505 HTTP Version Not Supported +[Date: Wed, 05 Jun 2024 13:01:20 UTC][client: 127.0.0.1:38636]HTTP/1.1 505 HTTP Version Not Supported +[Date: Wed, 05 Jun 2024 13:01:20 UTC][client: 127.0.0.1:38636]HTTP/1.1 501 Not Implemented +[Date: Wed, 05 Jun 2024 13:01:20 UTC][client: 127.0.0.1:38636]HTTP/1.1 501 Not Implemented +[Date: Wed, 05 Jun 2024 13:01:20 UTC][client: 127.0.0.1:38636]HTTP/1.1 400 Bad request +[Date: Wed, 05 Jun 2024 13:01:20 UTC][client: 127.0.0.1:38636]HTTP/1.1 400 Bad request +[Date: Wed, 05 Jun 2024 13:01:20 UTC][client: 127.0.0.1:38636]200 OK, responded for request GET +[Date: Wed, 05 Jun 2024 13:01:20 UTC][client: 127.0.0.1:38636]HTTP/1.1 505 HTTP Version Not Supported +[Date: Wed, 05 Jun 2024 13:01:20 UTC][client: 127.0.0.1:38636]HTTP/1.1 505 HTTP Version Not Supported +[Date: Wed, 05 Jun 2024 13:01:20 UTC][client: 127.0.0.1:38636]HTTP/1.1 501 Not Implemented +[Date: Wed, 05 Jun 2024 13:01:20 UTC][client: 127.0.0.1:38636]HTTP/1.1 501 Not Implemented +[Date: Wed, 05 Jun 2024 13:01:20 UTC][client: 127.0.0.1:38636]HTTP/1.1 400 Bad request +[Date: Wed, 05 Jun 2024 13:01:20 UTC][client: 127.0.0.1:38636]HTTP/1.1 400 Bad request diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..7dae104 --- /dev/null +++ b/Makefile @@ -0,0 +1,46 @@ +SRC_DIR := src +OBJ_DIR := obj +# all src files +SRC := $(wildcard $(SRC_DIR)/*.c) +# all objects +OBJ := $(OBJ_DIR)/y.tab.o $(OBJ_DIR)/lex.yy.o $(OBJ_DIR)/parse.o $(OBJ_DIR)/example.o +#OBJ_SERVER := $(OBJ_DIR)/y.tab.o $(OBJ_DIR)/lex.yy.o $(OBJ_DIR)/parse.o $(OBJ_DIR)/echo_server.o +# all binaries +BIN := example liso_server liso_client +# C compiler +CC := gcc +# C PreProcessor Flag +CPPFLAGS := -Iinclude +# compiler flags +CFLAGS := -g -Wall +# DEPS = parse.h y.tab.h + +default: all +all : example liso_server liso_client + +example: $(OBJ) + $(CC) $^ -o $@ + +$(SRC_DIR)/lex.yy.c: $(SRC_DIR)/lexer.l + flex -o $@ $^ + +$(SRC_DIR)/y.tab.c: $(SRC_DIR)/parser.y + yacc -d $^ + mv y.tab.c $@ + mv y.tab.h $(SRC_DIR)/y.tab.h + +$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c $(OBJ_DIR) + $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@ + +liso_server: $(OBJ_DIR)/liso_server.o $(OBJ_DIR)/lex.yy.o $(OBJ_DIR)/y.tab.o $(OBJ_DIR)/parse.o + $(CC) -g -Werror $^ -o $@ + +liso_client: $(OBJ_DIR)/liso_client.o + $(CC) -Werror $^ -o $@ + +$(OBJ_DIR): + mkdir $@ + +clean: + $(RM) $(OBJ) $(BIN) $(SRC_DIR)/lex.yy.c $(SRC_DIR)/y.tab.* + $(RM) -r $(OBJ_DIR) diff --git a/README.md b/README.md index 0187cfd..8596118 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,3 @@ -# ComputerNetwork_socket_lab - # project-1 This repository contains the starter code for ***CMU 15-441/641 Networking and the Internet Project 1: A Web Server Called Liso***. diff --git a/access_log b/access_log new file mode 100644 index 0000000..17627a2 --- /dev/null +++ b/access_log @@ -0,0 +1,2 @@ +www.cs.cmu.edu - - "GE /~prs/15-441-F15/ HTTP/1.1" 501 26 +www.cs.cmu.edu - - "GE /~prs/15-441-F15/ HTTP/1.1" 501 26 diff --git a/cgi/README b/cgi/README new file mode 100644 index 0000000..76f9d14 --- /dev/null +++ b/cgi/README @@ -0,0 +1,2 @@ +CGI Example Code - C server-side example, Python client examples; note: it doesn't show sending of content via stdin etc. +Daemonizing C Code - helper daemonizing code diff --git a/cgi/cgi.tar.gz b/cgi/cgi.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..ba31007e75cb2ec2e7d41e6967400e059b469d78 GIT binary patch literal 20480 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 BOU(cP literal 0 HcmV?d00001 diff --git a/cgi/daemonize.c b/cgi/daemonize.c new file mode 100644 index 0000000..9c65b76 --- /dev/null +++ b/cgi/daemonize.c @@ -0,0 +1,82 @@ +/****************************************************************************** + * Reference: http://www.enderunix.org/docs/eng/daemon.php * + * Modified by: Wolf Richter * + * O_EXCL Bug Fix by: Ming Han +#include +#include +#include +#include +#include +#include +#include +#include + +/***** Utility Functions *****/ + +/** + * internal signal handler + */ +void signal_handler(int sig) +{ + switch(sig) + { + case SIGHUP: + /* rehash the server */ + break; + case SIGTERM: + /* finalize and shutdown the server */ + // TODO: liso_shutdown(NULL, EXIT_SUCCESS); + break; + default: + break; + /* unhandled signal */ + } +} + +/** + * internal function daemonizing the process + */ +int daemonize(char* lock_file) +{ + /* drop to having init() as parent */ + int i, lfp, pid = fork(); + char str[256] = {0}; + if (pid < 0) exit(EXIT_FAILURE); + if (pid > 0) exit(EXIT_SUCCESS); + + setsid(); + + for (i = getdtablesize(); i>=0; i--) + close(i); + + i = open("/dev/null", O_RDWR); + dup(i); /* stdout */ + dup(i); /* stderr */ + umask(027); + + lfp = open(lock_file, O_RDWR|O_CREAT, 0640); + + if (lfp < 0) + exit(EXIT_FAILURE); /* can not open */ + + if (lockf(lfp, F_TLOCK, 0) < 0) + exit(EXIT_SUCCESS); /* can not lock */ + + /* only first instance continues */ + sprintf(str, "%d\n", getpid()); + write(lfp, str, strlen(str)); /* record pid to lockfile */ + + signal(SIGCHLD, SIG_IGN); /* child terminate signal */ + + signal(SIGHUP, signal_handler); /* hangup signal */ + signal(SIGTERM, signal_handler); /* software termination signal from kill */ + + // TODO: log --> "Successfully daemonized lisod process, pid %d." + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/echo_client b/echo_client new file mode 100644 index 0000000000000000000000000000000000000000..665efb01439a3eb90347207abfa361a1de54824e GIT binary patch literal 17232 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 Q&Hu)?UYy@g15Vk-H|%)<%K!iX literal 0 HcmV?d00001 diff --git a/include/parse.h b/include/parse.h new file mode 100644 index 0000000..a12e8a3 --- /dev/null +++ b/include/parse.h @@ -0,0 +1,29 @@ +#include +#include +#include + +#define SUCCESS 0 + +//Header field +typedef struct +{ + char header_name[4096]; + char header_value[4096]; +} Request_header; + +//HTTP Request Header +typedef struct +{ + char http_version[50]; + char http_method[50]; + char http_uri[4096]; + Request_header *headers; + int header_count; +} Request; + +// Request* parse(char *buffer, int size,int socketFd); +Request** parse(char *buffer, int size,int socketFd, int* request_num); + +// functions decalred in parser.y +int yyparse(); +void set_parsing_options(char *buf, size_t i, Request *request); diff --git a/liso_client b/liso_client new file mode 100644 index 0000000000000000000000000000000000000000..69e5016795618342476a52ec7492ba61aed77141 GIT binary patch literal 17200 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 literal 0 HcmV?d00001 diff --git a/liso_server b/liso_server new file mode 100644 index 0000000000000000000000000000000000000000..e494f8b16c45e20a98c68cd491c4a3cd233b1a9b GIT binary patch literal 65000 zcmeFa3wTu3**3iQ%rEpiNq1g)*$k=NRa7H~#vO9d5MCI5Y|wf3G#AlCPK-|zbW|N6RN zX07MAp7pF}9rvD{>insb9J;Pqms7h~Bh=`Xm^?)YpH>+pdD=+LgYRsur{)Ii5;#fE zlL@HuI-^uusj2Wzq?8-!kcif4XT@iwmW50WMLS;-{*lC5siye^f^xKV%Z~+!)F(1l zT0~=T74(v+B}elpxAr!PUwfNRWUTb0GR#V?`cWM}(^dUirxS%1O|w$+@+vqM5T;yI zBH`BQ3#vRTwdAgZ9PRv}SE^#XN|o1^UkX$KR;r5E1}!SNX~eKWi;4y=Dk-g6HgMU< z5d%jI%c(5O86xUU{p7v$@)@EewzqPHpr->Sj`T0~ueg5m_6ItC`JwOH*W&dPSM6Wu zCv6Zu)FJAn`?OVhs)M*(e0cTivaa*|8S_#{eG#(4L=s}Y$3sC{3~Xh;M&^9@^=;rs zwSg~#ejjM9FX}#@{_$<#8D8h(|GW+S@iy=~+Q8SefuGa{zH1wJM;rbe*#`cuHuM~B z1HZEk{9oI^_im%yZf)Q>)Sb`IA>e%|qxJP75a;7x+6Mm5ZQyTg13#$^dtPaS|JpY2 z#ckl9Yy)4}27W*r_#tiJJ#Erdl>iy2m>(!vT&$H;&I<&V6J7+~#l?#&W${2j zBZ?_4n**_Vfs(RP?WU5_A}T1W3XqjW&o5k5R#~hqwv<M`KogB3JZ(N11Ps}*}OUPOG@W0D!H|owiPZe2bOMP zB`X4R7SCfPN-d{U6c>ZO477lD>D0*+E}1hVXYepP8_f;L8LrKlJbl_67+Ac34yu?w z?UF@hrNz_d-L!~G7A!6+RfWuvtmkFq3?~0Ya}svi6pMo?R{*i_`SUGx>6jG}s+u)F z-`j9MrazZ3;WJy|{R;1Eg`c7DeOuwLQ~2Cg_&EwcvK1b|E3Uj&cyv#3`CH*vD||sK z{9Ot^vlV`$!q07me_Y`gw!%ND@a3)WFDd-8R`^#H-dyDq_FDe8;KS7t&$XK&IONxn z7<@(yJ{*J3jKQCb!Cw%AKNExJoMm0sxXd!SR6REgePmr*WAH57x*B8fmaj=W5QE1+U|$Dg z@bNZQ(+;zsFC;N?q#0MQn+S7Ah#VB~ zb%Z$-L>dKr6=4nmku3tALYQ4YvQfYj2y?iJ)C+htVGaS2RRSJDnB62&F5v!z+2td1 z1>A!$yLzNRz*&UZ#UptFP9w~&9my4NJmEybJ^?!jvnxkZ1^mxNfZ2s3nt;C`%&r?b zc@~IXpAlx4jT{m1CxqEmBL@Zi0bzF0NTYz?BFwHC*&^WA3A0N^HVSwzVGjL~dI4`E z%&r+(CE(`?vr9(G1^g6YP6?5@0)CV*yJn<7zz+~+myF~I_#VRSijiCa-$j^RFya&N z9faBSBB=ttm2g+Wnt&?^v#Ui;e#iRXOxQ>Gh=6Y*%&rwVDB$Y|vr9!91$-4@cBRM` z0Z$>!E)>});0c7;bt3fw9!;2CCbCMvLkP30M9Kx+pD?>fWUehgzaFr-2LE+(@X(F^ z;3xi?qbCcdPpvatqsa3U~WfV12}f?h{E}ZR$rv9`e^^%*@xcT}47uQ}`8XP}HV9C?8CFw^F%3 z`2H8q`hy4jUmx_>71&Jr!6wZ&WBMig^IY0)9|nkUo;0E_irej?Rf8lVSCn7Nq=^bO z7(*Z=>f;a9vT`tKo1nq&Psg#;S}FonuxkGG{yj$${hus>*uUF1EH~FTVP26xnClNNGyO07DvEzpRa_bH2mPr{d6`M^N%8yhIy1nU zFQJC9|3nflmUURhI@H}Knj};!q2Uqo1)GG4;dQ72swGIM`|tnR+#GoVqwV(_TsQn< zsU&<6`R{ZW zK}nU;y$O|oO{?!})1||FmzTkVmP;pw1ojnd&!L4rqr{0%%h9o|7uiYlRv|IP{?+Qvz77gu+Tx}o5Mm|y`okzifz zDi#;q57$)Fh(C{~K@wZjIFoX}I75!T#4>b5$9oFAcE_7Sd#pm6!v7NdP5!zUg&B2q zLQKVojK9gje@sSq41NO_+!kB4IYQO&`-K%_Kc_|C(#~M*!WM3k(D1{tvOQ(}1PNvr z!HmdQ=MM{-ccr56n-F5K^_4+$v$UfaNjMsua2d9uD}IrpMj#9o&0XD>JJs0&ZA;7RlEt?g3}c`wI@TpzU4*CG zMSm-1Mq0ZIMre>-+gjNgsqDx+=?X5!E&o1GWpTE$=b%iu_+?=mnjd%sfB01>Qx0pHTrx`J^SGW~n^oN;3wDctW5?Rb?!lKS&KpJnL>YmSWTcTh}6!9D)B zKk)|-`aMnl;6KS8yjQRzl0;FV`_70GYsa$jFb+bC(9BrR9cMoQWiN!u!Ed6MRrv_?rgAZZ1XHdE3LO4?ybn=5Gx zCGCi$g_+ciEkvgbulon{qITn@qtO_eS~>3Djgw_9y#5Qicq{x+vyPfF|Sp;klLn&t>YzB zOLnnx>5Ec?E5py7L{SIf9*kR$fh=pitJ8FL3(2wrETLKwF%kV(G6b8#FA6lh*|vS8 zwrL;s7TsHgv{KH+)q@vVCMMFvfx^VPlXk;wldCk21Y^K}Ij#|fVWGi9TNywPU@j=; za7f94_yKqptOv*%k_i;tDpr4cF`ttljgXC$M@p3O*M9>jCwNi*E(Q_@__g3WQK?FA zt|~zVz8Zs;TxB~6Of_JV%Kwje>@E~2TkHdvStBA_zkMg$pxLQuDR-w}Zx-3lMRTip z<}UEd3F2xTE{zNsqh|XwuIip=EE|0Qu>*ySUIJeg-(+-9I1IRN+<-9>p^=RIM&^UY z%S=MXwiwD1N%@teG)hXK3%FhosEh}h?D@p$w>Dr^L&9%i5C_N2k|QLNq<~=j*y*q9 z9KTD;0|$IN0mn7|pfmg&j&UGSPM%=?k(8G*W(%qOBWqLrq5LC2hC>E%!Tf_K^m^h_ zUeZ!tYUF0J&UkJ#JoS>xu{QtBQ2s%&J4DwoW)l5dmt#I=oXH>rjUGxZYTF6f6GLO! zUqe%neLV`PS#i+2G9%@s{5NF@(?~nFglm*Y%I<^Yg%h|lW!arCQp!fto4_M%l){Q?ue7t!e-qdg1lbp&_Fma;R3U z#ON3aI5Z5Oq>w)}Hf%ML};0 z=YOsS^Gds@Po##QDvqAyF#ZH+t3d@-val;z*o9ziGIoN-qvfq`(q~BeDAGF!`h%bY z(zbd?A1)0TCe(9`?r4|1P?p>gB+IwO$Zw6O+;^DCVEDH)t%{vSyliF5hI6Id#~@j9 z11T3rxmPJyH}-vShu1{l29wz5B({mz9}$~G?9W9R8Ga}V84uvwUw9H_u4PW`>p4sm zpfMsm>K4UE3WXF#g;2(g{KF(2MDMy0VEAbqhsnMRU;GXy^uhcOA$Aj0U|_6S@u3#z z3&da|Y8rLO^=39?bdxMcLir!EU%e_$R1A;8Ms{FU33rCEHD~ldTFn_p%IZg9IY!Ik z$T!F|8J}I_Ly9(=gE1ZW3!s!Z6!8j@kntM6>HWQXKI^6*Jand}F(sJ)PUJIa4jEfO z?yP1$V*UIedpGhs^F7qR>rDVhYVOq4O~4Z;~L@-z!;HoWmN*s3orOEq~2kT?W81B1Y}4qz&1$ zVLRu=kWnCYjB24Hls60kJQ(Eh#0MEc*D@!@Yd@N@Dqil@7GZeXioT*nZju9Csx8pl z77$(MKvVt>HuH(@V)U<@fEc2aP^mgU^3%|_($=Qd62x#%!kEh#=mWj5tEqN!Q)YzhRM!k=LfJTVA(1~l-)h)4ftV(Y`uOY#ZSy%8xY z(h>Af{(-tg2V^uU6S*>029YpoPs-iT3HHxG0=vF9WPF6|p);sK{ySXN@TP^ao06fV zO+o=3ae#Ln7-pfQUkcjrb%J&rw14g<$FLHMH{(yq&y z6Wf8TODN+gan=B(*!M~H&F8TDgT`SXL-~yuF#T%4#Mlp9F#j|vv5g|Q1s3@yT#OJu zgEhnI#z28)si^`?dL}LXfxC)9Xl$uH{b$jcceE>R`YX$Z{axH&Ku0(GqO|0cxlyH|4k!$%=F>CpPT%~MO{%Nk|qs3g)rp%5Q1F)7q zgCj(v{t8$;3J$pAOLSD|k+Vy1#pfVak_b2L&p(Ah_H(=9KONYj;-3eN+2oWJzXn-W zJj(8hmiu|liqBhAd~Hrl#iJq(M8mb`R{UB^*{J-_S@EdM>^5ayQ51My7?5&rBbrz? zgH~lgi8|brmB-AQ8(i_BKUl>MR(iQ`LKsWA>zT!2HH%N8of+Y&NKOjVLsCJYl>&5lM8eW0Ot>fpQ7k4ZYUD(64vx+l zFE#aVp$R4jjiG{K_#}g;B|}CAV2rWQ&^(ou&ImI(uN%b@WYi#xKqIk8Lw&-C#SbyK ztA@a;ENDc87Wn)nZLRTw0)YQDvh~rEZHMsy><-3iO}aC>CKLwKH# zm2MUmC;>NC0^?6y1Gc@FQ2|bapf9{MQLJ<0#7^VHl92H^s2G`9@Xr@mGK!YQz>$@mipoS9DOR+NW~%~IxmTLv9f3*})G z`LLiE>m)-}3kFQH@RhMjvMgs3H13hm^&-ib$iz02%Z#9rDLE!15q)nYGWGT_>SL?~ ztB&r@gN@c!Eeo(XGj3$he`IM z=+Y#Q8oDVBO?f^#LxhEJlL(D_1S6}BOl86l!;v@60w~z4iPKoi~WMncvG@(wb|_v z;X52~G#S4GfliG2AY}Z4%)H5TKr{&!Jfg^et%D2}G(IHBUqyduM;pIL&Ox_>PHk#y6pIeH=Lnv~YYP9-rJ-qzdxdhNPO);IJGc)b;t1vr5uNq} zTt*3a?0Yh&-(?MA)knXyB#CT(US_QD5j z(?>;3zZ+zG2=s|b9K#OB0DTD#<}n7;6`VyHhJ|7~RK;O~SXSP~2IA$3=Vnw(4(ls; zn%iPn_tMb2L_f@|7&lffhoY1z0Kp2Q*TNpVOkhm$`FJcfRI;P%<0 z5EOywq8=%=K~#>zCM#*_SBDkimctEW}rJT+Nvtfs0RI^E4oEZOxe*s#0S) zFS?;BAH6fI1=8(~BMwh_+OyUH)|2{)PLcz+oUxU#yB>2VEG77s-7Kkp%0C@ZIXMsZcGE z91GO=UT0*FLJ07tWe^Xk;0o`Q9e*nd+Y0}0gugbC(3HQLNzG2GIGeKiMx8#aWmze| z)z)(?sx!Xopx230w{mwm^)%XwQn&ea&+Y_W_TX22tgp^Z#t0|3k(I2W>I+j;H||w6URa2QE5XXD zA))+rWAaz8=#Nx{+d4E#2q8rYHJgR8zQak=7WB(ajuY`nw&3(Ce-mfKP4e_=3m4#` zh}Df%_lSYXAFAS$j>D`c9nClFaSzi>uk5boC)yYeF%P-d`3-0`t>9}~h%U@SJmrlcT(7^bcYRi$VLUo&J=SEo$k`}C8#sof-&?+Vr z7qqpKCX!%nJ)x%B^+>oVZ>pV&95ToiSUIE5XdhA7=Z{4Woxb^m>947!UPnksu30dnNA>D-z}65-6xo#mA|V%=`hD=?nbvag|GXa@Z?r9;`urxTFUBj zmJyO=*Cir*pP*ZAeBU2@9V1`(53e(HYX!~r^m=NFmQdR$Opr-0?Fb`EN+|t%j^JtC zJ<%d$Ygk3x(xM2}V4?`hsan(?kY$LZMHzLqA`C{=(h&h1&xs7{z4w5yeUq|QEVS+B z35w>iJiwCb>V@f{T44guePz6aM7*@wz%||kjF~$bNr@?|zlq0Tn2ZuR)_#W_xi#?D zP6t!XPJUxZUy8s88GpjiSaarVRjTM%;SnG3p^pPV;ye=HwT;!8(QXkE9VBRM0_DWu zkg*ZzSUy0pv?I>h0LU_fS@!sji2_SzEhq$~xE^DMma_H~$kL`^DL*+5ASCEgQ@1X* zrcpvgO6@DHSaw(y!~til=IVs6A7o7w^e+A-dHZ!9)86S_3eM^=W6#dG7yYRT? z6QNlTMh>%e#(#nLWr@Y+U`X%}e*Hav-Aa?0{r;N$IGBQ$YAW8xx9#Nr1hQbYPP6D%IaoAv?nVfJ@Q~|b>{*t z#^(#fu!P}NggS=@VLcW;7>Pb&J>J{KCtVSi(hOPcny|CxOlr!S5g-LIfY=XAy$!$H zv)O(CayFA{L%6Y#i=XpAZ{$0t?W<6#Dop%hr9Xsr37=WJjGyku!!y5+^7{uWa(EOd zVnUNvEBqeY_CK&U?IV*iAk(U#t>UX!5w{<#z1I-6Rn@nthe73Fw|}*uYmrG&GjRGQ zt1{#~xUT2H#mC@URQWLq z--WfQTsL9ogr^zAv>+!}ZP}GFGprgsoNlG;ZI*3Yt)0rZe%dQ-2m&b+}H@7P#xF6SSzu`@SDPgA`$CfMn%_uP-PL2*l*%n ztMbAdf=S9pctj{^dP?m^0MMnBh$Z!?y<(9hMVi77?iR6H&SIcHXAe7oRH*dgNTioo zP)8}T>v3AaCB}&h|BdN|c$i+A-qK<~tT;=rz|byj#}kN$;40}iXVt}c&OAq~hEhVt zQzBQ@Kk^`*DV8M|eMlF-ju-)FhRgY55#u)C*a-DST`x zygY5>)>|I*1~2eo7rOx8ynqDJm<|wG94Q*JkhPA7)lGZMa!>asgE*zGM?At-xi$F> z3RS0*d<=FbjuE#8t6m7s*y0aP+oT?})^PVI{I-M+O6XMy z9p0_20_SffbVO-60RtN`r&*_Q{Ix<|XUA>^emEp}ovk?zM>$F)M-84GtXa`mxbk_Z zJJ2K+0yGZLVN?)@c&QPdp#a_#(&Sx$P2ABF6f-Iwl_)qP*fF;Q7n-pN&pXDP)`e!U zSp4#9cnN}q&AL;TZ7YdZfwv?4SYTP|>k?nJt-7R%uC z)DzIvg?TlN*aM+_EQVM&>**JQM?{T|0Ee?bK?N%xss_7Qt^Dp~43+u&*h?e7!k2t1 zlq;rlZ3ym>)N?8Q_Ta=o5ff`w#g5>?$Y81^5`#S`%(2*8_#tE}^e_vJ(~Of*b34P_ z8kmbpY{JiQ^Y^8!n*ulN)>a@k%C?D!3tMs2yLFU=MU*s7&%^Ht1+SA)V(DtU?M)>a z=?Z^X!mSNIU=d<06b|KMu+phFf2(d3gfIBi%4vV)J^qwhszZqf5L`H-6LD^b0`B-7 zU|pjN>vA9be)!Yh;#6yN>uT_Jqq+llUJ^s5 zDSQiLTR1Ic-P=4G=a^EnZzi4sioUERrJFYX+VR&+4!%Er#(2CNrq{0S;?*w$nO;3U z_}%2-S5x~P!*F8y_k8CJfAkU*)&4c$8~jJ>eJxXi|C}29YGUy3NAvNUO#*M4dZ8zzj6GWSL&lh;=L^PyJPs~7=Q2!fAFmM327vc-eFmgeuXiLOXoX9 zaP^uuz}KtD*Xt%rNsl_&dTyK zIIGAvzpTP?t`9DSgY(BvlnwR&m3nFgS6n?ECjF1=M?LXBNRM50^`-~w1rL0^12o9% z2iOy%XE@)_V7->XdMSf?6+^r>32%NyYw)eCC8Y~|@_n*7@!CLMzNrW-pNuk}z(fV` zUe-Vh38jhed~Jcx=c{KKq6kM4%1Wc9REhxhEuB|FU3m2@<5^R$b)8ov6v?hivH9rZ z@IpoL;<6>wbRNn)yl)mt&P%o27n2%zzhttOi0?$4@x|lK^l=zd+;}sut|bBM)Nn%F z_NA-K;na1P1w>QB9p~m1ha}EzdgARXAx>O^dfuOcSGLL0i!o^fbV585{YB_^T8 zQ}EvARLIgcCq8ZcJHOT_R)>A(|JM#SyHUdTY4>V@(Kq20%$1AgRW2Ok0~E~_RxFw? zQRTiqy(;^R@x_C_Fd%S6B@0Rd=nE2AR3@>7Wq2>KlqoKsSAlmXS5yjFN(RbqDK5pk zp669ya3^BX(n@^uh0EIfd4YM0eDfC-FY{Fv&MPe~uJGaA(Zv;bpR!N9IC|i~(lXyX zF&ALm#`~c(?JN%KvT@`#4WA|Wtixv?J}2=Rj6>2Z@%a%xPvY}2K40ULgmdUi@Zq5~ zefR^)EiNtcmCg6vR5gD-tXf=BSy^19Ab}yg+9EAx~yV3s_0w3e9nU6z?@RdgL7mNef!a_SWlE!RW2OJR`S_8zfWHw$Hn4U zZJPEy{Kch}RTUPyd?B|m;osWLhH6>L_m(q9@-Gh*S3>_y^NK7-NiVdZGCt(x_`mzo z9ZnalDDBNhX5*i(_%9T|Dijgg9e%Cszi?`RhUAiCci z(PaTu+8vfaIlkCC=dgEXTeBhF#=f+;NOa*jSUgE}noz3oZR#zF2x*P$JFN_w)NAta zLiEyN8(4@Jt7EcNG}YoQlCEJ~NnPWz!=3sw8xA|eVMn-Yc6J{n)=detGnY9_#I~^CJ}TBFtNp41$1h=j1GyZ?b>Tbd_roPH!&&Q**-Bn z-kX+=a(QYQd!?kNrnYOBhRf?sPfyQi-yWyyF_)N2<%Ehix$EvYhqH2dX<*(mISgyD zzyMzr#;tO!(6M~OiX7MXkO%lAFBe9V`M<;O!vYRcKUlxyS5p5CyJF>(^f!NOZgzjz z-0a22htEKKM&mOPf2BaI8G99KFik8nNBfFOFp^bp*=S+P%gW0MszJYa*}{2MScw*C zmn8x zo0~5J{Mc`rn{PmR0_kl?6LI{p0qJ6#_%|Yb2=nPtq`zxwZgwH&4&dpDY@`q2@r;Q` zKfzNZMMxX)tj}7ctML@nCZs8UXl_1$^l_wNq=WICp6SxGFOl{|dJi6I^=_I6KqyeOfChCRT9m9~O7PDx2vYOd18WsT`SG`j~?P<|ple&|K<_C?tn@R{;tb8~wV#wVxV>9{1x?QCbl zB%%8@p!0s++uEvY>AOdI9L&;WwM^?Cd6k52zjZEc|VAGk~dU)0!{vp|9QFg5F@$O|* z^n;*h#nNX)?LP|o>!A0FrO%DhT^JkQ1RalQMeBb}l%5Sb<;6LR<-bW$`b5xQ1btep zyhAoH?JolT6VQ*hpnohBkiHu9O^2GBZ$&%V@#Cy=l0noTbO-0FSot}!d>?T8KzDAA1Yh2DtQ@}q!Y!m2Y_cTczVL0 zwhoTB9bGo#M3AO~Z(+E(xfpqELUQU)921f=?{?-V`|4a1lKZYR{K>g@y8X!`YvQIQ z=T#(+9G{#!KDqCNWFPpzKOxx^^U4P3sfQkPUHig~KkWtJ*8T3p;W^RjNIyr2xU?kRKc%L~tlwz#-e;k9g~Po&lw{jeff=Sr$L%{oNR zR28-G2R%aEw%f1d6 z)n28&RXReYlT><*O6RL|iAwKO>HR8wLZvUMbiYd9Q|WP)ex*{ky7A2?*m?C<=?Ilh zQt34+ov+d*D!o&s_p9^?l}c?t{M-7woeb|wFS%s2ukVbTs!9V@z6*1P=j09?S|y;t zD+iCv$sN{DVzmKamVqt1)$1y%S0s_YCUnaK)X3 zgu{$G!9;i80GjhM=6em~x5HRL%p?pfjy}VHak&iKk=L9KO7|N>9@FT9!kne((~jB+ zz&P=PY0YsbiB49*u|{OivfQyAb8ZG4C8rRj-O-d5YuAEa0~vSZBwZ zn03JzXI6mO?HEE_{98$y^Vg6y7V~eeJO2e_82Q7AUm9#D9^)r|wV365IP)j|s{=5mXA1ehWj@vOI2aSZV?NXK9t=r5%e>FS zq7s{#@0FExasUg{r%_v?PJ_$SzofQQ0R+;Ik&>n#0A*P^fA5#rUT3tdN`H~s zI_Q%D+>t&W--(&}bZDzd|2q|Q)_ESfHa$X_Ui#Z$s83HKWuP7bus;1w&=Ye6urd8T z0)qswDcwi5TmfuJKS9b6eFpSwO&>^y3>CIDrYEze!*#xodmo|@lc~jhKmq=Zfs{_fbodITruM+_M&lSE-VKmwmo2hOKx{XJD!iRQ zYImW?wu4-|G0b)hEY?P*#k~SyPX~OZd5G0K*Fr8Wo_UvteoaeY-t;swpU8ZoCmrUc zB{84sxsLf{=F>eZ$dkf+re{9&q%z;x!?kBxJLY{J{yoC9bPk7oJsd65GU$?AErC|Q z&32gpES|JGfV}r%+UIqH!@H64-X*N&BNX?(PSO*C!6d`8f?*jMo+E?#GEAsX&v_3^ zP|y8fPS3p)XwAbvXqG3I#v!+i3Lr*D0p zuVH@rB`hi1)1UZ!>g?-Dr0f)Sl3dR^@?6g8bfhPjdJ4WmKF{+fmU}&G;P>22dv0KU zrY9TJ^x4cW^h~Dg%`|zLmcSY0II_Ye4lPUbWtbjJr=DFXEdvj+K(G_LMMi?ir^@im z0=_f7*o^7qL9!-NOV+Z~jFiO`|1%27XveJP8OwYc^Furj!q^NiRTXvmC5Rd6E0AB9 z+9{7^WU$uw1*zx)BnYzxBlcLJa|pbV(Y_b5T@Img`u$|@qZUNs&Mshm!y!znU02x* zu7-6xtGjj;Faz1uuxe*@w+g~PqXJjM2EbQBw*@}~m=Ck)>p5$>8jb)yK-Ct!tGe3) zQ1qXV1edF!5p+7zf)DPj=JRHn{s2vZ{O;;*&rshl7=f;at>9k>r|27w3b-CHXAu3t zxdPq-crNXGNZPjv`sNqe;ChgsfFCXLy*sPB*QiZRUzo|O+jscVUzYM4A#fAzQ}AOu z5xm03pTIuZj@`5_9CG!$DRM+@0WU?Km%bqlLs-{NEL1Q!8Ww3?N(lC3m8>1?AFSO`-E9qh)cbBh zuLt}Z*2?;Tdj-56@Wu35&PD-m1pFOBP#+?FylF>ucRZ#fuIJ%PUcOs2eS|E2HOM|i zUZcp}e#!DKWN?Z$>p5F7+$qJijtS7QsBD3zU-X11G`yo)>p5NRN56yJyj}uVw^~+Z zB2_sXj?C#chhV-GI=G{{=N2VXD@C+QTk~YebOf5ak5)TY)`(ZP7g*sdGEhxd!%0;5 zPgHxQbl}Nd)zY@vQo~_r(0T^d=D)8}fd|pFZhwSX`c0DU03D%D05}%$lI1LDRZa=Z zVQrxHn3CWkme){_Wa&$#+D3Zj#!ixYk4&^#HrH*EYb$GcQgJ<`xTKytB*zxkLIo=W zK@13m7!Zb{(cI<(K)KBt)W>bIVcn(ymuMTY9&%|rQD?PTc@zHSW~KEm>M}Ug!9}?9 z@JPrxkJGM0CMBGt}}E2jEv{H&Tt4IFP`f zU1ykjCAjCtbI3K~_2mE-#&ca~BYDCACGS%Q?G_-O+43iMrZveNY=)4U1#*t8JG3(T-O-`bxxA&CID#&ca~4A=Q*_4a8FuIt=!TfmmU zb)BKsb;d^4SFG!dN0^oCI^$8+T(0YkCs=W=>m~r_HmM_#ZOR%XF{p^;l3!pSx3FF< znd`a~uIr3(I`Ju7*BN;-|1{)`@gnaw3B>&YEU8@A#jRoSsa)5^trc0W>*9hU%XOWZ zMVk`eAs5uQ)8Y&ysa)5YorrPD{hp%}0@%}WK9~{t$B{Uu;VVA#dS;h$G#xk!?2f(Y zK6*|cWaF+Nd?^R=`)@|pZIKF@8;zsG#Gr=GTa$b4VVN#g&^`~c4;mh}1m?xd7Nu4>`BYl`c%(O&4q@pQ8QA#R(KUL(@XF_}$BvTb*3Vud~*-6-(cpVC80E6fO zUM=o+t z?Yl=O9;|Z(rzQ+YLmw9gq-$|JgYcG;b-hl!$LUk7UO%x9DeT->1y@@Nd|KQkRIrd{ zJ*E@yac;B}jAOl?QCR#CQ(WFVsrChZs<3N=a+3EgHtdV4VK-W?b5O%?rC+x|`BwOK zt|F#aLBk#(Hd)-;{Aj8wXW9!sox*Rs-!51C+#A;?PX6|E~w9PHGpfLOkj|Y&)w>QxL+uWb<(VFc#b8l zWM~A0ELYMUuOxSwfPbPS;5uJ_v)M`&($j^^$iS#Da~hZjpzhT9f#dh4{f66^IeF?)(Y z`i$Hs-5jFhmBd@N#66Jc@(^t~>E?XvXz+KTCjc@G91RnD+@$GW2x(}OJDgK)Is`%1 zqg2yRyJf`9>`|iWUn;5TTIWer`WGR1WUMT&zg_G;78{^pe^JFE;(tzfmykGmk!1bW zmPms~x;%?c4GvlQOc}qsRQUxow9ztD>-iRIQRn{k7^y-$`--f-VIDMjzovtKqC^*F zU!}^cSLJy}aNOIZ=yUNC^aRG_t?su*OOB5eBf9kytmqByKa7$n7seo7`i3WIa#zaT zV4IZ{PsQWhgBACKk{R6Zg1Zx{FwW-f$?b#Q)4iCZ60UtR0dF@D$lFu#&g>#~I6d7m z%nQ6(l^*q z&2ZX~@iLvw@Rg8e^!0YJQI8vqBczIuttsn5meXYXUWM-|oANQs5Poa2^<*8Po|lZS ziu*a6I|UuG%e#`QEYkY)qwZUTNgoWAtP|~anG1;?g&2R7$&0cl@gxA(&t!t744Cz5 zMPG>h-ykZ?Gh9O?$9uN22$Xe#vOL8+waYt$V2bZea^Ajvg`|9VM)WB6MHH6 zR$4pG`G$h~S&U&x*XE|eLn17CIvEzuhTYX#_PD;1d==&hUf$VM`?XVcdVh9$KZ&=_ zN4$M$Mthg6!c-DJ0mh{*$F!}^D2@WbGm6%CZco9&^PEx0!wGfbV3>2D(mf4d>RiD+ zQ{=^c*p??4>Z}5LK;BUm6>zOv1#Wdn!EBsqm{edLO!NYqI+&OQv~@7?Fj>S6C*xb@ zt%C{Xt%C{Xt%C{X?Slyd_Q3=J`(T2AeK0}5KA0e2A50Li4<=^ALi=EXe{R=4n4rP- z!2|*OU}6mb`(R=m0Q+Eq!E7H)@SM{=nBXScKA5-%Z1%wf=PvtTf`EN6LBKwkAaMSJ z3EE~KOz<>hU+dEdR#KftFl(Jgu)5Z11eK)Xq-FqchWR+4L^dSN7F!`=*_r}tpHZ|r zjUe7SjS%^#p#rB7%!?xk_ZpTdjv(A?MHaEFxq~9hBZ#;x8j^T5zWxrdo#y6!R&fLo z*NGT)1fk9y(lnoG=3;~q_Z`f5W;HMGJD3R~pDGO=4}AJa&~V?u!TS#QwJN^TmZh30 z_aYRYH0I@f2h&ScMc!Y6Xr@1g{K8ak9?Qs}vAFLboI-+d)nK@a1v+@& z!E8Sj*$lDg>B-3RIK!)aNP!evp5D~qaUQggVoTI-pgWAY(_cyfN^HyY9i%!|VhYxOUjzyFOv3v) z^t{c8cJro#;|0<`S`Ijqdm_!J-=;qWLdQp8oW4?D#{6dHt92^W68UTc|5UmtI7!#s zWY78+_5MyL!Q(tq2uAX<#g79eJeaAu-y`cc)b^E5JU0G6_K{Od#5*IDj4Y?9)~%Wf+fUGP}oKb>nHYdWtX-frV4yVv#5es zbN`)cbIE$GgLscKSFvW@OLyIrUB#%wc9Zi?ublOoEJ+0aDGHi-qCSH z82;exT3K={pn(FK>*L)SM})DBWrEhd6Yc0E?D$*0)FOUVgsi^d2~5&iZ_)i-1c%YE zW7{vPvqG$5H-%{=rj)Me=OVw+(6}8KoqGGbUJ{rvc~+3;0);tAjGH_;t{sBs;8|dv zW?6$=ZwSm8@;uJ6ausG3HNQ^G5Eq9RqhT#DJ(e%Wj&7K;XCI~dv8>?=bAXscmUW@R zyg^J2c}Ba~cZ`OEyMXyQF&DeI2Xi(YT$weKC5>~@k4D2`%ES?qr^-G;%m!L~snUB8 zn4ZH~(rnjeMgXp!JqgcrJ#N8Qu#_3@zq1RHev%rdxj(evE~HO#zhS`v!oPC8?N|KY z(T0d?*%SqDC4GnSXn}&~lYYweON)M#aF)CHDoM}w5_Y?L#!>Eix53kWT)p`9V^lrs zA`%K!CD+5jz4JiInoM-9YQK$ai4Mfv>Ehin2r+xmW`V5+Zw;{hy3)$C&ev5Z$cA=a`i5Z`efx`0IP0Vp=u-Xf zqX}o7Gy&U*{$&zmQS4L~{EfP9736{m)S_wPmwrg~4S&UAzrP5iTb;~18^SB4{#%`= z1bk#=f6-Zf>|~Xk4To3u7vcM3q0!m!&dRJC>G~B;b^>R^rfS({D-~Q{Js{3?3k$1u z{tng;Tn76LE$eBTb-Sp9vtfO8)}IO2IKM%mSg>ckNAONn#_5%P-c_dGs6!R5d%-9B z+9Qf-RdwI~mq?;VF=g$cmQ9Lbb#+#dmOiE6wbfavgr8RMI(FV=IF(iKnU#ItQ3|h+ zdbOaTBq)s(eL6N)O=^iQ4a&(4O8EE?Oe zuqyi7mGF@%MirABiPP}qf#XD&xU>s~(2glW|IOp2%HuLYquvF^{y$^YrwIKBgZ|>A zXo`xNf}V#czrfj1d9`m)DX~s(q-!r11@M$gSbK#Pa(HjR6;wY=sJAvBw2_y-p??nh ziKMddOIX@4t8gg8g9#&)Y1Cbb(J-o;s{_1|Dh>-M`Pir*+PKSU{k*9MHi%u0qs5)r z|IJ;FGrG%h)~!P2TJCaOU)sAI*H>ap6}Mkq|6-%bU5+bem*e`5c)81Qon>C`a$L>K z%UzC3(+S934&InXK<;u}4gttrj>{zgxyx}G0+72Lmsi2+~?or#6@>G zaWT7`xbNTP#96zXxack?E@qb#7qiQWi`nJG#qM(Ae!wm#PVRELu*-X%K;LcMO|f(X zw!L`L#=~&tB+*{nYw@sAoDGjvx4%({OK@X#d-0f#=XuC+a_E4eF-g+4RA-Jyqw2{L ze4#p%Ye+qn4?XiRD|0#(rELX>X(Y20!-npakUw()Y3bDJXeh}15uw4f4P#VCapz_v zwcZI#me%PPGm*!Y1r@wHM>%*C$Pmw2%Z->}QqB-VwWhbzdnJ1loXMS%+u3x zbc`C0pjC=g%Xf-`QZIgjV)d041Cib6)-V(^pmehvEWzpss#Se0$16nSxqV3uZLLEx zwyCo%fOl2(869XtZ)Ol{(YWbrMQgukl-W^95j-g_JA@n-E{L+lL>Uhh1#I1$_l)Cy>L-gQSqQD}Saapx& z;DXYsK{u5IDkaOJlA8uCC@ege9m@Chp%CHYk9%s<&b+O3EZ^(&VZ6$O*kg z0*Unnd@%=aLFN0rC0A7`vPH;)h_~sMmE*moWfjGeXc@Fv>Y-thlW)(LEO=FMC6QPs zO6%sZa*~Ecp~HHX-q}Mp17Xu^&T{nfI!2|N>8AHJ#|7!;YmS~7$IOL}-sz4pUbDf` z!)xX_hIt($)6IMETT9*jklQiR>liI*M{acV^d2{_a|}y&dK{POQs826m<<*;gvX_W z2Moh>=kfs3!8%p;Q~EDT9uVY$<}4U z-`kb`$NePQ<-WI9o~NTA?(hc`mM@px0D1I?MeGp>EgAF(Q7h;X|5lVDtD=;_jV{B` zWx%$GQgEs6q_CQm%RmNEL}^9Na@w>!Cou0Ol!MF40?Syn?$tX#GW7cn zKlbp(?T5D?7O}9+ZEnA=(wx@j}!JZ5e*bCJF7F-MPdbLwN;ALf6k8uXa? zOMGpAbo(QYK3=r^=f=!mn&W=wOfcU=r1bDQ^$#984Og1-)ezCV*M#Y`JJV#%|YMLDIrUl$Cxf8%mc zm*Ji@^wZ~Fcl6KLZf-VTe$M>I(m`giqeq50*1XvKhxw(Ww|D31&97~CCR|i|+U)HZ znjSVA%pT5UbINB8OCAm{H)r)a^)T9HtkaVtl}B4$l(mgz#ae$12-mFOo>}LR-H%9= z+uV7I=3X{@$I^2ZEij+m zeA>C}J*USv;?%|+o1Z@q%jV|Q7jE;*bCdz$a@X+N+`QfF zA?fHlvz$w}ITL)tY8z|JlI=UpGj`vv^5y9 zoO8tQ&lms`>rSkvFqrSZZ4?W{p@AKx0~-fvmTnd zVAy3<;{Sr-msJg4(g2UwY#xXImn|4v)iCY~=-vGA~2@avW|w_*zpu23C%e)|tBV1-HJvX7!+Mj_iyYXL8P|<2AL8{vE%nGRMvu zT=l+l@qA}SjackXERNo3#~cH^wQHOm1FxI!Bl}C?Ska3avuaqlnAy$z z`f@XR3I>^)>m2>k9Yehv9|qRpESFRC6t}beHb?)=*LdwV8y&uJhd)vYCZMZ!ik6GeCG4vZDt=$c~7$TCE;NFRvE7O2ui-&dkmXniq3tMjDy8 z);6gE|FBI=9EwzoFqDm}f>A1|6k!QbyN*2GSy|7qi4vP+`})J9jz?(VP{4$3#JzDD}LnO6DOZa*cA%=dQ)X{$yhFC1}&RPU1$yAxYjpmP#Z0dS@1y-y2I@KZ4v3INY1Vk^u34?%ihtcCN} znoCbWGrzV@xBA{t5@R>w2zKKHh{ed*tRu^53I&&2jD*(OU(lMFP#iBe?0bu z?|S)Vk+V>t0D6e(LOFPb2^BSCV6Ae)pjVeq9RFQyiMN2ZWb zS52yuTKs%!BK4~{S(mJ&Rvk&MOegYd7n3jDIh*`)GW}rk`8zYo&n34eFUR>QoL{&# z`HzXM$@4*a@!?abJKnQoZnT(s7;D!JsgI-7>)t;9-PF2Q0Z$Z1(HW!3^R3jX^N&6F z*kix;Wa0|U1pEXv5qu4!=l^F`ume~gQT|V70)3nQ3#r@NofpoYJqsDw^#lej&r?6e z@5tx}M=SsI)x%s6C$=n4Y+Q@ci2E!NI7pI-4+(N&dWFOOe!rm9I}Ubg5lZ$TZWx)> z{Cn@kc%u!8Cp)QcIgI4;mk-J$Y)pNA-n0T^isd}hJqHZpdgKj1!e9i3at#Yggl8yM zfm5z+Htm2BlnTZ^!2~8O)tfCkhZw^Z<`xvPYyYk3$qgIq_BZMAY76`K-&`yp+6rQl zj90VGTP0w;uz&y%VQW4g28Rwz-eUG2*uQ-*PJ&j|oTwuZ1fs;e>+c|@4P zRm-vIWGn3gE7{<}J@tw<^4uz{88cTonycYSHdt4xR}1SPhT9>A@eLH{W+Ay@BZ{tM zi;#f{;d#S~*->nLp_WHKwVMpE(XQ6401nMePfhG2vxr=Uj;mMl?B@`V=jcLdE&>2F z<{);~f`;9&k!6}j7R*9w)jGNz56u>|DL}+5bE43!v&gv$E+9lg3xtRYQm8hB8FcH> zLethiy<;Cs=@zohU_OuM{#Jlyg+n#G%uW|s%p<%`rK=G|Osx$e>&Rh`P=u(i)iJfOkP}(tvt6*0 zFLb~RR12}gkVR8-h-iW^Do{?>t5y&!Wx8-j8+vVA{1S+eT^>-&7(l0|eF*l0rlNkf z4y9-xXKSbuU588rQbS(k3vrb4CA91p*220oC?T zwa_Zn*_I*}YdK6F@|Gu$XG}NJ7>P;87KR5fp%T?>c+_<$hgG>Y?{rI81ddbv4Vxik z2GZjgckg-v)4@|IWZ+af(og74LunVQEnKt=;+0c~(0*1k4^B+pGBtzpq3P?9U@%kc z2E9`$7faGL=pA;pXbxp*H4Km@dQUqAG#nskkkE4sZP<)cH;M2X_HB@8iNOpQCs(C< z8B z1ltmwl~9Kkcq4U^Dru)66yED`R@APw5q4@LIU^FL-;R~rbU~3dbA(J&BlGz-hbGgvZLQTnVv>6rmz9_I=S5cT>&yHw4u7BKbV~h^&W>z ztJyXCZ{3SDTVvyd3;15uh$(#~H)G^5eP9_O&9((HG8o_#1?nPKa(7{ciirDZ6A?w7 z7T^k|+)BTnQ9)S>gh=cy4!JnTZ)RrQ4ljJ(LdWqMW4P$y{h|&sNE1 zU!X1C137n5FtIBTbv3J6<$4btO(Zv$vq-Rm>9;@xz9ZLsYNsxLLq6|1_7wv!6NKsALX zbr+fuxyt4NL!^k5vFV}$qZaAtm~R%CRYvs}BGlX~(D$fS|%SWixB!^>M_WJp*M@`^A`9NZ?eOzjko z8HrtO=6Vx_H)eTz=Srl-RV3+HZX|jiK$I$EEK`a0l}wEKdKpwwjJ;VSSK>NQZpTjX zRe}a{J+9AVEv8Zq>KORYgKqa&Gb` zU0D=2ppR42(+8%_ZBx_R4;-2@6Vtm6nSB$pd-mPB4_LCikWq~c1Z!2k!@jklx$Lwg z?Zeoy1XQIh#1PpDU9sN6x&n6#ec1!8nZr7#lAR+FCyxpR-RBK~d{w*nCo8)|O^KtjFb zT^fXG%R*%G?S$+C#KMEHaUxXG=g1tND->m{fffsMu3%BVJdmKZcz}|E(Ht@!l^(Jb zZM(uEp=#|W=c?meR-lD46WL*IMFEa1YKu2oEE-Xot&A2*WI|TZ3p-|sh_T*bO8p^6 zfn6a84clc^TtrgA3IWV)#1DD|$|FdVGukDV1bI=ShsXv z={S6}xBqk;{x%5Z|x=%>_T2i7L z#bL}PgLf|l3j94o;J-8ko?Zf{5%hxKKi}~$z+)fUzbrWC^)Ea|1-^bwoZ@l^U+~~J z0X_ox>~`{DeLU!&Ix?WYs(`cJ(_T4U!C%_%_X9qN|1S-JKQ8604N8t5creKER}S9r z;9}JQ|GF=d;(yoSFL>?xk%Qmm;4rPoK>~ zze(UL0^O15T37FcgX{J~AeLj7!jITI`;`axFc`r&O&^hLaGgzp4?Fk~56;hDh=0<- zw>$iTmY=l%g;xZ=HqgCfUN{NzGf2vpA8_L=(N@A<)pmaDS(R7aiQ+ zVBrT2?(bWG!litFLzd+Z?(Z7$E(iCwrg*o5SGQO>{IyMjUvY4M+a1OZ9i-1Y0H>Vw z8`Wjto5w+c_vg1W797kfe!&8+aB$<`>G?RkUsos7X4z6F8D*S|lFSv5t9v;Cb z9Q?Eg|CEF4r=(Xne(rT}{cco;{pTHAzZ_Ng?*q<$S9_#>hpB^NCihB_J8^9kyO!}Aaa1DwigYff7%l{E~AH>cKa{M#OfnW5J`xiem9|@M; zr`~e-{(bNwln>YWCHK?!06sF{zP1VQRgkB@Weej@5Ps0{Db=CmSqJwwZJ8rHu`KZ0 zRTg~m6hA%+_)5%Urx((4LFa)_4#9t52>c0wFAMzbnErAI{#n3njd6a?15SR@jvt+W zUc=%x&8Qm=u2kIle9(IHvLW#CA@GSI@EO3#&w7ua-v(oY>Ma6)1^8U!@mZ7dmj(V; z(;Wx*KWpYLfUNhRS1-Q;9aJwjr6>Lw4}V(ZzjPh=~)9#sK?LSg0H>TPk#>mOFe&nn}uEFE?ql1m>;;$3ckOM(lr9_m#b$t1HKad zvclt^aUv+UBOaU^!w-@}N#M(t>{8qqg8xZZzHZQ<`h3?AIegBQ?{A6r1qXj(n{AP< zXuss(Z#uZHXdiQMe>1ix9o*jqjNcp&YVWgxuTt!%-vgX_?vKYehTxB(A1UWqPal>` z|1JyseayJUHub^ZdhVJb`mojE``fU65b$)L?cUj8hwpCzHxKwqxLl_kpGpuqe19{# zj|p6{`suwa2NKffEQnW*ldc?pOEbm}rF>rU^zb=6j1TIU#Ub_n-4OV{4uQWVaLE4` zEq}WlpFbn@E(`o^%`S29mkwLRg2TUh2%qmC0^je-@i%>Y4L7(IkVEiL+Lde*?%+iE zobu%JL(#YX^Y8VJsx+kD-vXTF`}6ZXjvs#q_)j~yzlX&ahm_ClTd23{&8j<3JqbAZ z|DNMt=YeO2l=Gr1$KTBE--qD8GX&1vEC=b&HACR<1Dt#YA5U9Jx@6lBeC}Yt_Nq6^ zl}^!T1Rv|e57=VxMYbFt8B$Jj2%Nix4&wiQz&TDY^~UKVfTvwu(d20C-*oV<d@aOcq^E%IObKIcs-CyHs$FTw(za$CO5=D*@l)&frX zZ}aqIT<{%IG|4sb;t(b+ye5R<9WQP}SU(KRt#GQT;Z-Fp(RF9aF?smH;C*NNc#x}C z8?-s(GdFF1-fVcmy)ESPWNJ*~;Nt5td)L~{1cd=xcqOochfI;eXu z^_|r(_M+dJr(!U?AdT1>`08J*4t(jV)+e5-6%B7vt$l8&?FGnvgOjyY#Ox`!ZmloQ z$e>24fkqV|dvIqU9b`8n@*vwN%`r<&OTJZdfYrvcs#ON!+j}zW9989<^KO zTWn{Y=-EotLIHrYRj4UKO%KjsA@&S;;U22#BJzU2TWe*H_iVsDYlyz;HfAS00H(~; z{v8G$S#iaJJHn2``zQA8nT%ht{cQ}~#LU!gSHkWc(}CHw_rUgvz2?Bqork7o%*@1g zI0#Wwme|@2On7iM$%SoEd*G;<7j7B!jG;|%+qPYM_iUdu8#5a-Hv+}JsfR^9TcImS z{IX#q;S9pdv=GFvTDuLxyQ?)<#BoHh zFh|4Q3mq<3`d2sgj4;k2$4X00n_@C9wP1AVlh_W4I5@;T62e*ohUC_~Ptdp9iq+HB zP%Ttpj)|kHw^_NKYehI^wc1uS7+GeWU0aPy&ZJDkQNPZpKY~+0QDsblWlvw|P}Is& z73ouj-mW&{3|jvKs&>q7&I;K_gPZR>BE*3K{#J0(vo&Do#SG7=9bem(vb8+)&t0LH z1|$_zyA7MfQ$`fX(D4VzgADCrv$VdA@m7TLy=#kMZ_k^l+ zL%aljg;(&T3~qgo9p?$+G%H>NJm5m{13;gMn-Ha~>Y#SPIk?iq$;6kXr#3W6qC@AG z&LC)3%z!>$Z}<#1FvrxJ@#5``&4ab-=1SSH z6lC(<8p^XN4Bm1@{RN{LgKNz~B})Q#)_~bOBkG#LX$CjhAS1I#h6^zu)nyLO6iROC zRf3ypFK0>ZaxD-FJtr0GLIJ`TJWX>r0W`=!e}fDbgH0Hc!`$g;H}R*o(!o|JlN zZVuirdW932od2#u)c^fC-)D^AU*CJGeOOcX*xIXrxY6TEWUw^v(W@O<({vOW z=lYzkVD1AQrB{2iroXI+F7@em0RCgd^i}@vcPE;zcXW7+l>?6pv131Sd{$9}=eE$_aRBj4;7AIuUsY%b@;nYVhhL5j#P5%LC^pjC~jf?)o|B(JW zpk@Clz4}j_cJya(EqbJ*8JzzR|7@bttDnW)cUr`AEF6c5LHSlaxF6S|^{YR|aco4$ z<8DW9bN%t7<-CatQTpEd;sr~g_C%jv^FP4}%ToT+3u(EuW(JOznCik%i>?fq4PKAC)FLC_Kw}J+0zLkL=L}xx?v5XzvsLq;;s +#include +#include +#include +#include +#include +#include "parse.h" + +int main(int argc, char **argv){ + //Read from the file the sample + int fd_in = open(argv[1], O_RDONLY); + int index; + char buf[8192]; + if(fd_in < 0) { + printf("Failed to open the file\n"); + return 0; + } + int readRet = read(fd_in,buf,8192); + int* request_num; + *request_num = 0; + //Parse the buffer to the parse function. You will need to pass the socket fd and the buffer would need to + //be read from that fd + Request** request = parse(buf,readRet,fd_in, request_num); + //Just printing everything + int k; + for(k = 0;k<*request_num;k++){ + printf("Http Method %s\n",request[k]->http_method); + printf("Http Version %s\n",request[k]->http_version); + printf("Http Uri %s\n",request[k]->http_uri); + for(index = 0;index < request[k]->header_count;index++){ + printf("Request Header\n"); + printf("Header name %s Header Value %s\n",request[k]->headers[index].header_name,request[k]->headers[index].header_value); + } + free(request[k]->headers); + request[k]->headers = NULL; + free(request[k]); + } + return 0; +} diff --git a/src/lex.yy.c b/src/lex.yy.c new file mode 100644 index 0000000..ce6b90c --- /dev/null +++ b/src/lex.yy.c @@ -0,0 +1,2018 @@ +#line 2 "src/lex.yy.c" + +#line 4 "src/lex.yy.c" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 6 +#define YY_FLEX_SUBMINOR_VERSION 4 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include +#include +#include +#include + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#ifndef SIZE_MAX +#define SIZE_MAX (~(size_t)0) +#endif + +#endif /* ! C99 */ + +#endif /* ! FLEXINT_H */ + +/* begin standard C++ headers. */ + +/* TODO: this is always defined, so inline it */ +#define yyconst const + +#if defined(__GNUC__) && __GNUC__ >= 3 +#define yynoreturn __attribute__((__noreturn__)) +#else +#define yynoreturn +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an + * integer in range [0..255] for use as an array index. + */ +#define YY_SC_TO_UI(c) ((YY_CHAR) (c)) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN (yy_start) = 1 + 2 * +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START (((yy_start) - 1) / 2) +#define YYSTATE YY_START +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart( yyin ) +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k. + * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. + * Ditto for the __ia64__ case accordingly. + */ +#define YY_BUF_SIZE 32768 +#else +#define YY_BUF_SIZE 16384 +#endif /* __ia64__ */ +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +extern int yyleng; + +extern FILE *yyin, *yyout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + #define YY_LESS_LINENO(n) + #define YY_LINENO_REWIND_TO(ptr) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = (yy_hold_char); \ + YY_RESTORE_YY_MORE_OFFSET \ + (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) +#define unput(c) yyunput( c, (yytext_ptr) ) + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + int yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* Stack of input buffers. */ +static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ +static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ +static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ + ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ + : NULL) +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] + +/* yy_hold_char holds the character lost when yytext is formed. */ +static char yy_hold_char; +static int yy_n_chars; /* number of characters read into yy_ch_buf */ +int yyleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = NULL; +static int yy_init = 0; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void yyrestart ( FILE *input_file ); +void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer ); +YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size ); +void yy_delete_buffer ( YY_BUFFER_STATE b ); +void yy_flush_buffer ( YY_BUFFER_STATE b ); +void yypush_buffer_state ( YY_BUFFER_STATE new_buffer ); +void yypop_buffer_state ( void ); + +static void yyensure_buffer_stack ( void ); +static void yy_load_buffer_state ( void ); +static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file ); +#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER ) + +YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size ); +YY_BUFFER_STATE yy_scan_string ( const char *yy_str ); +YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len ); + +void *yyalloc ( yy_size_t ); +void *yyrealloc ( void *, yy_size_t ); +void yyfree ( void * ); + +#define yy_new_buffer yy_create_buffer +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer( yyin, YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer( yyin, YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ +typedef flex_uint8_t YY_CHAR; + +FILE *yyin = NULL, *yyout = NULL; + +typedef int yy_state_type; + +extern int yylineno; +int yylineno = 1; + +extern char *yytext; +#ifdef yytext_ptr +#undef yytext_ptr +#endif +#define yytext_ptr yytext + +static yy_state_type yy_get_previous_state ( void ); +static yy_state_type yy_try_NUL_trans ( yy_state_type current_state ); +static int yy_get_next_buffer ( void ); +static void yynoreturn yy_fatal_error ( const char* msg ); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + (yytext_ptr) = yy_bp; \ + yyleng = (int) (yy_cp - yy_bp); \ + (yy_hold_char) = *yy_cp; \ + *yy_cp = '\0'; \ + (yy_c_buf_p) = yy_cp; +#define YY_NUM_RULES 13 +#define YY_END_OF_BUFFER 14 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static const flex_int16_t yy_accept[20] = + { 0, + 5, 5, 14, 12, 5, 12, 4, 10, 9, 7, + 2, 6, 8, 1, 13, 5, 3, 11, 0 + } ; + +static const YY_CHAR yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 5, 6, 7, 6, 6, 6, 6, 6, 7, + 7, 6, 6, 7, 6, 8, 9, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 11, 7, 7, + 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 7, 12, 7, 6, 6, 6, 6, 6, 6, 6, + + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 7, 6, 7, 6, 1, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13 + } ; + +static const YY_CHAR yy_meta[14] = + { 0, + 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, + 1, 1, 1 + } ; + +static const flex_int16_t yy_base[21] = + { 0, + 0, 0, 18, 19, 0, 13, 0, 19, 19, 19, + 19, 19, 19, 19, 19, 0, 12, 0, 19, 13 + } ; + +static const flex_int16_t yy_def[21] = + { 0, + 19, 1, 19, 19, 20, 19, 20, 19, 19, 19, + 19, 19, 19, 19, 19, 20, 19, 17, 0, 19 + } ; + +static const flex_int16_t yy_nxt[33] = + { 0, + 4, 5, 4, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 18, 16, 17, 18, 19, 3, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19 + } ; + +static const flex_int16_t yy_chk[33] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 17, 20, 6, 17, 3, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19 + } ; + +static yy_state_type yy_last_accepting_state; +static char *yy_last_accepting_cpos; + +extern int yy_flex_debug; +int yy_flex_debug = 0; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +char *yytext; +#line 1 "src/lexer.l" +/** + * @file lexer.l + * @brief Grammar for HTTP + * + * This file contains grammar for HTTP packets defined in RFC 2616 + * section 2: Notational Conventions and Generic Grammar. + * + * @author Rajul Bhatnagar (2016) + */ +#line 12 "src/lexer.l" +#include + +/* This file is generated by yacc */ +#include "y.tab.h" + + +/* Define LEXDEBUG to enable debug messages for this lex file */ +#define LEXDEBUG +#ifdef LEXDEBUG +#include +#define LPRINTF(...) printf(__VA_ARGS__) +#else +#define LPRINTF(...) +#endif + +#undef YY_INPUT +/* + * yylex() by default takes input from stdin. You might be wondering how + * to parse data from a buffer instead. This is how you do it. The way + * it works is, when yylex() needs more input, it invokes a macro + * called YYINPUT: + * + * YY_INPUT(lex_internal_buffer, number_of_bytes_read, max_number_of_bytes_to_read) + * + * We hack it, and we undef the macro, and redefine it to something else! + * + * The usage of this macro will be clear from the lex-yacc-example. + */ + +/* We need some global state (must be defined in parser.y) */ +extern char *parsing_buf; /* The buffer to read the data from */ +extern size_t parsing_buf_siz; /* Size of the buffer */ +extern int parsing_offset; /* Current offset in the buffer */ + +#define MIN(__a, __b) (((__a) < (__b)) ? (__a) : (__b)) + +/* Redefine YY_INPUT to read from a buffer instead of stdin! */ +#define YY_INPUT(__b, __r, __s) do { \ + __r = MIN(__s, parsing_buf_siz - parsing_offset); \ + memcpy(__b, parsing_buf + parsing_offset, __r); \ + parsing_offset += __r; \ + } while(0) + + + +#line 507 "src/lex.yy.c" +/* + * Following is a list of rules specified in RFC 2616 section 2: + * + * Lookup Table + * cr \x0d + * lf \x0a + * sp \x20 + * ht \x09 + * quote \" + * digit [0-9] + * ctl [\x0-\x1f\x7f] + * upalpha [A-Z] + * loalpha [a-z] + * alpha [A-Za-z] + * char [\x0-\x7f] + * octet [\x0-\x1f\xff] + * crlf {cr}{lf} + * lws \x0d\x0a(\x20|\x09)* + * hex [ABCDEFabcdef0-9] + * separators [\{\}\(\)\<\>@,;:\\\"/\[\]?=\x20\x09] + */ +/** + * Declarations + */ +/* Matches a digit. For e.g., 0, 8. */ +/* Matches a CRLF. Carriage return - linefeed sequence */ +/* Matches a Colon */ +/* Matches a space */ +/* Matches a any combination of spaces and horizontal tabs */ +/* Matches a CRLF followed by a ws */ +/* + * matches following characters: (RFC 2616, Section 2.2) + * ( ) < > @ , ; : \ " / [ ] ? = { } + */ +/* Matches a CTL*/ +/* + * (RFC 2616, Section 2.2) + * This rule matches _ANY_ character _EXCEPT_ separators (see above), + * and control characters (ascii values 0x0 - 0x1F and 0x7f). + * + * token_char = ( char - ctl - separators ) + * + * Note: A token can be detected as any combination of token characters. + */ +#line 552 "src/lex.yy.c" + +#define INITIAL 0 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +static int yy_init_globals ( void ); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int yylex_destroy ( void ); + +int yyget_debug ( void ); + +void yyset_debug ( int debug_flag ); + +YY_EXTRA_TYPE yyget_extra ( void ); + +void yyset_extra ( YY_EXTRA_TYPE user_defined ); + +FILE *yyget_in ( void ); + +void yyset_in ( FILE * _in_str ); + +FILE *yyget_out ( void ); + +void yyset_out ( FILE * _out_str ); + + int yyget_leng ( void ); + +char *yyget_text ( void ); + +int yyget_lineno ( void ); + +void yyset_lineno ( int _line_number ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap ( void ); +#else +extern int yywrap ( void ); +#endif +#endif + +#ifndef YY_NO_UNPUT + + static void yyunput ( int c, char *buf_ptr ); + +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy ( char *, const char *, int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen ( const char * ); +#endif + +#ifndef YY_NO_INPUT +#ifdef __cplusplus +static int yyinput ( void ); +#else +static int input ( void ); +#endif + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k */ +#define YY_READ_BUF_SIZE 16384 +#else +#define YY_READ_BUF_SIZE 8192 +#endif /* __ia64__ */ +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ + { \ + int c = '*'; \ + int n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(yyin); \ + } \ + }\ +\ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int yylex (void); + +#define YY_DECL int yylex (void) +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK /*LINTED*/break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + yy_state_type yy_current_state; + char *yy_cp, *yy_bp; + int yy_act; + + if ( !(yy_init) ) + { + (yy_init) = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! (yy_start) ) + (yy_start) = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! YY_CURRENT_BUFFER ) { + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer( yyin, YY_BUF_SIZE ); + } + + yy_load_buffer_state( ); + } + + { +#line 123 "src/lexer.l" + + +#line 126 "src/lexer.l" +/* + * Actions + * + * yytext: yytext is the "string" that matches a certain rule. For example, + * in the first rule 1: slash, you get the string that matched + * (in this case "/") in yytext. + * + * yylval: yylval is a variable used to communicate matched value in lex to + * yacc. yylval is a union of different types (please see parser.y) + * file for details. + */ + + +#line 786 "src/lex.yy.c" + + while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ + { + yy_cp = (yy_c_buf_p); + + /* Support of yytext. */ + *yy_cp = (yy_hold_char); + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = (yy_start); +yy_match: + do + { + YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 20 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 19 ); + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + if ( yy_act == 0 ) + { /* have to back up */ + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + yy_act = yy_accept[yy_current_state]; + } + + YY_DO_BEFORE_ACTION; + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = (yy_hold_char); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + goto yy_find_action; + +case 1: +YY_RULE_SETUP +#line 139 "src/lexer.l" +{ + /* Rule 0: Backslash */ + + LPRINTF("t:backslash; \n"); + + /* Copy character to yylval.i*/ + yylval.i = yytext[0]; + + /* + * This return statement lets terminates yylex() function and lets + * yacc know that a slash was found! + */ + return t_backslash; +} + YY_BREAK +case 2: +YY_RULE_SETUP +#line 154 "src/lexer.l" +{ + /* Rule 1: Slash */ + + LPRINTF("t:slash; \n"); + + /* Copy character to yylval.i*/ + yylval.i = yytext[0]; + + /* + * This return statement lets terminates yylex() function and lets + * yacc know that a slash was found! + */ + return t_slash; +} + YY_BREAK +case 3: +/* rule 3 can match eol */ +YY_RULE_SETUP +#line 169 "src/lexer.l" +{ + /* Rule 2: CRLF */ + + LPRINTF("t:crlf; \n"); + + /* + * No need to communicate the value of CRLF to yacc, so no + * yylval here. + */ + + return t_crlf; +} + YY_BREAK +case 4: +YY_RULE_SETUP +#line 182 "src/lexer.l" +{ + /* Rule 3: Space */ + + LPRINTF("t:sp '%s'; \n", yytext); + + yylval.i = yytext[0]; + + return t_sp; +} + YY_BREAK +case 5: +YY_RULE_SETUP +#line 192 "src/lexer.l" +{ + /* Rule 4: A sequence of white spaces */ + + LPRINTF("t:ht; \n"); + + /* Very important to communicate the value here! */ + strcpy(yylval.str, yytext); + + return t_ws; +} + YY_BREAK +case 6: +YY_RULE_SETUP +#line 203 "src/lexer.l" +{ + /* Rule 5: A digit */ + + LPRINTF("t:digit %d; \n", atoi(yytext)); + + yylval.i = atoi(yytext); + + return t_digit; +} + YY_BREAK +case 7: +YY_RULE_SETUP +#line 213 "src/lexer.l" +{ + /* Rule 6: A dot */ + + LPRINTF("t:dot; \n"); + yylval.i = '.'; + return t_dot; +} + YY_BREAK +case 8: +YY_RULE_SETUP +#line 221 "src/lexer.l" +{ + /* Rule 7: A colon */ + + LPRINTF("t:colon; \n"); + yylval.i = ':'; + return t_colon; +} + YY_BREAK +case 9: +YY_RULE_SETUP +#line 229 "src/lexer.l" +{ + /* Rule 8: A separator */ + + LPRINTF("t:separators \'%s\'\n", yytext); + yylval.i = yytext[0]; + return t_separators; +} + YY_BREAK +case 10: +YY_RULE_SETUP +#line 237 "src/lexer.l" +{ + /* Rule 9: A character allowed in a token */ + + LPRINTF("t:token_char %s\n", yytext); + /* + * Again, it is important to communicate the value back + * Otherwise, yacc has no way to know which character matched the rule + */ + yylval.i = yytext[0]; + return t_token_char; +} + YY_BREAK +case 11: +/* rule 11 can match eol */ +YY_RULE_SETUP +#line 249 "src/lexer.l" +{ + /* Rule 10: Linear white spaces */ + + LPRINTF("t:lws\n"); + return t_lws; +} + YY_BREAK +case 12: +/* rule 12 can match eol */ +YY_RULE_SETUP +#line 256 "src/lexer.l" +{ + LPRINTF("t:ctl\n"); + return t_ctl; +} + YY_BREAK +case 13: +YY_RULE_SETUP +#line 261 "src/lexer.l" +ECHO; + YY_BREAK +#line 1009 "src/lex.yy.c" +case YY_STATE_EOF(INITIAL): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = (yy_hold_char); + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++(yy_c_buf_p); + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = (yy_c_buf_p); + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_END_OF_FILE: + { + (yy_did_buffer_switch_on_eof) = 0; + + if ( yywrap( ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = + (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + (yy_c_buf_p) = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ + } /* end of user's declarations */ +} /* end of yylex */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +static int yy_get_next_buffer (void) +{ + char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + char *source = (yytext_ptr); + int number_to_move, i; + int ret_val; + + if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1); + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; + + else + { + int num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; + + int yy_c_buf_p_offset = + (int) ((yy_c_buf_p) - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yyrealloc( (void *) b->yy_ch_buf, + (yy_size_t) (b->yy_buf_size + 2) ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = NULL; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + (yy_n_chars), num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + if ( (yy_n_chars) == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart( yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc( + (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + /* "- 2" to take care of EOB's */ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2); + } + + (yy_n_chars) += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; + + (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + static yy_state_type yy_get_previous_state (void) +{ + yy_state_type yy_current_state; + char *yy_cp; + + yy_current_state = (yy_start); + + for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) + { + YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 20 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) +{ + int yy_is_jam; + char *yy_cp = (yy_c_buf_p); + + YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 20 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + yy_is_jam = (yy_current_state == 19); + + return yy_is_jam ? 0 : yy_current_state; +} + +#ifndef YY_NO_UNPUT + + static void yyunput (int c, char * yy_bp ) +{ + char *yy_cp; + + yy_cp = (yy_c_buf_p); + + /* undo effects of setting up yytext */ + *yy_cp = (yy_hold_char); + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + int number_to_move = (yy_n_chars) + 2; + char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; + char *source = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; + + while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = + (yy_n_chars) = (int) YY_CURRENT_BUFFER_LVALUE->yy_buf_size; + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + + (yytext_ptr) = yy_bp; + (yy_hold_char) = *yy_cp; + (yy_c_buf_p) = yy_cp; +} + +#endif + +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput (void) +#else + static int input (void) +#endif + +{ + int c; + + *(yy_c_buf_p) = (yy_hold_char); + + if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + /* This was really a NUL. */ + *(yy_c_buf_p) = '\0'; + + else + { /* need more input */ + int offset = (int) ((yy_c_buf_p) - (yytext_ptr)); + ++(yy_c_buf_p); + + switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart( yyin ); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap( ) ) + return 0; + + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = (yytext_ptr) + offset; + break; + } + } + } + + c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ + *(yy_c_buf_p) = '\0'; /* preserve yytext */ + (yy_hold_char) = *++(yy_c_buf_p); + + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * + * @note This function does not reset the start condition to @c INITIAL . + */ + void yyrestart (FILE * input_file ) +{ + + if ( ! YY_CURRENT_BUFFER ){ + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer( yyin, YY_BUF_SIZE ); + } + + yy_init_buffer( YY_CURRENT_BUFFER, input_file ); + yy_load_buffer_state( ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * + */ + void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) +{ + + /* TODO. We should be able to replace this entire function body + * with + * yypop_buffer_state(); + * yypush_buffer_state(new_buffer); + */ + yyensure_buffer_stack (); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + yy_load_buffer_state( ); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + (yy_did_buffer_switch_on_eof) = 1; +} + +static void yy_load_buffer_state (void) +{ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + (yy_hold_char) = *(yy_c_buf_p); +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * + * @return the allocated buffer state. + */ + YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer( b, file ); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with yy_create_buffer() + * + */ + void yy_delete_buffer (YY_BUFFER_STATE b ) +{ + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yyfree( (void *) b->yy_ch_buf ); + + yyfree( (void *) b ); +} + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a yyrestart() or at EOF. + */ + static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) + +{ + int oerrno = errno; + + yy_flush_buffer( b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then yy_init_buffer was _probably_ + * called from yyrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; + + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * + */ + void yy_flush_buffer (YY_BUFFER_STATE b ) +{ + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + yy_load_buffer_state( ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * + */ +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) +{ + if (new_buffer == NULL) + return; + + yyensure_buffer_stack(); + + /* This block is copied from yy_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + (yy_buffer_stack_top)++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from yy_switch_to_buffer. */ + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * + */ +void yypop_buffer_state (void) +{ + if (!YY_CURRENT_BUFFER) + return; + + yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + if ((yy_buffer_stack_top) > 0) + --(yy_buffer_stack_top); + + if (YY_CURRENT_BUFFER) { + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void yyensure_buffer_stack (void) +{ + yy_size_t num_to_alloc; + + if (!(yy_buffer_stack)) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ + (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + (yy_buffer_stack_max) = num_to_alloc; + (yy_buffer_stack_top) = 0; + return; + } + + if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + yy_size_t grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = (yy_buffer_stack_max) + grow_size; + (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc + ((yy_buffer_stack), + num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + /* zero only the new slots.*/ + memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); + (yy_buffer_stack_max) = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return NULL; + + b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = NULL; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer( b ); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to yylex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * yy_scan_bytes() instead. + */ +YY_BUFFER_STATE yy_scan_string (const char * yystr ) +{ + + return yy_scan_bytes( yystr, (int) strlen(yystr) ); +} + +/** Setup the input buffer state to scan the given bytes. The next call to yylex() will + * scan from a @e copy of @a bytes. + * @param yybytes the byte buffer to scan + * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len ) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = (yy_size_t) (_yybytes_len + 2); + buf = (char *) yyalloc( n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer( buf, n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +static void yynoreturn yy_fatal_error (const char* msg ) +{ + fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + yytext[yyleng] = (yy_hold_char); \ + (yy_c_buf_p) = yytext + yyless_macro_arg; \ + (yy_hold_char) = *(yy_c_buf_p); \ + *(yy_c_buf_p) = '\0'; \ + yyleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/** Get the current line number. + * + */ +int yyget_lineno (void) +{ + + return yylineno; +} + +/** Get the input stream. + * + */ +FILE *yyget_in (void) +{ + return yyin; +} + +/** Get the output stream. + * + */ +FILE *yyget_out (void) +{ + return yyout; +} + +/** Get the length of the current token. + * + */ +int yyget_leng (void) +{ + return yyleng; +} + +/** Get the current token. + * + */ + +char *yyget_text (void) +{ + return yytext; +} + +/** Set the current line number. + * @param _line_number line number + * + */ +void yyset_lineno (int _line_number ) +{ + + yylineno = _line_number; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param _in_str A readable stream. + * + * @see yy_switch_to_buffer + */ +void yyset_in (FILE * _in_str ) +{ + yyin = _in_str ; +} + +void yyset_out (FILE * _out_str ) +{ + yyout = _out_str ; +} + +int yyget_debug (void) +{ + return yy_flex_debug; +} + +void yyset_debug (int _bdebug ) +{ + yy_flex_debug = _bdebug ; +} + +static int yy_init_globals (void) +{ + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from yylex_destroy(), so don't allocate here. + */ + + (yy_buffer_stack) = NULL; + (yy_buffer_stack_top) = 0; + (yy_buffer_stack_max) = 0; + (yy_c_buf_p) = NULL; + (yy_init) = 0; + (yy_start) = 0; + +/* Defined in main.c */ +#ifdef YY_STDINIT + yyin = stdin; + yyout = stdout; +#else + yyin = NULL; + yyout = NULL; +#endif + + /* For future reference: Set errno on error, since we are called by + * yylex_init() + */ + return 0; +} + +/* yylex_destroy is for both reentrant and non-reentrant scanners. */ +int yylex_destroy (void) +{ + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + yy_delete_buffer( YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + yypop_buffer_state(); + } + + /* Destroy the stack itself. */ + yyfree((yy_buffer_stack) ); + (yy_buffer_stack) = NULL; + + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * yylex() is called, initialization will occur. */ + yy_init_globals( ); + + return 0; +} + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, const char * s2, int n ) +{ + + int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (const char * s ) +{ + int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *yyalloc (yy_size_t size ) +{ + return malloc(size); +} + +void *yyrealloc (void * ptr, yy_size_t size ) +{ + + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return realloc(ptr, size); +} + +void yyfree (void * ptr ) +{ + free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +#line 261 "src/lexer.l" + + +int yywrap(void) { +return 0; } + diff --git a/src/lexer.l b/src/lexer.l new file mode 100644 index 0000000..68c7910 --- /dev/null +++ b/src/lexer.l @@ -0,0 +1,263 @@ +/** + * @file lexer.l + * @brief Grammar for HTTP + * + * This file contains grammar for HTTP packets defined in RFC 2616 + * section 2: Notational Conventions and Generic Grammar. + * + * @author Rajul Bhatnagar (2016) + */ + +%{ +#include + +/* This file is generated by yacc */ +#include "y.tab.h" + + +/* Define LEXDEBUG to enable debug messages for this lex file */ +#define LEXDEBUG +#ifdef LEXDEBUG +#include +#define LPRINTF(...) printf(__VA_ARGS__) +#else +#define LPRINTF(...) +#endif + +#undef YY_INPUT +/* + * yylex() by default takes input from stdin. You might be wondering how + * to parse data from a buffer instead. This is how you do it. The way + * it works is, when yylex() needs more input, it invokes a macro + * called YYINPUT: + * + * YY_INPUT(lex_internal_buffer, number_of_bytes_read, max_number_of_bytes_to_read) + * + * We hack it, and we undef the macro, and redefine it to something else! + * + * The usage of this macro will be clear from the lex-yacc-example. + */ + +/* We need some global state (must be defined in parser.y) */ +extern char *parsing_buf; /* The buffer to read the data from */ +extern size_t parsing_buf_siz; /* Size of the buffer */ +extern int parsing_offset; /* Current offset in the buffer */ + +#define MIN(__a, __b) (((__a) < (__b)) ? (__a) : (__b)) + +/* Redefine YY_INPUT to read from a buffer instead of stdin! */ +#define YY_INPUT(__b, __r, __s) do { \ + __r = MIN(__s, parsing_buf_siz - parsing_offset); \ + memcpy(__b, parsing_buf + parsing_offset, __r); \ + parsing_offset += __r; \ + } while(0) + + + +%} + +/* + * Following is a list of rules specified in RFC 2616 section 2: + * + * Lookup Table + * cr \x0d + * lf \x0a + * sp \x20 + * ht \x09 + * quote \" + * digit [0-9] + * ctl [\x0-\x1f\x7f] + * upalpha [A-Z] + * loalpha [a-z] + * alpha [A-Za-z] + * char [\x0-\x7f] + * octet [\x0-\x1f\xff] + * crlf {cr}{lf} + * lws \x0d\x0a(\x20|\x09)* + * hex [ABCDEFabcdef0-9] + * separators [\{\}\(\)\<\>@,;:\\\"/\[\]?=\x20\x09] + */ + +/** + * Declarations + */ + +/* Matches a digit. For e.g., 0, 8. */ +digit [0-9] + +/* Matches a CRLF. Carriage return - linefeed sequence */ +crlf \x0d\x0a + +/* Matches a Colon */ +colon : + +/* Matches a space */ +sp \x20 + +/* Matches a any combination of spaces and horizontal tabs */ +ws [\x20\x09]* + +/* Matches a CRLF followed by a ws */ +lws \x0d\x0a(\x20|\x09)* + +/* + * matches following characters: (RFC 2616, Section 2.2) + * ( ) < > @ , ; : \ " / [ ] ? = { } + */ +separators [\(\)\<\>@\,;:\\\"\/\[\]?=\{\}\x20\x09] + +/* Matches a CTL*/ +ctl [\x0-\x1f\x7f] + +/* + * (RFC 2616, Section 2.2) + * This rule matches _ANY_ character _EXCEPT_ separators (see above), + * and control characters (ascii values 0x0 - 0x1F and 0x7f). + * + * token_char = ( char - ctl - separators ) + * + * Note: A token can be detected as any combination of token characters. + */ +token_char [\x0-\x7f]{-}[\x0-\x1f\x7f]{-}[\{\}\(\)\<\>@\,;:\\\"/\[\]?=\x20\x09] + +%% +%{ +/* + * Actions + * + * yytext: yytext is the "string" that matches a certain rule. For example, + * in the first rule 1: slash, you get the string that matched + * (in this case "/") in yytext. + * + * yylval: yylval is a variable used to communicate matched value in lex to + * yacc. yylval is a union of different types (please see parser.y) + * file for details. + */ +%} + +"\\" { + /* Rule 0: Backslash */ + + LPRINTF("t:backslash; \n"); + + /* Copy character to yylval.i*/ + yylval.i = yytext[0]; + + /* + * This return statement lets terminates yylex() function and lets + * yacc know that a slash was found! + */ + return t_backslash; +} + +"\/" { + /* Rule 1: Slash */ + + LPRINTF("t:slash; \n"); + + /* Copy character to yylval.i*/ + yylval.i = yytext[0]; + + /* + * This return statement lets terminates yylex() function and lets + * yacc know that a slash was found! + */ + return t_slash; +} + +{crlf} { + /* Rule 2: CRLF */ + + LPRINTF("t:crlf; \n"); + + /* + * No need to communicate the value of CRLF to yacc, so no + * yylval here. + */ + + return t_crlf; +} + +{sp} { + /* Rule 3: Space */ + + LPRINTF("t:sp '%s'; \n", yytext); + + yylval.i = yytext[0]; + + return t_sp; +} + +{ws} { + /* Rule 4: A sequence of white spaces */ + + LPRINTF("t:ht; \n"); + + /* Very important to communicate the value here! */ + strcpy(yylval.str, yytext); + + return t_ws; +} + +{digit} { + /* Rule 5: A digit */ + + LPRINTF("t:digit %d; \n", atoi(yytext)); + + yylval.i = atoi(yytext); + + return t_digit; +} + +"." { + /* Rule 6: A dot */ + + LPRINTF("t:dot; \n"); + yylval.i = '.'; + return t_dot; +} + +{colon} { + /* Rule 7: A colon */ + + LPRINTF("t:colon; \n"); + yylval.i = ':'; + return t_colon; +} + +{separators} { + /* Rule 8: A separator */ + + LPRINTF("t:separators \'%s\'\n", yytext); + yylval.i = yytext[0]; + return t_separators; +} + +{token_char} { + /* Rule 9: A character allowed in a token */ + + LPRINTF("t:token_char %s\n", yytext); + /* + * Again, it is important to communicate the value back + * Otherwise, yacc has no way to know which character matched the rule + */ + yylval.i = yytext[0]; + return t_token_char; +} + +{lws} { + /* Rule 10: Linear white spaces */ + + LPRINTF("t:lws\n"); + return t_lws; +} + +{ctl} { + LPRINTF("t:ctl\n"); + return t_ctl; +} + +%% + +int yywrap(void) { +return 0; } diff --git a/src/liso_client.c b/src/liso_client.c new file mode 100644 index 0000000..010bd30 --- /dev/null +++ b/src/liso_client.c @@ -0,0 +1,91 @@ +/****************************************************************************** +* echo_client.c * +* * +* Description: This file contains the C source code for an echo client. The * +* client connects to an arbitrary and sends input * +* from stdin. * +* * +* Authors: Athula Balachandran , * +* Wolf Richter * +* * +*******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ECHO_PORT 9999 +#define BUF_SIZE 4096 + +/** + * argv[1] : 主机名 + * argv[2] : 端口号 +**/ + +int main(int argc, char* argv[]) +{ + if (argc != 4) + { + fprintf(stderr, "usage: %s ",argv[0]); + return EXIT_FAILURE; + } + + char buf[BUF_SIZE*2]; + + int status, client_sockfd; + struct addrinfo hints; + memset(&hints, 0, sizeof(struct addrinfo)); + struct addrinfo *servinfo; //will point to the results + hints.ai_family = AF_INET; //IPv4 + hints.ai_socktype = SOCK_STREAM; //TCP stream sockets + hints.ai_flags = AI_PASSIVE; //fill in my IP for me + + if ((status = getaddrinfo(argv[1], argv[2], &hints, &servinfo)) != 0) + { + fprintf(stderr, "getaddrinfo error: %s \n", gai_strerror(status)); + return EXIT_FAILURE; + } + + if((client_sockfd = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol)) == -1) + { + fprintf(stderr, "Socket failed"); + return EXIT_FAILURE; + } + + if (connect (client_sockfd, servinfo->ai_addr, servinfo->ai_addrlen) == -1) + { + fprintf(stderr, "Connect"); + return EXIT_FAILURE; + } + + char msg[BUF_SIZE*2]; + //fgets(msg, BUF_SIZE, stdin); + + FILE *sample; + sample = fopen(argv[3], "r"); + fread(msg, BUF_SIZE*2, 1, sample); //sample to msg, one time read 1 maximum, read BUF_SIZE times + fclose(sample); + + int bytes_received; + fprintf(stdout, "Sending====\n%s\n====\n", msg); + // send(sock, msg , strlen(msg), 0); + write(client_sockfd, msg, strlen(msg)); + if((bytes_received = recv(client_sockfd, buf, BUF_SIZE*2, 0)) > 1) + { + buf[bytes_received] = '\0'; + fprintf(stdout, "Received====\n%s\n====\n", buf); + } + + freeaddrinfo(servinfo); + //close(sock); + return EXIT_SUCCESS; +} + + diff --git a/src/liso_server.c b/src/liso_server.c new file mode 100644 index 0000000..055bb19 --- /dev/null +++ b/src/liso_server.c @@ -0,0 +1,234 @@ +/****************************************************************************** +* echo_server.c * +* * +* Description: This file contains the C source code for an echo server. The * +* server runs on a hard-coded port and simply write back anything* +* sent to it by connected clients. It does not support * +* concurrent clients. * +* * +* Authors: Athula Balachandran , * +* Wolf Richter * +* * +*******************************************************************************/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "parse.h" + +#define ECHO_PORT 9999 +#define BUF_SIZE 4096 + +Request** parse(char *buffer, int size, int socketFd, int* request_num); + +char* process(char*buf, int size){ + char temp[100]; + time_t Time; + struct tm *info; + Time = time(NULL); + info = localtime(&Time); + strftime(temp,100,"%a, %d %b %Y %k:%M:%S",info); + strcat(temp, " UTC"); + + Request** request = (Request**)malloc(sizeof(Request*)*100); + + int* request_num = (int*)malloc(sizeof(int)); + *request_num = 0; + request = parse(buf, size, 0, request_num); + + char* buffer = (char*)malloc(sizeof(char) * BUF_SIZE * (*request_num)); + memset(buffer,0,BUF_SIZE * (*request_num)); + //TODO: only get the first request, how to get others + + for(int k = 0;k<(*request_num);k++){ + char response[BUF_SIZE] = {0}; + + if(request[k]==NULL){ + + sprintf(response, "HTTP/1.1 400 Bad request\r\n\r\n"); + FILE* log = fopen("./Log.txt", "a"); + fprintf(log, "[Date: %s][client: 127.0.0.1:38636]HTTP/1.1 400 Bad request\n", temp); + fclose(log); + } + + else { + if (strcmp(request[k]->http_version, "HTTP/1.1") == 0) { + if (strcmp(request[k]->http_method, "GET") == 0) { + char htmlstr[BUF_SIZE]; + FILE *index = fopen("./static_site/index.html", "r"); + + if (index == NULL || strcmp(request[k]->http_uri, "/") != 0) { + sprintf(response, "HTTP/1.1 404 Not Found\r\n\r\n"); + FILE* log = fopen("./Log.txt", "a"); + fprintf(log, "[Date: %s][client: 127.0.0.1:38636]HTTP/1.1 404 Not Found\n", temp); + fclose(log); + } else { + fread(htmlstr, BUF_SIZE, 1, index); + fclose(index); + struct stat file_stat; + stat("./static_site/index.html", &file_stat); + char last_modified[100]; + strftime(last_modified, sizeof(last_modified), "%a, %d %b %Y %H:%M:%S %Z", localtime(&file_stat.st_mtime)); + + sprintf(response, "HTTP/1.1 200 OK\r\n" + "Server: liso/1.1\r\n" + "Date: %s\r\n" + "Content-Length: %ld\r\n" + "Content-Type: text/html\r\n" + "Last-Modified: %s\r\n" + "Connection: keep-alive\r\n\r\n%s", + temp, strlen(htmlstr), last_modified, htmlstr); + + FILE *log = fopen("Log.txt", "a"); + fprintf(log, "[Date: %s][client: 127.0.0.1:38636]200 OK, responded for request GET\n", temp); + fclose(log); + } + } else if (strcmp(request[k]->http_method, "HEAD") == 0) { + FILE *file = fopen("./static_site/index.html", "r"); + if (file == NULL || strcmp(request[k]->http_uri, "/") != 0) { + sprintf(response, "HTTP/1.1 404 Not Found\r\n\r\n"); + } else { + fclose(file); + struct stat file_stat; + stat("./static_site/index.html", &file_stat); + char last_modified[100]; + strftime(last_modified, sizeof(last_modified), "%a, %d %b %Y %H:%M:%S %Z", localtime(&file_stat.st_mtime)); + + sprintf(response, "HTTP/1.1 200 OK\r\n" + "Server: liso/1.1\r\n" + "Date: %s\r\n" + "Content-Length: %ld\r\n" + "Content-Type: text/html\r\n" + "Last-Modified: %s\r\n" + "Connection: keep-alive\r\n\r\n", + temp, (long)file_stat.st_size, last_modified); + } + } else if (strcmp(request[k]->http_method, "POST") == 0) { + sprintf(response, "HTTP/1.1 200 OK\r\n\r\n"); + FILE *log = fopen("Log.txt", "a"); + fprintf(log, "[Date: %s][client: 127.0.0.1:38636]200 OK, responded for request POST\n", temp); + fclose(log); + } else { + sprintf(response, "HTTP/1.1 501 Not Implemented\r\n\r\n"); + FILE *log = fopen("Log.txt", "a"); + fprintf(log, "[Date: %s][client: 127.0.0.1:38636]HTTP/1.1 501 Not Implemented\n", temp); + fclose(log); + } + } else { + sprintf(response, "HTTP/1.1 505 HTTP Version Not Supported\r\n\r\n"); + FILE *log = fopen("Log.txt", "a"); + fprintf(log, "[Date: %s][client: 127.0.0.1:38636]HTTP/1.1 505 HTTP Version Not Supported\n", temp); + fclose(log); + } + } + + strcat(buffer, response); + } + return buffer; +} + + +int close_socket(int sock) { + if (close(sock)) { + fprintf(stderr, "Failed closing socket.\n"); + return 1; + } + return 0; +} + +int main(int argc, char* argv[]) { + int server_sockfd, client_sockfd; + fd_set readfds, testfds; + struct sockaddr_in server_address, client_address; + char buf[BUF_SIZE*2]; + char *pro_buf; + socklen_t client_len; + ssize_t readret; + int ready_num, fd, nread; + + fprintf(stdout, "----- Liso Server -----\n"); + + if ((server_sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) { + fprintf(stderr, "Failed creating socket.\n"); + return EXIT_FAILURE; + } + + server_address.sin_family = AF_INET; + server_address.sin_port = htons(ECHO_PORT); + server_address.sin_addr.s_addr = INADDR_ANY; + + // 绑定 + if (bind(server_sockfd, (struct sockaddr *) &server_address, sizeof(server_address))) { + close_socket(server_sockfd); + fprintf(stderr, "Failed binding socket.\n"); + return EXIT_FAILURE; + } + + // 监听 + if (listen(server_sockfd, 5)) { + close_socket(server_sockfd); + fprintf(stderr, "Error listening on socket.\n"); + return EXIT_FAILURE; + } + + FD_ZERO(&readfds); + FD_SET(server_sockfd, &readfds); + + while (1) { + testfds = readfds; + printf("server waiting\n"); + + ready_num = select(FD_SETSIZE, &testfds, NULL, NULL, NULL); + if (ready_num < 1) { + perror("server"); + exit(1); + } + + for (fd = 0; fd < FD_SETSIZE; fd++) { + if (FD_ISSET(fd, &testfds)) { + if (fd == server_sockfd) { + client_len = sizeof(client_address); + client_sockfd = accept(server_sockfd, (struct sockaddr *)&client_address, &client_len); + if (client_sockfd == -1) { + perror("accept"); + continue; + } + FD_SET(client_sockfd, &readfds); + printf("adding client on fd %d\n", client_sockfd); + } else { + ioctl(fd, FIONREAD, &nread); + if (nread == 0) { + close(fd); + FD_CLR(fd, &readfds); + printf("removing client on fd %d\n", fd); + } else { + readret = read(fd, buf, BUF_SIZE); + if (readret > 0) { + pro_buf = process(buf, readret); + write(fd, pro_buf, strlen(pro_buf)); + free(pro_buf); + memset(buf, 0, BUF_SIZE); + } else if (readret == -1) { + perror("read"); + close(fd); + FD_CLR(fd, &readfds); + } + printf("serving client on fd %d\n", fd); + } + } + } + } + } + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/src/parse.c b/src/parse.c new file mode 100644 index 0000000..901c655 --- /dev/null +++ b/src/parse.c @@ -0,0 +1,77 @@ +#include "parse.h" + +/** +* Given a char buffer returns the parsed request headers +*/ + + + +Request** parse(char *buffer, int size, int socketFd,int* request_num) { + //1. divided to multiple requests and stored to substring + //2. set_parsing_options and yyparse, using loop store to **requests + //3. return + int i = 0; + int temp = 0; + //Valid End State + Request *request = (Request *) malloc(sizeof(Request)); + //restore the information of each request + char** substring = (char**)malloc(sizeof(char*)*8192); + char** address = (char**)malloc(sizeof(char*)*8192); + int* strlength = (int*)malloc(sizeof(int)*8192); + for(i=0;i<100;i++){ + substring[i] = (char*)malloc(sizeof(char)*8192); + address[i] = (char*)malloc(sizeof(char)*8192); + } + + + request->header_count=0; + //TODO You will need to handle resizing this in parser.y + + // request->headers = (Request_header *) malloc(sizeof(Request_header)*1); //storage overflow + //TODO I need to parse like this: 1.get substring 2.transform to request 3.store request to requests + address[0] = buffer; + + while(strstr(address[*request_num],"\r\n\r\n")){ + *request_num = *request_num + 1; + address[*request_num] = strstr(address[*request_num - 1],"\r\n\r\n"); + address[*request_num] = address[*request_num] + 4; + + } + + strlength[0] = address[1]-address[0]; + strncpy(substring[0],address[0],strlength[0]); + + for(temp = 1;temp < *request_num;temp++){ + strlength[temp] = address[temp + 1]-address[temp]; + strncpy(substring[temp],address[temp],strlength[temp]); + } + + Request** requests = (Request**)malloc(sizeof(Request*)*4000); + for(i=0;i<*request_num;i++){ + requests[i] = (Request*)malloc(sizeof(Request)*1000); + } + + for(i = 0;i < *request_num; i++){ + set_parsing_options(substring[i], strlength[i], request); + yylex_destroy(); + if (yyparse() == SUCCESS) { + strcpy(requests[i]->http_method, request->http_method); + strcpy(requests[i]->http_uri, request->http_uri); + strcpy(requests[i]->http_version, request->http_version); + } + else{ + requests[i] = NULL; + free(requests[i]); + } + } + + + return requests; + + //TODO Handle Malformed Requests + yylex_destroy(); + printf("Parsing Failed\n"); + return NULL; +} + + diff --git a/src/parser.y b/src/parser.y new file mode 100644 index 0000000..30ee91a --- /dev/null +++ b/src/parser.y @@ -0,0 +1,241 @@ +/** + * @file parser.y + * @brief Grammar for HTTP + * @author Rajul Bhatnagar (2016) + */ + +%{ +#include "parse.h" + +/* Define YACCDEBUG to enable debug messages for this lex file */ +//#define YACCDEBUG +#define YYERROR_VERBOSE +#ifdef YACCDEBUG +#include +#define YPRINTF(...) printf(__VA_ARGS__) +#else +#define YPRINTF(...) +#endif + +/* yyparse() calls yyerror() on error */ +void yyerror (const char *s); + +void set_parsing_options(char *buf, size_t siz, Request *parsing_request); + +/* yyparse() calls yylex() to get tokens */ +extern int yylex(); + + +/* +** Global variables required for parsing from buffer +** instead of stdin: +*/ + +/* Pointer to the buffer that contains input */ +char *parsing_buf; + +/* Current position in the buffer */ +int parsing_offset; + +/* Buffer size */ +size_t parsing_buf_siz; + +/* Current parsing_request Header Struct */ +Request *parsing_request; + +%} + + +/* Various types values that we can get from lex */ +%union { + char str[8192]; + int i; +} + +%start request + +/* + * Tokens that yacc expects from lex, essentially these are the tokens + * declared in declaration section of lex file. + */ +%token t_crlf +%token t_backslash +%token t_slash +%token t_digit +%token t_dot +%token t_token_char +%token t_lws +%token t_colon +%token t_separators +%token t_sp +%token t_ws +%token t_ctl + +/* Type of value returned for these tokens */ +%type t_crlf +%type t_backslash +%type t_slash +%type t_digit +%type t_dot +%type t_token_char +%type t_lws +%type t_colon +%type t_separators +%type t_sp +%type t_ws +%type t_ctl + +/* + * Followed by this, you should have types defined for all the intermediate + * rules that you will define. These are some of the intermediate rules: + */ +%type allowed_char_for_token +%type allowed_char_for_text +%type ows +%type token +%type text + +%% + +/* +** The following 2 rules define a token. +*/ + +/* + * Rule 1: Allowed characters in a token + * + * An excerpt from RFC 2616: + * -- + * token = 1* + * -- + */ +allowed_char_for_token: +t_token_char; | +t_digit { + $$ = '0' + $1; +}; | +t_dot; + +/* + * Rule 2: A token is a sequence of all allowed token chars. + */ +token: +allowed_char_for_token { + YPRINTF("token: Matched rule 1.\n"); + snprintf($$, 8192, "%c", $1); +}; | +token allowed_char_for_token { + YPRINTF("token: Matched rule 2.\n"); + memcpy($$, $1, strlen($1)); + $$[strlen($1)] = $2; + $$[strlen($1) + 1] = 0; + // snprintf($$, 8192, "%s%c", $1, $2); +}; + +/* +** The following 2 rules define text. +*/ +/* + * + * Rule 3: Allowed characters in text + * + * An excerpt from RFC 2616, section 2.2: + * -- + * The TEXT rule is only used for descriptive field contents and values + * that are not intended to be interpreted by the message parser. Words + * of *TEXT MAY contain characters from character sets other than ISO- + * 8859-1 [22] only when encoded according to the rules of RFC 2047 + * [14]. + * + * TEXT = + * -- + * + */ + +allowed_char_for_text: +allowed_char_for_token; | +t_separators { + $$ = $1; +}; | +t_colon { + $$ = $1; +}; | +t_slash { + $$ = $1; +}; + +/* + * Rule 4: Text is a sequence of characters allowed in text as per RFC. May + * also contains spaces. + */ +text: allowed_char_for_text { + YPRINTF("text: Matched rule 1.\n"); + snprintf($$, 8192, "%c", $1); +}; | +text ows allowed_char_for_text { + YPRINTF("text: Matched rule 2.\n"); + memcpy($$, $1, strlen($1)); + memcpy($$ + strlen($1), $2, strlen($2)); + $$[strlen($1) + strlen($2)] = $3; + $$[strlen($1) + strlen($2) + 1] = 0; + // snprintf($$, 8192, "%s%s%c", $1, $2, $3); +}; + +/* + * Rule 5: Optional white spaces + */ +ows: { + YPRINTF("OWS: Matched rule 1\n"); + $$[0]=0; +}; | +t_sp { + YPRINTF("OWS: Matched rule 2\n"); + snprintf($$, 8192, "%c", $1); +}; | +t_ws { + YPRINTF("OWS: Matched rule 3\n"); + snprintf($$, 8192, "%s", $1); +}; + +request_line: token t_sp text t_sp text t_crlf { + YPRINTF("request_Line:\n%s\n%s\n%s\n",$1, $3,$5); + strcpy(parsing_request->http_method, $1); + strcpy(parsing_request->http_uri, $3); + strcpy(parsing_request->http_version, $5); +} + +request_header: token ows t_colon ows text ows t_crlf { + parsing_request->headers = (Request_header *) realloc(parsing_request->headers,sizeof(Request_header)*((parsing_request->header_count) + 1)); + YPRINTF("request_Header:\n%s\n%s\n",$1,$5); + strcpy(parsing_request->headers[parsing_request->header_count].header_name, $1); + strcpy(parsing_request->headers[parsing_request->header_count].header_value, $5); + parsing_request->header_count++; +}; +| request_header request_header{ + YPRINTF("request_Header pattern 2\n"); +}; + +/* + * You need to fill this rule, and you are done! You have all the assembly + * needed. You may wish to define your own rules. Please read RFC 2616. + * All the best! + * + */ +request: request_line request_header t_crlf{ + YPRINTF("parsing_request: Matched Success.\n"); + return SUCCESS; +}; + +%% + +/* C code */ + +void set_parsing_options(char *buf, size_t siz, Request *request) +{ + parsing_buf = buf; + parsing_offset = 0; + parsing_buf_siz = siz; + parsing_request = request; +} + +void yyerror (const char *s) {fprintf (stderr, "%s\n", s);} \ No newline at end of file diff --git a/src/y.tab.c b/src/y.tab.c new file mode 100644 index 0000000..5050997 --- /dev/null +++ b/src/y.tab.c @@ -0,0 +1,1669 @@ +/* A Bison parser, made by GNU Bison 3.0.4. */ + +/* Bison implementation for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "3.0.4" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + + + + +/* Copy the first part of user declarations. */ +#line 7 "src/parser.y" /* yacc.c:339 */ + +#include "parse.h" + +/* Define YACCDEBUG to enable debug messages for this lex file */ +//#define YACCDEBUG +#define YYERROR_VERBOSE +#ifdef YACCDEBUG +#include +#define YPRINTF(...) printf(__VA_ARGS__) +#else +#define YPRINTF(...) +#endif + +/* yyparse() calls yyerror() on error */ +void yyerror (const char *s); + +void set_parsing_options(char *buf, size_t siz, Request *parsing_request); + +/* yyparse() calls yylex() to get tokens */ +extern int yylex(); + + +/* +** Global variables required for parsing from buffer +** instead of stdin: +*/ + +/* Pointer to the buffer that contains input */ +char *parsing_buf; + +/* Current position in the buffer */ +int parsing_offset; + +/* Buffer size */ +size_t parsing_buf_siz; + +/* Current parsing_request Header Struct */ +Request *parsing_request; + + +#line 107 "y.tab.c" /* yacc.c:339 */ + +# ifndef YY_NULLPTR +# if defined __cplusplus && 201103L <= __cplusplus +# define YY_NULLPTR nullptr +# else +# define YY_NULLPTR 0 +# endif +# endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +/* In a future release of Bison, this section will be replaced + by #include "y.tab.h". */ +#ifndef YY_YY_Y_TAB_H_INCLUDED +# define YY_YY_Y_TAB_H_INCLUDED +/* Debug traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int yydebug; +#endif + +/* Token type. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + enum yytokentype + { + t_crlf = 258, + t_backslash = 259, + t_slash = 260, + t_digit = 261, + t_dot = 262, + t_token_char = 263, + t_lws = 264, + t_colon = 265, + t_separators = 266, + t_sp = 267, + t_ws = 268, + t_ctl = 269 + }; +#endif +/* Tokens. */ +#define t_crlf 258 +#define t_backslash 259 +#define t_slash 260 +#define t_digit 261 +#define t_dot 262 +#define t_token_char 263 +#define t_lws 264 +#define t_colon 265 +#define t_separators 266 +#define t_sp 267 +#define t_ws 268 +#define t_ctl 269 + +/* Value type. */ +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED + +union YYSTYPE +{ +#line 50 "src/parser.y" /* yacc.c:355 */ + + char str[8192]; + int i; + +#line 180 "y.tab.c" /* yacc.c:355 */ +}; + +typedef union YYSTYPE YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define YYSTYPE_IS_DECLARED 1 +#endif + + +extern YYSTYPE yylval; + +int yyparse (void); + +#endif /* !YY_YY_Y_TAB_H_INCLUDED */ + +/* Copy the second part of user declarations. */ + +#line 197 "y.tab.c" /* yacc.c:358 */ + +#ifdef short +# undef short +#endif + +#ifdef YYTYPE_UINT8 +typedef YYTYPE_UINT8 yytype_uint8; +#else +typedef unsigned char yytype_uint8; +#endif + +#ifdef YYTYPE_INT8 +typedef YYTYPE_INT8 yytype_int8; +#else +typedef signed char yytype_int8; +#endif + +#ifdef YYTYPE_UINT16 +typedef YYTYPE_UINT16 yytype_uint16; +#else +typedef unsigned short int yytype_uint16; +#endif + +#ifdef YYTYPE_INT16 +typedef YYTYPE_INT16 yytype_int16; +#else +typedef short int yytype_int16; +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif ! defined YYSIZE_T +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned int +# endif +#endif + +#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + +#ifndef YY_ +# if defined YYENABLE_NLS && YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(Msgid) dgettext ("bison-runtime", Msgid) +# endif +# endif +# ifndef YY_ +# define YY_(Msgid) Msgid +# endif +#endif + +#ifndef YY_ATTRIBUTE +# if (defined __GNUC__ \ + && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ + || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C +# define YY_ATTRIBUTE(Spec) __attribute__(Spec) +# else +# define YY_ATTRIBUTE(Spec) /* empty */ +# endif +#endif + +#ifndef YY_ATTRIBUTE_PURE +# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) +#endif + +#ifndef YY_ATTRIBUTE_UNUSED +# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) +#endif + +#if !defined _Noreturn \ + && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) +# if defined _MSC_VER && 1200 <= _MSC_VER +# define _Noreturn __declspec (noreturn) +# else +# define _Noreturn YY_ATTRIBUTE ((__noreturn__)) +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(E) ((void) (E)) +#else +# define YYUSE(E) /* empty */ +#endif + +#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ +/* Suppress an incorrect diagnostic about yylval being uninitialized. */ +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ + _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") +# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ + _Pragma ("GCC diagnostic pop") +#else +# define YY_INITIAL_VALUE(Value) Value +#endif +#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_END +#endif +#ifndef YY_INITIAL_VALUE +# define YY_INITIAL_VALUE(Value) /* Nothing. */ +#endif + + +#if ! defined yyoverflow || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS +# include /* INFRINGES ON USER NAME SPACE */ + /* Use EXIT_SUCCESS as a witness for stdlib.h. */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's 'empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined EXIT_SUCCESS \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined EXIT_SUCCESS +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined EXIT_SUCCESS +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +# define YYCOPY_NEEDED 1 + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (0) + +#endif + +#if defined YYCOPY_NEEDED && YYCOPY_NEEDED +/* Copy COUNT objects from SRC to DST. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(Dst, Src, Count) \ + __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) +# else +# define YYCOPY(Dst, Src, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (Dst)[yyi] = (Src)[yyi]; \ + } \ + while (0) +# endif +# endif +#endif /* !YYCOPY_NEEDED */ + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 12 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 52 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 15 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 9 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 19 +/* YYNSTATES -- Number of states. */ +#define YYNSTATES 34 + +/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned + by yylex, with out-of-bounds checking. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 269 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM + as returned by yylex, without out-of-bounds checking. */ +static const yytype_uint8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 +}; + +#if YYDEBUG + /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ +static const yytype_uint8 yyrline[] = +{ + 0, 113, 113, 114, 117, 123, 127, 156, 157, 160, + 163, 171, 175, 187, 191, 195, 200, 207, 214, 224 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE || 0 +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "t_crlf", "t_backslash", "t_slash", + "t_digit", "t_dot", "t_token_char", "t_lws", "t_colon", "t_separators", + "t_sp", "t_ws", "t_ctl", "$accept", "allowed_char_for_token", "token", + "allowed_char_for_text", "text", "ows", "request_line", "request_header", + "request", YY_NULLPTR +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[NUM] -- (External) token number corresponding to the + (internal) symbol number NUM (which must be that of a token). */ +static const yytype_uint16 yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269 +}; +# endif + +#define YYPACT_NINF -24 + +#define yypact_value_is_default(Yystate) \ + (!!((Yystate) == (-24))) + +#define YYTABLE_NINF -1 + +#define yytable_value_is_error(Yytable_value) \ + 0 + + /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +static const yytype_int8 yypact[] = +{ + 30, -24, -24, -24, -24, 13, 30, 7, 36, -24, + 27, 42, -24, -24, -24, -24, -24, -24, 3, -24, + -24, 2, -24, 30, 36, 36, 39, 1, -24, 36, + -24, 39, 21, -24 +}; + + /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. + Performed when YYTABLE does not specify something else to do. Zero + means the default is an error. */ +static const yytype_uint8 yydefact[] = +{ + 0, 3, 4, 2, 5, 0, 0, 0, 0, 6, + 13, 0, 1, 10, 9, 8, 7, 11, 13, 14, + 15, 0, 19, 18, 0, 0, 13, 13, 12, 0, + 16, 13, 0, 17 +}; + + /* YYPGOTO[NTERM-NUM]. */ +static const yytype_int8 yypgoto[] = +{ + -24, 0, 18, -23, -21, -9, -24, 24, -24 +}; + + /* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int8 yydefgoto[] = +{ + -1, 16, 10, 17, 18, 25, 6, 23, 7 +}; + + /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule whose + number is the opposite. If YYTABLE_NINF, syntax error. */ +static const yytype_uint8 yytable[] = +{ + 4, 21, 28, 27, 30, 9, 4, 12, 31, 28, + 9, 4, 26, 19, 20, 24, 20, 29, 5, 1, + 2, 3, 32, 4, 33, 8, 13, 1, 2, 3, + 11, 14, 15, 1, 2, 3, 1, 2, 3, 19, + 20, 13, 1, 2, 3, 22, 14, 15, 1, 2, + 3, 19, 20 +}; + +static const yytype_uint8 yycheck[] = +{ + 0, 10, 25, 24, 3, 5, 6, 0, 29, 32, + 10, 11, 10, 12, 13, 12, 13, 26, 0, 6, + 7, 8, 31, 23, 3, 12, 5, 6, 7, 8, + 6, 10, 11, 6, 7, 8, 6, 7, 8, 12, + 13, 5, 6, 7, 8, 3, 10, 11, 6, 7, + 8, 12, 13 +}; + + /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint8 yystos[] = +{ + 0, 6, 7, 8, 16, 17, 21, 23, 12, 16, + 17, 22, 0, 5, 10, 11, 16, 18, 19, 12, + 13, 20, 3, 22, 12, 20, 10, 19, 18, 20, + 3, 19, 20, 3 +}; + + /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint8 yyr1[] = +{ + 0, 15, 16, 16, 16, 17, 17, 18, 18, 18, + 18, 19, 19, 20, 20, 20, 21, 22, 22, 23 +}; + + /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = +{ + 0, 2, 1, 1, 1, 1, 2, 1, 1, 1, + 1, 1, 3, 0, 1, 1, 6, 7, 2, 3 +}; + + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ +while (0) + +/* Error token number */ +#define YYTERROR 1 +#define YYERRCODE 256 + + + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) + +/* This macro is provided for backward compatibility. */ +#ifndef YY_LOCATION_PRINT +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +#endif + + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) + + +/*----------------------------------------. +| Print this symbol's value on YYOUTPUT. | +`----------------------------------------*/ + +static void +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +{ + FILE *yyo = yyoutput; + YYUSE (yyo); + if (!yyvaluep) + return; +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# endif + YYUSE (yytype); +} + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +static void +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +{ + YYFPRINTF (yyoutput, "%s %s (", + yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); + + yy_symbol_value_print (yyoutput, yytype, yyvaluep); + YYFPRINTF (yyoutput, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +static void +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (0) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +static void +yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule) +{ + unsigned long int yylno = yyrline[yyrule]; + int yynrhs = yyr2[yyrule]; + int yyi; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, + yystos[yyssp[yyi + 1 - yynrhs]], + &(yyvsp[(yyi + 1) - (yynrhs)]) + ); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyssp, yyvsp, Rule); \ +} while (0) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +static YYSIZE_T +yystrlen (const char *yystr) +{ + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +# endif + +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +static char * +yystpcpy (char *yydest, const char *yysrc) +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + YYSIZE_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return yystrlen (yystr); + + return yystpcpy (yyres, yystr) - yyres; +} +# endif + +/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message + about the unexpected token YYTOKEN for the state stack whose top is + YYSSP. + + Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is + not large enough to hold the message. In that case, also set + *YYMSG_ALLOC to the required number of bytes. Return 2 if the + required number of bytes is too large to store. */ +static int +yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, + yytype_int16 *yyssp, int yytoken) +{ + YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); + YYSIZE_T yysize = yysize0; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + /* Internationalized format string. */ + const char *yyformat = YY_NULLPTR; + /* Arguments of yyformat. */ + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + /* Number of reported tokens (one for the "unexpected", one per + "expected"). */ + int yycount = 0; + + /* There are many possibilities here to consider: + - If this state is a consistent state with a default action, then + the only way this function was invoked is if the default action + is an error action. In that case, don't check for expected + tokens because there are none. + - The only way there can be no lookahead present (in yychar) is if + this state is a consistent state with a default action. Thus, + detecting the absence of a lookahead is sufficient to determine + that there is no unexpected or expected token to report. In that + case, just report a simple "syntax error". + - Don't assume there isn't a lookahead just because this state is a + consistent state with a default action. There might have been a + previous inconsistent state, consistent state with a non-default + action, or user semantic action that manipulated yychar. + - Of course, the expected token list depends on states to have + correct lookahead information, and it depends on the parser not + to perform extra reductions after fetching a lookahead from the + scanner and before detecting a syntax error. Thus, state merging + (from LALR or IELR) and default reductions corrupt the expected + token list. However, the list is correct for canonical LR with + one exception: it will still contain any token that will not be + accepted due to an error action in a later state. + */ + if (yytoken != YYEMPTY) + { + int yyn = yypact[*yyssp]; + yyarg[yycount++] = yytname[yytoken]; + if (!yypact_value_is_default (yyn)) + { + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. In other words, skip the first -YYN actions for + this state because they are default actions. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yyx; + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR + && !yytable_value_is_error (yytable[yyx + yyn])) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + break; + } + yyarg[yycount++] = yytname[yyx]; + { + YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); + if (! (yysize <= yysize1 + && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + } + } + } + } + + switch (yycount) + { +# define YYCASE_(N, S) \ + case N: \ + yyformat = S; \ + break + YYCASE_(0, YY_("syntax error")); + YYCASE_(1, YY_("syntax error, unexpected %s")); + YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); + YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); + YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); + YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); +# undef YYCASE_ + } + + { + YYSIZE_T yysize1 = yysize + yystrlen (yyformat); + if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + } + + if (*yymsg_alloc < yysize) + { + *yymsg_alloc = 2 * yysize; + if (! (yysize <= *yymsg_alloc + && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) + *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; + return 1; + } + + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + { + char *yyp = *yymsg; + int yyi = 0; + while ((*yyp = *yyformat) != '\0') + if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyformat += 2; + } + else + { + yyp++; + yyformat++; + } + } + return 0; +} +#endif /* YYERROR_VERBOSE */ + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +{ + YYUSE (yyvaluep); + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + YYUSE (yytype); + YY_IGNORE_MAYBE_UNINITIALIZED_END +} + + + + +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; +/* Number of syntax errors so far. */ +int yynerrs; + + +/*----------. +| yyparse. | +`----------*/ + +int +yyparse (void) +{ + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + + /* The stacks and their tools: + 'yyss': related to states. + 'yyvs': related to semantic values. + + Refer to the stacks through separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; + + YYSIZE_T yystacksize; + + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken = 0; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + yyssp = yyss = yyssa; + yyvsp = yyvs = yyvsa; + yystacksize = YYINITDEPTH; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyexhaustedlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yypact_value_is_default (yyn)) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = yylex (); + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yytable_value_is_error (yyn)) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the shifted token. */ + yychar = YYEMPTY; + + yystate = yyn; + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END + + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + '$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 3: +#line 114 "src/parser.y" /* yacc.c:1646 */ + { + (yyval.i) = '0' + (yyvsp[0].i); +} +#line 1291 "y.tab.c" /* yacc.c:1646 */ + break; + + case 5: +#line 123 "src/parser.y" /* yacc.c:1646 */ + { + YPRINTF("token: Matched rule 1.\n"); + snprintf((yyval.str), 8192, "%c", (yyvsp[0].i)); +} +#line 1300 "y.tab.c" /* yacc.c:1646 */ + break; + + case 6: +#line 127 "src/parser.y" /* yacc.c:1646 */ + { + YPRINTF("token: Matched rule 2.\n"); + memcpy((yyval.str), (yyvsp[-1].str), strlen((yyvsp[-1].str))); + (yyval.str)[strlen((yyvsp[-1].str))] = (yyvsp[0].i); + (yyval.str)[strlen((yyvsp[-1].str)) + 1] = 0; + // snprintf($$, 8192, "%s%c", $1, $2); +} +#line 1312 "y.tab.c" /* yacc.c:1646 */ + break; + + case 8: +#line 157 "src/parser.y" /* yacc.c:1646 */ + { + (yyval.i) = (yyvsp[0].i); +} +#line 1320 "y.tab.c" /* yacc.c:1646 */ + break; + + case 9: +#line 160 "src/parser.y" /* yacc.c:1646 */ + { + (yyval.i) = (yyvsp[0].i); +} +#line 1328 "y.tab.c" /* yacc.c:1646 */ + break; + + case 10: +#line 163 "src/parser.y" /* yacc.c:1646 */ + { + (yyval.i) = (yyvsp[0].i); +} +#line 1336 "y.tab.c" /* yacc.c:1646 */ + break; + + case 11: +#line 171 "src/parser.y" /* yacc.c:1646 */ + { + YPRINTF("text: Matched rule 1.\n"); + snprintf((yyval.str), 8192, "%c", (yyvsp[0].i)); +} +#line 1345 "y.tab.c" /* yacc.c:1646 */ + break; + + case 12: +#line 175 "src/parser.y" /* yacc.c:1646 */ + { + YPRINTF("text: Matched rule 2.\n"); + memcpy((yyval.str), (yyvsp[-2].str), strlen((yyvsp[-2].str))); + memcpy((yyval.str) + strlen((yyvsp[-2].str)), (yyvsp[-1].str), strlen((yyvsp[-1].str))); + (yyval.str)[strlen((yyvsp[-2].str)) + strlen((yyvsp[-1].str))] = (yyvsp[0].i); + (yyval.str)[strlen((yyvsp[-2].str)) + strlen((yyvsp[-1].str)) + 1] = 0; + // snprintf($$, 8192, "%s%s%c", $1, $2, $3); +} +#line 1358 "y.tab.c" /* yacc.c:1646 */ + break; + + case 13: +#line 187 "src/parser.y" /* yacc.c:1646 */ + { + YPRINTF("OWS: Matched rule 1\n"); + (yyval.str)[0]=0; +} +#line 1367 "y.tab.c" /* yacc.c:1646 */ + break; + + case 14: +#line 191 "src/parser.y" /* yacc.c:1646 */ + { + YPRINTF("OWS: Matched rule 2\n"); + snprintf((yyval.str), 8192, "%c", (yyvsp[0].i)); +} +#line 1376 "y.tab.c" /* yacc.c:1646 */ + break; + + case 15: +#line 195 "src/parser.y" /* yacc.c:1646 */ + { + YPRINTF("OWS: Matched rule 3\n"); + snprintf((yyval.str), 8192, "%s", (yyvsp[0].str)); +} +#line 1385 "y.tab.c" /* yacc.c:1646 */ + break; + + case 16: +#line 200 "src/parser.y" /* yacc.c:1646 */ + { + YPRINTF("request_Line:\n%s\n%s\n%s\n",(yyvsp[-5].str), (yyvsp[-3].str),(yyvsp[-1].str)); + strcpy(parsing_request->http_method, (yyvsp[-5].str)); + strcpy(parsing_request->http_uri, (yyvsp[-3].str)); + strcpy(parsing_request->http_version, (yyvsp[-1].str)); +} +#line 1396 "y.tab.c" /* yacc.c:1646 */ + break; + + case 17: +#line 207 "src/parser.y" /* yacc.c:1646 */ + { + parsing_request->headers = (Request_header *) realloc(parsing_request->headers,sizeof(Request_header)*((parsing_request->header_count) + 1)); + YPRINTF("request_Header:\n%s\n%s\n",(yyvsp[-6].str),(yyvsp[-2].str)); + strcpy(parsing_request->headers[parsing_request->header_count].header_name, (yyvsp[-6].str)); + strcpy(parsing_request->headers[parsing_request->header_count].header_value, (yyvsp[-2].str)); + parsing_request->header_count++; +} +#line 1408 "y.tab.c" /* yacc.c:1646 */ + break; + + case 18: +#line 214 "src/parser.y" /* yacc.c:1646 */ + { + YPRINTF("request_Header pattern 2\n"); +} +#line 1416 "y.tab.c" /* yacc.c:1646 */ + break; + + case 19: +#line 224 "src/parser.y" /* yacc.c:1646 */ + { + YPRINTF("parsing_request: Matched Success.\n"); + return SUCCESS; +} +#line 1425 "y.tab.c" /* yacc.c:1646 */ + break; + + +#line 1429 "y.tab.c" /* yacc.c:1646 */ + default: break; + } + /* User semantic actions sometimes alter yychar, and that requires + that yytoken be updated with the new translation. We take the + approach of translating immediately before every use of yytoken. + One alternative is translating here after every semantic action, + but that translation would be missed if the semantic action invokes + YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or + if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an + incorrect destructor might then be invoked immediately. In the + case of YYERROR or YYBACKUP, subsequent parser actions might lead + to an incorrect destructor call or verbose syntax error message + before the lookahead is translated. */ + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + /* Now 'shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*--------------------------------------. +| yyerrlab -- here on detecting error. | +`--------------------------------------*/ +yyerrlab: + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); + + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if ! YYERROR_VERBOSE + yyerror (YY_("syntax error")); +#else +# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ + yyssp, yytoken) + { + char const *yymsgp = YY_("syntax error"); + int yysyntax_error_status; + yysyntax_error_status = YYSYNTAX_ERROR; + if (yysyntax_error_status == 0) + yymsgp = yymsg; + else if (yysyntax_error_status == 1) + { + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); + if (!yymsg) + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + yysyntax_error_status = 2; + } + else + { + yysyntax_error_status = YYSYNTAX_ERROR; + yymsgp = yymsg; + } + } + yyerror (yymsgp); + if (yysyntax_error_status == 2) + goto yyexhaustedlab; + } +# undef YYSYNTAX_ERROR +#endif + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + + /* Pacify compilers like GCC when the user code never invokes + YYERROR and the label yyerrorlab therefore never appears in user + code. */ + if (/*CONSTCOND*/ 0) + goto yyerrorlab; + + /* Do not reclaim the symbols of the rule whose action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (!yypact_value_is_default (yyn)) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + + yydestruct ("Error: popping", + yystos[yystate], yyvsp); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END + + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#if !defined yyoverflow || YYERROR_VERBOSE +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: + if (yychar != YYEMPTY) + { + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = YYTRANSLATE (yychar); + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval); + } + /* Do not reclaim the symbols of the rule whose action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[*yyssp], yyvsp); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif +#if YYERROR_VERBOSE + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +#endif + return yyresult; +} +#line 229 "src/parser.y" /* yacc.c:1906 */ + + +/* C code */ + +void set_parsing_options(char *buf, size_t siz, Request *request) +{ + parsing_buf = buf; + parsing_offset = 0; + parsing_buf_siz = siz; + parsing_request = request; +} + +void yyerror (const char *s) {fprintf (stderr, "%s\n", s);} diff --git a/src/y.tab.h b/src/y.tab.h new file mode 100644 index 0000000..6908b02 --- /dev/null +++ b/src/y.tab.h @@ -0,0 +1,99 @@ +/* A Bison parser, made by GNU Bison 3.0.4. */ + +/* Bison interface for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +#ifndef YY_YY_Y_TAB_H_INCLUDED +# define YY_YY_Y_TAB_H_INCLUDED +/* Debug traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int yydebug; +#endif + +/* Token type. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + enum yytokentype + { + t_crlf = 258, + t_backslash = 259, + t_slash = 260, + t_digit = 261, + t_dot = 262, + t_token_char = 263, + t_lws = 264, + t_colon = 265, + t_separators = 266, + t_sp = 267, + t_ws = 268, + t_ctl = 269 + }; +#endif +/* Tokens. */ +#define t_crlf 258 +#define t_backslash 259 +#define t_slash 260 +#define t_digit 261 +#define t_dot 262 +#define t_token_char 263 +#define t_lws 264 +#define t_colon 265 +#define t_separators 266 +#define t_sp 267 +#define t_ws 268 +#define t_ctl 269 + +/* Value type. */ +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED + +union YYSTYPE +{ +#line 50 "src/parser.y" /* yacc.c:1909 */ + + char str[8192]; + int i; + +#line 87 "y.tab.h" /* yacc.c:1909 */ +}; + +typedef union YYSTYPE YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define YYSTYPE_IS_DECLARED 1 +#endif + + +extern YYSTYPE yylval; + +int yyparse (void); + +#endif /* !YY_YY_Y_TAB_H_INCLUDED */ diff --git a/static_site/images/liso_header.png b/static_site/images/liso_header.png new file mode 100644 index 0000000000000000000000000000000000000000..e6e85d8e09469ba3a82a3d20cc9748f97c2640c6 GIT binary patch literal 17431 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 + + + + Liso the Friendly Web Server + + + + + + + + diff --git a/static_site/style.css b/static_site/style.css new file mode 100644 index 0000000..a55a3ba --- /dev/null +++ b/static_site/style.css @@ -0,0 +1,8 @@ +body { background-color: #000; font-family: Serif; font-size: 1.2em; + color: #fff; text-shadow: #808080 0.1em 0.1em 0.2em; } +img { display: block; margin: auto; } +p { text-align: justify; margin-top: 25px; } + +a { color: #808080; text-decoration: none; } + +#page { width: 800px; margin: auto; }