From 8b756e368a33a02d7783053b84bc1e5b50419ff0 Mon Sep 17 00:00:00 2001 From: Jeffrey Armstrong Date: Fri, 9 Oct 2015 10:34:49 -0400 Subject: Initial commit --- client/f16.c | 73 ++++++++++++ client/f16.h | 9 ++ client/readme.txt | 62 ++++++++++ client/walker.c | 330 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 474 insertions(+) create mode 100644 client/f16.c create mode 100644 client/f16.h create mode 100644 client/readme.txt create mode 100644 client/walker.c (limited to 'client') diff --git a/client/f16.c b/client/f16.c new file mode 100644 index 0000000..2fd05f9 --- /dev/null +++ b/client/f16.c @@ -0,0 +1,73 @@ +/* Recursive Walking Backup + * Copyright © 2015 Jeffrey Armstrong + * http://jeff.rainbow-100.com/ + * + * 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 . + */ + +/* f16.c - Implementation of a Fletcher 16-bit checksum. The file also + * contains a simple test program that can be enabled by defining + * TEST_FLETCHER at compile time. + */ + +#include + +/* Computes the Fletcher 16-bit checksum and returns the value in the + * b1 and b2 arguments. + */ +void fletcher16(unsigned char *data, + int n, + unsigned char *b1, + unsigned char *b2) +{ +int c1, c2; +int i; +int toint; + + c1 = 0; c2 = 0; + for(i=0;i 2) { + fletcher16(TEST_STR, strlen(TEST_STR), &b1, &b2); + printf("Results for '%s': %d, %d\n", TEST_STR, (int)b1, (int)b2); + } else { + fp = fopen(argv[1], "rb"); + fread(buf, sizeof(char), 64, fp); + fletcher16(buf, 64, &b1, &b2); + printf("Results for 1st 64 bytes: %d, %d\n", (int)b1, (int)b2); + fclose(fp); + } + return (int)b1; +} + +#endif diff --git a/client/f16.h b/client/f16.h new file mode 100644 index 0000000..44203d0 --- /dev/null +++ b/client/f16.h @@ -0,0 +1,9 @@ +#ifndef _F16_HDR_ +#define _F16_HDR_ + +void fletcher16(unsigned char *data, + int n, + unsigned char *b1, + unsigned char *b2); + +#endif /* _F16_HDR_ */ diff --git a/client/readme.txt b/client/readme.txt new file mode 100644 index 0000000..64690ea --- /dev/null +++ b/client/readme.txt @@ -0,0 +1,62 @@ +Backup Tree Walker +================== + +This software will recursively walk a directory tree and transmit every +file encountered to server software via a serial port. The transmission +protocol is quite basic. When a file is encountered, the name of the +file, in absolute path format, is transmitted to the server followed by +a semicolon. When the server responds with "OK" followed by a semicolon, +this program sends a single byte of how many bytes it will send, 64 by +default. After the block length, it sends the block. Finally, it sends +two bytes representing a Fletcher 16 checksum. This program then waits +until the server responds with "OK," "RETRY," or "ABORT" followed by a +semicolon. On "OK," the server repeats the process with another block. + +Requirements +------------ + +The client software requires FosLib, available at: + + https://bitbucket.org/ArmstrongJ/foslib + +Make sure, when building the library above, to use the same compiler +and memory model. This code works perfectly with the small memory +model. + +Building +-------- + +The code has only recently been tested with Borland Turbo C 2.0. To +compile with Turbo C, use the following: + + tcc -ms -DTURBOC walker.c f16.c fossil.lib + +The command above compiles using a small memory model. The "-DTURBOC" +flag is necessary so that the proper directory search routines are used. + +If compiling with Microsoft C or, possibly, Open Watcom, a similar +command can be used without the "-DTURBOC" flag. + +Executing +--------- + +The backup program, WALKER.EXE, accepts two mandatory arguments, the FOSSIL +driver port and the speed in bits per second. A third, optional argument +specifies the directory in which to start the recursive traversal. By +default, the routine will always start in E: since most people are probably +using this software on a Rainbow 100. If you're using a more obscure system +like an IBM PC, you'll want to specify the third argument. + +To transfer everything on drive E: over COM port 1 (FOSSIL port 0) at 9600bps, +use the following command: + + walker 0 9600 + +To transfer everything in the F:\SRC directory at speed 19200, use the +following command: + + walker 0 19200 F:\SRC + +Note that the speeds are limited by what FOSSIL drivers support. The top +speed is 38400. + diff --git a/client/walker.c b/client/walker.c new file mode 100644 index 0000000..e764332 --- /dev/null +++ b/client/walker.c @@ -0,0 +1,330 @@ +/* Recursive Walking Backup + * Copyright © 2015 Jeffrey Armstrong + * http://jeff.rainbow-100.com/ + * + * 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 . + */ + +/* walker.c - This program will walk a directory (by default E:), including + * recursively, and transmit every file via FOSSIL to a server + * program. To compile with Borland Turbo C (2.0 or 2.01), be + * sure to define TURBOC. + */ + +#include +#include + +#include "fossil.h" +#include "f16.h" + +#ifdef TURBOC + +#include + +#define FFNAME(x) x.ff_name +#define FFATTRIB(x) x.ff_attrib + +#define SEARCH_FLAGS FA_DIREC + +#else + +/* MSC defines things a bit differently */ + +#define findfirst(x, y, z) _dos_findfirst(x, z, y) +#define findnext(x) _dos_findnext(x) + +#define SEARCH_FLAGS _A_SUBDIR | _A_NORMAL +#define FA_DIREC _A_SUBDIR + +#define ffblk find_t + +#define FFNAME(x) x.name +#define FFATTRIB(x) x.attrib + +#endif + +static char response[16]; + +/* The transmission block size. This many bytes are transfered + * prior to sending the checksum. Do not increase above 255! + */ +#define BLOCK_SIZE 64 + +/* Define this constant to prohibit FOSSIL initialization */ +/* #define NO_FOS_INIT 1 */ + +/* Sends a null-terminated string */ +void fos_send(const char *text) +{ +int i, length, r; + + length = strlen(text); + for(i=0;i 0) { + i = 0; + do { + if(i > 8) { + rlen = -1; + break; + } + + i++; + transmit(buf, rlen); + read_response(); + } while(strcmp("OK;", response) != 0); + } + return rlen; +} + +/* Sends the filename to the server and reads the server response */ +int report_file(const char *fullname) +{ + fos_send(fullname); + fos_send(";"); + + read_response(); + if(strcmp("OK;", response) == 0) + return 1; + else + return 0; + +} + +/* Wrapper for sending a file, along with all the bookkeeping, to + * the server software. This function will open the file and request + * sending all blocks until the entire file is transmitted. It also + * produces minimum reports of progress. + */ +int send_file(const char *fullname) +{ +FILE *fp; +int result; +char cmd[512]; + + printf("File: %s .. ", fullname); + + if(report_file(fullname) == 1) + printf("SENDING..."); + else { + printf("ABORT\n"); + return 0; + } + fp = fopen(fullname, "rb"); + + result = 0; + do { + /* printf("."); */ + result = send_block(fp); + } while(result > 0); + + /* Send a 0 length flag */ + F_Send_Char(TRANSMIT, '\0'); + F_Flush_Out(); + + fclose(fp); + printf("DONE\n"); + + return 1 /* result */; +} + +/* Walks the directory tree starting at the directory specified, and + * sends every file. When a directory is encountered, this function + * is called recursively. + */ +int list_dir(const char *directory) +{ +int fcount; +struct ffblk walker; +char *fname; +char *fullname; +char *path; + + fcount = 0; + + fullname = (char *)malloc((strlen(directory)+16)*sizeof(char)); + + printf("Entering: %s\n", directory); + + path = (char *)malloc((strlen(directory)+8)*sizeof(char)); + sprintf(path, "%s\\*.*", directory); + + /* Loop files */ + if(findfirst(path, &walker, SEARCH_FLAGS) == 0) { + do { + /* Populate fname */ + fname = FFNAME(walker); + if(fname[0] != '.') { + sprintf(fullname, "%s\\%s", directory, fname); + + if(FFATTRIB(walker) & FA_DIREC) { + + fcount += list_dir(fullname); + + } else if(send_file(fullname) != 1) { + + break; + + } else { + + fcount++; + + } + } + } while(findnext(&walker) == 0); + } + + free(fullname); + free(path); + + return fcount; +} + +/* Initializes the COM port and FOSSIL driver */ +int start_comm(long fspeed) +{ +#ifndef NO_FOS_INIT + + printf("Initializing FOSSIL "); + if(!F_Init()) { + printf("FAIL\n"); + return 0; + } else + printf("OK\n"); + + printf("Configuring FOSSIL "); + if (!F_Set_Baud(fspeed)) { + printf("FAIL (speed)\n"); + return 0; + } + + Fl_Ctrl(TXONXOFF|RXONXOFF); /* CTSRTS); */ + printf("OK\n"); + + printf("Raising DTR "); + F_Dtr(TRUE); + printf("OK\n"); +#endif + + return 1; +} + +int main(int argc, char *argv[]) +{ +int fcount; +char *directory; +long fspeed; +char c; + + if(argc < 3) { + printf("Usage: %s port speed [directory (optional)]\n", argv[0]); + return 0; + } + + port = atoi(argv[1]); + fspeed = atol(argv[2]); + printf("Configuring Port %d for %d BPS...\n", port, fspeed); + + dcd_ignore = TRUE; + + if(argc == 3) { + directory = "E:"; + } else { + directory = argv[3]; + } + + if(start_comm(fspeed) != 1) { + return 0; + } + + printf("Sending test string...\n"); + fos_send("ONLINE"); + printf("Press Q to quit or anything else to continue...\n"); + scanf("%c", &c); + if(c == 'q' || c == 'Q') return 0; + + printf("Starting in %s\n\n", directory); + + fcount = list_dir(directory); + + printf("TOTAL: %d\n\n", fcount); + + F_De_Init(); + + return fcount; +} -- cgit v1.2.3