/* 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; }