summaryrefslogtreecommitdiff
path: root/client/walker.c
diff options
context:
space:
mode:
authorJeffrey Armstrong <jeffrey.armstrong@approximatrix.com>2015-10-09 10:34:49 -0400
committerJeffrey Armstrong <jeffrey.armstrong@approximatrix.com>2015-10-09 10:34:49 -0400
commit8b756e368a33a02d7783053b84bc1e5b50419ff0 (patch)
tree658a81b96d4522fe3b7e0b33661dc265dbc968e8 /client/walker.c
downloadrback-8b756e368a33a02d7783053b84bc1e5b50419ff0.tar.gz
rback-8b756e368a33a02d7783053b84bc1e5b50419ff0.zip
Initial commitHEADmaster
Diffstat (limited to 'client/walker.c')
-rw-r--r--client/walker.c330
1 files changed, 330 insertions, 0 deletions
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 <jeff@rainbow-100.com>
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+/* 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 <stdio.h>
+#include <dos.h>
+
+#include "fossil.h"
+#include "f16.h"
+
+#ifdef TURBOC
+
+#include <dir.h>
+
+#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<length;i++) {
+ r = F_Send_Char(TRANSMIT, text[i]);
+ }
+ F_Flush_Out();
+}
+
+/* Reads a semicolon-terminated response from the serial port
+ * and stores the value in the global array "response."
+ */
+void read_response()
+{
+char c;
+int i;
+
+ while(!F_NBPeek());
+
+ memset(response, 0, 16);
+
+ c = 13;
+ i = 0;
+ while(c != ';') {
+ while(!F_NBPeek());
+ c = Get_Raw();
+ response[i] = c;
+ i++;
+ }
+ /* printf("RESPONSE(%s) .. ", response); */
+}
+
+/* Tranmits the passed buffer, measuring "rlen" bytes long, to
+ * the server. The protocol first sends the number of bytes in
+ * the buffer, then the buffer itself, and, finally, a two-byte
+ * Fletcher 16 checksum for the buffer.
+ */
+void transmit(unsigned char *buf, int rlen)
+{
+int i;
+unsigned char b1, b2;
+
+ F_Send_Char(TRANSMIT, (unsigned char)rlen);
+ for(i=0;i<rlen;i++) {
+ F_Send_Char(TRANSMIT, buf[i]);
+ if(i % 8 == 0)
+ F_Flush_Out();
+ }
+ fletcher16(buf, rlen, &b1, &b2);
+ F_Send_Char(TRANSMIT, b1);
+ F_Send_Char(TRANSMIT, b2);
+
+ F_Flush_Out();
+}
+
+/* Transmits the next block in a file pointer. The actual sending
+ * is handled by the "transmit()" function. This routine handles
+ * loading the block from the file and subsequently dealing with the
+ * server response.
+ */
+int send_block(FILE *fp)
+{
+int rlen, i;
+unsigned char buf[BLOCK_SIZE];
+unsigned char b1, b2;
+
+ if(fp == NULL) return -1;
+
+ rlen = fread(buf, sizeof(char), BLOCK_SIZE, fp);
+ if(rlen > 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;
+}