OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [libnetworking/] [pppd/] [chat.c] - Blame information for rev 857

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 30 unneback
/*
2
 *      Chat -- a program for automatic session establishment (i.e. dial
3
 *              the phone and log in).
4
 *
5
 * Standard termination codes:
6
 *  0 - successful completion of the script
7
 *  1 - invalid argument, expect string too large, etc.
8
 *  2 - error on an I/O operation or fatal error condition.
9
 *  3 - timeout waiting for a simple string.
10
 *  4 - the first string declared as "ABORT"
11
 *  5 - the second string declared as "ABORT"
12
 *  6 - ... and so on for successive ABORT strings.
13
 *
14
 *      This software is in the public domain.
15
 *
16
 * -----------------
17
 *      added -T and -U option and \T and \U substitution to pass a phone
18
 *      number into chat script. Two are needed for some ISDN TA applications.
19
 *      Keith Dart <kdart@cisco.com>
20
 *
21
 *
22
 *      Added SAY keyword to send output to stderr.
23
 *      This allows to turn ECHO OFF and to output specific, user selected,
24
 *      text to give progress messages. This best works when stderr
25
 *      exists (i.e.: pppd in nodetach mode).
26
 *
27
 *      Added HANGUP directives to allow for us to be called
28
 *      back. When HANGUP is set to NO, chat will not hangup at HUP signal.
29
 *      We rely on timeouts in that case.
30
 *
31
 *      Added CLR_ABORT to clear previously set ABORT string. This has been
32
 *      dictated by the HANGUP above as "NO CARRIER" (for example) must be
33
 *      an ABORT condition until we know the other host is going to close
34
 *      the connection for call back. As soon as we have completed the
35
 *      first stage of the call back sequence, "NO CARRIER" is a valid, non
36
 *      fatal string. As soon as we got called back (probably get "CONNECT"),
37
 *      we should re-arm the ABORT "NO CARRIER". Hence the CLR_ABORT command.
38
 *      Note that CLR_ABORT packs the abort_strings[] array so that we do not
39
 *      have unused entries not being reclaimed.
40
 *
41
 *      In the same vein as above, added CLR_REPORT keyword.
42
 *
43
 *      Allow for comments. Line starting with '#' are comments and are
44
 *      ignored. If a '#' is to be expected as the first character, the
45
 *      expect string must be quoted.
46
 *
47
 *
48
 *              Francis Demierre <Francis@SwissMail.Com>
49
 *              Thu May 15 17:15:40 MET DST 1997
50
 *
51
 *
52
 *      Added -r "report file" switch & REPORT keyword.
53
 *              Robert Geer <bgeer@xmission.com>
54
 *
55
 *      Added -s "use stderr" and -S "don't use syslog" switches.
56
 *              June 18, 1997
57
 *              Karl O. Pinc <kop@meme.com>
58
 *
59
 *
60
 *      Added -e "echo" switch & ECHO keyword
61
 *              Dick Streefland <dicks@tasking.nl>
62
 *
63
 *
64
 *      Considerable updates and modifications by
65
 *              Al Longyear <longyear@pobox.com>
66
 *              Paul Mackerras <paulus@cs.anu.edu.au>
67
 *
68
 *
69
 *      The original author is:
70
 *
71
 *              Karl Fox <karl@MorningStar.Com>
72
 *              Morning Star Technologies, Inc.
73
 *              1760 Zollinger Road
74
 *              Columbus, OH  43221
75
 *              (614)451-1883
76
 *
77
 *
78
 */
79
 
80
#ifndef lint
81
/* static char rcsid[] = ""; */
82
#endif
83
 
84
#include <stdio.h>
85
#include <ctype.h>
86
#include <time.h>
87
#include <fcntl.h>
88
#include <signal.h>
89
#include <errno.h>
90
#include <string.h>
91
#include <stdlib.h>
92
#include <unistd.h>
93
#include <sys/types.h>
94
#include <sys/stat.h>
95
#include <syslog.h>
96
 
97
#undef  TERMIOS
98
#define TERMIOS
99
 
100
 
101
#include <termios.h>
102
 
103
#define STR_LEN 1024
104
char temp2[STR_LEN];
105
 
