⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chat.c

📁 经典的ppp程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *	Chat -- a program for automatic session establishment (i.e. dial *		the phone and log in). * * Standard termination codes: *  0 - successful completion of the script *  1 - invalid argument, expect string too large, etc. *  2 - error on an I/O operation or fatal error condition. *  3 - timeout waiting for a simple string. *  4 - the first string declared as "ABORT" *  5 - the second string declared as "ABORT" *  6 - ... and so on for successive ABORT strings. * *	This software is in the public domain. * * ----------------- *	22-May-99 added environment substitutuion, enabled with -E switch. *	Andreas Arens <andras@cityweb.de>. * *	12-May-99 added a feature to read data to be sent from a file, *	if the send string starts with @.  Idea from gpk <gpk@onramp.net>. * *	added -T and -U option and \T and \U substitution to pass a phone *	number into chat script. Two are needed for some ISDN TA applications. *	Keith Dart <kdart@cisco.com> *	 * *	Added SAY keyword to send output to stderr. *      This allows to turn ECHO OFF and to output specific, user selected, *      text to give progress messages. This best works when stderr *      exists (i.e.: pppd in nodetach mode). * * 	Added HANGUP directives to allow for us to be called *      back. When HANGUP is set to NO, chat will not hangup at HUP signal. *      We rely on timeouts in that case. * *      Added CLR_ABORT to clear previously set ABORT string. This has been *      dictated by the HANGUP above as "NO CARRIER" (for example) must be *      an ABORT condition until we know the other host is going to close *      the connection for call back. As soon as we have completed the *      first stage of the call back sequence, "NO CARRIER" is a valid, non *      fatal string. As soon as we got called back (probably get "CONNECT"), *      we should re-arm the ABORT "NO CARRIER". Hence the CLR_ABORT command. *      Note that CLR_ABORT packs the abort_strings[] array so that we do not *      have unused entries not being reclaimed. * *      In the same vein as above, added CLR_REPORT keyword. * *      Allow for comments. Line starting with '#' are comments and are *      ignored. If a '#' is to be expected as the first character, the  *      expect string must be quoted. * * *		Francis Demierre <Francis@SwissMail.Com> * 		Thu May 15 17:15:40 MET DST 1997 * * *      Added -r "report file" switch & REPORT keyword. *              Robert Geer <bgeer@xmission.com> * *      Added -s "use stderr" and -S "don't use syslog" switches. *              June 18, 1997 *              Karl O. Pinc <kop@meme.com> * * *	Added -e "echo" switch & ECHO keyword *		Dick Streefland <dicks@tasking.nl> * * *	Considerable updates and modifications by *		Al Longyear <longyear@pobox.com> *		Paul Mackerras <paulus@cs.anu.edu.au> * * *	The original author is: * *		Karl Fox <karl@MorningStar.Com> *		Morning Star Technologies, Inc. *		1760 Zollinger Road *		Columbus, OH  43221 *		(614)451-1883 * */#ifndef __STDC__#define const#endif#ifndef lintstatic const char rcsid[] = "$Id: chat.c,v 1.26 1999/12/23 01:39:54 paulus Exp $";#endif#include <stdio.h>#include <ctype.h>#include <time.h>#include <fcntl.h>#include <signal.h>#include <errno.h>#include <string.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <syslog.h>#ifndef TERMIO#undef	TERMIOS#define TERMIOS#endif#ifdef TERMIO#include <termio.h>#endif#ifdef TERMIOS#include <termios.h>#endif#define	STR_LEN	1024#ifndef SIGTYPE#define SIGTYPE void#endif#undef __P#undef __V#ifdef __STDC__#include <stdarg.h>#define __V(x)	x#define __P(x)	x#else#include <varargs.h>#define __V(x)	(va_alist) va_dcl#define __P(x)	()#define const#endif#ifndef O_NONBLOCK#define O_NONBLOCK	O_NDELAY#endif#ifdef SUNOSextern int sys_nerr;extern char *sys_errlist[];#define memmove(to, from, n)	bcopy(from, to, n)#define strerror(n)		((unsigned)(n) < sys_nerr? sys_errlist[(n)] :\				 "unknown error")#endif/*************** Micro getopt() *********************************************/#define	OPTION(c,v)	(_O&2&&**v?*(*v)++:!c||_O&4?0:(!(_O&1)&& \				(--c,++v),_O=4,c&&**v=='-'&&v[0][1]?*++*v=='-'\				&&!v[0][1]?(--c,++v,0):(_O=2,*(*v)++):0))#define	OPTARG(c,v)	(_O&2?**v||(++v,--c)?(_O=1,--c,*v++): \				(_O=4,(char*)0):(char*)0)#define	OPTONLYARG(c,v)	(_O&2&&**v?(_O=1,--c,*v++):(char*)0)#define	ARG(c,v)	(c?(--c,*v++):(char*)0)static int _O = 0;		/* Internal state *//*************** Micro getopt() *********************************************/char *program_name;#define	MAX_ABORTS		50#define	MAX_REPORTS		50#define	DEFAULT_CHAT_TIMEOUT	45int echo          = 0;int verbose       = 0;int to_log        = 1;int to_stderr     = 0;int Verbose       = 0;int quiet         = 0;int report        = 0;int use_env       = 0;int exit_code     = 0;FILE* report_fp   = (FILE *) 0;char *report_file = (char *) 0;char *chat_file   = (char *) 0;char *phone_num   = (char *) 0;char *phone_num2  = (char *) 0;int timeout       = DEFAULT_CHAT_TIMEOUT;int have_tty_parameters = 0;#ifdef TERMIO#define term_parms struct termio#define get_term_param(param) ioctl(0, TCGETA, param)#define set_term_param(param) ioctl(0, TCSETA, param)struct termio saved_tty_parameters;#endif#ifdef TERMIOS#define term_parms struct termios#define get_term_param(param) tcgetattr(0, param)#define set_term_param(param) tcsetattr(0, TCSANOW, param)struct termios saved_tty_parameters;#endifchar *abort_string[MAX_ABORTS], *fail_reason = (char *)0,	fail_buffer[50];int n_aborts = 0, abort_next = 0, timeout_next = 0, echo_next = 0;int clear_abort_next = 0;char *report_string[MAX_REPORTS] ;char  report_buffer[50] ;int n_reports = 0, report_next = 0, report_gathering = 0 ; int clear_report_next = 0;int say_next = 0, hup_next = 0;void *dup_mem __P((void *b, size_t c));void *copy_of __P((char *s));void usage __P((void));void logf __P((const char *fmt, ...));void fatal __P((int code, const char *fmt, ...));SIGTYPE sigalrm __P((int signo));SIGTYPE sigint __P((int signo));SIGTYPE sigterm __P((int signo));SIGTYPE sighup __P((int signo));void unalarm __P((void));void init __P((void));void set_tty_parameters __P((void));void echo_stderr __P((int));void break_sequence __P((void));void terminate __P((int status));void do_file __P((char *chat_file));int  get_string __P((register char *string));int  put_string __P((register char *s));int  write_char __P((int c));int  put_char __P((int c));int  get_char __P((void));void chat_send __P((register char *s));char *character __P((int c));void chat_expect __P((register char *s));char *clean __P((register char *s, int sending));void break_sequence __P((void));void terminate __P((int status));void pack_array __P((char **array, int end));char *expect_strtok __P((char *, char *));int vfmtmsg __P((char *, int, const char *, va_list));	/* vsprintf++ */int main __P((int, char *[]));void *dup_mem(b, c)void *b;size_t c;{    void *ans = malloc (c);    if (!ans)	fatal(2, "memory error!");    memcpy (ans, b, c);    return ans;}void *copy_of (s)char *s;{    return dup_mem (s, strlen (s) + 1);}/* * chat [ -v ] [ -E ] [ -T number ] [ -U number ] [ -t timeout ] [ -f chat-file ] \ * [ -r report-file ] \ *		[...[[expect[-say[-expect...]] say expect[-say[-expect]] ...]]] * *	Perform a UUCP-dialer-like chat script on stdin and stdout. */intmain(argc, argv)     int argc;     char **argv;{    int option;    char *arg;    program_name = *argv;    tzset();    while ((option = OPTION(argc, argv)) != 0) {	switch (option) {	case 'e':	    ++echo;	    break;	case 'E':	    ++use_env;	    break;	case 'v':	    ++verbose;	    break;	case 'V':	    ++Verbose;	    break;	case 's':	    ++to_stderr;	    break;	case 'S':	    to_log = 0;	    break;	case 'f':	    if ((arg = OPTARG(argc, argv)) != NULL)		    chat_file = copy_of(arg);	    else		usage();	    break;	case 't':	    if ((arg = OPTARG(argc, argv)) != NULL)		timeout = atoi(arg);	    else		usage();	    break;	case 'r':	    arg = OPTARG (argc, argv);	    if (arg) {		if (report_fp != NULL)		    fclose (report_fp);		report_file = copy_of (arg);		report_fp   = fopen (report_file, "a");		if (report_fp != NULL) {		    if (verbose)			fprintf (report_fp, "Opening \"%s\"...\n",				 report_file);		    report = 1;		}	    }	    break;	case 'T':	    if ((arg = OPTARG(argc, argv)) != NULL)		phone_num = copy_of(arg);	    else		usage();	    break;	case 'U':	    if ((arg = OPTARG(argc, argv)) != NULL)		phone_num2 = copy_of(arg);	    else		usage();	    break;	default:	    usage();	    break;	}    }/* * Default the report file to the stderr location */    if (report_fp == NULL)	report_fp = stderr;    if (to_log) {#ifdef ultrix	openlog("chat", LOG_PID);#else	openlog("chat", LOG_PID | LOG_NDELAY, LOG_LOCAL2);	if (verbose)	    setlogmask(LOG_UPTO(LOG_INFO));	else	    setlogmask(LOG_UPTO(LOG_WARNING));#endif    }    init();        if (chat_file != NULL) {	arg = ARG(argc, argv);	if (arg != NULL)	    usage();	else	    do_file (chat_file);    } else {	while ((arg = ARG(argc, argv)) != NULL) {	    chat_expect(arg);	    if ((arg = ARG(argc, argv)) != NULL)		chat_send(arg);	}    }    terminate(0);    return 0;}/* *  Process a chat script when read from a file. */void do_file (chat_file)char *chat_file;{    int linect, sendflg;    char *sp, *arg, quote;    char buf [STR_LEN];    FILE *cfp;    cfp = fopen (chat_file, "r");    if (cfp == NULL)	fatal(1, "%s -- open failed: %m", chat_file);    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);}/* *	We got an error parsing the command line. */void usage(){    fprintf(stderr, "\Usage: %s [-e] [-E] [-v] [-V] [-t timeout] [-r report-file]\n\     [-T phone-number] [-U phone-number2] {-f chat-file | chat-script}\n", program_name);    exit(1);}char line[1024];/* * Send a message to syslog and/or stderr. */void logf __V((const char *fmt, ...)){    va_list args;#ifdef __STDC__    va_start(args, fmt);#else    char *fmt;    va_start(args);    fmt = va_arg(args, char *);#endif    vfmtmsg(line, sizeof(line), fmt, args);    if (to_log)	syslog(LOG_INFO, "%s", line);    if (to_stderr)	fprintf(stderr, "%s\n", line);}/* *	Print an error message and terminate. */void fatal __V((int code, const char *fmt, ...)){    va_list args;#ifdef __STDC__    va_start(args, fmt);#else    int code;    char *fmt;    va_start(args);    code = va_arg(args, int);    fmt = va_arg(args, char *);#endif    vfmtmsg(line, sizeof(line), fmt, args);    if (to_log)	syslog(LOG_ERR, "%s", line);    if (to_stderr)	fprintf(stderr, "%s\n", line);    terminate(code);}int alarmed = 0;SIGTYPE sigalrm(signo)int signo;{    int flags;    alarm(1);    alarmed = 1;		/* Reset alarm to avoid race window */    signal(SIGALRM, sigalrm);	/* that can cause hanging in read() */    if ((flags = fcntl(0, F_GETFL, 0)) == -1)	fatal(2, "Can't get file mode flags on stdin: %m");    if (fcntl(0, F_SETFL, flags | O_NONBLOCK) == -1)	fatal(2, "Can't set file mode flags on stdin: %m");    if (verbose)	logf("alarm");}void unalarm(){    int flags;    if ((flags = fcntl(0, F_GETFL, 0)) == -1)	fatal(2, "Can't get file mode flags on stdin: %m");    if (fcntl(0, F_SETFL, flags & ~O_NONBLOCK) == -1)	fatal(2, "Can't set file mode flags on stdin: %m");}SIGTYPE sigint(signo)int signo;{    fatal(2, "SIGINT");}SIGTYPE sigterm(signo)int signo;{    fatal(2, "SIGTERM");}SIGTYPE sighup(signo)int signo;{    fatal(2, "SIGHUP");}void init(){    signal(SIGINT, sigint);    signal(SIGTERM, sigterm);    signal(SIGHUP, sighup);    set_tty_parameters();    signal(SIGALRM, sigalrm);    alarm(0);    alarmed = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -