From 3a5ef7e3652628339d790a0c9a40ae6081ee2770 Mon Sep 17 00:00:00 2001 From: Ian C Date: Tue, 3 Mar 2020 19:35:15 +0000 Subject: Changed so that the UNIX portion is a server. --- client/Makefile | 5 - client/nft.c | 415 ------------------------------------------ server/Makefile | 5 + server/nfts.c | 510 ++++++++++++++++++++++++++++++++++++++++++++++++++++ server/spectrum.tap | Bin 0 -> 107 bytes 5 files changed, 515 insertions(+), 420 deletions(-) delete mode 100644 client/Makefile delete mode 100644 client/nft.c create mode 100644 server/Makefile create mode 100644 server/nfts.c create mode 100644 server/spectrum.tap diff --git a/client/Makefile b/client/Makefile deleted file mode 100644 index 9869b14..0000000 --- a/client/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -nft: nft.c - $(CC) -o nft nft.c - -clean: - rm -f nft core nft.exe diff --git a/client/nft.c b/client/nft.c deleted file mode 100644 index 9d03295..0000000 --- a/client/nft.c +++ /dev/null @@ -1,415 +0,0 @@ -/* Next File Transfer Client - Copyright (C) 2020 Ian Cowburn - - 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 . - -*/ -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -static const char *name; - - -static void *Malloc(size_t len) -{ - void *p; - - p = malloc(len); - - if (!p) - { - perror(name); - exit(EXIT_FAILURE); - } - - return p; -} - - -static char *GetLine(char *buff, size_t len) -{ - size_t l; - - if (feof(stdin)) - { - return NULL; - } - - printf("NFT> "); - - if (!fgets(buff, len, stdin)) - { - return NULL; - } - - l = strlen(buff); - - if (l > 0 && buff[l-1]=='\n') - { - buff[l-1]=0; - } - - if (l) - { - return buff; - } - else - { - return GetLine(buff, len); - } -} - - -static int Connect(const char *n, int p) -{ - struct hostent *remote; - struct sockaddr_in addr; - int sock; - - if (!(remote = gethostbyname(n))) - { - fprintf(stderr,"%s: unknown host %s\n",name,n); - exit(EXIT_FAILURE); - } - - memcpy(&addr.sin_addr, remote->h_addr, remote->h_length); - - if ((sock = socket(AF_INET, SOCK_STREAM, 0))==-1) - { - perror(name); - exit(EXIT_FAILURE); - } - - addr.sin_family = AF_INET; - addr.sin_port = htons(p); - - if (connect(sock,(void*)&addr,sizeof(addr)) == -1) - { - perror(name); - exit(EXIT_FAILURE); - } - - return sock; -} - - -static int Read(int sock, char *buff, size_t len) -{ - while(len > 0) - { - size_t rd; - - rd = read(sock, buff, len); - - if (rd == -1) - { - perror(name); - return 0; - } - else if (rd == 0) - { - return 0; - } - else - { - len -= rd; - buff += rd; - } - } - - return 1; -} - - -static int Write(int sock, const char *buff, size_t len) -{ - while(len > 0) - { - size_t wr; - - wr = write(sock, buff, len); - - if (wr == -1) - { - perror(name); - return 0; - } - else if (wr == 0) - { - return 0; - } - else - { - len -= wr; - buff += wr; - } - } - - return 1; -} - - -static int WriteBlock(int sock, const char *block, size_t len) -{ - char buff[32]; - - if (len > 99999) - { - fprintf(stderr, "%s: length of block %zu too large\n", name, len); - return 0; - } - - snprintf(buff, sizeof buff, "%.5zu", len); - - if (!Write(sock, buff, 5)) - { - return 0; - } - - if (!Write(sock, block, len)) - { - return 0; - } - - return 1; -} - - -static size_t ReadSize(int sock) -{ - char buff[32]; - - if (!Read(sock, buff, 5)) - { - return 0; - } - - return atoi(buff); -} - - -static size_t FileSize(const char *path) -{ - struct stat st; - - if (stat(path, &st) == 0) - { - return st.st_size; - } - else - { - return 0; - } -} - - -static int Put(int sock, const char *path) -{ - int quit = 0; - char status[3] = {0}; - size_t len; - int fd; - - if ((len = FileSize(path)) == 0) - { - perror(path); - } - else - { - char *buff; - int fd; - - buff = Malloc(len); - - fd = open(path, O_RDONLY); - read(fd, buff, len); - close(fd); - - if (!Write(sock, "PF", 2)) - { - quit = 1; - } - - if (!quit && !WriteBlock(sock, path, strlen(path))) - { - quit = 1; - } - - if (!quit && !WriteBlock(sock, buff, len)) - { - quit = 1; - } - - if (!quit && Read(sock, status, 2)) - { - if (strcmp(status, "!E") == 0) - { - printf("Command failed\n"); - } - } - else - { - quit = 1; - } - - } - - return quit; -} - - -static int Get(int sock, const char *path) -{ - int quit = 0; - char status[3] = {0}; - int fd; - - if ((fd = open(path, O_WRONLY|O_CREAT|O_TRUNC)) == -1) - { - perror(path); - return 0; - } - - if (!Write(sock, "GF", 2)) - { - quit = 1; - } - - if (!quit && !WriteBlock(sock, path, strlen(path))) - { - quit = 1; - } - - if (!quit && Read(sock, status, 2)) - { - if (strcmp(status, "!E") == 0) - { - printf("Command failed\n"); - } - else - { - size_t len; - - if ((len = ReadSize(sock)) > 0) - { - char buff[100000]; - - if (Read(sock, buff, len)) - { - write(fd, buff, len); - } - else - { - quit = 1; - } - } - } - } - else - { - quit = 1; - } - - close(fd); - - return quit; -} - - -static int Cd(int sock, const char *path) -{ - int quit = 0; - - return quit; -} - - -static int Mkdir(int sock, const char *path) -{ - int quit = 0; - - return quit; -} - - -int main(int argc, char *argv[]) -{ - char buff[1024]; - int sock; - int quit = 0; - - if ((name = strrchr(argv[0], '/'))) - { - name++; - } - else - { - name = argv[0]; - } - - if (argc<3) - { - fprintf(stderr,"%s: usage %s host port\n",name,name); - exit(EXIT_FAILURE); - } - - sock = Connect(argv[1],atoi(argv[2])); - - while(!quit && GetLine(buff, sizeof buff)) - { - char *tok; - - tok = strtok(buff, " \t"); - - if (strcmp(tok, "exit") == 0) - { - break; - } - else if (strcmp(tok, "put") == 0) - { - quit = Put(sock, strtok(NULL, " \t")); - } - else if (strcmp(tok, "get") == 0) - { - quit = Get(sock, strtok(NULL, " \t")); - } - else if (strcmp(tok, "cd") == 0) - { - quit = Cd(sock, strtok(NULL, " \t")); - } - else if (strcmp(tok, "mkdir") == 0) - { - quit = Mkdir(sock, strtok(NULL, " \t")); - } - else - { - printf("Unrecognised command '%s'\n", tok); - } - } - - close(sock); - - return EXIT_SUCCESS; -} diff --git a/server/Makefile b/server/Makefile new file mode 100644 index 0000000..4be1a08 --- /dev/null +++ b/server/Makefile @@ -0,0 +1,5 @@ +nfts: nfts.c + $(CC) -o nfts nfts.c + +clean: + rm -f nfts core nfts.exe diff --git a/server/nfts.c b/server/nfts.c new file mode 100644 index 0000000..18ab896 --- /dev/null +++ b/server/nfts.c @@ -0,0 +1,510 @@ +/* Next File Transfer Client + Copyright (C) 2020 Ian Cowburn + + 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 . + +*/ +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static const char *name; + + +static void *Malloc(size_t len) +{ + void *p; + + p = malloc(len); + + if (!p) + { + perror(name); + exit(EXIT_FAILURE); + } + + return p; +} + + +static char *GetLine(char *buff, size_t len) +{ + size_t l; + + if (feof(stdin)) + { + return NULL; + } + + printf("NFT> "); + + if (!fgets(buff, len, stdin)) + { + return NULL; + } + + l = strlen(buff); + + if (l > 0 && buff[l-1]=='\n') + { + buff[l-1]=0; + } + + if (l) + { + return buff; + } + else + { + return GetLine(buff, len); + } +} + + +static int Connect(const char *n, int p) +{ + struct hostent *remote; + struct sockaddr_in addr; + int sock; + + if (!(remote = gethostbyname(n))) + { + fprintf(stderr,"%s: unknown host %s\n",name,n); + exit(EXIT_FAILURE); + } + + memcpy(&addr.sin_addr, remote->h_addr, remote->h_length); + + if ((sock = socket(AF_INET, SOCK_STREAM, 0))==-1) + { + perror(name); + exit(EXIT_FAILURE); + } + + addr.sin_family = AF_INET; + addr.sin_port = htons(p); + + if (connect(sock,(void*)&addr,sizeof(addr)) == -1) + { + perror(name); + exit(EXIT_FAILURE); + } + + return sock; +} + + +static int Read(int sock, char *buff, size_t len) +{ + while(len > 0) + { + size_t rd; + + rd = read(sock, buff, len); + + if (rd == -1) + { + perror(name); + return 0; + } + else if (rd == 0) + { + return 0; + } + else + { + len -= rd; + buff += rd; + } + } + + return 1; +} + + +static int Write(int sock, const char *buff, size_t len) +{ + while(len > 0) + { + size_t wr; + + wr = write(sock, buff, len); + + if (wr == -1) + { + perror(name); + return 0; + } + else if (wr == 0) + { + return 0; + } + else + { + len -= wr; + buff += wr; + } + } + + return 1; +} + + +static int WriteBlock(int sock, const char *block, size_t len) +{ + char buff[32]; + + if (len > 999999) + { + fprintf(stderr, "%s: length of block %zu too large\n", name, len); + return 0; + } + + snprintf(buff, sizeof buff, "%.6zu", len); + + if (!Write(sock, buff, 6)) + { + return 0; + } + + if (!Write(sock, block, len)) + { + return 0; + } + + return 1; +} + + +static size_t ReadSize(int sock) +{ + char buff[32]; + + if (!Read(sock, buff, 6)) + { + return 0; + } + + return atoi(buff); +} + + +static size_t FileSize(const char *path) +{ + struct stat st; + + if (stat(path, &st) == 0) + { + return st.st_size; + } + else + { + return 0; + } +} + + +static int Put(int sock, const char *path) +{ + int quit = 0; + char status[3] = {0}; + size_t len; + int fd; + + if ((len = FileSize(path)) == 0) + { + perror(path); + } + else + { + char *buff; + int fd; + + buff = Malloc(len); + + fd = open(path, O_RDONLY); + read(fd, buff, len); + close(fd); + + if (!Write(sock, "PF", 2)) + { + quit = 1; + } + + if (!quit && !WriteBlock(sock, path, strlen(path))) + { + quit = 1; + } + + if (!quit && !WriteBlock(sock, buff, len)) + { + quit = 1; + } + + if (!quit && Read(sock, status, 2)) + { + if (strcmp(status, "!E") == 0) + { + printf("Command failed\n"); + } + else if (strcmp(status, "OK") == 0) + { + printf("OK\n"); + } + else + { + printf("Unknown status '%s'\n", status); + } + } + else + { + quit = 1; + } + + free(buff); + } + + return quit; +} + + +static int Get(int sock, const char *path) +{ + int quit = 0; + char status[3] = {0}; + int fd; + + if ((fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, 0666)) == -1) + { + perror(path); + return 0; + } + + if (!Write(sock, "GF", 2)) + { + quit = 1; + } + + if (!quit && !WriteBlock(sock, path, strlen(path))) + { + quit = 1; + } + + if (!quit && Read(sock, status, 2)) + { + if (strcmp(status, "!E") == 0) + { + printf("Command failed\n"); + } + else if (strcmp(status, "OK") == 0) + { + size_t len; + + printf("OK\n"); + + if ((len = ReadSize(sock)) > 0) + { + char *buff; + + buff = Malloc(len); + + if (Read(sock, buff, len)) + { + write(fd, buff, len); + } + else + { + quit = 1; + } + } + } + else + { + printf("Unknown status '%s'\n", status); + } + } + else + { + quit = 1; + } + + close(fd); + + return quit; +} + + +static int Cd(int sock, const char *path) +{ + int quit = 0; + char status[3] = {0}; + size_t len; + int fd; + + if (path) + { + if (!Write(sock, "CD", 2)) + { + quit = 1; + } + + if (!quit && !WriteBlock(sock, path, strlen(path))) + { + quit = 1; + } + + if (!quit && Read(sock, status, 2)) + { + if (strcmp(status, "!E") == 0) + { + printf("Command failed\n"); + } + else if (strcmp(status, "OK") == 0) + { + printf("OK\n"); + } + else + { + printf("Unknown status '%s'\n", status); + } + } + else + { + quit = 1; + } + } + else + { + printf("Missing path\n"); + } + + return quit; +} + + +static int Mkdir(int sock, const char *path) +{ + int quit = 0; + char status[3] = {0}; + + if (path) + { + if (!Write(sock, "MD", 2)) + { + quit = 1; + } + + if (!quit && !WriteBlock(sock, path, strlen(path))) + { + quit = 1; + } + + if (!quit && Read(sock, status, 2)) + { + if (strcmp(status, "!E") == 0) + { + printf("Command failed\n"); + } + else if (strcmp(status, "OK") == 0) + { + printf("OK\n"); + } + else + { + printf("Unknown status '%s'\n", status); + } + } + else + { + quit = 1; + } + } + else + { + printf("Missing path\n"); + } + + return quit; +} + + +int main(int argc, char *argv[]) +{ + char buff[1024]; + int sock; + int quit = 0; + + if ((name = strrchr(argv[0], '/'))) + { + name++; + } + else + { + name = argv[0]; + } + + if (argc<3) + { + fprintf(stderr,"%s: usage %s host port\n",name,name); + exit(EXIT_FAILURE); + } + + sock = Connect(argv[1],atoi(argv[2])); + + while(!quit && GetLine(buff, sizeof buff)) + { + char *tok; + + tok = strtok(buff, " \t"); + + if (strcmp(tok, "exit") == 0) + { + break; + } + else if (strcmp(tok, "put") == 0) + { + quit = Put(sock, strtok(NULL, " \t")); + } + else if (strcmp(tok, "get") == 0) + { + quit = Get(sock, strtok(NULL, " \t")); + } + else if (strcmp(tok, "cd") == 0) + { + quit = Cd(sock, strtok(NULL, " \t")); + } + else if (strcmp(tok, "mkdir") == 0) + { + quit = Mkdir(sock, strtok(NULL, " \t")); + } + else + { + printf("Unrecognised command '%s'\n", tok); + } + } + + close(sock); + + return EXIT_SUCCESS; +} diff --git a/server/spectrum.tap b/server/spectrum.tap new file mode 100644 index 0000000..3b5ad43 Binary files /dev/null and b/server/spectrum.tap differ -- cgit v1.2.3