106
#ifndef SIGTYPE
107
#define SIGTYPE void
108
#endif
109
 
110
#undef __P
111
#undef __V
112
 
113
#ifdef __STDC__
114
#include <stdarg.h>
115
#define __V(x)  x
116
#define __P(x)  x
117
#else
118
#include <varargs.h>
119
#define __V(x)  (va_alist) va_dcl
120
#define __P(x)  ()
121
#define const
122
#endif
123
 
124
#ifndef O_NONBLOCK
125
#define O_NONBLOCK      O_NDELAY
126
#endif
127
 
128
 
129
/*************** Micro getopt() *********************************************/
130
#define OPTION(c,v)     (_O&2&&**v?*(*v)++:!c||_O&4?0:(!(_O&1)&& \
131
                                (--c,++v),_O=4,c&&**v=='-'&&v[0][1]?*++*v=='-'\
132
                                &&!v[0][1]?(--c,++v,0):(_O=2,*(*v)++):0))
133
#define OPTARG(c,v)     (_O&2?**v||(++v,--c)?(_O=1,--c,*v++): \
134
                                (_O=4,(char*)0):(char*)0)
135
#define OPTONLYARG(c,v) (_O&2&&**v?(_O=1,--c,*v++):(char*)0)
136
#define ARG(c,v)        (c?(--c,*v++):(char*)0)
137
 
138
#if 0
139
static int _O = 0;               /* Internal state */
140
#endif
141
/*************** Micro getopt() *********************************************/
142
 
143
char *program_name;
144
 
145
#define MAX_ABORTS              5
146
#define MAX_REPORTS             5
147
#define DEFAULT_CHAT_TIMEOUT    45
148
#define fcntl(a, b,c ) 0
149
#define MAX_TIMEOUTS 10
150
 
151
int echo          = 0;
152
int verbose       = 0;
153
int to_log        = 1;
154
int to_stderr     = 0;
155
int Verbose       = 0;
156
int quiet         = 0;
157
int report        = 0;
158
int exit_code     = 0;
159
static int speed=0;
160
char *report_file = (char *) 0;
161
char *chat_file   = (char *) 0;
162
char *phone_num   = (char *) 0;
163
char *phone_num2  = (char *) 0;
164
int chat_timeout       = DEFAULT_CHAT_TIMEOUT;
165
static int timeout       = DEFAULT_CHAT_TIMEOUT;
166
int have_tty_parameters = 0;
167
 
168
#ifdef TERMIOS
169
#define term_parms struct termios
170
#define get_term_param(param) tcgetattr(modem_fd, param)
171
#define set_term_param(param) tcsetattr(modem_fd, TCSANOW, param)
172
struct termios saved_tty_parameters;
173
#endif
174
 
175
char *abort_string[MAX_ABORTS]={"BUSY","NO DIALTONE","NO CARRIER","NO ASWER","RINGING\r\n\r\nRINGING"};
176
char *fail_reason = (char *)0,
177
        fail_buffer[50];
178
int n_aborts = MAX_ABORTS, abort_next = 0, timeout_next = 0, echo_next = 0;
179
int clear_abort_next = 0;
180
 
181
char *report_string[MAX_REPORTS] ;
182
char  report_buffer[50] ;
183
int n_reports = 0, report_next = 0, report_gathering = 0 ;
184
int clear_report_next = 0;
185
 
186
int say_next = 0, hup_next = 0;
187
 
188
void *dup_mem __P((void *b, size_t c));
189
void *copy_of __P((char *s));
190
/*
191
SIGTYPE sigalrm __P((int signo));
192
SIGTYPE sigint __P((int signo));
193
SIGTYPE sigterm __P((int signo));
194
SIGTYPE sighup __P((int signo));
195
*/
196
void unalarm __P((void));
197
void init __P((void));
198
void set_tty_parameters __P((void));
199
void echo_stderr __P((int));
200
void break_sequence __P((void));
201
void terminate __P((int status));
202
void do_file __P((char *chat_file));
203
int  get_string __P((register char *string));
204
int  put_string __P((register char *s));
205
int  write_char __P((int c));
206
int  put_char __P((int c));
207
int  get_char __P((void));
208
void chat_send __P((register char *s));
209
char *character __P((int c));
210
void chat_expect __P((register char *s));
211
char *clean __P((register char *s, int sending));
212
void break_sequence __P((void));
213
void terminate __P((int status));
214
void pack_array __P((char **array, int end));
215
char *expect_strtok __P((char *, char *));
216
int vfmtmsg __P((char *, int, const char *, va_list));  /* vsprintf++ */
217
 
