int getty_chat(char *scrstr, int timeout, int debug) { int r = -1; chat_alarm = timeout ? timeout : CHAT_DEFAULT_TIMEOUT; chat_debug = debug; if (scrstr != NULL) { char **script; if (chat_debug & CHATDEBUG_MISC) syslog(LOG_DEBUG, "getty_chat script='%s'", scrstr); if ((script = read_chat(&scrstr)) != NULL) { int i = r = 0; int off = 0; sig_t old_alarm; /* * We need to be in raw mode for all this * Rely on caller... */ old_alarm = signal(SIGALRM, chat_alrm); chat_unalarm(); /* Force blocking mode at start */ /* * This is the send/expect loop */ while (r == 0 && script[i] != NULL) if ((r = chat_expect(script[i++])) == 0 && script[i] != NULL) r = chat_send(script[i++]); signal(SIGALRM, old_alarm); free(script); free(scrstr); /* * Ensure stdin is in blocking mode */ ioctl(STDIN_FILENO, FIONBIO, &off); } if (chat_debug & CHATDEBUG_MISC) syslog(LOG_DEBUG, "getty_chat %s", result(r)); } return r; }
int chatmain(int fd, int mode, char *pScript) { char arg[80]; char *script; /* initialize exit code */ exit_code = 0; ttyfd = fd; script=pScript; if ( debug ) { dbglog("chat_main: %s\n", script); } /* get first expect string */ script = getnextcommand(script,arg); while (( script != NULL ) && ( exit_code == 0 )) { /* process the expect string */ chat_expect(arg); if ( exit_code == 0 ) { /* get the next send string */ script = getnextcommand(script,arg); if ( script != NULL ) { /* process the send string */ chat_send(arg); /* get the next expect string */ script = getnextcommand(script,arg); } } } ttyfd = (int)-1; return ( exit_code ); }
void do_file(char *chatfile) { int linect, sendflg; char *sp, *arg, quote; char buf [STR_LEN]; FILE *cfp; cfp = fopen (chatfile, "r"); if (cfp == NULL) fatal(1, "%s -- open failed: %m", chatfile); linect = 0; sendflg = 0; while (fgets(buf, STR_LEN, cfp) != NULL) { sp = strchr (buf, '\n'); if (sp) *sp = '\0'; linect++; sp = buf; /* lines starting with '#' are comments. If a real '#' is to be expected, it should be quoted .... */ if ( *sp == '#' ) continue; while (*sp != '\0') { if (*sp == ' ' || *sp == '\t') { ++sp; continue; } if (*sp == '"' || *sp == '\'') { quote = *sp++; arg = sp; while (*sp != quote) { if (*sp == '\0') fatal(1, "unterminated quote (line %d)", linect); if (*sp++ == '\\') { if (*sp != '\0') ++sp; } } } else { arg = sp; while (*sp != '\0' && *sp != ' ' && *sp != '\t') ++sp; } if (*sp != '\0') *sp++ = '\0'; if (sendflg) chat_send (arg); else chat_expect (arg); sendflg = !sendflg; } } fclose (cfp); }
/* * chat [-esSvV] [-f chat-file] [-r report-file] [-t timeout] * [-T phone-number] [-U phone-number2] [chat-script] * where chat-script has the form: * [...[[expect[-send[-expect...]] send expect[-send[-expect]] ...]]] * * Perform a UUCP-dialer-like chat script on stdin and stdout. */ int main(int argc, char *argv[]) { int option; tzset(); while ((option = getopt(argc, argv, "ef:r:sSt:T:U:vV")) != -1) { switch (option) { case 'e': ++echo; break; case 'f': if (chat_file != NULL) free(chat_file); chat_file = copy_of(optarg); break; case 'r': if (report_fp != NULL) fclose(report_fp); if (report_file != NULL) free(report_file); report_file = copy_of(optarg); report_fp = fopen(report_file, "a"); if (report_fp != NULL) { if (verbose) fprintf(report_fp, "Opening \"%s\"...\n", report_file); } else fatal(2, "cannot open \"%s\" for appending", report_file); break; case 's': ++to_stderr; break; case 'S': to_log = 0; break; case 't': timeout = atoi(optarg); break; case 'T': if (phone_num != NULL) free(phone_num); phone_num = copy_of(optarg); break; case 'U': if (phone_num2 != NULL) free(phone_num2); phone_num2 = copy_of(optarg); break; case 'v': ++verbose; break; case 'V': ++Verbose; break; default: usage(); break; } } argc -= optind; argv += optind; /* * Default the report file to the stderr location */ if (report_fp == NULL) report_fp = stderr; if (to_log) { openlog("chat", LOG_PID | LOG_NDELAY, LOG_LOCAL2); if (verbose) setlogmask(LOG_UPTO(LOG_INFO)); else setlogmask(LOG_UPTO(LOG_WARNING)); } if (chat_file != NULL) { if (*argv != NULL) usage(); else { init(); do_file(chat_file); } } else { init(); while (*argv != NULL && argc > 0) { chat_expect(*argv); argv++; argc--; if (*argv != NULL && argc > 0) { chat_send(*argv); argv++; argc--; } } } terminate(0); return 0; }
static int chat_line_run(FAR struct chat* priv, FAR const struct chat_line* line) { int ret = 0; int numarg; vdbg("type %d, rhs %s\n", line->type, line->rhs); switch (line->type) { case CHAT_LINE_TYPE_COMMAND: if (priv->ctl.verbose) { fprintf(stderr, "chat: cmd %d, arg %s\n", line->lhs.command, line->rhs); } switch (line->lhs.command) { case CHAT_COMMAND_ABORT: /* TODO */ break; case CHAT_COMMAND_ECHO: if (strcmp(line->rhs, "ON")) { priv->ctl.echo = true; } else { priv->ctl.echo = false; } break; case CHAT_COMMAND_PAUSE: numarg = atoi(line->rhs); if (numarg < 0) { numarg = 0; } sleep(numarg); break; case CHAT_COMMAND_SAY: fprintf(stderr, "%s\n", line->rhs); break; case CHAT_COMMAND_TIMEOUT: numarg = atoi(line->rhs); if (numarg < 0) { vdbg("invalid timeout string %s\n", line->rhs); } else { vdbg("timeout is %d s\n", numarg); priv->ctl.timeout = numarg; } break; default: break; } break; case CHAT_LINE_TYPE_EXPECT_SEND: if (priv->ctl.verbose) { fprintf(stderr, "chat: %s %s\n", line->lhs.expect, line->rhs); } ret = chat_expect(priv, line->lhs.expect); if (!ret) { /* Discard anything after the confirmed expectation */ chat_flush(priv); ret = chat_send(priv, line->rhs); } break; default: ret = -EINVAL; break; } return ret; }