/* dcp.c Revised edition of dcp Stuart Lynne May/87 Copyright (c) Richard H. Lamb 1985, 1986, 1987 Changes Copyright (c) Stuart Lynne 1987 Maintenance Notes: 25Aug87 - Added a version number - Jal 25Aug87 - Return 0 if contact made with host, or 5 otherwise. 04Sep87 - Bug causing premature sysend() fixed. - Randall Jessup. */ /* "DCP" a uucp clone. Copyright Richard H. Lamb 1985,1986,1987 */ /* This program implements a uucico type file transfer and remote execution type protocol. */ #define VERSION "1.0" #include "dcp.h" /* */ int pktsize; /* packet size for pro */ FILE *logfile; /* system log file */ FILE *syslog; /* system log file */ FILE *fw; /* cfile pointer */ char state; /* system state*/ char cfile[80]; /* work file pointer */ int remote; /* -1 means we're remote ..7*/ int msgtime; /* timout setting */ char fromfile[132]; char hostfile[132]; /* host version of fromfile */ char tofile[132]; int fp; /* current disk file ptr */ int size; /* nbytes in buff */ FILE *fsys; char Rmtname[20]; char rmtname[20]; char * cctime; char proto[5]; /* char loginseq[256]; */ char sysline[BUFSIZ]; char s_systems[64]; char s_logfile[64]; char s_syslog[64]; char *flds[60]; int kflds; int debuglevel; /* debugging flag */ unsigned int checksum(); /* */ /* new usage dcp [-xn] -r0 slave mode dcp [-xn] -shost call host dcp [-xn] -sall call all hosts dcp [-xn] call any hosts as required by C. files */ complain( s ) char *s; { fprintf( stderr, "Please set your %s environment variable.", s ); } static void cant( file ) char *file; { fprintf( stderr, "Can't open: \"%s\"\n", file ); exit( 8 ); } dcpmain( argc, argv ) int argc; char*argv[]; { FILE *ftmp; char line[132]; int Contact = FALSE; if ( name == NULL || *name == '\0' ) { complain( NAME ); exit( -1 ); } if ( nodename == NULL || *nodename == '\0' ) { complain( NODENAME ); exit( -1 ); } mkfilename( s_logfile, spooldir, LOGFILE ); mkfilename( s_syslog, spooldir, SYSLOG ); mkfilename( s_systems, confdir, SYSTEMS ); if ( (logfile = FOPEN( s_logfile, "a", 't' )) == NULL ) cant( s_logfile ); if ( (syslog = FOPEN( s_syslog, "a", 't' )) == NULL ) cant( s_syslog ); fp = -1; fw = (FILE *)NULL; remote = MASTER; strcpy( Rmtname, "any" ); debuglevel = 1; remote = MASTER; printmsg(0, "\f\t\t\tUUPC Version %s\n", VERSION ); while ( --argc ) { if ( **++argv == '-') { switch(argv[0][1]) { case 'x': debuglevel = atoi( &argv[0][2] ); break; case 's': sprintf( Rmtname, "%.7s", &argv[0][2] ); break; case 'r': remote = atoi( &argv[0][2] ); break; default: break; } } } if ( remote == MASTER ) { printmsg( 0, "Calling %s %d", Rmtname, debuglevel ); if (( fsys = FOPEN( s_systems, "r", 't' )) == (char *)NULL ) exit( FAILED ); state = 'I'; while (TRUE) { printmsg( 4, "Mstate = %c", state ); switch (state) { case 'I': state = getsystem(); break; case 'S': state = callup(); break; case 'P': state = startup(); break; case 'D': state = master(); Contact = TRUE; break; case 'Y': state = sysend(); break; case 'G': if ( strcmp( Rmtname, "any" ) == SAME ) state = 'Y'; else state = 'I'; break; } if (state == 'A') break; } fclose( fsys ); } else { if (openline( device, speed ) == -1) return(FALSE); state = 'L'; while (TRUE) { printmsg( 4, "Sstate = %c", state ); switch (state) { case 'L': state = login(); break; case 'I': state = startup(); break; case 'R': state = slave(); break; case 'Y': state = sysend(); break; } if (state == 'A') break; } closeline(); } /* fprintf( stderr, "calling dcxqt\n" ); */ if (dcxqt()) printmsg( 0, "ERROR in DCXQT" ); /* scan and process any recieved files */ fclose( syslog ); fclose( logfile ); if (Contact ) return 0; else return 5; } /* */ /* ** ** **master ** ** */ master() { state = 'I'; while (TRUE) { printmsg( 4, "Top level state (master mode) %c", state ); switch (state) { case 'I': state = sinit(); break; case 'B': state = scandir(); break; case 'S': state = send(); break; case 'Q': state = sbreak(); break; case 'G': state = receive(); break; case 'C': state = 'Y'; break; case 'Y': state = endp(); break; case 'P': return('Y'); case 'A': return('A'); default: return('A'); } } } /* */ /* ** ** **slave ** ** */ slave() { state = 'I'; while (TRUE) { printmsg( 4, "Top level state (slave mode) %c", state ); switch (state) { case 'I': state = rinit(); break; case 'F': state = receive(); break; case 'C': state = schkdir(); break; case 'T': state = 'B'; break; case 'B': state = scandir(); break; case 'S': state = send(); break; case 'Q': state = sbreak(); break; case 'G': return('Y'); case 'Y': state = endp(); break; case 'P': return('Y'); case 'A': return('A'); default: return('A'); } } } /* */ /* * r e c e i v e * * This is the state table switcher for receiving files. */ receive() { state = 'F';/* Receive-Init is the start state */ while (TRUE) { printmsg( 4, " receive state: %c", state ); switch (state)/* Do until done */ { case 'F': state = rfile(); break; /* Receive-File */ case 'D': state = rdata(); break; /* Receive-Data */ case 'C': return('C');/* Complete state */ case 'A': return('Y');/* "Abort" state */ default: return('Y'); } } } /* */ /* * s e n d * * Sendsw is the state table switcher for sending files. It loops until * either it finishes, or an error is encountered. The routines called * by sendsw are responsible for changing the state. * */ send() { fp = -1; /* reset file getter/opener */ state = 'F';/* Send initiate is the start state */ while (TRUE)/* Do this as long as necessary */ { printmsg( 4, "send state: %c", state ); switch (state) { case 'F': state = sfile(); break; /* Send-File */ case 'D': state = sdata(); break; /* Send-Data */ case 'Z': state = seof(); break; /* Send-End-of-File */ case 'B': return ('B'); /* Complete */ case 'A': return ('Y'); /* "Abort" */ default: return ('Y'); /* Unknown, fail */ } } } /* */ /* A command formatter for DCP. RH Lamb */ /* sets up stdin and stdout on various machines */ /* There is NO command checking so watch what you send and who you */ /* let accsess your machine. "C rm /usr/*.*" could be executed. */ dcxqt() { int i; char command[60], input[60], output[60], line[BUFSIZ]; char *cp; while (dscandir()) { strcpy( line, cfile ); fw = FOPEN( line, "r", 'b' );/* imported X file */ strcpy(cfile, line); printmsg( 2, "dcxqt:%s %ld", cfile, fw ); input[0] = '\0'; output[0] = '\0'; command[0] = '\0'; while ( fgets( line, BUFSIZ, fw ) != (char *)NULL ) { cp = index( line, '\n' ); if ( cp != (char *)NULL ) *cp = '\0'; printmsg( 8, "dcxqt: %s", line ); switch (line[0]) { case 'U': break; case 'I': strcpy( input, &line[2] ); break; case 'O': strcpy( output, &line[2] ); break; case 'C': strcpy( command, &line[2] ); break; case 'R': break; default : break; } } fclose( fw ); printmsg( 0, "xqt: %s\n", command ); shell( command, input, output, (char *)NULL ); unlink(cfile); importpath( hostfile, input ); unlink(hostfile); importpath( hostfile, output ); unlink(hostfile); } return(0); } /**/ /* * p r i n t m s g * * Print error message on standard output if not remote. */ /*VARARGS1*/ printmsg(level, fmt, a1, a2, a3, a4, a5) int level; char *fmt; char *a1, *a2, *a3, *a4, *a5; { char msg[256]; if ( debuglevel > level ) { sprintf( msg, fmt, a1, a2, a3, a4, a5 ); strcat( msg, "\n" ); if ( remote == MASTER ) fputs( msg, stdout ); fputs( msg, logfile ); } }