218
#if 0
219
int usleep( long usec );                                  /* returns 0 if ok, else -1 */
220
#endif
221
 
222
extern int input_fd,output_fd;
223
 
224
int main __P((int, char *[]));
225
 
226
void *dup_mem(b, c)
227
void *b;
228
size_t c;
229
{
230
    void *ans = malloc (c);
231
    if (!ans)
232
                return NULL;
233
 
234
    memcpy (ans, b, c);
235
    return ans;
236
}
237
 
238
void *copy_of (s)
239
char *s;
240
{
241
    return dup_mem (s, strlen (s) + 1);
242
}
243
 
244
/*
245
 * chat [ -v ] [-T number] [-U number] [ -t timeout ] [ -f chat-file ] \
246
 * [ -r report-file ] \
247
 *              [...[[expect[-say[-expect...]] say expect[-say[-expect]] ...]]]
248
 *
249
 *      Perform a UUCP-dialer-like chat script on stdin and stdout.
250
 */
251
char *getnextcommand(char **string)
252
{
253
        char *buf=*string,*res;
254
        res=strchr(buf,'@');
255
        if (res==NULL)
256
                return NULL;
257
        *res='\0';
258
        *string=res+1;
259
        return buf;
260
}
261
 
262
 
263
extern int modem_fd;
264
int
265
        chatmain(argv)
266
     char *argv;
267
{
268
    char *arg;
269
        int i;
270
        char *t;
271
        exit_code=0;
272
        speed=0;
273
/*
274
 * Default the report file to the stderr location
275
 */
276
/*    if (report_fp == NULL)
277
        report_fp = stderr;
278
*/
279
    init();
280
        while ( (arg = getnextcommand(&argv)) != NULL) {
281
            chat_expect(arg);
282
                if (exit_code>0) break;
283
            t=temp2;
284
 
285
                while(*t)
286
                {
287
                        if (strncmp("CARRIER",t,7)==0)
288
                        {/* parse speed information */
289
                                i=0;
290
                                while(!isdigit(t[i]))
291
                                        i++;
292
                                t=&t[i];
293
                                i=0;
294
                                while(isdigit(t[i]))
295
                                        i++;
296
                                t[i]=0;
297
                                sscanf(t,"%d",&speed);
298
                                break;
299
                        }
300
                        t++;
301
                }
302
            if ((arg = getnextcommand(&argv)) != NULL)
303
                chat_send(arg);
304
                if (exit_code>0) break;
305
        }
306
 
307
    if (exit_code) return exit_code;
308
    return -speed;
309
}
310
 
311
 
312
 
313
/*
314
 *      Print an error message and terminate.
315
 */
316
 
317
void init()
318
{
319
    set_tty_parameters();
320
        speed=0;
321
}
322
 
323
void set_tty_parameters()
324
{
325
    term_parms t;
326
 
327
        if (get_term_param (&t) < 0)
328
                syslog(LOG_NOTICE,"Can't get terminal parameters:")
329
                ;
330
 
331
    saved_tty_parameters = t;
332
    have_tty_parameters  = 1;
333
    t.c_iflag     |= IGNBRK | ISTRIP | IGNPAR;
334
    t.c_oflag      = 0;
335
    t.c_lflag      = 0;
336
    t.c_cc[VERASE] =
337
    t.c_cc[VKILL]  = 0;
338
    t.c_cc[VMIN]   = 0;
339
    t.c_cc[VTIME]  = 1;
340
    if (set_term_param (&t) < 0)
341
                syslog(LOG_NOTICE,"Can't set terminal parameters:")
342
                ;
343
}
344
 
345
void break_sequence()
346
{
347
 
348
/*    tcsendbreak (0, 0);*/
349
}
350
 
