/*--------------------------------------------------------------------*/ /* s c r i p t . c */ /* */ /* Script processing routines for UUPC/extended */ /* */ /* John H. DuBois III 3/31/90 */ /*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/ /* System include files */ /*--------------------------------------------------------------------*/ #include #include #include #include #include /*--------------------------------------------------------------------*/ /* UUPC/extended include files */ /*--------------------------------------------------------------------*/ #include "lib.h" #include "dcp.h" #include "dcpsys.h" #include "hostable.h" #include "hlib.h" #include "modem.h" #include "script.h" #include "security.h" #include "ssleep.h" #include "catcher.h" #include "ulib.h" /*--------------------------------------------------------------------*/ /* Local defines */ /*--------------------------------------------------------------------*/ #define MAXMATCH 64 /* max length of search string; must be a power of 2 */ #define QINDMASK (MAXMATCH - 1) /* bit mask to get queue index */ #define EOTMSG "\004\r\004\r" /*--------------------------------------------------------------------*/ /* Internal function prototypes */ /*--------------------------------------------------------------------*/ static int StrMatch(char *MatchStr, char C, char **failure); /* Internal match routine */ static boolean Match( char *Search, char *Buffer, size_t *SearchPos); static size_t MatchInit( const char *MatchStr ); static boolean writestr(register char *s); /*--------------------------------------------------------------------*/ /* Global variables */ /*--------------------------------------------------------------------*/ currentfile(); /* * e x p e c t s t r * * wait for a pattern on input * * * expectstr reads characters from input using sread, and * compares them to a search string. It reads characters until * either the search string has been seen on the input or a * specified timeout interval has passed without any characters * being read. * * Global variables: none. * * Input parameters: * Search is the string that is searched for on the input. * Timeout is the timeout interval passed to sread. * * Output parameters: none. * * Return value: * TRUE is returned if the search string is found on input. * FALSE is returned if sread times out. */ int expectstr(char *Search, unsigned int Timeout, char **failure) { char buf[BUFSIZ]; int result; time_t quit = time( NULL ) + Timeout; register char *ptr = buf; printmsg(2, "wanted \"%s\"", Search); if (!strlen(Search)) /* expects nothing */ return TRUE; StrMatch(Search,'\0', failure); /* set up search string */ do { if (ptr == &buf[BUFSIZ-1]) ptr = buf; /* Save last character for term \0 */ if (sread(ptr , 1, (int) (quit - time(NULL))) < 1) { /* The scan failed? */ char *s; if ( terminate_processing ) return 0; while ( ptr > buf ) if (*(--ptr) > ' ') break; /* Locate the last printable char */ *(ptr+1) = '\0'; /* Terminate the string */ for ( s = buf; (*s > '\0') && (*s <= ' '); s++ ); /* Locate the first printable char */ while ( ptr-- > s )/* Zap control chars */ if (*ptr < ' ') *ptr = '?'; if ( debuglevel < 2 ) printmsg(1, "wanted \"%s\"", Search); printmsg(1, "got ??? \"%s\"",s ); return FALSE; } /* if (sread(ptr , 1, Timeout) < 1) */ *ptr &= 0x7f; result = StrMatch(Search, *ptr++, failure); } while (!result); return result; } /*expectstr*/ /* * StrMatch: Incrementally search for a string. * John H. DuBois III 3/31/90 * StrMatch searches for a string in a sequence of characters. * The string to search for is passed in an initial setup call * (input character in this call is \0) * Further calls with the search string pass one * character per call. * The characters are built up into an input string. * After each character is added to the input string, * the search string is compared to the last length(search string) * characters of the input string to determine whether the search * string has been found. * * Global variables: none. * * Input parameters: * MatchStr is the string to search for. * C is the character to add to the input string. * It is ignored on a setup call. * * Output parameters: None. * * Return value: * On the setup call, -1 is returned if the search string is * longer than the input string buffer. Otherwise, 0 is returned. * * On comparison calls, * 1 is returned if the search string has been found. * > 1 is returned if a failure string has been found. * Otherwise 0 is returned. */ static int StrMatch(char *MatchStr, char C, char **failure) { /* * The input string is stored in a circular buffer of MAXMATCH * characters. If the search string is found in the input, * then the last character added to the buffer will be the last * character of the search string. Therefore, the string * compare will always start SearchLen characters behind the * position where characters are added to the buffer. */ static char Buffer[MAXMATCH]; /* Input string buffer */ static size_t PutPos; /* Where to add chars to buffer */ static size_t SearchPos[MAXLIST]; static size_t SearchPosition; /* Buffer loc to start compare */ static size_t alternates; size_t subscript; /*--------------------------------------------------------------------*/ /* Handle initialize call */ /*--------------------------------------------------------------------*/ if ( C == '\0') { /* Set up call */ memset(Buffer,'\0',MAXMATCH); /* Clear buffer */ PutPos = 0; SearchPosition = MatchInit( MatchStr ); alternates = 0; if ( failure != NULL ) { while (failure[alternates] != NULL ) { SearchPos[alternates] = MatchInit( failure[alternates] ); alternates++; } /* while (failure[alternates] != NULL ) */ } /* if ( failure != NULL ) */ return 0; } /* if (MatchStr) */ /*--------------------------------------------------------------------*/ /* Look for primary match */ /*--------------------------------------------------------------------*/ Buffer[ PutPos++ & QINDMASK] = C; if (Match( MatchStr, Buffer, &SearchPosition)) { printmsg(2, "got that"); return 1; } /*--------------------------------------------------------------------*/ /* Look for alternate matches */ /*--------------------------------------------------------------------*/ if ( alternates > 0 ) { subscript = alternates; while ( subscript-- ) { if (Match( failure[subscript], Buffer, &SearchPos[subscript])) { printmsg(0,"got \"%s\" (failure)",failure[subscript]); return 2; } } /* while ( subscript-- ) */ } /* if ( alternates > 0 ) */ return 0; } /* StrMatch */ /*--------------------------------------------------------------------*/ /* m a t c h */ /* */ /* Match a single string */ /*--------------------------------------------------------------------*/ static boolean Match( char *Search, char *Buffer, size_t *SearchPos) { int BufInd; /* Index to input string buffer for string compare */ char *SearchInd; /* Index to search string for string compare */ *SearchPos += 1; for (BufInd = *SearchPos, SearchInd = Search; *SearchInd; SearchInd++) { if (Buffer[BufInd++ & QINDMASK] != *SearchInd) return FALSE; } return TRUE; } /* Match */ /*--------------------------------------------------------------------*/ /* M a t c h I n i t */ /* */ /* Initialize one set of parameters for MATCH */ /*--------------------------------------------------------------------*/ static size_t MatchInit( const char *MatchStr ) { size_t SearchLen = strlen(MatchStr); if (SearchLen > MAXMATCH) { printmsg(0,"StrMatch: String to match '%s' is too long.\n", MatchStr); panic(); } return MAXMATCH - SearchLen; } /* MatchInit */ /*--------------------------------------------------------------------*/ /* w r i t e s t r */ /* */ /* Send a string to the port during login */ /*--------------------------------------------------------------------*/ static boolean writestr(register char *s) { register char last = '\0'; boolean nocr = FALSE; unsigned char digit; if equal(s,"BREAK") { ssendbrk(0); return TRUE; /* Don't bother with a CR after this */ } while (*s) { if (last == '\\') { last = *s; switch (*s) { case 'd': /* delay */ case 'D': ssleep(2); break; case 'c': /* don't output CR at end of string */ case 'C': nocr = TRUE; break; case 'r': /* carriage return */ case 'R': case 'm': case 'M': slowwrite("\r", 1); break; case 'n': /* new line */ case 'N': slowwrite("\n", 1); break; case 'p': /* delay */ case 'P': ddelay(400); break; case 'b': /* backspace */ case 'B': slowwrite("\b", 1); break; case 't': /* tab */ case 'T': slowwrite("\t", 1); break; case 's': /* space */ case 'S': slowwrite(" ", 1); break; case 'z': /* set serial port speed */ case 'Z': SIOSpeed(atoi(++s)); while (isdigit(*(s+1))) s++; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': digit = 0; while( (*s >= '0') && (*s < '8')) digit = (unsigned char) (digit * 8 + *s++ - '0'); s--; /* Backup before non-numeric char */ slowwrite((char *) &digit,1); break; default: /* ordinary character */ slowwrite(s, 1); last = '\0'; /* Zap any repeated backslash (\) */ } } else if (*s != '\\') /* backslash */ slowwrite(s, 1); else last = *s; s++; } return nocr; } /*writestr*/ /* s e n d s t r Send line of login sequence */ void sendstr(char *str) { printmsg(2, "sending \"%s\"", str); if (equaln(str, "BREAK", 5)) { int nulls; nulls = atoi(&str[5]); if (nulls <= 0 || nulls > 10) nulls = 3; ssendbrk(nulls); /* send a break signal */ return; } if (equal(str, "EOT")) { slowwrite(EOTMSG, strlen(EOTMSG)); return; } if (equal(str, "\"\"")) *str = '\0'; if (!equal(str,"")) { if (!writestr(str)) { slowwrite("\r", 1); } } else slowwrite("\r", 1); return; } /*sendstr*/