19b1aec48SLars Fredriksen /* 29b1aec48SLars Fredriksen * Chat -- a program for automatic session establishment (i.e. dial 39b1aec48SLars Fredriksen * the phone and log in). 49b1aec48SLars Fredriksen * 59f65f104SPeter Wemm * Standard termination codes: 69f65f104SPeter Wemm * 0 - successful completion of the script 79f65f104SPeter Wemm * 1 - invalid argument, expect string too large, etc. 89f65f104SPeter Wemm * 2 - error on an I/O operation or fatal error condtion. 99f65f104SPeter Wemm * 3 - timeout waiting for a simple string. 109f65f104SPeter Wemm * 4 - the first string declared as "ABORT" 119f65f104SPeter Wemm * 5 - the second string declared as "ABORT" 129f65f104SPeter Wemm * 6 - ... and so on for successive ABORT strings. 139f65f104SPeter Wemm * 149b1aec48SLars Fredriksen * This software is in the public domain. 159b1aec48SLars Fredriksen * 169b1aec48SLars Fredriksen * Please send all bug reports, requests for information, etc. to: 179b1aec48SLars Fredriksen * 189b1aec48SLars Fredriksen * Al Longyear (longyear@netcom.com) 199b1aec48SLars Fredriksen * (I was the last person to change this code.) 209b1aec48SLars Fredriksen * 219f65f104SPeter Wemm * Added -r "report file" switch & REPORT keyword. 229f65f104SPeter Wemm * Robert Geer <bgeer@xmission.com> 239f65f104SPeter Wemm * 249b1aec48SLars Fredriksen * The original author is: 259b1aec48SLars Fredriksen * 269b1aec48SLars Fredriksen * Karl Fox <karl@MorningStar.Com> 279b1aec48SLars Fredriksen * Morning Star Technologies, Inc. 289b1aec48SLars Fredriksen * 1760 Zollinger Road 299b1aec48SLars Fredriksen * Columbus, OH 43221 309b1aec48SLars Fredriksen * (614)451-1883 319f65f104SPeter Wemm * 329b1aec48SLars Fredriksen */ 339b1aec48SLars Fredriksen 349f65f104SPeter Wemm static char rcsid[] = "$Id: chat.c,v 1.1.1.1 1994/11/12 05:25:32 lars Exp $"; 359b1aec48SLars Fredriksen 369b1aec48SLars Fredriksen #include <stdio.h> 379f65f104SPeter Wemm #include <time.h> 389b1aec48SLars Fredriksen #include <fcntl.h> 399b1aec48SLars Fredriksen #include <signal.h> 409b1aec48SLars Fredriksen #include <errno.h> 419b1aec48SLars Fredriksen #include <string.h> 429b1aec48SLars Fredriksen #include <stdlib.h> 439b1aec48SLars Fredriksen #include <sys/types.h> 449b1aec48SLars Fredriksen #include <sys/stat.h> 459b1aec48SLars Fredriksen #include <syslog.h> 469b1aec48SLars Fredriksen 479b1aec48SLars Fredriksen #ifndef TERMIO 489b1aec48SLars Fredriksen #undef TERMIOS 499b1aec48SLars Fredriksen #define TERMIOS 509b1aec48SLars Fredriksen #endif 519b1aec48SLars Fredriksen 529b1aec48SLars Fredriksen #ifdef TERMIO 539b1aec48SLars Fredriksen #include <termio.h> 549b1aec48SLars Fredriksen #endif 559b1aec48SLars Fredriksen #ifdef TERMIOS 569b1aec48SLars Fredriksen #include <termios.h> 579b1aec48SLars Fredriksen #endif 589b1aec48SLars Fredriksen 599b1aec48SLars Fredriksen #define STR_LEN 1024 609b1aec48SLars Fredriksen 619b1aec48SLars Fredriksen #ifndef SIGTYPE 629b1aec48SLars Fredriksen #define SIGTYPE void 639b1aec48SLars Fredriksen #endif 649b1aec48SLars Fredriksen 659b1aec48SLars Fredriksen #ifdef __STDC__ 669b1aec48SLars Fredriksen #undef __P 679b1aec48SLars Fredriksen #define __P(x) x 689b1aec48SLars Fredriksen #else 699b1aec48SLars Fredriksen #define __P(x) () 709b1aec48SLars Fredriksen #define const 719b1aec48SLars Fredriksen #endif 729b1aec48SLars Fredriksen 739f65f104SPeter Wemm #ifndef O_NONBLOCK 749f65f104SPeter Wemm #define O_NONBLOCK O_NDELAY 759f65f104SPeter Wemm #endif 769f65f104SPeter Wemm 779b1aec48SLars Fredriksen /*************** Micro getopt() *********************************************/ 789b1aec48SLars Fredriksen #define OPTION(c,v) (_O&2&&**v?*(*v)++:!c||_O&4?0:(!(_O&1)&& \ 799b1aec48SLars Fredriksen (--c,++v),_O=4,c&&**v=='-'&&v[0][1]?*++*v=='-'\ 809b1aec48SLars Fredriksen &&!v[0][1]?(--c,++v,0):(_O=2,*(*v)++):0)) 819b1aec48SLars Fredriksen #define OPTARG(c,v) (_O&2?**v||(++v,--c)?(_O=1,--c,*v++): \ 829b1aec48SLars Fredriksen (_O=4,(char*)0):(char*)0) 839b1aec48SLars Fredriksen #define OPTONLYARG(c,v) (_O&2&&**v?(_O=1,--c,*v++):(char*)0) 849b1aec48SLars Fredriksen #define ARG(c,v) (c?(--c,*v++):(char*)0) 859b1aec48SLars Fredriksen 869b1aec48SLars Fredriksen static int _O = 0; /* Internal state */ 879b1aec48SLars Fredriksen /*************** Micro getopt() *********************************************/ 889b1aec48SLars Fredriksen 899b1aec48SLars Fredriksen char *program_name; 909b1aec48SLars Fredriksen 919b1aec48SLars Fredriksen #define MAX_ABORTS 50 929f65f104SPeter Wemm #define MAX_REPORTS 50 939b1aec48SLars Fredriksen #define DEFAULT_CHAT_TIMEOUT 45 949b1aec48SLars Fredriksen 959b1aec48SLars Fredriksen int verbose = 0; 969b1aec48SLars Fredriksen int quiet = 0; 979f65f104SPeter Wemm int report = 0; 989f65f104SPeter Wemm int exit_code = 0; 999f65f104SPeter Wemm FILE* report_fp = (FILE *) 0; 1009f65f104SPeter Wemm char *report_file = (char *) 0; 1019b1aec48SLars Fredriksen char *chat_file = (char *) 0; 1029b1aec48SLars Fredriksen int timeout = DEFAULT_CHAT_TIMEOUT; 1039b1aec48SLars Fredriksen 1049b1aec48SLars Fredriksen int have_tty_parameters = 0; 1059f65f104SPeter Wemm 1069b1aec48SLars Fredriksen #ifdef TERMIO 1079f65f104SPeter Wemm #define term_parms struct termio 1089f65f104SPeter Wemm #define get_term_param(param) ioctl(0, TCGETA, param) 1099f65f104SPeter Wemm #define set_term_param(param) ioctl(0, TCSETA, param) 1109b1aec48SLars Fredriksen struct termio saved_tty_parameters; 1119b1aec48SLars Fredriksen #endif 1129f65f104SPeter Wemm 1139b1aec48SLars Fredriksen #ifdef TERMIOS 1149f65f104SPeter Wemm #define term_parms struct termios 1159f65f104SPeter Wemm #define get_term_param(param) tcgetattr(0, param) 1169f65f104SPeter Wemm #define set_term_param(param) tcsetattr(0, TCSANOW, param) 1179b1aec48SLars Fredriksen struct termios saved_tty_parameters; 1189b1aec48SLars Fredriksen #endif 1199b1aec48SLars Fredriksen 1209b1aec48SLars Fredriksen char *abort_string[MAX_ABORTS], *fail_reason = (char *)0, 1219b1aec48SLars Fredriksen fail_buffer[50]; 1229b1aec48SLars Fredriksen int n_aborts = 0, abort_next = 0, timeout_next = 0; 1239b1aec48SLars Fredriksen 1249f65f104SPeter Wemm char *report_string[MAX_REPORTS] ; 1259f65f104SPeter Wemm char report_buffer[50] ; 1269f65f104SPeter Wemm int n_reports = 0, report_next = 0, report_gathering = 0 ; 1279f65f104SPeter Wemm 1289b1aec48SLars Fredriksen void *dup_mem __P((void *b, size_t c)); 1299b1aec48SLars Fredriksen void *copy_of __P((char *s)); 1309b1aec48SLars Fredriksen void usage __P((void)); 1319b1aec48SLars Fredriksen void logf __P((const char *str)); 1329b1aec48SLars Fredriksen void logflush __P((void)); 1339b1aec48SLars Fredriksen void fatal __P((const char *msg)); 1349b1aec48SLars Fredriksen void sysfatal __P((const char *msg)); 1359b1aec48SLars Fredriksen SIGTYPE sigalrm __P((int signo)); 1369b1aec48SLars Fredriksen SIGTYPE sigint __P((int signo)); 1379b1aec48SLars Fredriksen SIGTYPE sigterm __P((int signo)); 1389b1aec48SLars Fredriksen SIGTYPE sighup __P((int signo)); 1399b1aec48SLars Fredriksen void unalarm __P((void)); 1409b1aec48SLars Fredriksen void init __P((void)); 1419b1aec48SLars Fredriksen void set_tty_parameters __P((void)); 1429b1aec48SLars Fredriksen void break_sequence __P((void)); 1439b1aec48SLars Fredriksen void terminate __P((int status)); 1449b1aec48SLars Fredriksen void do_file __P((char *chat_file)); 1459b1aec48SLars Fredriksen int get_string __P((register char *string)); 1469b1aec48SLars Fredriksen int put_string __P((register char *s)); 1479b1aec48SLars Fredriksen int write_char __P((int c)); 1489f65f104SPeter Wemm int put_char __P((int c)); 1499b1aec48SLars Fredriksen int get_char __P((void)); 1509b1aec48SLars Fredriksen void chat_send __P((register char *s)); 1519f65f104SPeter Wemm char *character __P((int c)); 1529b1aec48SLars Fredriksen void chat_expect __P((register char *s)); 1539b1aec48SLars Fredriksen char *clean __P((register char *s, int sending)); 1549b1aec48SLars Fredriksen void break_sequence __P((void)); 1559b1aec48SLars Fredriksen void terminate __P((int status)); 1569b1aec48SLars Fredriksen void die __P((void)); 1579b1aec48SLars Fredriksen 1589b1aec48SLars Fredriksen void *dup_mem(b, c) 1599b1aec48SLars Fredriksen void *b; 1609b1aec48SLars Fredriksen size_t c; 1619b1aec48SLars Fredriksen { 1629b1aec48SLars Fredriksen void *ans = malloc (c); 1639b1aec48SLars Fredriksen if (!ans) 1649f65f104SPeter Wemm { 1659b1aec48SLars Fredriksen fatal ("memory error!\n"); 1669f65f104SPeter Wemm } 1679b1aec48SLars Fredriksen memcpy (ans, b, c); 1689b1aec48SLars Fredriksen return ans; 1699b1aec48SLars Fredriksen } 1709b1aec48SLars Fredriksen 1719b1aec48SLars Fredriksen void *copy_of (s) 1729b1aec48SLars Fredriksen char *s; 1739b1aec48SLars Fredriksen { 1749b1aec48SLars Fredriksen return dup_mem (s, strlen (s) + 1); 1759b1aec48SLars Fredriksen } 1769b1aec48SLars Fredriksen 1779b1aec48SLars Fredriksen /* 1789f65f104SPeter Wemm * chat [ -v ] [ -t timeout ] [ -f chat-file ] [ -r report-file ] \ 1799b1aec48SLars Fredriksen * [...[[expect[-say[-expect...]] say expect[-say[-expect]] ...]]] 1809b1aec48SLars Fredriksen * 1819b1aec48SLars Fredriksen * Perform a UUCP-dialer-like chat script on stdin and stdout. 1829b1aec48SLars Fredriksen */ 1839b1aec48SLars Fredriksen int 1849b1aec48SLars Fredriksen main(argc, argv) 1859b1aec48SLars Fredriksen int argc; 1869b1aec48SLars Fredriksen char **argv; 1879b1aec48SLars Fredriksen { 1889b1aec48SLars Fredriksen int option; 1899b1aec48SLars Fredriksen char *arg; 1909b1aec48SLars Fredriksen 1919b1aec48SLars Fredriksen program_name = *argv; 1929f65f104SPeter Wemm tzset(); 1939b1aec48SLars Fredriksen 1949b1aec48SLars Fredriksen while (option = OPTION(argc, argv)) 1959f65f104SPeter Wemm { 1969b1aec48SLars Fredriksen switch (option) 1979b1aec48SLars Fredriksen { 1989b1aec48SLars Fredriksen case 'v': 1999b1aec48SLars Fredriksen ++verbose; 2009b1aec48SLars Fredriksen break; 2019b1aec48SLars Fredriksen 2029b1aec48SLars Fredriksen case 'f': 2039b1aec48SLars Fredriksen if (arg = OPTARG(argc, argv)) 2049f65f104SPeter Wemm { 2059b1aec48SLars Fredriksen chat_file = copy_of(arg); 2069f65f104SPeter Wemm } 2079b1aec48SLars Fredriksen else 2089f65f104SPeter Wemm { 2099b1aec48SLars Fredriksen usage(); 2109f65f104SPeter Wemm } 2119b1aec48SLars Fredriksen break; 2129b1aec48SLars Fredriksen 2139b1aec48SLars Fredriksen case 't': 2149b1aec48SLars Fredriksen if (arg = OPTARG(argc, argv)) 2159f65f104SPeter Wemm { 2169b1aec48SLars Fredriksen timeout = atoi(arg); 2179f65f104SPeter Wemm } 2189b1aec48SLars Fredriksen else 2199f65f104SPeter Wemm { 2209b1aec48SLars Fredriksen usage(); 2219f65f104SPeter Wemm } 2229f65f104SPeter Wemm break; 2239b1aec48SLars Fredriksen 2249f65f104SPeter Wemm case 'r': 2259f65f104SPeter Wemm arg = OPTARG (argc, argv); 2269f65f104SPeter Wemm if (arg) 2279f65f104SPeter Wemm { 2289f65f104SPeter Wemm if (report_fp != NULL) 2299f65f104SPeter Wemm { 2309f65f104SPeter Wemm fclose (report_fp); 2319f65f104SPeter Wemm } 2329f65f104SPeter Wemm report_file = copy_of (arg); 2339f65f104SPeter Wemm report_fp = fopen (report_file, "a"); 2349f65f104SPeter Wemm if (report_fp != NULL) 2359f65f104SPeter Wemm { 2369f65f104SPeter Wemm if (verbose) 2379f65f104SPeter Wemm { 2389f65f104SPeter Wemm fprintf (report_fp, "Opening \"%s\"...\n", 2399f65f104SPeter Wemm report_file); 2409f65f104SPeter Wemm } 2419f65f104SPeter Wemm report = 1; 2429f65f104SPeter Wemm } 2439f65f104SPeter Wemm } 2449b1aec48SLars Fredriksen break; 2459b1aec48SLars Fredriksen 2469b1aec48SLars Fredriksen default: 2479b1aec48SLars Fredriksen usage(); 2489f65f104SPeter Wemm break; 2499f65f104SPeter Wemm } 2509f65f104SPeter Wemm } 2519f65f104SPeter Wemm /* 2529f65f104SPeter Wemm * Default the report file to the stderr location 2539f65f104SPeter Wemm */ 2549f65f104SPeter Wemm if (report_fp == NULL) 2559f65f104SPeter Wemm { 2569f65f104SPeter Wemm report_fp = stderr; 2579b1aec48SLars Fredriksen } 2589b1aec48SLars Fredriksen 2599b1aec48SLars Fredriksen #ifdef ultrix 2609b1aec48SLars Fredriksen openlog("chat", LOG_PID); 2619b1aec48SLars Fredriksen #else 2629b1aec48SLars Fredriksen openlog("chat", LOG_PID | LOG_NDELAY, LOG_LOCAL2); 2639b1aec48SLars Fredriksen 2649f65f104SPeter Wemm if (verbose) 2659f65f104SPeter Wemm { 2669b1aec48SLars Fredriksen setlogmask(LOG_UPTO(LOG_INFO)); 2679f65f104SPeter Wemm } 2689f65f104SPeter Wemm else 2699f65f104SPeter Wemm { 2709b1aec48SLars Fredriksen setlogmask(LOG_UPTO(LOG_WARNING)); 2719b1aec48SLars Fredriksen } 2729b1aec48SLars Fredriksen #endif 2739b1aec48SLars Fredriksen 2749b1aec48SLars Fredriksen init(); 2759b1aec48SLars Fredriksen 2769b1aec48SLars Fredriksen if (chat_file != NULL) 2779b1aec48SLars Fredriksen { 2789b1aec48SLars Fredriksen arg = ARG(argc, argv); 2799b1aec48SLars Fredriksen if (arg != NULL) 2809f65f104SPeter Wemm { 2819b1aec48SLars Fredriksen usage(); 2829f65f104SPeter Wemm } 2839b1aec48SLars Fredriksen else 2849f65f104SPeter Wemm { 2859b1aec48SLars Fredriksen do_file (chat_file); 2869b1aec48SLars Fredriksen } 2879f65f104SPeter Wemm } 2889b1aec48SLars Fredriksen else 2899b1aec48SLars Fredriksen { 2909b1aec48SLars Fredriksen while (arg = ARG(argc, argv)) 2919b1aec48SLars Fredriksen { 2929b1aec48SLars Fredriksen chat_expect(arg); 2939b1aec48SLars Fredriksen 2949b1aec48SLars Fredriksen if (arg = ARG(argc, argv)) 2959f65f104SPeter Wemm { 2969b1aec48SLars Fredriksen chat_send(arg); 2979b1aec48SLars Fredriksen } 2989b1aec48SLars Fredriksen } 2999f65f104SPeter Wemm } 3009b1aec48SLars Fredriksen 3019b1aec48SLars Fredriksen terminate(0); 3029b1aec48SLars Fredriksen } 3039b1aec48SLars Fredriksen 3049b1aec48SLars Fredriksen /* 3059b1aec48SLars Fredriksen * Process a chat script when read from a file. 3069b1aec48SLars Fredriksen */ 3079b1aec48SLars Fredriksen 3089b1aec48SLars Fredriksen void do_file (chat_file) 3099b1aec48SLars Fredriksen char *chat_file; 3109b1aec48SLars Fredriksen { 3119b1aec48SLars Fredriksen int linect, len, sendflg; 3129b1aec48SLars Fredriksen char *sp, *arg, quote; 3139b1aec48SLars Fredriksen char buf [STR_LEN]; 3149b1aec48SLars Fredriksen FILE *cfp; 3159b1aec48SLars Fredriksen 3169f65f104SPeter Wemm cfp = fopen (chat_file, "r"); 3179f65f104SPeter Wemm if (cfp == NULL) 3189b1aec48SLars Fredriksen { 3199b1aec48SLars Fredriksen syslog (LOG_ERR, "%s -- open failed: %m", chat_file); 3209b1aec48SLars Fredriksen terminate (1); 3219b1aec48SLars Fredriksen } 3229b1aec48SLars Fredriksen 3239b1aec48SLars Fredriksen linect = 0; 3249b1aec48SLars Fredriksen sendflg = 0; 3259b1aec48SLars Fredriksen 3269b1aec48SLars Fredriksen while (fgets(buf, STR_LEN, cfp) != NULL) 3279b1aec48SLars Fredriksen { 3289b1aec48SLars Fredriksen sp = strchr (buf, '\n'); 3299b1aec48SLars Fredriksen if (sp) 3309f65f104SPeter Wemm { 3319b1aec48SLars Fredriksen *sp = '\0'; 3329f65f104SPeter Wemm } 3339b1aec48SLars Fredriksen 3349b1aec48SLars Fredriksen linect++; 3359b1aec48SLars Fredriksen sp = buf; 3369b1aec48SLars Fredriksen while (*sp != '\0') 3379b1aec48SLars Fredriksen { 3389b1aec48SLars Fredriksen if (*sp == ' ' || *sp == '\t') 3399b1aec48SLars Fredriksen { 3409b1aec48SLars Fredriksen ++sp; 3419b1aec48SLars Fredriksen continue; 3429b1aec48SLars Fredriksen } 3439b1aec48SLars Fredriksen 3449b1aec48SLars Fredriksen if (*sp == '"' || *sp == '\'') 3459b1aec48SLars Fredriksen { 3469b1aec48SLars Fredriksen quote = *sp++; 3479b1aec48SLars Fredriksen arg = sp; 3489b1aec48SLars Fredriksen while (*sp != quote) 3499b1aec48SLars Fredriksen { 3509b1aec48SLars Fredriksen if (*sp == '\0') 3519b1aec48SLars Fredriksen { 3529b1aec48SLars Fredriksen syslog (LOG_ERR, "unterminated quote (line %d)", 3539b1aec48SLars Fredriksen linect); 3549b1aec48SLars Fredriksen terminate (1); 3559b1aec48SLars Fredriksen } 3569b1aec48SLars Fredriksen 3579b1aec48SLars Fredriksen if (*sp++ == '\\') 3589f65f104SPeter Wemm { 3599b1aec48SLars Fredriksen if (*sp != '\0') 3609f65f104SPeter Wemm { 3619b1aec48SLars Fredriksen ++sp; 3629b1aec48SLars Fredriksen } 3639b1aec48SLars Fredriksen } 3649f65f104SPeter Wemm } 3659f65f104SPeter Wemm } 3669b1aec48SLars Fredriksen else 3679b1aec48SLars Fredriksen { 3689b1aec48SLars Fredriksen arg = sp; 3699b1aec48SLars Fredriksen while (*sp != '\0' && *sp != ' ' && *sp != '\t') 3709f65f104SPeter Wemm { 3719b1aec48SLars Fredriksen ++sp; 3729b1aec48SLars Fredriksen } 3739f65f104SPeter Wemm } 3749b1aec48SLars Fredriksen 3759b1aec48SLars Fredriksen if (*sp != '\0') 3769f65f104SPeter Wemm { 3779b1aec48SLars Fredriksen *sp++ = '\0'; 3789f65f104SPeter Wemm } 3799b1aec48SLars Fredriksen 3809b1aec48SLars Fredriksen if (sendflg) 3819b1aec48SLars Fredriksen { 3829b1aec48SLars Fredriksen chat_send (arg); 3839b1aec48SLars Fredriksen } 3849b1aec48SLars Fredriksen else 3859b1aec48SLars Fredriksen { 3869b1aec48SLars Fredriksen chat_expect (arg); 3879b1aec48SLars Fredriksen } 3889b1aec48SLars Fredriksen sendflg = !sendflg; 3899b1aec48SLars Fredriksen } 3909b1aec48SLars Fredriksen } 3919b1aec48SLars Fredriksen fclose (cfp); 3929b1aec48SLars Fredriksen } 3939b1aec48SLars Fredriksen 3949b1aec48SLars Fredriksen /* 3959b1aec48SLars Fredriksen * We got an error parsing the command line. 3969b1aec48SLars Fredriksen */ 3979b1aec48SLars Fredriksen void usage() 3989b1aec48SLars Fredriksen { 3999b1aec48SLars Fredriksen fprintf(stderr, "\ 4009f65f104SPeter Wemm Usage: %s [-v] [-t timeout] [-r report-file] {-f chat-file | chat-script}\n", 4019b1aec48SLars Fredriksen program_name); 4029b1aec48SLars Fredriksen exit(1); 4039b1aec48SLars Fredriksen } 4049b1aec48SLars Fredriksen 4059b1aec48SLars Fredriksen char line[256]; 4069b1aec48SLars Fredriksen char *p; 4079b1aec48SLars Fredriksen 4089b1aec48SLars Fredriksen void logf (str) 4099b1aec48SLars Fredriksen const char *str; 4109b1aec48SLars Fredriksen { 4119b1aec48SLars Fredriksen p = line + strlen(line); 4129b1aec48SLars Fredriksen strcat (p, str); 4139b1aec48SLars Fredriksen 4149b1aec48SLars Fredriksen if (str[strlen(str)-1] == '\n') 4159b1aec48SLars Fredriksen { 4169b1aec48SLars Fredriksen syslog (LOG_INFO, "%s", line); 4179b1aec48SLars Fredriksen line[0] = 0; 4189b1aec48SLars Fredriksen } 4199b1aec48SLars Fredriksen } 4209b1aec48SLars Fredriksen 4219b1aec48SLars Fredriksen void logflush() 4229b1aec48SLars Fredriksen { 4239b1aec48SLars Fredriksen if (line[0] != 0) 4249b1aec48SLars Fredriksen { 4259b1aec48SLars Fredriksen syslog(LOG_INFO, "%s", line); 4269b1aec48SLars Fredriksen line[0] = 0; 4279b1aec48SLars Fredriksen } 4289b1aec48SLars Fredriksen } 4299b1aec48SLars Fredriksen 4309b1aec48SLars Fredriksen /* 4319f65f104SPeter Wemm * Terminate with an error. 4329b1aec48SLars Fredriksen */ 4339b1aec48SLars Fredriksen void die() 4349b1aec48SLars Fredriksen { 4359b1aec48SLars Fredriksen terminate(1); 4369b1aec48SLars Fredriksen } 4379b1aec48SLars Fredriksen 4389b1aec48SLars Fredriksen /* 4399b1aec48SLars Fredriksen * Print an error message and terminate. 4409b1aec48SLars Fredriksen */ 4419b1aec48SLars Fredriksen 4429b1aec48SLars Fredriksen void fatal (msg) 4439b1aec48SLars Fredriksen const char *msg; 4449b1aec48SLars Fredriksen { 4459b1aec48SLars Fredriksen syslog(LOG_ERR, "%s", msg); 4469f65f104SPeter Wemm terminate(2); 4479b1aec48SLars Fredriksen } 4489b1aec48SLars Fredriksen 4499b1aec48SLars Fredriksen /* 4509b1aec48SLars Fredriksen * Print an error message along with the system error message and 4519b1aec48SLars Fredriksen * terminate. 4529b1aec48SLars Fredriksen */ 4539b1aec48SLars Fredriksen 4549b1aec48SLars Fredriksen void sysfatal (msg) 4559b1aec48SLars Fredriksen const char *msg; 4569b1aec48SLars Fredriksen { 4579b1aec48SLars Fredriksen syslog(LOG_ERR, "%s: %m", msg); 4589f65f104SPeter Wemm terminate(2); 4599b1aec48SLars Fredriksen } 4609b1aec48SLars Fredriksen 4619b1aec48SLars Fredriksen int alarmed = 0; 4629b1aec48SLars Fredriksen 4639b1aec48SLars Fredriksen SIGTYPE sigalrm(signo) 4649b1aec48SLars Fredriksen int signo; 4659b1aec48SLars Fredriksen { 4669b1aec48SLars Fredriksen int flags; 4679b1aec48SLars Fredriksen 4689b1aec48SLars Fredriksen alarm(1); 4699b1aec48SLars Fredriksen alarmed = 1; /* Reset alarm to avoid race window */ 4709b1aec48SLars Fredriksen signal(SIGALRM, sigalrm); /* that can cause hanging in read() */ 4719b1aec48SLars Fredriksen 4729b1aec48SLars Fredriksen logflush(); 4739b1aec48SLars Fredriksen if ((flags = fcntl(0, F_GETFL, 0)) == -1) 4749f65f104SPeter Wemm { 4759b1aec48SLars Fredriksen sysfatal("Can't get file mode flags on stdin"); 4769f65f104SPeter Wemm } 4779b1aec48SLars Fredriksen else 4789f65f104SPeter Wemm { 4799f65f104SPeter Wemm if (fcntl(0, F_SETFL, flags | O_NONBLOCK) == -1) 4809f65f104SPeter Wemm { 4819b1aec48SLars Fredriksen sysfatal("Can't set file mode flags on stdin"); 4829f65f104SPeter Wemm } 4839f65f104SPeter Wemm } 4849b1aec48SLars Fredriksen 4859b1aec48SLars Fredriksen if (verbose) 4869b1aec48SLars Fredriksen { 4879b1aec48SLars Fredriksen syslog(LOG_INFO, "alarm"); 4889b1aec48SLars Fredriksen } 4899b1aec48SLars Fredriksen } 4909b1aec48SLars Fredriksen 4919b1aec48SLars Fredriksen void unalarm() 4929b1aec48SLars Fredriksen { 4939b1aec48SLars Fredriksen int flags; 4949b1aec48SLars Fredriksen 4959b1aec48SLars Fredriksen if ((flags = fcntl(0, F_GETFL, 0)) == -1) 4969f65f104SPeter Wemm { 4979b1aec48SLars Fredriksen sysfatal("Can't get file mode flags on stdin"); 4989f65f104SPeter Wemm } 4999b1aec48SLars Fredriksen else 5009f65f104SPeter Wemm { 5019f65f104SPeter Wemm if (fcntl(0, F_SETFL, flags & ~O_NONBLOCK) == -1) 5029f65f104SPeter Wemm { 5039b1aec48SLars Fredriksen sysfatal("Can't set file mode flags on stdin"); 5049b1aec48SLars Fredriksen } 5059f65f104SPeter Wemm } 5069f65f104SPeter Wemm } 5079b1aec48SLars Fredriksen 5089b1aec48SLars Fredriksen SIGTYPE sigint(signo) 5099b1aec48SLars Fredriksen int signo; 5109b1aec48SLars Fredriksen { 5119b1aec48SLars Fredriksen fatal("SIGINT"); 5129b1aec48SLars Fredriksen } 5139b1aec48SLars Fredriksen 5149b1aec48SLars Fredriksen SIGTYPE sigterm(signo) 5159b1aec48SLars Fredriksen int signo; 5169b1aec48SLars Fredriksen { 5179b1aec48SLars Fredriksen fatal("SIGTERM"); 5189b1aec48SLars Fredriksen } 5199b1aec48SLars Fredriksen 5209b1aec48SLars Fredriksen SIGTYPE sighup(signo) 5219b1aec48SLars Fredriksen int signo; 5229b1aec48SLars Fredriksen { 5239b1aec48SLars Fredriksen fatal("SIGHUP"); 5249b1aec48SLars Fredriksen } 5259b1aec48SLars Fredriksen 5269b1aec48SLars Fredriksen void init() 5279b1aec48SLars Fredriksen { 5289b1aec48SLars Fredriksen signal(SIGINT, sigint); 5299b1aec48SLars Fredriksen signal(SIGTERM, sigterm); 5309b1aec48SLars Fredriksen signal(SIGHUP, sighup); 5319b1aec48SLars Fredriksen 5329b1aec48SLars Fredriksen set_tty_parameters(); 5339b1aec48SLars Fredriksen signal(SIGALRM, sigalrm); 5349b1aec48SLars Fredriksen alarm(0); 5359b1aec48SLars Fredriksen alarmed = 0; 5369b1aec48SLars Fredriksen } 5379b1aec48SLars Fredriksen 5389b1aec48SLars Fredriksen void set_tty_parameters() 5399b1aec48SLars Fredriksen { 5409f65f104SPeter Wemm #if defined(get_term_param) 5419f65f104SPeter Wemm term_parms t; 5429b1aec48SLars Fredriksen 5439f65f104SPeter Wemm if (get_term_param (&t) < 0) 5449f65f104SPeter Wemm { 5459b1aec48SLars Fredriksen sysfatal("Can't get terminal parameters"); 5469f65f104SPeter Wemm } 5479b1aec48SLars Fredriksen 5489b1aec48SLars Fredriksen saved_tty_parameters = t; 5499b1aec48SLars Fredriksen have_tty_parameters = 1; 5509b1aec48SLars Fredriksen 5519b1aec48SLars Fredriksen t.c_iflag |= IGNBRK | ISTRIP | IGNPAR; 5529b1aec48SLars Fredriksen t.c_oflag = 0; 5539b1aec48SLars Fredriksen t.c_lflag = 0; 5549f65f104SPeter Wemm t.c_cc[VERASE] = 5559f65f104SPeter Wemm t.c_cc[VKILL] = 0; 5569b1aec48SLars Fredriksen t.c_cc[VMIN] = 1; 5579b1aec48SLars Fredriksen t.c_cc[VTIME] = 0; 5589b1aec48SLars Fredriksen 5599f65f104SPeter Wemm if (set_term_param (&t) < 0) 5609f65f104SPeter Wemm { 5619b1aec48SLars Fredriksen sysfatal("Can't set terminal parameters"); 5629f65f104SPeter Wemm } 5639b1aec48SLars Fredriksen #endif 5649b1aec48SLars Fredriksen } 5659b1aec48SLars Fredriksen 5669b1aec48SLars Fredriksen void break_sequence() 5679b1aec48SLars Fredriksen { 5689b1aec48SLars Fredriksen #ifdef TERMIOS 5699b1aec48SLars Fredriksen tcsendbreak (0, 0); 5709b1aec48SLars Fredriksen #endif 5719b1aec48SLars Fredriksen } 5729b1aec48SLars Fredriksen 5739b1aec48SLars Fredriksen void terminate(status) 5749b1aec48SLars Fredriksen int status; 5759b1aec48SLars Fredriksen { 5769f65f104SPeter Wemm if (report_file != (char *) 0 && report_fp != (FILE *) NULL) 5779f65f104SPeter Wemm { 5789f65f104SPeter Wemm if (verbose) 5799f65f104SPeter Wemm { 5809f65f104SPeter Wemm fprintf (report_fp, "Closing \"%s\".\n", report_file); 5819f65f104SPeter Wemm } 5829f65f104SPeter Wemm fclose (report_fp); 5839f65f104SPeter Wemm report_fp = (FILE*) NULL; 5849f65f104SPeter Wemm } 5859f65f104SPeter Wemm 5869f65f104SPeter Wemm #if defined(get_term_param) 5879f65f104SPeter Wemm if (have_tty_parameters) 5889f65f104SPeter Wemm { 5899f65f104SPeter Wemm if (set_term_param (&saved_tty_parameters) < 0) 5909f65f104SPeter Wemm { 5919b1aec48SLars Fredriksen syslog(LOG_ERR, "Can't restore terminal parameters: %m"); 5929b1aec48SLars Fredriksen exit(1); 5939b1aec48SLars Fredriksen } 5949f65f104SPeter Wemm } 5959f65f104SPeter Wemm #endif 5969f65f104SPeter Wemm 5979b1aec48SLars Fredriksen exit(status); 5989b1aec48SLars Fredriksen } 5999b1aec48SLars Fredriksen 6009b1aec48SLars Fredriksen /* 6019b1aec48SLars Fredriksen * 'Clean up' this string. 6029b1aec48SLars Fredriksen */ 6039b1aec48SLars Fredriksen char *clean(s, sending) 6049b1aec48SLars Fredriksen register char *s; 6059b1aec48SLars Fredriksen int sending; 6069b1aec48SLars Fredriksen { 6079b1aec48SLars Fredriksen char temp[STR_LEN], cur_chr; 6089b1aec48SLars Fredriksen register char *s1; 6099b1aec48SLars Fredriksen int add_return = sending; 6109b1aec48SLars Fredriksen #define isoctal(chr) (((chr) >= '0') && ((chr) <= '7')) 6119b1aec48SLars Fredriksen 6129b1aec48SLars Fredriksen s1 = temp; 6139b1aec48SLars Fredriksen while (*s) 6149b1aec48SLars Fredriksen { 6159b1aec48SLars Fredriksen cur_chr = *s++; 6169b1aec48SLars Fredriksen if (cur_chr == '^') 6179b1aec48SLars Fredriksen { 6189b1aec48SLars Fredriksen cur_chr = *s++; 6199b1aec48SLars Fredriksen if (cur_chr == '\0') 6209b1aec48SLars Fredriksen { 6219b1aec48SLars Fredriksen *s1++ = '^'; 6229b1aec48SLars Fredriksen break; 6239b1aec48SLars Fredriksen } 6249b1aec48SLars Fredriksen cur_chr &= 0x1F; 6259b1aec48SLars Fredriksen if (cur_chr != 0) 6269f65f104SPeter Wemm { 6279b1aec48SLars Fredriksen *s1++ = cur_chr; 6289f65f104SPeter Wemm } 6299b1aec48SLars Fredriksen continue; 6309b1aec48SLars Fredriksen } 6319b1aec48SLars Fredriksen 6329b1aec48SLars Fredriksen if (cur_chr != '\\') 6339b1aec48SLars Fredriksen { 6349b1aec48SLars Fredriksen *s1++ = cur_chr; 6359b1aec48SLars Fredriksen continue; 6369b1aec48SLars Fredriksen } 6379b1aec48SLars Fredriksen 6389b1aec48SLars Fredriksen cur_chr = *s++; 6399b1aec48SLars Fredriksen if (cur_chr == '\0') 6409b1aec48SLars Fredriksen { 6419b1aec48SLars Fredriksen if (sending) 6429b1aec48SLars Fredriksen { 6439b1aec48SLars Fredriksen *s1++ = '\\'; 6449b1aec48SLars Fredriksen *s1++ = '\\'; 6459b1aec48SLars Fredriksen } 6469b1aec48SLars Fredriksen break; 6479b1aec48SLars Fredriksen } 6489b1aec48SLars Fredriksen 6499b1aec48SLars Fredriksen switch (cur_chr) 6509b1aec48SLars Fredriksen { 6519b1aec48SLars Fredriksen case 'b': 6529b1aec48SLars Fredriksen *s1++ = '\b'; 6539b1aec48SLars Fredriksen break; 6549b1aec48SLars Fredriksen 6559b1aec48SLars Fredriksen case 'c': 6569b1aec48SLars Fredriksen if (sending && *s == '\0') 6579f65f104SPeter Wemm { 6589b1aec48SLars Fredriksen add_return = 0; 6599f65f104SPeter Wemm } 6609b1aec48SLars Fredriksen else 6619f65f104SPeter Wemm { 6629b1aec48SLars Fredriksen *s1++ = cur_chr; 6639f65f104SPeter Wemm } 6649b1aec48SLars Fredriksen break; 6659b1aec48SLars Fredriksen 6669b1aec48SLars Fredriksen case '\\': 6679b1aec48SLars Fredriksen case 'K': 6689b1aec48SLars Fredriksen case 'p': 6699b1aec48SLars Fredriksen case 'd': 6709b1aec48SLars Fredriksen if (sending) 6719f65f104SPeter Wemm { 6729b1aec48SLars Fredriksen *s1++ = '\\'; 6739f65f104SPeter Wemm } 6749b1aec48SLars Fredriksen 6759b1aec48SLars Fredriksen *s1++ = cur_chr; 6769b1aec48SLars Fredriksen break; 6779b1aec48SLars Fredriksen 6789b1aec48SLars Fredriksen case 'q': 6799b1aec48SLars Fredriksen quiet = ! quiet; 6809b1aec48SLars Fredriksen break; 6819b1aec48SLars Fredriksen 6829b1aec48SLars Fredriksen case 'r': 6839b1aec48SLars Fredriksen *s1++ = '\r'; 6849b1aec48SLars Fredriksen break; 6859b1aec48SLars Fredriksen 6869b1aec48SLars Fredriksen case 'n': 6879b1aec48SLars Fredriksen *s1++ = '\n'; 6889b1aec48SLars Fredriksen break; 6899b1aec48SLars Fredriksen 6909b1aec48SLars Fredriksen case 's': 6919b1aec48SLars Fredriksen *s1++ = ' '; 6929b1aec48SLars Fredriksen break; 6939b1aec48SLars Fredriksen 6949b1aec48SLars Fredriksen case 't': 6959b1aec48SLars Fredriksen *s1++ = '\t'; 6969b1aec48SLars Fredriksen break; 6979b1aec48SLars Fredriksen 6989b1aec48SLars Fredriksen case 'N': 6999b1aec48SLars Fredriksen if (sending) 7009b1aec48SLars Fredriksen { 7019b1aec48SLars Fredriksen *s1++ = '\\'; 7029b1aec48SLars Fredriksen *s1++ = '\0'; 7039b1aec48SLars Fredriksen } 7049b1aec48SLars Fredriksen else 7059f65f104SPeter Wemm { 7069b1aec48SLars Fredriksen *s1++ = 'N'; 7079f65f104SPeter Wemm } 7089b1aec48SLars Fredriksen break; 7099b1aec48SLars Fredriksen 7109b1aec48SLars Fredriksen default: 7119b1aec48SLars Fredriksen if (isoctal (cur_chr)) 7129b1aec48SLars Fredriksen { 7139b1aec48SLars Fredriksen cur_chr &= 0x07; 7149b1aec48SLars Fredriksen if (isoctal (*s)) 7159b1aec48SLars Fredriksen { 7169b1aec48SLars Fredriksen cur_chr <<= 3; 7179b1aec48SLars Fredriksen cur_chr |= *s++ - '0'; 7189b1aec48SLars Fredriksen if (isoctal (*s)) 7199b1aec48SLars Fredriksen { 7209b1aec48SLars Fredriksen cur_chr <<= 3; 7219b1aec48SLars Fredriksen cur_chr |= *s++ - '0'; 7229b1aec48SLars Fredriksen } 7239b1aec48SLars Fredriksen } 7249b1aec48SLars Fredriksen 7259b1aec48SLars Fredriksen if (cur_chr != 0 || sending) 7269b1aec48SLars Fredriksen { 7279b1aec48SLars Fredriksen if (sending && (cur_chr == '\\' || cur_chr == 0)) 7289f65f104SPeter Wemm { 7299b1aec48SLars Fredriksen *s1++ = '\\'; 7309f65f104SPeter Wemm } 7319b1aec48SLars Fredriksen *s1++ = cur_chr; 7329b1aec48SLars Fredriksen } 7339b1aec48SLars Fredriksen break; 7349b1aec48SLars Fredriksen } 7359b1aec48SLars Fredriksen 7369b1aec48SLars Fredriksen if (sending) 7379f65f104SPeter Wemm { 7389b1aec48SLars Fredriksen *s1++ = '\\'; 7399f65f104SPeter Wemm } 7409b1aec48SLars Fredriksen *s1++ = cur_chr; 7419b1aec48SLars Fredriksen break; 7429b1aec48SLars Fredriksen } 7439b1aec48SLars Fredriksen } 7449b1aec48SLars Fredriksen 7459b1aec48SLars Fredriksen if (add_return) 7469f65f104SPeter Wemm { 7479b1aec48SLars Fredriksen *s1++ = '\r'; 7489f65f104SPeter Wemm } 7499b1aec48SLars Fredriksen 7509b1aec48SLars Fredriksen *s1++ = '\0'; /* guarantee closure */ 7519b1aec48SLars Fredriksen *s1++ = '\0'; /* terminate the string */ 7529b1aec48SLars Fredriksen return dup_mem (temp, (size_t) (s1 - temp)); /* may have embedded nuls */ 7539b1aec48SLars Fredriksen } 7549b1aec48SLars Fredriksen 7559b1aec48SLars Fredriksen /* 7569b1aec48SLars Fredriksen * Process the expect string 7579b1aec48SLars Fredriksen */ 7589b1aec48SLars Fredriksen void chat_expect(s) 7599b1aec48SLars Fredriksen register char *s; 7609b1aec48SLars Fredriksen { 7619b1aec48SLars Fredriksen if (strcmp(s, "ABORT") == 0) 7629b1aec48SLars Fredriksen { 7639b1aec48SLars Fredriksen ++abort_next; 7649b1aec48SLars Fredriksen return; 7659b1aec48SLars Fredriksen } 7669b1aec48SLars Fredriksen 7679f65f104SPeter Wemm if (strcmp(s, "REPORT") == 0) 7689f65f104SPeter Wemm { 7699f65f104SPeter Wemm ++report_next; 7709f65f104SPeter Wemm return; 7719f65f104SPeter Wemm } 7729f65f104SPeter Wemm 7739b1aec48SLars Fredriksen if (strcmp(s, "TIMEOUT") == 0) 7749b1aec48SLars Fredriksen { 7759b1aec48SLars Fredriksen ++timeout_next; 7769b1aec48SLars Fredriksen return; 7779b1aec48SLars Fredriksen } 7789b1aec48SLars Fredriksen 7799b1aec48SLars Fredriksen while (*s) 7809b1aec48SLars Fredriksen { 7819b1aec48SLars Fredriksen register char *hyphen; 7829b1aec48SLars Fredriksen 7839b1aec48SLars Fredriksen for (hyphen = s; *hyphen; ++hyphen) 7849f65f104SPeter Wemm { 7859b1aec48SLars Fredriksen if (*hyphen == '-') 7869f65f104SPeter Wemm { 7879b1aec48SLars Fredriksen if (hyphen == s || hyphen[-1] != '\\') 7889f65f104SPeter Wemm { 7899b1aec48SLars Fredriksen break; 7909f65f104SPeter Wemm } 7919f65f104SPeter Wemm } 7929f65f104SPeter Wemm } 7939b1aec48SLars Fredriksen 7949b1aec48SLars Fredriksen if (*hyphen == '-') 7959b1aec48SLars Fredriksen { 7969b1aec48SLars Fredriksen *hyphen = '\0'; 7979b1aec48SLars Fredriksen 7989b1aec48SLars Fredriksen if (get_string(s)) 7999f65f104SPeter Wemm { 8009b1aec48SLars Fredriksen return; 8019f65f104SPeter Wemm } 8029b1aec48SLars Fredriksen else 8039b1aec48SLars Fredriksen { 8049b1aec48SLars Fredriksen s = hyphen + 1; 8059b1aec48SLars Fredriksen 8069b1aec48SLars Fredriksen for (hyphen = s; *hyphen; ++hyphen) 8079f65f104SPeter Wemm { 8089b1aec48SLars Fredriksen if (*hyphen == '-') 8099f65f104SPeter Wemm { 8109b1aec48SLars Fredriksen if (hyphen == s || hyphen[-1] != '\\') 8119f65f104SPeter Wemm { 8129b1aec48SLars Fredriksen break; 8139f65f104SPeter Wemm } 8149f65f104SPeter Wemm } 8159f65f104SPeter Wemm } 8169b1aec48SLars Fredriksen 8179b1aec48SLars Fredriksen if (*hyphen == '-') 8189b1aec48SLars Fredriksen { 8199b1aec48SLars Fredriksen *hyphen = '\0'; 8209b1aec48SLars Fredriksen 8219b1aec48SLars Fredriksen chat_send(s); 8229b1aec48SLars Fredriksen s = hyphen + 1; 8239b1aec48SLars Fredriksen } 8249b1aec48SLars Fredriksen else 8259b1aec48SLars Fredriksen { 8269b1aec48SLars Fredriksen chat_send(s); 8279b1aec48SLars Fredriksen return; 8289b1aec48SLars Fredriksen } 8299b1aec48SLars Fredriksen } 8309b1aec48SLars Fredriksen } 8319b1aec48SLars Fredriksen else 8329f65f104SPeter Wemm { 8339b1aec48SLars Fredriksen if (get_string(s)) 8349f65f104SPeter Wemm { 8359b1aec48SLars Fredriksen return; 8369f65f104SPeter Wemm } 8379b1aec48SLars Fredriksen else 8389b1aec48SLars Fredriksen { 8399b1aec48SLars Fredriksen if (fail_reason) 8409f65f104SPeter Wemm { 8419b1aec48SLars Fredriksen syslog(LOG_INFO, "Failed (%s)", fail_reason); 8429f65f104SPeter Wemm } 8439b1aec48SLars Fredriksen else 8449f65f104SPeter Wemm { 8459b1aec48SLars Fredriksen syslog(LOG_INFO, "Failed"); 8469f65f104SPeter Wemm } 8479b1aec48SLars Fredriksen 8489f65f104SPeter Wemm terminate(exit_code); 8499f65f104SPeter Wemm } 8509b1aec48SLars Fredriksen } 8519b1aec48SLars Fredriksen } 8529b1aec48SLars Fredriksen } 8539b1aec48SLars Fredriksen 8549b1aec48SLars Fredriksen char *character(c) 8559f65f104SPeter Wemm int c; 8569b1aec48SLars Fredriksen { 8579b1aec48SLars Fredriksen static char string[10]; 8589b1aec48SLars Fredriksen char *meta; 8599b1aec48SLars Fredriksen 8609b1aec48SLars Fredriksen meta = (c & 0x80) ? "M-" : ""; 8619b1aec48SLars Fredriksen c &= 0x7F; 8629b1aec48SLars Fredriksen 8639b1aec48SLars Fredriksen if (c < 32) 8649f65f104SPeter Wemm { 8659b1aec48SLars Fredriksen sprintf(string, "%s^%c", meta, (int)c + '@'); 8669f65f104SPeter Wemm } 8679b1aec48SLars Fredriksen else 8689f65f104SPeter Wemm { 8699b1aec48SLars Fredriksen if (c == 127) 8709f65f104SPeter Wemm { 8719b1aec48SLars Fredriksen sprintf(string, "%s^?", meta); 8729f65f104SPeter Wemm } 8739b1aec48SLars Fredriksen else 8749f65f104SPeter Wemm { 8759b1aec48SLars Fredriksen sprintf(string, "%s%c", meta, c); 8769f65f104SPeter Wemm } 8779f65f104SPeter Wemm } 8789b1aec48SLars Fredriksen 8799b1aec48SLars Fredriksen return (string); 8809b1aec48SLars Fredriksen } 8819b1aec48SLars Fredriksen 8829b1aec48SLars Fredriksen /* 8839b1aec48SLars Fredriksen * process the reply string 8849b1aec48SLars Fredriksen */ 8859b1aec48SLars Fredriksen void chat_send (s) 8869b1aec48SLars Fredriksen register char *s; 8879b1aec48SLars Fredriksen { 8889b1aec48SLars Fredriksen if (abort_next) 8899b1aec48SLars Fredriksen { 8909b1aec48SLars Fredriksen char *s1; 8919b1aec48SLars Fredriksen 8929b1aec48SLars Fredriksen abort_next = 0; 8939b1aec48SLars Fredriksen 8949b1aec48SLars Fredriksen if (n_aborts >= MAX_ABORTS) 8959f65f104SPeter Wemm { 8969b1aec48SLars Fredriksen fatal("Too many ABORT strings"); 8979f65f104SPeter Wemm } 8989b1aec48SLars Fredriksen 8999b1aec48SLars Fredriksen s1 = clean(s, 0); 9009b1aec48SLars Fredriksen 9019f65f104SPeter Wemm if (strlen(s1) > strlen(s) 9029f65f104SPeter Wemm || strlen(s1) + 1 > sizeof(fail_buffer)) 9039b1aec48SLars Fredriksen { 9049b1aec48SLars Fredriksen syslog(LOG_WARNING, "Illegal or too-long ABORT string ('%s')", s); 9059b1aec48SLars Fredriksen die(); 9069b1aec48SLars Fredriksen } 9079b1aec48SLars Fredriksen 9089b1aec48SLars Fredriksen abort_string[n_aborts++] = s1; 9099b1aec48SLars Fredriksen 9109b1aec48SLars Fredriksen if (verbose) 9119b1aec48SLars Fredriksen { 9129b1aec48SLars Fredriksen logf("abort on ("); 9139b1aec48SLars Fredriksen 9149b1aec48SLars Fredriksen for (s1 = s; *s1; ++s1) 9159f65f104SPeter Wemm { 9169b1aec48SLars Fredriksen logf(character(*s1)); 9179f65f104SPeter Wemm } 9189b1aec48SLars Fredriksen 9199b1aec48SLars Fredriksen logf(")\n"); 9209b1aec48SLars Fredriksen } 9219f65f104SPeter Wemm return; 9229b1aec48SLars Fredriksen } 9239f65f104SPeter Wemm 9249f65f104SPeter Wemm if (report_next) 9259f65f104SPeter Wemm { 9269f65f104SPeter Wemm char *s1; 9279f65f104SPeter Wemm 9289f65f104SPeter Wemm report_next = 0; 9299f65f104SPeter Wemm if (n_reports >= MAX_REPORTS) 9309f65f104SPeter Wemm { 9319f65f104SPeter Wemm fatal("Too many REPORT strings"); 9329f65f104SPeter Wemm } 9339f65f104SPeter Wemm 9349f65f104SPeter Wemm s1 = clean(s, 0); 9359f65f104SPeter Wemm 9369f65f104SPeter Wemm if (strlen(s1) > strlen(s) || strlen(s1) > sizeof fail_buffer - 1) 9379f65f104SPeter Wemm { 9389f65f104SPeter Wemm syslog(LOG_WARNING, "Illegal or too-long REPORT string ('%s')", s); 9399f65f104SPeter Wemm die(); 9409f65f104SPeter Wemm } 9419f65f104SPeter Wemm 9429f65f104SPeter Wemm report_string[n_reports++] = s1; 9439f65f104SPeter Wemm 9449f65f104SPeter Wemm if (verbose) 9459f65f104SPeter Wemm { 9469f65f104SPeter Wemm logf("report ("); 9479f65f104SPeter Wemm s1 = s; 9489f65f104SPeter Wemm while (*s1) 9499f65f104SPeter Wemm { 9509f65f104SPeter Wemm logf(character(*s1)); 9519f65f104SPeter Wemm ++s1; 9529f65f104SPeter Wemm } 9539f65f104SPeter Wemm logf(")\n"); 9549f65f104SPeter Wemm } 9559f65f104SPeter Wemm return; 9569f65f104SPeter Wemm } 9579f65f104SPeter Wemm 9589b1aec48SLars Fredriksen if (timeout_next) 9599b1aec48SLars Fredriksen { 9609b1aec48SLars Fredriksen timeout_next = 0; 9619b1aec48SLars Fredriksen timeout = atoi(s); 9629b1aec48SLars Fredriksen 9639b1aec48SLars Fredriksen if (timeout <= 0) 9649f65f104SPeter Wemm { 9659b1aec48SLars Fredriksen timeout = DEFAULT_CHAT_TIMEOUT; 9669f65f104SPeter Wemm } 9679b1aec48SLars Fredriksen 9689b1aec48SLars Fredriksen if (verbose) 9699b1aec48SLars Fredriksen { 9709b1aec48SLars Fredriksen syslog(LOG_INFO, "timeout set to %d seconds", timeout); 9719b1aec48SLars Fredriksen } 9729f65f104SPeter Wemm return; 9739f65f104SPeter Wemm } 9749f65f104SPeter Wemm 9759f65f104SPeter Wemm if (strcmp(s, "EOT") == 0) 9769f65f104SPeter Wemm { 9779f65f104SPeter Wemm s = "^D\\c"; 9789b1aec48SLars Fredriksen } 9799b1aec48SLars Fredriksen else 9809b1aec48SLars Fredriksen { 9819b1aec48SLars Fredriksen if (strcmp(s, "BREAK") == 0) 9829f65f104SPeter Wemm { 9839b1aec48SLars Fredriksen s = "\\K\\c"; 9849f65f104SPeter Wemm } 9859f65f104SPeter Wemm } 9869f65f104SPeter Wemm 9879b1aec48SLars Fredriksen if (!put_string(s)) 9889b1aec48SLars Fredriksen { 9899b1aec48SLars Fredriksen syslog(LOG_INFO, "Failed"); 9909b1aec48SLars Fredriksen terminate(1); 9919b1aec48SLars Fredriksen } 9929b1aec48SLars Fredriksen } 9939b1aec48SLars Fredriksen 9949b1aec48SLars Fredriksen int get_char() 9959b1aec48SLars Fredriksen { 9969b1aec48SLars Fredriksen int status; 9979b1aec48SLars Fredriksen char c; 9989b1aec48SLars Fredriksen 9999b1aec48SLars Fredriksen status = read(0, &c, 1); 10009b1aec48SLars Fredriksen 10019b1aec48SLars Fredriksen switch (status) 10029b1aec48SLars Fredriksen { 10039b1aec48SLars Fredriksen case 1: 10049b1aec48SLars Fredriksen return ((int)c & 0x7F); 10059b1aec48SLars Fredriksen 10069b1aec48SLars Fredriksen default: 10079b1aec48SLars Fredriksen syslog(LOG_WARNING, "warning: read() on stdin returned %d", 10089b1aec48SLars Fredriksen status); 10099b1aec48SLars Fredriksen 10109b1aec48SLars Fredriksen case -1: 10119b1aec48SLars Fredriksen if ((status = fcntl(0, F_GETFL, 0)) == -1) 10129f65f104SPeter Wemm { 10139b1aec48SLars Fredriksen sysfatal("Can't get file mode flags on stdin"); 10149f65f104SPeter Wemm } 10159b1aec48SLars Fredriksen else 10169f65f104SPeter Wemm { 10179f65f104SPeter Wemm if (fcntl(0, F_SETFL, status & ~O_NONBLOCK) == -1) 10189f65f104SPeter Wemm { 10199b1aec48SLars Fredriksen sysfatal("Can't set file mode flags on stdin"); 10209f65f104SPeter Wemm } 10219f65f104SPeter Wemm } 10229b1aec48SLars Fredriksen 10239b1aec48SLars Fredriksen return (-1); 10249b1aec48SLars Fredriksen } 10259b1aec48SLars Fredriksen } 10269b1aec48SLars Fredriksen 10279b1aec48SLars Fredriksen int put_char(c) 10289f65f104SPeter Wemm int c; 10299b1aec48SLars Fredriksen { 10309b1aec48SLars Fredriksen int status; 10319f65f104SPeter Wemm char ch = c; 10329b1aec48SLars Fredriksen 10339f65f104SPeter Wemm usleep(10000); /* inter-character typing delay (?) */ 10349b1aec48SLars Fredriksen 10359f65f104SPeter Wemm status = write(1, &ch, 1); 10369b1aec48SLars Fredriksen 10379b1aec48SLars Fredriksen switch (status) 10389b1aec48SLars Fredriksen { 10399b1aec48SLars Fredriksen case 1: 10409b1aec48SLars Fredriksen return (0); 10419b1aec48SLars Fredriksen 10429b1aec48SLars Fredriksen default: 10439b1aec48SLars Fredriksen syslog(LOG_WARNING, "warning: write() on stdout returned %d", 10449b1aec48SLars Fredriksen status); 10459b1aec48SLars Fredriksen 10469b1aec48SLars Fredriksen case -1: 10479b1aec48SLars Fredriksen if ((status = fcntl(0, F_GETFL, 0)) == -1) 10489f65f104SPeter Wemm { 10499b1aec48SLars Fredriksen sysfatal("Can't get file mode flags on stdin"); 10509f65f104SPeter Wemm } 10519b1aec48SLars Fredriksen else 10529f65f104SPeter Wemm { 10539f65f104SPeter Wemm if (fcntl(0, F_SETFL, status & ~O_NONBLOCK) == -1) 10549f65f104SPeter Wemm { 10559b1aec48SLars Fredriksen sysfatal("Can't set file mode flags on stdin"); 10569f65f104SPeter Wemm } 10579f65f104SPeter Wemm } 10589b1aec48SLars Fredriksen 10599b1aec48SLars Fredriksen return (-1); 10609b1aec48SLars Fredriksen } 10619b1aec48SLars Fredriksen } 10629b1aec48SLars Fredriksen 10639b1aec48SLars Fredriksen int write_char (c) 10649b1aec48SLars Fredriksen int c; 10659b1aec48SLars Fredriksen { 10669b1aec48SLars Fredriksen if (alarmed || put_char(c) < 0) 10679b1aec48SLars Fredriksen { 10689b1aec48SLars Fredriksen extern int errno; 10699b1aec48SLars Fredriksen 10709f65f104SPeter Wemm alarm(0); 10719f65f104SPeter Wemm alarmed = 0; 10729b1aec48SLars Fredriksen 10739b1aec48SLars Fredriksen if (verbose) 10749b1aec48SLars Fredriksen { 10759b1aec48SLars Fredriksen if (errno == EINTR || errno == EWOULDBLOCK) 10769f65f104SPeter Wemm { 10779b1aec48SLars Fredriksen syslog(LOG_INFO, " -- write timed out"); 10789f65f104SPeter Wemm } 10799b1aec48SLars Fredriksen else 10809f65f104SPeter Wemm { 10819b1aec48SLars Fredriksen syslog(LOG_INFO, " -- write failed: %m"); 10829b1aec48SLars Fredriksen } 10839f65f104SPeter Wemm } 10849b1aec48SLars Fredriksen return (0); 10859b1aec48SLars Fredriksen } 10869b1aec48SLars Fredriksen return (1); 10879b1aec48SLars Fredriksen } 10889b1aec48SLars Fredriksen 10899b1aec48SLars Fredriksen int put_string (s) 10909b1aec48SLars Fredriksen register char *s; 10919b1aec48SLars Fredriksen { 10929b1aec48SLars Fredriksen s = clean(s, 1); 10939b1aec48SLars Fredriksen 10949b1aec48SLars Fredriksen if (verbose) 10959b1aec48SLars Fredriksen { 10969b1aec48SLars Fredriksen logf("send ("); 10979b1aec48SLars Fredriksen 10989b1aec48SLars Fredriksen if (quiet) 10999f65f104SPeter Wemm { 11009b1aec48SLars Fredriksen logf("??????"); 11019f65f104SPeter Wemm } 11029b1aec48SLars Fredriksen else 11039b1aec48SLars Fredriksen { 11049b1aec48SLars Fredriksen register char *s1 = s; 11059b1aec48SLars Fredriksen 11069b1aec48SLars Fredriksen for (s1 = s; *s1; ++s1) 11079f65f104SPeter Wemm { 11089b1aec48SLars Fredriksen logf(character(*s1)); 11099b1aec48SLars Fredriksen } 11109f65f104SPeter Wemm } 11119b1aec48SLars Fredriksen 11129b1aec48SLars Fredriksen logf(")\n"); 11139b1aec48SLars Fredriksen } 11149b1aec48SLars Fredriksen 11159b1aec48SLars Fredriksen alarm(timeout); alarmed = 0; 11169b1aec48SLars Fredriksen 11179b1aec48SLars Fredriksen while (*s) 11189b1aec48SLars Fredriksen { 11199b1aec48SLars Fredriksen register char c = *s++; 11209b1aec48SLars Fredriksen 11219b1aec48SLars Fredriksen if (c != '\\') 11229b1aec48SLars Fredriksen { 11239b1aec48SLars Fredriksen if (!write_char (c)) 11249f65f104SPeter Wemm { 11259b1aec48SLars Fredriksen return 0; 11269f65f104SPeter Wemm } 11279b1aec48SLars Fredriksen continue; 11289b1aec48SLars Fredriksen } 11299b1aec48SLars Fredriksen 11309b1aec48SLars Fredriksen c = *s++; 11319b1aec48SLars Fredriksen switch (c) 11329b1aec48SLars Fredriksen { 11339b1aec48SLars Fredriksen case 'd': 11349b1aec48SLars Fredriksen sleep(1); 11359b1aec48SLars Fredriksen break; 11369b1aec48SLars Fredriksen 11379b1aec48SLars Fredriksen case 'K': 11389b1aec48SLars Fredriksen break_sequence(); 11399b1aec48SLars Fredriksen break; 11409b1aec48SLars Fredriksen 11419b1aec48SLars Fredriksen case 'p': 11429f65f104SPeter Wemm usleep(10000); /* 1/100th of a second (arg is microseconds) */ 11439b1aec48SLars Fredriksen break; 11449b1aec48SLars Fredriksen 11459b1aec48SLars Fredriksen default: 11469b1aec48SLars Fredriksen if (!write_char (c)) 11479b1aec48SLars Fredriksen return 0; 11489b1aec48SLars Fredriksen break; 11499b1aec48SLars Fredriksen } 11509b1aec48SLars Fredriksen } 11519b1aec48SLars Fredriksen 11529b1aec48SLars Fredriksen alarm(0); 11539b1aec48SLars Fredriksen alarmed = 0; 11549b1aec48SLars Fredriksen return (1); 11559b1aec48SLars Fredriksen } 11569b1aec48SLars Fredriksen 11579b1aec48SLars Fredriksen /* 11589b1aec48SLars Fredriksen * 'Wait for' this string to appear on this file descriptor. 11599b1aec48SLars Fredriksen */ 11609b1aec48SLars Fredriksen int get_string(string) 11619b1aec48SLars Fredriksen register char *string; 11629b1aec48SLars Fredriksen { 11639b1aec48SLars Fredriksen char temp[STR_LEN]; 11649b1aec48SLars Fredriksen int c, printed = 0, len, minlen; 11659b1aec48SLars Fredriksen register char *s = temp, *end = s + STR_LEN; 11669b1aec48SLars Fredriksen 11679b1aec48SLars Fredriksen fail_reason = (char *)0; 11689b1aec48SLars Fredriksen string = clean(string, 0); 11699b1aec48SLars Fredriksen len = strlen(string); 11709b1aec48SLars Fredriksen minlen = (len > sizeof(fail_buffer)? len: sizeof(fail_buffer)) - 1; 11719b1aec48SLars Fredriksen 11729b1aec48SLars Fredriksen if (verbose) 11739b1aec48SLars Fredriksen { 11749b1aec48SLars Fredriksen register char *s1; 11759b1aec48SLars Fredriksen 11769b1aec48SLars Fredriksen logf("expect ("); 11779b1aec48SLars Fredriksen 11789b1aec48SLars Fredriksen for (s1 = string; *s1; ++s1) 11799f65f104SPeter Wemm { 11809b1aec48SLars Fredriksen logf(character(*s1)); 11819f65f104SPeter Wemm } 11829b1aec48SLars Fredriksen 11839b1aec48SLars Fredriksen logf(")\n"); 11849b1aec48SLars Fredriksen } 11859b1aec48SLars Fredriksen 11869b1aec48SLars Fredriksen if (len > STR_LEN) 11879b1aec48SLars Fredriksen { 11889b1aec48SLars Fredriksen syslog(LOG_INFO, "expect string is too long"); 11899f65f104SPeter Wemm exit_code = 1; 11909b1aec48SLars Fredriksen return 0; 11919b1aec48SLars Fredriksen } 11929b1aec48SLars Fredriksen 11939b1aec48SLars Fredriksen if (len == 0) 11949b1aec48SLars Fredriksen { 11959b1aec48SLars Fredriksen if (verbose) 11969b1aec48SLars Fredriksen { 11979b1aec48SLars Fredriksen syslog(LOG_INFO, "got it"); 11989b1aec48SLars Fredriksen } 11999b1aec48SLars Fredriksen 12009b1aec48SLars Fredriksen return (1); 12019b1aec48SLars Fredriksen } 12029b1aec48SLars Fredriksen 12039f65f104SPeter Wemm alarm(timeout); 12049f65f104SPeter Wemm alarmed = 0; 12059b1aec48SLars Fredriksen 12069b1aec48SLars Fredriksen while ( ! alarmed && (c = get_char()) >= 0) 12079b1aec48SLars Fredriksen { 12089f65f104SPeter Wemm int n, abort_len, report_len; 12099b1aec48SLars Fredriksen 12109b1aec48SLars Fredriksen if (verbose) 12119b1aec48SLars Fredriksen { 12129b1aec48SLars Fredriksen if (c == '\n') 12139f65f104SPeter Wemm { 12149b1aec48SLars Fredriksen logf("\n"); 12159f65f104SPeter Wemm } 12169b1aec48SLars Fredriksen else 12179f65f104SPeter Wemm { 12189b1aec48SLars Fredriksen logf(character(c)); 12199b1aec48SLars Fredriksen } 12209f65f104SPeter Wemm } 12219b1aec48SLars Fredriksen 12229b1aec48SLars Fredriksen *s++ = c; 12239b1aec48SLars Fredriksen 12249b1aec48SLars Fredriksen if (s - temp >= len && 12259b1aec48SLars Fredriksen c == string[len - 1] && 12269b1aec48SLars Fredriksen strncmp(s - len, string, len) == 0) 12279b1aec48SLars Fredriksen { 12289b1aec48SLars Fredriksen if (verbose) 12299b1aec48SLars Fredriksen { 12309b1aec48SLars Fredriksen logf(" -- got it\n"); 12319b1aec48SLars Fredriksen } 12329b1aec48SLars Fredriksen 12339f65f104SPeter Wemm alarm(0); 12349f65f104SPeter Wemm alarmed = 0; 12359b1aec48SLars Fredriksen return (1); 12369b1aec48SLars Fredriksen } 12379b1aec48SLars Fredriksen 12389b1aec48SLars Fredriksen for (n = 0; n < n_aborts; ++n) 12399f65f104SPeter Wemm { 12409b1aec48SLars Fredriksen if (s - temp >= (abort_len = strlen(abort_string[n])) && 12419b1aec48SLars Fredriksen strncmp(s - abort_len, abort_string[n], abort_len) == 0) 12429b1aec48SLars Fredriksen { 12439b1aec48SLars Fredriksen if (verbose) 12449b1aec48SLars Fredriksen { 12459b1aec48SLars Fredriksen logf(" -- failed\n"); 12469b1aec48SLars Fredriksen } 12479b1aec48SLars Fredriksen 12489f65f104SPeter Wemm alarm(0); 12499f65f104SPeter Wemm alarmed = 0; 12509f65f104SPeter Wemm exit_code = n + 4; 12519b1aec48SLars Fredriksen strcpy(fail_reason = fail_buffer, abort_string[n]); 12529b1aec48SLars Fredriksen return (0); 12539b1aec48SLars Fredriksen } 12549f65f104SPeter Wemm } 12559f65f104SPeter Wemm 12569f65f104SPeter Wemm if (!report_gathering) 12579f65f104SPeter Wemm { 12589f65f104SPeter Wemm for (n = 0; n < n_reports; ++n) 12599f65f104SPeter Wemm { 12609f65f104SPeter Wemm if ((report_string[n] != (char*) NULL) && 12619f65f104SPeter Wemm s - temp >= (report_len = strlen(report_string[n])) && 12629f65f104SPeter Wemm strncmp(s - report_len, report_string[n], report_len) == 0) 12639f65f104SPeter Wemm { 12649f65f104SPeter Wemm time_t time_now = time ((time_t*) NULL); 12659f65f104SPeter Wemm struct tm* tm_now = localtime (&time_now); 12669f65f104SPeter Wemm 12679f65f104SPeter Wemm strftime (report_buffer, 20, "%b %d %H:%M:%S ", tm_now); 12689f65f104SPeter Wemm strcat (report_buffer, report_string[n]); 12699f65f104SPeter Wemm 12709f65f104SPeter Wemm report_string[n] = (char *) NULL; 12719f65f104SPeter Wemm report_gathering = 1; 12729f65f104SPeter Wemm break; 12739f65f104SPeter Wemm } 12749f65f104SPeter Wemm } 12759f65f104SPeter Wemm } 12769f65f104SPeter Wemm else 12779f65f104SPeter Wemm { 12789f65f104SPeter Wemm if (!iscntrl (c)) 12799f65f104SPeter Wemm { 12809f65f104SPeter Wemm int rep_len = strlen (report_buffer); 12819f65f104SPeter Wemm report_buffer[rep_len] = c; 12829f65f104SPeter Wemm report_buffer[rep_len + 1] = '\0'; 12839f65f104SPeter Wemm } 12849f65f104SPeter Wemm else 12859f65f104SPeter Wemm { 12869f65f104SPeter Wemm report_gathering = 0; 12879f65f104SPeter Wemm fprintf (report_fp, "chat: %s\n", report_buffer); 12889f65f104SPeter Wemm } 12899f65f104SPeter Wemm } 12909b1aec48SLars Fredriksen 12919b1aec48SLars Fredriksen if (s >= end) 12929b1aec48SLars Fredriksen { 12939b1aec48SLars Fredriksen strncpy (temp, s - minlen, minlen); 12949b1aec48SLars Fredriksen s = temp + minlen; 12959b1aec48SLars Fredriksen } 12969b1aec48SLars Fredriksen 12979b1aec48SLars Fredriksen if (alarmed && verbose) 12989f65f104SPeter Wemm { 12999b1aec48SLars Fredriksen syslog(LOG_WARNING, "warning: alarm synchronization problem"); 13009b1aec48SLars Fredriksen } 13019f65f104SPeter Wemm } 13029b1aec48SLars Fredriksen 13039b1aec48SLars Fredriksen alarm(0); 13049b1aec48SLars Fredriksen 13059b1aec48SLars Fredriksen if (verbose && printed) 13069b1aec48SLars Fredriksen { 13079b1aec48SLars Fredriksen if (alarmed) 13089f65f104SPeter Wemm { 13099b1aec48SLars Fredriksen logf(" -- read timed out\n"); 13109f65f104SPeter Wemm } 13119b1aec48SLars Fredriksen else 13129b1aec48SLars Fredriksen { 13139b1aec48SLars Fredriksen logflush(); 13149b1aec48SLars Fredriksen syslog(LOG_INFO, " -- read failed: %m"); 13159b1aec48SLars Fredriksen } 13169b1aec48SLars Fredriksen } 13179b1aec48SLars Fredriksen 13189f65f104SPeter Wemm exit_code = 3; 13199b1aec48SLars Fredriksen alarmed = 0; 13209b1aec48SLars Fredriksen return (0); 13219b1aec48SLars Fredriksen } 13229b1aec48SLars Fredriksen 13239f65f104SPeter Wemm #ifdef NO_USLEEP 13249b1aec48SLars Fredriksen #include <sys/types.h> 13259b1aec48SLars Fredriksen #include <sys/time.h> 13269b1aec48SLars Fredriksen 13279b1aec48SLars Fredriksen /* 13289b1aec48SLars Fredriksen usleep -- support routine for 4.2BSD system call emulations 13299b1aec48SLars Fredriksen last edit: 29-Oct-1984 D A Gwyn 13309b1aec48SLars Fredriksen */ 13319b1aec48SLars Fredriksen 13329b1aec48SLars Fredriksen extern int select(); 13339b1aec48SLars Fredriksen 13349b1aec48SLars Fredriksen int 13359b1aec48SLars Fredriksen usleep( usec ) /* returns 0 if ok, else -1 */ 13369b1aec48SLars Fredriksen long usec; /* delay in microseconds */ 13379b1aec48SLars Fredriksen { 13389b1aec48SLars Fredriksen static struct /* `timeval' */ 13399b1aec48SLars Fredriksen { 13409b1aec48SLars Fredriksen long tv_sec; /* seconds */ 13419b1aec48SLars Fredriksen long tv_usec; /* microsecs */ 13429b1aec48SLars Fredriksen } delay; /* _select() timeout */ 13439b1aec48SLars Fredriksen 13449b1aec48SLars Fredriksen delay.tv_sec = usec / 1000000L; 13459b1aec48SLars Fredriksen delay.tv_usec = usec % 1000000L; 13469b1aec48SLars Fredriksen 13479b1aec48SLars Fredriksen return select( 0, (long *)0, (long *)0, (long *)0, &delay ); 13489b1aec48SLars Fredriksen } 13499b1aec48SLars Fredriksen #endif 1350