351
/*void terminate(status)
352
int status;
353
{
354
    echo_stderr(-1);
355
 
356
    if (have_tty_parameters) {
357
        if (set_term_param (&saved_tty_parameters) < 0)
358
            fatal(2, "Can't restore terminal parameters: %m");
359
    }
360
}
361
*/
362
/*
363
 *      'Clean up' this string.
364
 */
365
char *clean(s, sending)
366
register char *s;
367
int sending;  /* set to 1 when sending (putting) this string. */
368
{
369
    char temp[STR_LEN], cur_chr;
370
    register char *s1, *phchar;
371
    int add_return = sending;
372
#define isoctal(chr) (((chr) >= '0') && ((chr) <= '7'))
373
 
374
    s1 = temp;
375
    while (*s) {
376
        cur_chr = *s++;
377
        if (cur_chr == '^') {
378
            cur_chr = *s++;
379
            if (cur_chr == '\0') {
380
                *s1++ = '^';
381
                break;
382
            }
383
            cur_chr &= 0x1F;
384
            if (cur_chr != 0) {
385
                *s1++ = cur_chr;
386
            }
387
            continue;
388
        }
389
 
390
        if (cur_chr != '\\') {
391
            *s1++ = cur_chr;
392
            continue;
393
        }
394
 
395
        cur_chr = *s++;
396
        if (cur_chr == '\0') {
397
            if (sending) {
398
                *s1++ = '\\';
399
                *s1++ = '\\';
400
            }
401
            break;
402
        }
403
 
404
        switch (cur_chr) {
405
        case 'b':
406
            *s1++ = '\b';
407
            break;
408
 
409
        case 'c':
410
            if (sending && *s == '\0')
411
                add_return = 0;
412
            else
413
                *s1++ = cur_chr;
414
            break;
415
 
416
        case '\\':
417
        case 'K':
418
        case 'p':
419
        case 'd':
420
            if (sending)
421
                *s1++ = '\\';
422
 
423
            *s1++ = cur_chr;
424
            break;
425
 
426
        case 'T':
427
            if (sending && phone_num) {
428
                for ( phchar = phone_num; *phchar != '\0'; phchar++)
429
                    *s1++ = *phchar;
430
            }
431
            else {
432
                *s1++ = '\\';
433
                *s1++ = 'T';
434
            }
435
            break;
436
 
437
        case 'U':
438
            if (sending && phone_num2) {
439
                for ( phchar = phone_num2; *phchar != '\0'; phchar++)
440
                    *s1++ = *phchar;
441
            }
442
            else {
443
                *s1++ = '\\';
444
                *s1++ = 'U';
445
            }
446
            break;
447
 
448
        case 'q':
449
            quiet = 1;
450
            break;
451
 
452
        case 'r':
453
            *s1++ = '\r';
454
            break;
455
 
456
        case 'n':
457
            *s1++ = '\n';
458
            break;
459
 
460
        case 's':
461
            *s1++ = ' ';
462
            break;
463
 
464
        case 't':
465
            *s1++ = '\t';
466
            break;
467
 
468
        case 'N':
469
            if (sending) {
470
                *s1++ = '\\';
471
                *s1++ = '\0';
472
            }
473
            else
474
                *s1++ = 'N';
475
            break;
476
 
477
        default:
478
            if (isoctal (cur_chr)) {
479
                cur_chr &= 0x07;
480
                if (isoctal (*s)) {
481
                    cur_chr <<= 3;
482
                    cur_chr |= *s++ - '0';
483
                    if (isoctal (*s)) {
484
                        cur_chr <<= 3;
485
                        cur_chr |= *s++ - '0';
486
                    }
487
                }
488
 
489
                if (cur_chr != 0 || sending) {
490
                    if (sending && (cur_chr == '\\' || cur_chr == 0))
491
                        *s1++ = '\\';
492
                    *s1++ = cur_chr;
493
                }
494
                break;
495
            }
496
 
497
            if (sending)
498
                *s1++ = '\\';
499
            *s1++ = cur_chr;
500
            break;
501
        }
502
    }
503
 
504
    if (add_return)
505
        *s1++ = '\r';
506
 
507
    *s1++ = '\0'; /* guarantee closure */
508
    *s1++ = '\0'; /* terminate the string */
509
    return dup_mem (temp, (size_t) (s1 - temp)); /* may have embedded nuls */
510
}
511
 
