/* MAIN.C (c) 1996 Oliver Kraus Versions: 1.0 simple tranfer version 2.0 rewritten 2.1 keep date/time, crc-16 2.2 write error with zero-size files 2.3 rewitten file access */ #include #include #include #include #include "tptx.h" #include "tprx.h" #include "crdir.h" #include "cmdline.h" #include "cbreak.h" /* #include "debugmem.h" */ char *init_error = "init error"; /* time bytes/s size pos/crc name xxx% xxxx.xs xxxxxxx xxxxxxxxx xxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx */ char *head_str = " time bytes/s pos/size crc name\n" "------------------------------------------------------------------------------\n"; long cl_socket = 2007; int is_subdir = 0; int is_help = 0; int is_test_mode = 0; int is_disable_crc = 0; int is_crc32 = 0; int is_verbose = 0; cl_entry_struct cl_list[] = { { CL_TYP_LONG, "sn", &cl_socket, 0 }, { CL_TYP_ON, "test", &is_test_mode, 0 }, { CL_TYP_ON, "nocrc", &is_disable_crc, 0 }, { CL_TYP_ON, "crc32", &is_crc32, 0 }, { CL_TYP_ON, "help", &is_help, 0 }, { CL_TYP_ON, "h", &is_help, 0 }, { CL_TYP_ON, "?", &is_help, 0 }, { CL_TYP_ON, "s", &is_subdir, 0 }, { CL_TYP_ON, "v", &is_verbose, 0 }, CL_ENTRY_LAST }; void help(void) { printf("ipxcopy [options] [filemask] V2.4 " __DATE__ "\n"); printf("file transfer program, based on ipx\n"); printf("freeware by Oliver Kraus, kraus@lrs.e-technik.uni-erlangen.de\n"); printf("options:\n"); printf(" -h -? show this text\n"); printf(" -sn num socketnumber (current: %ld)\n", cl_socket ); printf("transmitter only:\n"); printf(" -v verbose mode\n" ); printf(" -s include subdirectories\n" ); printf(" -test do not write files\n"); printf(" -nocrc disable crc\n"); printf(" -crc32 use crc-32 (default: crc-16)\n"); printf("filemask:\n"); printf(" * match zero, one or more characters\n"); printf(" ? match exactly one character\n"); } void print_pdata(tp_pdata_struct *d, int is_end) { long t; size_t len, offset = 0; t = clock()-d->file_start; len = strlen(d->path); if ( len > 37 ) offset = len-37; if ( is_end == 0 ) { printf("%3ld%% %4ld.%lds %7ld %9ld/%-9ld %-37s\r", (long)(d->curr*100L)/d->total, (long)t/CLOCKS_PER_SEC, (long)(((t*10L)/CLOCKS_PER_SEC) % 10L), (d->curr*CLOCKS_PER_SEC)/t, (long)d->curr, (long)d->total, d->path+offset); } else { printf("%3ld%% %4ld.%lds %7ld %9ld %08lx %-37s\r", (long)(100L), (long)t/CLOCKS_PER_SEC, (long)(((t*10L)/CLOCKS_PER_SEC) % 10L), (d->curr*CLOCKS_PER_SEC)/t, (long)d->total, (unsigned long)d->crc, d->path+offset); } fflush(stdout); } int rx_aux( int msg, void *data ) { tp_pdata_struct *d = (tp_pdata_struct *)data; switch(msg) { case TP_MSG_PSTART: break; case TP_MSG_PDATA: print_pdata(d, 0); break; case TP_MSG_PEND: print_pdata(d, 1); printf("\n"); break; } return 1; } int rx() { tprx_type tprx; tprx = tprx_Open((short)cl_socket); if ( tprx == NULL ) return 1; tprx_SetAux(tprx, rx_aux); printf(head_str); for(;;) { if ( tprx_Dispatch(tprx) != 0 ) break; } tprx_Close(tprx); return 0; } int tx_aux( int msg, void *data ) { tp_pdata_struct *d = (tp_pdata_struct *)data; switch(msg) { case TP_MSG_PSTART: break; case TP_MSG_PDATA: print_pdata(d, 0); break; case TP_MSG_PEND: print_pdata(d, 1); printf("\n"); break; } return 1; } int tx(tptx_type tptx, char *phy_name, char *log_name) { int ret; tptx_Send(tptx, phy_name, log_name); for(;;) { ret = tptx_Dispatch(tptx); if ( ret == 2 ) return 0; if ( ret != 0 ) break; } return 1; } int file_tx() { static char drive[10]; static char dir[C_MAX_PATHNAME]; static char fname[C_MAX_FILE]; static char ext[C_MAX_FILE]; static char path[C_MAX_PATHNAME]; CRDIR *d; struct c_dirent *e; tptx_type tptx; clock_t total_start = clock(); clock_t total_time; long files, dirs; strupr(cl_file_list[0]); _splitpath( cl_file_list[0], drive, dir, fname, ext ); strcpy(path, drive); strcat(path, dir); strcat(fname, ext); if ( strcmp(fname, "*.*") == 0 ) strcpy(fname, "*"); if ( is_subdir ) d = c_openrdir(path, fname, CRDIR_GO_DIRS|CRDIR_RET_DIRS); else d = c_openrdir(path, fname, 0); if ( d == NULL ) { printf("init error with path '%s', filemask '%s'\n", path, fname); return 0; } tptx = tptx_Open((short)cl_socket); if ( tptx == NULL ) { c_closerdir(d); return 0; } tptx_SetAux(tptx, tx_aux); if ( is_test_mode != 0 ) tptx_SetFlag(tptx, TP_FLAG_IS_TEST_MODE); if ( is_disable_crc != 0 ) tptx_SetFlag(tptx, TP_FLAG_IS_DISABLE_CRC); if ( is_crc32 != 0 ) tptx_SetFlag(tptx, TP_FLAG_IS_CRC32); files = 0; dirs = 0; printf(head_str); for(;;) { static char phy_path[_MAX_PATH]; static char log_path[_MAX_PATH]; e = c_readrdir(d); if ( e == NULL ) break; sprintf(phy_path, "%s%s","",c_get_name(e)); sprintf(log_path, "%s%s",c_getpath(d),c_get_name(e)); if ( is_verbose != 0 ) { fprintf(stdout, "%s --> %s\n", phy_path, log_path); fflush(stdout); } if ( c_is_dir(e) != 0 ) { dirs++; if ( tx(tptx, NULL, log_path) == 0 ) break; } else { files++; if ( tx(tptx, phy_path, log_path) == 0 ) break; } } c_closerdir(d); if ( e == NULL ) { total_time = clock()-total_start; printf(" ------ ------- ---------\n"); printf(" %4ld.%lds %7ld %9ld bytes in %ld files and %ld dirs\n", (long)tptx->f_time_sum/CLOCKS_PER_SEC, (long)(((tptx->f_time_sum*10L)/CLOCKS_PER_SEC) % 10L), (tptx->f_len_sum*CLOCKS_PER_SEC)/tptx->f_time_sum, (long)tptx->f_len_sum, files, dirs); if ( is_verbose != 0 ) { printf("total%4ld.%lds %7ld %9ld\n", (long)total_time/CLOCKS_PER_SEC, (long)(((total_time*10L)/CLOCKS_PER_SEC) % 10L), (tptx->f_len_sum*CLOCKS_PER_SEC)/total_time, (long)tptx->f_len_sum); } } tptx_Close(tptx); return 1; } int main(int argc, char *argv[]) { static char path[C_MAX_PATHNAME]; int ret; /* FILE *fp = fopen("error.log", "w"); malloc_SetWarningLevel(8); malloc_SetStream(fp); */ if ( cl_Do(cl_list, argc, argv) == 0 ) { puts("cmdline error"); help(); return 1; } if ( is_help != 0 ) { help(); return 1; } break_Install(); strcpy(path, c_getcwd()); if ( cl_file_cnt < 1 ) { puts("ipxcopy receiver (-h for help)"); ret = (rx() == 0 ? 1 : 0); } else { puts("ipxcopy transmitter"); if ( is_test_mode != 0 ) puts("test mode enabled"); if ( is_disable_crc != 0 ) puts("crc calculation disabled"); ret = (file_tx() == 0 ? 1 : 0); } /* malloc_PrintInfo(); fclose(fp); */ c_set_path(path); break_Remove(); return ret; }