diff --git a/.gitignore b/.gitignore index c047fbc..cdc109e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .vscode/ *.out +*.o diff --git a/http/Makefile b/http/Makefile new file mode 100644 index 0000000..3f141d8 --- /dev/null +++ b/http/Makefile @@ -0,0 +1,27 @@ +CC = gcc +CFLAGS = -std=c99 -pedantic -Wall -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_SVID_SOURCE -D_POSIX_C_SOURCE=200809L -g -c +TARGET_1 = client +TARGET_2 = server + +all: $(TARGET_1).c $(TARGET_2).c + $(CC) $(CFLAGS) $(TARGET_1).c $(TARGET_2).c + $(CC) $(TARGET_1).o -o $(TARGET_1) + $(CC) $(TARGET_2).o -o $(TARGET_2) + +client: $(TARGET_1).c + $(CC) $(CFLAGS) $(TARGET_1).c + $(CC) $(TARGET_1).o -o $(TARGET_1) + +server: $(TARGET_2).c + $(CC) $(CFLAGS) $(TARGET_2).c + $(CC) $(TARGET_2).o -o $(TARGET_2) + +install: + cp $(TARGET_1) /usr/local/bin/myhttp-$(TARGET_1) + cp $(TARGET_2) /usr/local/bin/myhttp-$(TARGET_2) + +clean: + $(RM) $(TARGET_1).o + $(RM) $(TARGET_1) + $(RM) $(TARGET_2).o + $(RM) $(TARGET_2) \ No newline at end of file diff --git a/http/client.c b/http/client.c index e69de29..f3ee0dc 100644 --- a/http/client.c +++ b/http/client.c @@ -0,0 +1,84 @@ +#define _GNU_SOURCE ///< in order for optarg to be defined +#include +#include +#include +#include +#include "shared/http.h" + +int main(int argc, char *argv[]) { + check_opts_number(argc); + + int port = 80; + char *ofile = NULL; + char *dir = NULL; + char *url = NULL; + int c; + + /// Process the options + while((c = getopt(argc, argv, "p:o:d:h")) != -1) { + switch(c) { + case 'p': + port = atoi(optarg); + break; + case 'o': + ofile = optarg; + break; + case 'd': + dir = optarg; + break; + case 'h': + printf("Command usage:\n"); + print_usage(); + exit(EXIT_SUCCESS); + break; + case '?': + print_usage(); + exit(EXIT_FAILURE); + default: + abort(); + } + } + + /// Check for the case that both output file and directory are set + if(ofile != NULL && dir != NULL) { + printf("Either output file or directory is specified. You cannot use both.\n"); + print_usage(); + exit(EXIT_FAILURE); + } + + /// Check if the required argument is there + if(argv[optind] == NULL) { + fprintf(stderr, "Mandatory argument 'url' missing.\n"); + print_usage(); + exit(EXIT_FAILURE); + } else { + url = argv[optind]; + } + + const char *full_url = strstr(url, "http://") + 7; //< the full url starts after http:// + const char *path = strstr(full_url, "/"); +} + +static void print_usage(void) { + printf("client [-p PORT] [ -o FILE | -d DIR ] URL\n"); +} + +/** + * @brief Function to check the number of arguments + * @details Checks the number of arguments supplied to the command line. + * If the arguments are less than the required or more than possible, it exits + * @param argc Number of arguments obtained from the command line + * @return none + * + **/ +static void check_opts_number(int argc) { + if(argc <= 1) { + fprintf(stderr, "At least one argument expected.\n"); + print_usage(); + exit(EXIT_FAILURE); + } else if(argc > 6) { + fprintf(stderr, "Too many arguments supplied.\n"); + print_usage(); + exit(EXIT_FAILURE); + } +} diff --git a/http/shared/http.h b/http/shared/http.h new file mode 100644 index 0000000..fe1f2e6 --- /dev/null +++ b/http/shared/http.h @@ -0,0 +1,7 @@ +#ifndef HTTP_HEADER_FILE +#define HTTP_HEADER_FILE + +static void print_usage(); +static void check_opts_number(int argc); + +#endif \ No newline at end of file diff --git a/mygrep/Makefile b/mygrep/Makefile index c160c19..b6c7638 100644 --- a/mygrep/Makefile +++ b/mygrep/Makefile @@ -2,7 +2,7 @@ CC = gcc CFLAGS = -std=c99 -pedantic -Wall -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_SVID_SOURCE -D_POSIX_C_SOURCE=200809L -g -c TARGET = mygrep -all: $(TARGET).c +all: $(TARGET).c $(CC) $(CFLAGS) $(TARGET).c $(CC) $(TARGET).o -o $(TARGET) diff --git a/mygrep/mygrep.c b/mygrep/mygrep.c index 4283678..fa7d47b 100644 --- a/mygrep/mygrep.c +++ b/mygrep/mygrep.c @@ -1,3 +1,32 @@ +/** + * @file mygrep.c + * @author Ivaylo Ivanov 11777707 + * @date 03.11.2018 + * + * @brief Main program module. + * + * A reduced variation of the Unix-command `grep`. + * It reads in several files and prints all lines containing a keyword. + * + * SYNOPSIS + * mygrep [-i] [-o outfile] keyword [file...] + * + * The program `mygrep` reads files line by line and for each line checks whether it contains the search + * term keyword. The line is printed if it contains the keyword, otherwise it is not printed. + * The program accepts lines of any length. + * + * If one or multiple input files are specified (given as positional arguments after keyword), then mygrep + * reads each of them in the order they are given. If no input file is specified, the program reads from + * `stdin`. + * + * If the option `-o` is given, the output is written to the specified file (outfile). Otherwise, the output is + * written to `stdout`. + * + * If the option `-i` is given, the program does not differentiate between lower and upper case letters, i.e. + * the search for the keyword in a line is case insensitive. + * + **/ + #define _GNU_SOURCE ///< in order for strcasestr to work #include #include @@ -85,11 +114,11 @@ static void print_usage(void) { /** * @brief Function to check the number of arguments - * @details Checks the number of arguments supplied to the command line. + * @details Checks the number of arguments supplied to the command line. * If the arguments are less than the required or more than possible, it exits * @param argc Number of arguments obtained from the command line - * @return none - * + * @return none + * **/ static void check_opts_number(int argc) { if(argc <= 1) { @@ -105,17 +134,17 @@ static void check_opts_number(int argc) { /** * @brief Function to check whether or not a string is contained in another string - * @details Checks whether or not a substring is contained in a line. + * @details Checks whether or not a substring is contained in a line. * If it is there and no output file is passed, it will print the line to stdout * If it is there and an output file is passed, it will append the line to the end of the output file - * + * * @param * to_check: String to be checked against * to_find: String to search for * iflag: Whether or not to ignore the casing of the letters * ofile: The file to append the output to * @return none - * + * **/ static void check_for_string(char *to_check, char *to_find, int iflag, char *ofile) { if(ofile == NULL) {