512
/*
513
 * A modified version of 'strtok'. This version skips \ sequences.
514
 */
515
 
516
char *expect_strtok (s, term)
517
     char *s, *term;
518
{
519
    static  char *str   = "";
520
    int     escape_flag = 0;
521
    char   *result;
522
 
523
/*
524
 * If a string was specified then do initial processing.
525
 */
526
    if (s)
527
        str = s;
528
 
529
/*
530
 * If this is the escape flag then reset it and ignore the character.
531
 */
532
    if (*str)
533
        result = str;
534
    else
535
        result = (char *) 0;
536
 
537
    while (*str) {
538
        if (escape_flag) {
539
            escape_flag = 0;
540
            ++str;
541
            continue;
542
        }
543
 
544
        if (*str == '\\') {
545
            ++str;
546
            escape_flag = 1;
547
            continue;
548
        }
549
 
550
/*
551
 * If this is not in the termination string, continue.
552
 */
553
        if (strchr (term, *str) == (char *) 0) {
554
            ++str;
555
            continue;
556
        }
557
 
558
/*
559
 * This is the terminator. Mark the end of the string and stop.
560
 */
561
        *str++ = '\0';
562
        break;
563
    }
564
    return (result);
565
}
566
 
567
/*
568
 * Process the expect string
569
 */
570
 
571
void   chat_expect (s)
572
char *s;
573
{
574
    char *expect;
575
    char *reply;
576
 
577
    if (strcmp(s, "HANGUP") == 0) {
578
        ++hup_next;
579
        return ;
580
    }
581
 
582
    if (strcmp(s, "ABORT") == 0) {
583
        ++abort_next;
584
        return ;
585
    }
586
 
587
    if (strcmp(s, "CLR_ABORT") == 0) {
588
        ++clear_abort_next;
589
        return ;
590
    }
591
 
592
    if (strcmp(s, "REPORT") == 0) {
593
        ++report_next;
594
        return ;
595
    }
596
 
597
    if (strcmp(s, "CLR_REPORT") == 0) {
598
        ++clear_report_next;
599
        return ;
600
    }
601
 
602
    if (strcmp(s, "TIMEOUT") == 0) {
603
        ++timeout_next;
604
        return ;
605
    }
606
 
607
    if (strcmp(s, "ECHO") == 0) {
608
        ++echo_next;
609
        return ;
610
    }
611
 
612
    if (strcmp(s, "SAY") == 0) {
613
        ++say_next;
614
        return ;
615
    }
616
 
617
/*
618
 * Fetch the expect and reply string.
619
 */
620
    for (;;) {
621
        expect = expect_strtok (s, "-");
622
        s      = (char *)0 ;
623
 
624
        if (expect == (char *) 0)
625
            return ;
626
 
627
        reply = expect_strtok (s, "-");
628
 
629
/*
630
 * Handle the expect string. If successful then exit.
631
 */
632
        if (get_string (expect))
633
            return;
634
 
635
/*
636
 * If there is a sub-reply string then send it. Otherwise any condition
637
 * is terminal.
638
 */
639
        if (reply == (char *) 0 || exit_code != 3)
640
            break;
641
 
642
        chat_send (reply);
643
    }
644
 
645
/*
646
 * The expectation did not occur. This is terminal.
647
 */
648
    return ;
649
}
650
 
651
/*
652
 *  process the reply string
653
 */
