X-Git-Url: http://git.ozlabs.org/?a=blobdiff_plain;f=chat%2Fchat.c;h=47248fa65c3d2897c293c2079f227a42a7152ac8;hb=968c0d2221f53d7de4abf422caed01c079c20e2c;hp=1f362a2e2aedd88b89d85778474abbdb019435a6;hpb=a6f2276a5e205ec00e611391a5899fceca773c4f;p=ppp.git diff --git a/chat/chat.c b/chat/chat.c index 1f362a2..47248fa 100644 --- a/chat/chat.c +++ b/chat/chat.c @@ -14,6 +14,9 @@ * This software is in the public domain. * * ----------------- + * 22-May-99 added environment substitutuion, enabled with -E switch. + * Andreas Arens . + * * 12-May-99 added a feature to read data to be sent from a file, * if the send string starts with @. Idea from gpk . * @@ -77,11 +80,14 @@ * Columbus, OH 43221 * (614)451-1883 * - * */ +#ifndef __STDC__ +#define const +#endif + #ifndef lint -static char rcsid[] = "$Id: chat.c,v 1.21 1999/05/12 06:13:22 paulus Exp $"; +static const char rcsid[] = "$Id: chat.c,v 1.29 2003/03/04 06:17:21 fcusack Exp $"; #endif #include @@ -166,6 +172,7 @@ 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; @@ -196,7 +203,7 @@ 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] ; +char report_buffer[256] ; int n_reports = 0, report_next = 0, report_gathering = 0 ; int clear_report_next = 0; @@ -204,6 +211,7 @@ int say_next = 0, hup_next = 0; void *dup_mem __P((void *b, size_t c)); void *copy_of __P((char *s)); +char *grow __P((char *s, char **p, size_t len)); void usage __P((void)); void logf __P((const char *fmt, ...)); void fatal __P((int code, const char *fmt, ...)); @@ -253,8 +261,23 @@ char *s; return dup_mem (s, strlen (s) + 1); } +/* grow a char buffer and keep a pointer offset */ +char *grow(s, p, len) +char *s; +char **p; +size_t len; +{ + size_t l = *p - s; /* save p as distance into s */ + + s = realloc(s, len); + if (!s) + fatal(2, "memory error!"); + *p = s + l; /* restore p */ + return s; +} + /* - * chat [ -v ] [-T number] [-U number] [ -t timeout ] [ -f chat-file ] \ + * chat [ -v ] [ -E ] [ -T number ] [ -U number ] [ -t timeout ] [ -f chat-file ] \ * [ -r report-file ] \ * [...[[expect[-say[-expect...]] say expect[-say[-expect]] ...]]] * @@ -277,6 +300,10 @@ main(argc, argv) ++echo; break; + case 'E': + ++use_env; + break; + case 'v': ++verbose; break; @@ -458,8 +485,8 @@ char *chat_file; void usage() { fprintf(stderr, "\ -Usage: %s [-e] [-v] [-t timeout] [-r report-file] [-T phone-number]\n\ - [-U phone-number2] {-f chat-file | chat-script}\n", program_name); +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); } @@ -615,26 +642,26 @@ int status; exit(status); terminating = 1; echo_stderr(-1); - if (report_file != (char *) 0 && report_fp != (FILE *) NULL) { /* * Allow the last of the report string to be gathered before we terminate. */ - if (report_gathering) { - int c, rep_len; + if (report_gathering) { + int c, rep_len; - rep_len = strlen(report_buffer); - while (rep_len + 1 <= sizeof(report_buffer)) { - alarm(1); - c = get_char(); - alarm(0); - if (c < 0 || iscntrl(c)) - break; - report_buffer[rep_len] = c; - ++rep_len; - } - report_buffer[rep_len] = 0; - fprintf (report_fp, "chat: %s\n", report_buffer); + rep_len = strlen(report_buffer); + while (rep_len + 1 <= sizeof(report_buffer)) { + alarm(1); + c = get_char(); + alarm(0); + if (c < 0 || iscntrl(c)) + break; + report_buffer[rep_len] = c; + ++rep_len; } + report_buffer[rep_len] = 0; + fprintf (report_fp, "chat: %s\n", report_buffer); + } + if (report_file != (char *) 0 && report_fp != (FILE *) NULL) { if (verbose) fprintf (report_fp, "Closing \"%s\".\n", report_file); fclose (report_fp); @@ -658,51 +685,78 @@ char *clean(s, sending) register char *s; int sending; /* set to 1 when sending (putting) this string. */ { - char temp[STR_LEN], cur_chr; - register char *s1, *phchar; + char cur_chr; + char *s1, *p, *phchar; int add_return = sending; -#define isoctal(chr) (((chr) >= '0') && ((chr) <= '7')) + size_t len = strlen(s) + 3; /* see len comments below */ + +#define isoctal(chr) (((chr) >= '0') && ((chr) <= '7')) +#define isalnumx(chr) ((((chr) >= '0') && ((chr) <= '9')) \ + || (((chr) >= 'a') && ((chr) <= 'z')) \ + || (((chr) >= 'A') && ((chr) <= 'Z')) \ + || (chr) == '_') - s1 = temp; + p = s1 = malloc(len); + if (!p) + fatal(2, "memory error!"); while (*s) { cur_chr = *s++; if (cur_chr == '^') { cur_chr = *s++; if (cur_chr == '\0') { - *s1++ = '^'; + *p++ = '^'; break; } cur_chr &= 0x1F; if (cur_chr != 0) { - *s1++ = cur_chr; + *p++ = cur_chr; + } + continue; + } + + if (use_env && cur_chr == '$') { /* ARI */ + char c; + + phchar = s; + while (isalnumx(*s)) + s++; + c = *s; /* save */ + *s = '\0'; + phchar = getenv(phchar); + *s = c; /* restore */ + if (phchar) { + len += strlen(phchar); + s1 = grow(s1, &p, len); + while (*phchar) + *p++ = *phchar++; } continue; } if (cur_chr != '\\') { - *s1++ = cur_chr; + *p++ = cur_chr; continue; } cur_chr = *s++; if (cur_chr == '\0') { if (sending) { - *s1++ = '\\'; - *s1++ = '\\'; + *p++ = '\\'; + *p++ = '\\'; /* +1 for len */ } break; } switch (cur_chr) { case 'b': - *s1++ = '\b'; + *p++ = '\b'; break; case 'c': if (sending && *s == '\0') add_return = 0; else - *s1++ = cur_chr; + *p++ = cur_chr; break; case '\\': @@ -710,30 +764,33 @@ int sending; /* set to 1 when sending (putting) this string. */ case 'p': case 'd': if (sending) - *s1++ = '\\'; - - *s1++ = cur_chr; + *p++ = '\\'; + *p++ = cur_chr; break; case 'T': if (sending && phone_num) { - for ( phchar = phone_num; *phchar != '\0'; phchar++) - *s1++ = *phchar; + len += strlen(phone_num); + s1 = grow(s1, &p, len); + for (phchar = phone_num; *phchar != '\0'; phchar++) + *p++ = *phchar; } else { - *s1++ = '\\'; - *s1++ = 'T'; + *p++ = '\\'; + *p++ = 'T'; } break; case 'U': if (sending && phone_num2) { - for ( phchar = phone_num2; *phchar != '\0'; phchar++) - *s1++ = *phchar; + len += strlen(phone_num2); + s1 = grow(s1, &p, len); + for (phchar = phone_num2; *phchar != '\0'; phchar++) + *p++ = *phchar; } else { - *s1++ = '\\'; - *s1++ = 'U'; + *p++ = '\\'; + *p++ = 'U'; } break; @@ -742,30 +799,37 @@ int sending; /* set to 1 when sending (putting) this string. */ break; case 'r': - *s1++ = '\r'; + *p++ = '\r'; break; case 'n': - *s1++ = '\n'; + *p++ = '\n'; break; case 's': - *s1++ = ' '; + *p++ = ' '; break; case 't': - *s1++ = '\t'; + *p++ = '\t'; break; case 'N': if (sending) { - *s1++ = '\\'; - *s1++ = '\0'; + *p++ = '\\'; + *p++ = '\0'; } else - *s1++ = 'N'; + *p++ = 'N'; break; - + + case '$': /* ARI */ + if (use_env) { + *p++ = cur_chr; + break; + } + /* FALL THROUGH */ + default: if (isoctal (cur_chr)) { cur_chr &= 0x07; @@ -780,25 +844,24 @@ int sending; /* set to 1 when sending (putting) this string. */ if (cur_chr != 0 || sending) { if (sending && (cur_chr == '\\' || cur_chr == 0)) - *s1++ = '\\'; - *s1++ = cur_chr; + *p++ = '\\'; + *p++ = cur_chr; } break; } if (sending) - *s1++ = '\\'; - *s1++ = cur_chr; + *p++ = '\\'; + *p++ = cur_chr; break; } } if (add_return) - *s1++ = '\r'; + *p++ = '\r'; /* +2 for len */ - *s1++ = '\0'; /* guarantee closure */ - *s1++ = '\0'; /* terminate the string */ - return dup_mem (temp, (size_t) (s1 - temp)); /* may have embedded nuls */ + *p = '\0'; /* +3 for len */ + return s1; } /* @@ -978,7 +1041,7 @@ register char *s; if (say_next) { say_next = 0; - s = clean(s,0); + s = clean(s, 1); write(2, s, strlen(s)); free(s); return; @@ -1059,8 +1122,8 @@ register char *s; fatal(2, "Too many REPORT strings"); s1 = clean(s, 0); - - if (strlen(s1) > strlen(s) || strlen(s1) > sizeof fail_buffer - 1) + if (strlen(s1) > strlen(s) + || strlen(s1) + 1 > sizeof(fail_buffer)) fatal(1, "Illegal or too-long REPORT string ('%v')", s); report_string[n_reports++] = s1; @@ -1080,7 +1143,8 @@ register char *s; s1 = clean(s, 0); - if (strlen(s1) > strlen(s) || strlen(s1) > sizeof fail_buffer - 1) + if (strlen(s1) > strlen(s) + || strlen(s1) + 1 > sizeof(fail_buffer)) fatal(1, "Illegal or too-long REPORT string ('%v')", s); old_max = n_reports; @@ -1434,7 +1498,8 @@ register char *string; if (s >= end) { if (logged < s - minlen) { - logf("%0.*v", s - logged, logged); + if (verbose) + logf("%0.*v", s - logged, logged); logged = s; } s -= minlen;