654
void chat_send (s)
655
register char *s;
656
{
657
    if (say_next) {
658
        say_next = 0;
659
        s = clean(s,0);
660
        write(modem_fd, s, strlen(s));
661
        free(s);
662
        return;
663
    }
664
 
665
    if (hup_next) {
666
        hup_next = 0;
667
    }
668
 
669
    if (echo_next) {
670
        echo_next = 0;
671
        echo = (strcmp(s, "ON") == 0);
672
        return;
673
    }
674
 
675
    if (abort_next) {
676
        /* char *s1; */
677
 
678
 
679
           ;
680
 
681
 
682
        return;
683
    }
684
 
685
 
686
/*    if (report_next) {
687
        char *s1;
688
 
689
        report_next = 0;
690
        if (n_reports >= MAX_REPORTS)
691
            {
692
              exit_code=2;
693
              return;
694
            }
695
 
696
        s1 = clean(s, 0);
697
 
698
        if (strlen(s1) > strlen(s) || strlen(s1) > sizeof fail_buffer - 1)
699
            {
700
              exit_code=1;
701
              return;
702
            }
703
 
704
        report_string[n_reports++] = s1;
705
 
706
        return;
707
    }
708
*/
709
/*    if (clear_report_next) {
710
        char *s1;
711
        int   i;
712
        int   old_max;
713
        int   pack = 0;
714
 
715
        clear_report_next = 0;
716
 
717
        s1 = clean(s, 0);
718
 
719
        if (strlen(s1) > strlen(s) || strlen(s1) > sizeof fail_buffer - 1)
720
            {
721
              exit_code=1;
722
              return;
723
            }
724
 
725
        old_max = n_reports;
726
        for (i=0; i < n_reports; i++) {
727
            if ( strcmp(s1,report_string[i]) == 0 ) {
728
                free(report_string[i]);
729
                report_string[i] = NULL;
730
                pack++;
731
                n_reports--;
732
            }
733
        }
734
        free(s1);
735
        if (pack)
736
            pack_array(report_string,old_max);
737
 
738
        return;
739
    }
740
*/
741
 
742
    if (timeout_next) {
743
        timeout=atoi(s);
744
        timeout_next = 0;
745
        chat_timeout = atoi(s);
746
 
747
        if (chat_timeout <= 0)
748
            chat_timeout = DEFAULT_CHAT_TIMEOUT;
749
 
750
 
751
        return;
752
    }
753
    if (strcmp(s, "EOT") == 0)
754
        s = "^D\\c";
755
    else if (strcmp(s, "BREAK") == 0)
756
        s = "\\K\\c";
757
 
758
    if (!put_string(s))
759
            {
760
              exit_code=1;
761
              return;
762
            }
763
}
764
 
765
int get_char()
766
{
767
    int status;
768
    char c;
769
    int tries=MAX_TIMEOUTS;
770
 
771
        while(tries)
772
        {
773
            status = read(modem_fd, &c, 1);
774
            switch (status) {
775
                   case 1:
776
                                return ((int)c & 0x7F);
777
                    default:
778
                                tries--;
779
            }
780
    }
781
        return -1;
782
}
783
 
784
int put_char(c)
785
int c;
786
{
787
    int status;
788
    char ch = c;
789
 
790
        /* inter-character typing delay (?) */
791
 
792
    status = write(modem_fd, &ch, 1);
793
 
794
    switch (status) {
795
    case 1:
796
        return (0);
797
 
798
    default:
799
 
800
 
801
    }
802
  return 0;
803
}
804
 
805
int write_char (c)
806
int c;
807
{
808
    if (put_char(c) < 0) {
809
        return (0);
810
    }
811
    return (1);
812
}
813
 
814
int put_string (s)
815
register char *s;
816
{
817
 
818
 
819
    quiet = 0;
820
    s = clean(s, 1);
821
    while (*s) {
822
        register char c = *s++;
823
 
824
        if (c != '\\') {
825
            if (!write_char (c))
826
                return 0;
827
            continue;
828
        }
829
 
830
        c = *s++;
831
        switch (c) {
832
        case 'd':
833
            sleep(1);
834
            break;
835
 
836
        case 'K':
837
            break_sequence();
838
            break;
839
 
840
        case 'p':
841
            usleep(10000);      /* 1/100th of a second (arg is microseconds) */
842
            break;
843
 
844
        default:
845
            if (!write_char (c))
846
                return 0;
847
            break;
848
        }
849
    }
850
 
851
   /* alarm(0);*/
852
    return (1);
853
}
854
 
855
/*
856
 *      Echo a character to stderr.
857
 *      When called with -1, a '\n' character is generated when
858
 *      the cursor is not at the beginning of a line.
859
 */
860
void echo_stderr(n)
861
int n;
862
{
863
/*    static int need_lf;
864
    char *s;
865
 
866
    switch (n) {
867
    case '\r':
868
        break;
869
    case -1:
870
        if (need_lf == 0)
871
            break;
872
 
873
    case '\n':
874
        write(2, "\n", 1);
875
        need_lf = 0;
876
        break;
877
    default:
878
        s = character(n);
879
        write(2, s, strlen(s));
880
        need_lf = 1;
881
        break;
882
    }*/
883
}
884
 
885
/*
886
 *      'Wait for' this string to appear on this file descriptor.
887
 */
888
 
889
int get_string(string)
890
register char *string;
891
{
892
    int c, len, minlen;
893
    register char *s = temp2, *end = s + STR_LEN;
894
    char *logged = temp2;
895
    struct termios tios;
896
 
897
    tcgetattr(modem_fd, &tios);
898
    tios.c_cc[VMIN] = 0;
899
    tios.c_cc[VTIME] = timeout*10/MAX_TIMEOUTS;
900
    tcsetattr(modem_fd, TCSANOW, &tios);
901
 
902
    string = clean(string, 0);
903
    len = strlen(string);
904
    minlen = (len > sizeof(fail_buffer)? len: sizeof(fail_buffer)) - 1;
905
 
906
    if (len > STR_LEN) {
907
        exit_code = 1;
908
        return 0;
909
    }
910
 
911
    if (len == 0) {
912
                        return (1);
913
    }
914
 
915
 
916
   while ( (c = get_char()) >= 0) {
917
                int n, abort_len;
918
 
919
        *s++ = c;
920
        *s=0;
921
 
922
        if (s - temp2 >= len &&
923
            c == string[len - 1] &&
924
            strncmp(s - len, string, len) == 0) {
925
            return (1);
926
        }
927
 
928
        for (n = 0; n < n_aborts; ++n) {
929
            if (s - temp2 >= (abort_len = strlen(abort_string[n])) &&
930
                strncmp(s - abort_len, abort_string[n], abort_len) == 0) {
931
 
932
                exit_code = n + 4;
933
                strcpy(fail_reason = fail_buffer, abort_string[n]);
934
                return (0);
935
            }
936
        }
937
 
938
        if (s >= end) {
939
            if (logged < s - minlen) {
940
                logged = s;
941
            }
942
            s -= minlen;
943
            memmove(temp2, s, minlen);
944
            logged = temp2 + (logged - s);
945
            s = temp2 + minlen;
946
        }
947
    }
948
    exit_code = 3;
949
    return (0);
950
}
951
 
952
/*
953
 * Gross kludge to handle Solaris versions >= 2.6 having usleep.
954
 */
955
 
956
/*
957
  usleep -- support routine for 4.2BSD system call emulations
958
  last edit:  29-Oct-1984     D A Gwyn
959
  */
960
 
961
 
962
#if 0
963
int
964
usleep( usec )                            /* returns 0 if ok, else -1 */
965
    long                usec;           /* delay in microseconds */
966
{
967
  rtems_status_code status;
968
  rtems_interval    ticks_per_second;
969
  rtems_interval    ticks;
970
  status = rtems_clock_get(
971
    RTEMS_CLOCK_GET_TICKS_PER_SECOND,
972
    &ticks_per_second);
973
    ticks = (usec * (ticks_per_second/1000))/1000;
974
    status = rtems_task_wake_after( ticks );
975
  return 0;
976
}
977
#endif
978
 
979
void pack_array (array, end)
980
    char **array; /* The address of the array of string pointers */
981
    int    end;   /* The index of the next free entry before CLR_ */
982
{
983
    int i, j;
984
 
985
    for (i = 0; i < end; i++) {
986
        if (array[i] == NULL) {
987
            for (j = i+1; j < end; ++j)
988
                if (array[j] != NULL)
989
                    array[i++] = array[j];
990
            for (; i < end; ++i)
991
                array[i] = NULL;
992
            break;
993
        }
994
    }
995
}
996
 
997
/*
998
 * vfmtmsg - format a message into a buffer.  Like vsprintf except we
999
 * also specify the length of the output buffer, and we handle the
1000
 * %m (error message) format.
1001
 * Doesn't do floating-point formats.
1002
 * Returns the number of chars put into buf.
1003
 */
1004
#define OUTCHAR(c)      (buflen > 0? (--buflen, *buf++ = (c)): 0)

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.