Spelling fixes
[oweals/cde.git] / cde / programs / dtterm / tests / shared / qalib.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these libraries and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: qalib.c /main/4 1996/10/01 16:27:40 drk $ */
24 /*************************************************************
25 *  Module Name        :  qalib.c 
26 *  Original Author    :  Panacom 
27 *  Revision Date      :  10/21/92 
28 *  Revision Author    :  Randall Robinson 
29 *  Data Files         :  None
30 *
31 *  Abstract           :  This file contains the global variable definitions, 
32                          and the common function definitions used between
33                          all (most) test.
34 *                        
35 *                        Many variable and functions definitions have been 
36 *                        left in place that were originally used by Panacom, 
37 *                        and are no longer necessary. 
38 ***************************************************************/
39 #ifndef _QALIB_INCLUDE
40 #define _QALIB_INCLUDE
41
42 #include "include_files.h"
43
44 #define __nu            "\0"
45 #define __eq            "\005"
46 #define __ak            "\006"
47 #define __lf            "\n"
48 #define __cr            "\015"
49 #define __d1            "\021"
50 #define __d2            "\022"
51 #define __d3            "\023"
52
53 #define __buf_len       4096
54 #define __ack_time_out  10
55
56 /*  not used functionally */
57 typedef struct __TIME {
58     short Hund, Sec, Min, Hour;
59 } __TIME;
60
61 /*
62 typedef struct __INS8250 {
63     short Thr, Rbr, Ier, Iir, Lcr, Mcr, Lsr, Msr;
64 } __INS8250;
65 */
66 /*
67 typedef union __REGISTERS {
68     struct {
69         short Ax, Bx, Cx, Dx, Bp, Si, Di, Ds, Es, Flags;
70     } U1;
71     struct {
72         uchar Al, Ah, Bl, Bh, Cl, Ch, Dl, Dh;
73     } U2;
74 } __REGISTERS;
75 */
76
77 /* not used functionally  */
78 typedef enum {
79     _B110, _B150, _B300, _B600, _B1200, _B2400, _B4800, _B9600, _B19200, _B38400
80 } __BAUD_TYPE;
81
82
83 /* not used functionally  */
84 typedef struct __DATACOM_REC {
85     __BAUD_TYPE Baud;  
86     uchar Parity, Data_Bits, Stop_Bits;
87     Char Intrig, Interm, Hand_Shake;
88     double Time_Out;
89     boolean Echo, Xoffed;
90     short Xcount, Ea_Count;
91 } __DATACOM_REC;
92
93 /* not used functionally  */
94 typedef __DATACOM_REC __DATACOM_TYPE[4];
95 typedef uchar __BUFFER_TYPE[__buf_len + 1];
96 typedef __BUFFER_TYPE __BUFFERS[4];
97 typedef short __POINTERS[4];
98
99
100 /* These are needed */
101 /* global variables */
102 int fd_test = -1;               /* file descriptor for /dev/tty  */
103 FILE *f_test = (FILE *)NULL;    /* file pointer to /dev/tty      */
104 int __DEBUG = 0;                /* set from command by   "-D:Y   */
105
106 struct termios termio_orig, termio_test;    /* for /dev/tty      */
107
108
109 typedef char __C_BUFFER[BUFSIZ];
110 __C_BUFFER buffer;  
111
112
113 /* ******   In the john dir: these flags not needed. Config.c file
114  ********   controls these parameters, but they are needed in the
115  ********   other 3 dirs. 
116 */
117 int page_mode= 0;
118 int block_mode=0;
119 int autolf_mode=0;
120 int DC1_hndshk=1, DC2_hndshk = 0, NO_hndskh=0;
121 int inh_hndshk=0, inh_DC2=1;
122
123
124 Char Input_Terminator[4];    /* used */
125 Char Input_Trigger[4];       /* not used yet functionally, but still used
126                                 in some functions as a variable.  RCR */
127
128 Static FILE *__Message_File;                   /* for the .LOG file */
129 Static boolean __Group_Not_Running;    /* used to have something to do with
130                                           option -D                         */
131 Static Char __File_Name[256], __Command_Line[256];
132 Static Char __Message_File_NAME[_FNSIZE];
133 Static boolean __Manual, __Log_Every_Thing, __Log_Msg;
134
135
136 /* function declarations */
137 extern void logln(); 
138 void timeout ();
139 void cleanup ();
140 char *vis();
141 char *in();
142
143
144 /* not used functionally */
145 Static uchar __default_test_term = 1, __default_ref_term = 0,
146              __default_aux_a = 0, __default_aux_b = 0;
147 /*
148 Static uchar __com_jump_table[4][6] = {
149     { 0x2e, 0xff, 0x16, 0, 0, 1 },
150     { 0x2e, 0xff, 0x16, 0, 0, 2 },
151     { 0x2e, 0xff, 0x16, 0, 0, 3 },
152     { 0x2e, 0xff, 0x16, 0, 0, 4 }
153 };
154 */
155
156 /*
157 Static __INS8250 __rs232[4] = {
158     { 0x3f8, 0x3f8, 0x3f9, 0x3fa, 0x3fb, 0x3fc, 0x3fd, 0x3fe },
159     { 0x2f8, 0x2f8, 0x2f9, 0x2fa, 0x2fb, 0x2fc, 0x2fd, 0x2fe },
160     { 0x3e8, 0x3e8, 0x3e9, 0x3ea, 0x3eb, 0x3ec, 0x3ed, 0x3ee },
161     { 0x2e8, 0x2e8, 0x2e9, 0x2ea, 0x2eb, 0x2ec, 0x2ed, 0x2ee }
162 };
163 */
164
165 /* not needed functionally, currently just as place holders. */
166 Static __DATACOM_REC __default_datacom_rec = {
167     _B9600, 0, 8, 1, '\021', '\015', 'E', 60000.0, false, false, 0, 0
168 };
169 Static short __com_int_addr = 0, __data_segment = 0;
170 Static uchar Test_Com=0, Ref_Com, Aux_A_Com, Aux_B_Com;
171 Static __DATACOM_TYPE __Data_Com;
172 Static boolean __Refpres, __Aux_A_Pres, __Aux_B_Pres;
173
174
175 /*
176 Static uchar __Rs_Error;
177 Static __BUFFERS __The_Buffs;
178 Static __POINTERS __Heads, __Tails;      
179 Static short __Oldcs[4], __Oldip[4];
180 Static __REGISTERS __Regs; 
181 Static boolean __Initialized, __Rs_Time_Out;
182 */
183
184
185 /* These are needed */
186 Char **P_argv;                   /* pascal global **argv */
187 int P_argc=0;                          /* pascal gloabal argc  */
188 int P_ioresult;
189 Char STRTMP[256];
190 Char HAND_SHAKE;
191
192
193 /* **********  start of function definitions   ************/
194
195
196 Static void
197 PAUSE(double Sec)
198 {
199   sleep( (unsigned int)Sec);
200 }
201
202
203 Static void
204 SETSTRLEN(Char *S, short E)
205 {
206     S[(long)((int)E)] = '\0';
207 }
208
209
210 Static void
211 STRAPPEND(Char *S1, Char *S2)
212 {
213     if ((int) strlen(S1) + (int) strlen(S2) <= 255)
214         strcat(S1, S2);
215 }
216
217
218 Static void
219 STRDELETE(Char *S, short P, short N)
220 {
221    MODULE_ERR("STRDELETE not supported");
222    cleanup(0);
223    return;
224
225 }
226 /* STRINSERT and strinsert both not supported yet, Do not understand
227    the intent of them.                 
228 */
229 Static void
230 STRINSERT(Char *S1, Char *S2, short P)
231 {
232   MODULE_ERR("STRINSERT not supported yet");
233   cleanup(0);
234   return;
235
236 }
237
238 /* Starting at "start_pos" from string "input", copy the results into
239    "Result".            
240 */
241 Static Char *
242 strsub(Char *Result, Char *input, short start_pos, short len)
243 {
244   Char STR1[256];
245   Char *tmp;
246   int i;
247   
248   for(i=1; i <= start_pos; i++)
249      input++;
250   tmp= input;
251   strcpy(Result, tmp);
252   return Result;
253 }
254
255 /* Do not understand the intent behind STRMOVE. NOT supported yet. */
256 Static void
257 STRMOVE(short N, Char *S1_, short P1, Char *S2, short P2)
258 {
259
260     MODULE_ERR("STRMOVE not supported yet");
261     cleanup(0);
262     return;
263
264 }
265
266
267 Static Char *
268 STRRPT(Char *Result, Char *S, short N)
269 {
270     Char St[256];
271     short I;
272
273     *St = '\0';
274     for (I = 1; I <= N; I++)
275         strcat(St, S);
276     return strcpy(Result, St);
277 }
278
279
280 Static short
281 STRLEN(Char *S)
282 {
283     return ((short) strlen(S));
284 }
285
286
287 /* this function only supports returning position of one char (not
288    a string).  "num" is the occurrence of the character's position to
289    return.                                                         */
290 Static short
291 strpos2(Char *S1, Char *S2, short num)
292 {
293    Char STR1[256];
294    short found = 0;
295    short done = 0;
296    short index = 0;
297    
298    strcpy(STR1,S1);
299
300    while(!done) {
301      if(STR1[index] == S2[0]) {
302        found++;
303      }
304      if(found == num)
305        done = 1;
306      else
307        index++;
308    }
309
310    return index;
311 }
312     
313
314 Static short
315 STRPOS(Char *S1, Char *S2)
316 {
317     return strpos2(S2, S1, 1);
318 }
319
320
321 Static Char *
322 STRLTRIM(Char *Result, Char *S_)
323 {
324     Char S[256];
325     boolean Done;
326     Char *tmp;
327     strcpy(S, S_);
328     Done = false;
329     if (*S == '\0')
330         return strcpy(Result, S);
331     if (S[0] != ' ')
332         return strcpy(Result, S);
333     do {
334     /*    strdelete((void *)S, 1, 1);  */
335     /* remove the first blank          */
336     /*    strcpy(S,strchar(S,S[1]));  This is not working */
337         tmp = S + sizeof(Char);
338         strcpy(S,tmp);
339         if (*S != '\0') {
340             if (S[0] != ' ')
341                 Done = true;
342         }
343         else {
344             Done = true;
345         }
346     } while (!Done);
347     return strcpy(Result, S);
348 }
349
350 Static Char *
351 STRRTRIM(Char *Result, Char *S_)
352 {
353     Char S[256];
354     boolean Done;
355
356     strcpy(S, S_);
357     Done = false;
358     if (*S == '\0')
359         return strcpy(Result, S);
360     if (S[(int) strlen(S) - 1] != ' ')
361         return strcpy(Result, S);
362     do {
363      /*    strdelete((void *)S, strlen(S), 1);  */
364      /*   remove trailing blank                 */
365         S[(int) strlen(S) - 1]='\0';
366         if (*S != '\0') {
367             if (S[(int) strlen(S) - 1] != ' ')
368                 Done = true;
369         }
370         else {
371             Done = true;
372         }
373     } while (!Done);
374     return strcpy(Result, S);
375 }
376
377
378 Static Char *
379 UPCASE_STRING(Char *Result, Char *S_)
380 {
381     Char S[256];
382     short I, FORLIM;
383
384     strcpy(S, S_);
385     FORLIM = (short) strlen(S);
386     for (I = 0; I < FORLIM; I++)
387         S[I] = toupper(S[I]);
388     return strcpy(Result, S);
389 }
390
391
392 Static void
393 FIX_STRING(Char *S)
394 {
395     Char STR1[256], STR2[256], STR3[256];
396
397     strcpy(S, UPCASE_STRING(STR1, STRRTRIM(STR2, STRLTRIM(STR3, S))));
398 }
399
400
401 Static Char *
402 TOHEXSTR(Char *Result, short Num)
403 {
404     static Char the_chars[16] = "0123456789ABCDEF";
405     short I;
406
407     Result[4] = '\0';
408     for (I = 0; I <= 3; I++)
409         Result[3 - I] = the_chars[(((unsigned)Num) >> (I * 4)) & 0xf];
410     return Result;
411 }
412
413
414 Static void
415 SUBTIME(__TIME Time2, __TIME Time1, __TIME *Time_Out)
416 {
417     if (Time1.Hund < Time2.Hund) {
418         Time1.Sec--;
419         Time1.Hund += 100;
420     }
421     Time_Out->Hund = Time1.Hund - Time2.Hund;
422     if (Time1.Sec < Time2.Sec) {
423         Time1.Min--;
424         Time1.Sec += 60;
425     }
426     Time_Out->Sec = Time1.Sec - Time2.Sec;
427     if (Time1.Min < Time2.Min) {
428         Time1.Hour--;
429         Time1.Min += 60;
430     }
431     Time_Out->Min = Time1.Min - Time2.Min;
432     Time_Out->Hour = Time1.Hour - Time2.Hour;
433 }
434
435
436 Static void
437 GET_TIME(__TIME *Cur_Time)
438
439    ;
440 }
441
442
443 Static void
444 COM_INT_ROUTINE(void)
445 {
446     uchar Com_Num, In_Char;
447     boolean Use_It;
448 ;
449 }
450
451
452 Static void
453 RS232_CLEANUP(uchar Com)
454 {
455 ;
456 }
457
458
459 /*Static */void
460 DONE(void)
461 {
462     (void) cleanup(0);
463
464 }
465
466
467 Static void
468 __ERROR(short Num, short Where)
469 {
470     Char STR2[256];
471
472     printf("\nProgram terminated before completed.\n");
473     printf("Program counter is $%s.  Error Number is %d.\n",
474            TOHEXSTR(STR2, Where), Num);
475     DONE();
476 }
477
478
479 int
480 MODULE_ERR(Char *S)
481 {
482    perror(S);
483    if(fprintf(__Message_File, "*** Fatal Error ***  %s\n", S) < 0) {
484      perror("MODULE_ERR: fprintf: ");
485      DONE();
486    }
487    DONE();
488    return 1;
489
490 }
491
492
493 Static void
494 SET_DATA_COM(__BAUD_TYPE Speed, uchar Parity, uchar Stop, uchar Data_Bits,
495              uchar Com)
496 {
497
498 ;
499 }
500
501 /* Only supporting test terminal (no reference terminal).  If support
502    reference terminal, must pass in correct file descriptor. Now,
503    var "Com" is not used. Only left in to keep from having to make
504    changes.                                                           */
505 Static void
506 FLUSH_BUFFER_COM(short Com)
507 {
508
509     if(tcflush(fd_test,TCIOFLUSH) < 0) {
510        MODULE_ERR("FLUSH_BUFFER_COM: tcflush:"); 
511        DONE();
512     } 
513 }
514
515 /* No refernece terminal supported, only 1 (test) terminal to flush. */
516 Static void
517 FLUSH_BUFFERS(void)
518 {
519   FLUSH_BUFFER_COM(1);
520    
521 }
522
523
524 Static short
525 READY(uchar Com, short Time_Out)
526 {
527 ;
528
529 }
530
531
532 #define enq_count       80
533 #define time_out_const  32000
534
535 /*
536 Static void
537 RS232_OUT(Char Param, uchar Com)
538 {
539
540 ;
541
542 }
543 */
544
545 #undef enq_count
546 #undef time_out_const
547
548 /* Only test terminal supported. */
549 Static void
550 __WRITE_BOTH(Char Ch)
551 {
552    Char STR1[256];
553
554    sprintf(STR1,"%s",Ch);
555    WRITETEST(STR1);
556
557 }
558
559 /*
560 Static void
561 RS232_INIT(uchar Com)
562 {
563 ;
564
565 }
566 */
567
568 Static void
569 INIT_DEFAULTS(int Echo)
570 {
571
572 /* These can be removed, they are not used functionally.  Only to keep
573    some having to change some function parameters.
574 */
575 char Device[30];
576     Test_Com = __default_test_term;
577     Ref_Com = __default_ref_term;
578     Aux_A_Com = __default_aux_a;
579     Aux_B_Com = __default_aux_b;
580     __Refpres = (__default_ref_term != 0);
581     __Aux_A_Pres = (__default_aux_a != 0);
582     __Aux_B_Pres = (__default_aux_b != 0);
583     __Data_Com[0] = __default_datacom_rec;
584     __Data_Com[1] = __default_datacom_rec;
585     __Data_Com[2] = __default_datacom_rec;
586     __Data_Com[3] = __default_datacom_rec;
587     /* __Rs_Time_Out = false;               */
588 /* ****************************************************************/ 
589
590     /* Open /dev/tty and obtain file descriptor and FILE pointer. */
591     if((fd_test = open("/dev/tty", O_RDWR)) < 0) {
592       (void) perror("INIT_DEFAULTS: /dev/tty open:");
593       (void) exit(1);
594     }
595
596     f_test = fdopen(fd_test, "w"); 
597     (void) setvbuf(f_test, (char *) 0, _IONBF, 0);
598
599     /* get struct termio for later restoration and use for setting defaults */
600     if(tcgetattr(fd_test, &termio_orig) < 0) {
601       (void) perror("INIT_DEFAULTS: tcgetattr:");
602       (void) exit(1);
603     }
604     
605     /* Default settings determined from PANACOM tests, and translated to
606        HP_UX environment. Along with default settings using struct termios. */
607
608 /* Canonical Input is OFF  */
609
610     termio_test = termio_orig;
611     termio_test.c_iflag &= ~(ICRNL | IUCLC | IXANY);
612     termio_test.c_iflag |= (IXON | IXOFF);  
613     termio_test.c_lflag &= ~(ICANON | ECHO);
614     termio_test.c_cflag |= (CS8 | CREAD);
615     termio_test.c_cc[VMIN] = 1;    
616     termio_test.c_cc[VTIME] = 0;  
617   
618    
619 /* Canonical Input is ON  */
620 /*
621    termio_test = termio_orig;
622    termio_test.c_iflag |= (IXON | IXOFF);
623    termio_test.c_lflag |= (ICANON);
624    termio_test.c_lflag &= ~(ECHO);
625    termio_test.c_cflag |= CS8; 
626    termio_test.c_cc[VINTR] = _POSIX_VDISABLE;
627    termio_test.c_cc[VQUIT] = _POSIX_VDISABLE;
628    termio_test.c_cc[VERASE] = _POSIX_VDISABLE;
629    termio_test.c_cc[VKILL] = _POSIX_VDISABLE;
630    termio_test.c_cc[VEOF] = _POSIX_VDISABLE;
631 */
632      
633
634
635 /* turn on signal handlers... */
636     (void) signal(SIGHUP, cleanup);
637     (void) signal(SIGINT, cleanup);
638     (void) signal(SIGQUIT, cleanup);
639     (void) signal(SIGTERM, cleanup);
640
641     /* set a 2 minute timeout... */
642     (void) signal(SIGALRM, timeout);
643     /* (void) alarm(240);  */
644
645
646     /* set new terminal control attributes */
647     if(tcsetattr(fd_test,TCSADRAIN,&termio_test) < 0) {
648       (void) perror("tcsetattr New");
649       (void) exit(1);
650     }
651
652     /* default terminal settings  */
653     SPEEDTEST(B9600);
654     PARITYTEST("4");                  /* 8 bit no parity */
655     HANDSHAKE_COM("X");               /* IXON and IXOFF  */
656     if (Echo) ECHO_COM("ON");         /* echoing on     */
657     else ECHO_COM("OFF");         /* echoing off     */
658
659 }
660
661
662 Local boolean
663 CHECK_COM(uchar Test)
664 {
665    return true;
666
667 }
668
669
670 Static boolean
671 PORT_ASSIGNMENTS_OK(uchar Test, uchar Ref, uchar Aux_A, uchar Aux_B)
672 {
673     boolean Ok;
674     
675     Ok = true;       /* don't need */
676     return Ok;
677
678 }
679
680
681 /* Local variables for START: */
682 struct LOC_START {
683     short I, J;
684 } ;
685
686 /* Local variables for GET_PARAMS: */
687 struct LOC_GET_PARAMS {
688     struct LOC_START *LINK;
689 } ;
690
691
692 /* gets name of program to use for log file name */ 
693 Local Char *
694 GET_PROG_NAME(Char *Result, struct LOC_GET_PARAMS *LINK)
695 {
696     short Addres, I, J;
697     Char Path[256];
698
699     /* Just using argc and argv to return program name. */
700     return strcpy(Result,P_argv[0]);
701 }
702
703
704 /* during pasrsing of command line. Sets the value for the 4 different
705    Com ports.  Not functionally needed anymore
706 */
707 Local boolean
708 PUT_NUM(uchar *Default, Char *Buffer, struct LOC_GET_PARAMS *LINK)
709 {
710     boolean Ok;
711
712     Ok = ((int) strlen(Buffer) == 4);
713     if (!Ok)
714         return Ok;
715     if (Buffer[3] >= '0' && Buffer[3] <= '4')
716         *Default = Buffer[3] - '0';
717     else
718         Ok = false;
719     return Ok;
720 }
721
722 /* Used to grab string that will be place in global var: __Command_Line.
723    This is associated with option: -C. 
724 */
725 Local void
726 GET_COMMAND_LINE(short *I, Char *Current_, struct LOC_GET_PARAMS *LINK)
727 {
728     Char Current[256];
729     Char STR1[256];
730     short FORLIM;
731
732     strcpy(Current, Current_);
733     strcpy(Current, strsub(STR1, Current, strpos2(Current, "\"", 1) + 1,
734                            (int) strlen(Current)));
735     sprintf(STR1, "%.*s", strpos2(Current, "\"", 1) - 1, Current);
736     strcpy(Current, STR1);
737     if (Current[0] == ' ')
738         (*I)++;
739     FORLIM = (int) strlen(Current);
740     for (LINK->LINK->J = 2; LINK->LINK->J <= FORLIM; LINK->LINK->J++) {
741         if (Current[LINK->LINK->J - 1] == ' ' && Current[LINK->LINK->J - 2] != ' ')
742             (*I)++;
743     }
744     strcpy(__Command_Line, Current);
745 }
746
747 /* Parses command line, looking at each option and doing the right thing. */
748 Local void
749 GET_PARAMS(struct LOC_START *LINK)
750 {
751     struct LOC_GET_PARAMS V;
752     Char Buffer[256], Current[256];
753
754     
755     boolean Bad_Params;
756     Char STR1[256];
757     Char STR2[256];
758
759     V.LINK = LINK;
760
761     __Group_Not_Running = true;
762 #if 0
763     sprintf(__File_Name, "%s.LOG", GET_PROG_NAME(STR1, &V));
764 #endif
765    
766     *__Command_Line = '\0';   
767     
768     LINK->I = 1;
769     Bad_Params = false;
770     while (LINK->I < P_argc && !Bad_Params) {
771         strcpy(Buffer, P_argv[LINK->I]);
772         if ((char) Buffer[0] != '-' || (int) strlen(Buffer) < 2) {
773             Bad_Params = true;
774             break;
775         }
776         switch (toupper(Buffer[1])) {
777
778           case 'T':
779             if (!PUT_NUM(&__default_test_term, Buffer, &V))
780                 Bad_Params = true;
781             break;
782
783           case 'R':
784             if (!PUT_NUM(&__default_ref_term, Buffer, &V))
785                 Bad_Params = true;
786             break;
787
788           case 'A':
789             if (!PUT_NUM(&__default_aux_a, Buffer, &V))
790                 Bad_Params = true;
791             break;
792
793           case 'B':
794             if (!PUT_NUM(&__default_aux_b, Buffer, &V))
795                 Bad_Params = true;
796             break;
797
798           case 'C':
799               GET_COMMAND_LINE(&LINK->I, P_argv[LINK->I], &V);
800             break;
801
802           case 'M':
803             if (strlen(Buffer) == 4) {
804                 if (toupper(Buffer[3]) == 'Y') {
805                     __Manual = true;
806                 }
807                 else if (toupper(Buffer[3]) != 'Y')
808                     Bad_Params = true;
809             }
810             else {
811                 Bad_Params = true;
812             }
813             break;
814
815           case 'E':
816             __Log_Every_Thing = true;
817             __Log_Msg = true;
818             break;
819
820           case 'L':
821             __Log_Msg = true;
822             if ((int) strlen(Buffer) > 3)
823                 strsub(__File_Name, Buffer, 4, strlen(Buffer));
824             break;
825
826           case 'D':
827          /*   __Group_Not_Running = false;  */
828          /*  Option 'D' is being switched to debug mode. */
829             
830             __DEBUG = 1;
831             break;
832
833           default:
834             Bad_Params = true;
835             break;
836         }
837         LINK->I++;
838     }
839     if (Bad_Params)
840         MODULE_ERR("Bad parameter line.  Please see manual for information");
841     if (!PORT_ASSIGNMENTS_OK(__default_test_term, __default_ref_term,
842                              __default_aux_a, __default_aux_b))
843         MODULE_ERR("Bad Port assignments in command line. See manual");
844     sprintf(__Command_Line, "NM%s", strcpy(STR2, __Command_Line));
845     if (!__Manual)
846         __Command_Line[1] = 'A';
847     if (__Refpres)
848         __Command_Line[0] = 'R';
849 }
850
851 /* Initialize routine. Every program call this.  */
852 /* The 4 com ports are not functionally needed.  */
853 /*Static */void
854 START(uchar Test, uchar Ref, uchar Aux1, uchar Aux2, int Echo)
855 {
856
857
858     struct LOC_START V;
859     _PROCEDURE TEMP;
860
861     __Refpres = false;
862     __Aux_A_Pres = false;
863     __Aux_B_Pres = false;
864     if (!PORT_ASSIGNMENTS_OK(Test, Ref, Aux1, Aux2))
865         MODULE_ERR("Invalid ports specified in START.  See manual for details");
866     __Manual = false;
867
868     
869     __Log_Msg = false;
870     __Log_Every_Thing = false;
871
872     /* set system variables based upon input from command line options. */    
873     GET_PARAMS(&V);
874     if (__Log_Msg) {
875         strcpy(__Message_File_NAME, __File_Name);
876         if (__Message_File != NULL)
877             __Message_File = freopen(__Message_File_NAME, "w", __Message_File);
878         else
879             __Message_File = fopen(__Message_File_NAME, "w");
880         _SETIO(__Message_File != NULL, FileNotFound);
881         if (P_ioresult != 0)
882             MODULE_ERR("Illegal log file name specified OR not DOS 3.x");
883     }
884     INIT_DEFAULTS(Echo);
885 }
886
887
888 /* prints to xxx.LOG file all data read and written thru READ_COM and 
889    WRITE_COM.  Triggered by option -E, __Log_EveryThing.
890 */
891 Static void
892 LOG_IT(char *S, short Howmany, Char Which_Way)
893 {
894     short I, Count;
895     Char Who[256];
896     Char S1[3];
897     boolean Ok;
898     Char STR1[256];
899
900     Count = 1;
901    
902     strcpy(Who,"Terminal"); 
903     switch (Which_Way) {
904
905       case 'R':
906         strcat(Who, " ==> HOST");
907         break;
908
909       case 'W':
910         sprintf(Who, "HOST ==> %s", strcpy(STR1, Who));
911         break;
912
913       default:
914         MODULE_ERR("Bad call to Log_it.  Bad \"which_way\"");
915         break;
916     }
917     
918  
919     _SETIO(fprintf(__Message_File, "%s\n", Who) >= 0, FileWriteError);
920     Ok = (P_ioresult == 0);
921     
922     if(fprintf(__Message_File, "%s\n",vis(S)) < 0) {
923       perror("fprintf __Message_File");
924     } 
925
926
927 }
928
929 /* have not seen a use for yet */
930 #define display_row     25
931 #define line_length     79
932
933
934 Local Char
935 READ_CHAR(void)
936 {
937
938 ;
939
940 }
941
942
943 Static boolean
944 YESNOKEY(Char *Prompt_, boolean Default)
945 {
946 ;
947
948 }
949
950 #undef display_row
951 #undef line_length
952
953
954 Static short
955 ASCIIINT(Char *S, short *Er)
956 {
957     short I;
958
959     I = 0;
960     if ((int) strlen(S) > 10) {
961         *Er = 0;
962         return I;
963     }
964     *Er = (sscanf(S, "%hd", &I) == 0);
965     if (*Er == 0)
966         *Er = 2;
967     else
968         *Er = 1;
969     return I;
970 }
971
972
973 Static Char *
974 INTASCII(Char *Result, short Num)
975 {
976     Char St[256];
977
978     sprintf(St, "%d", Num);
979     return strcpy(Result, St);
980 }
981
982
983 Static char * 
984 READ_COM(int fd, char *terminator)
985 {
986     char *c;
987     char STR1[BUFSIZ];
988    
989
990     /* Based upon settings of strap G and H determine Handshake scheme. */
991     /* Currently, on support 3 versions of the handshake scheme.        */
992 #if 0
993     if(!inh_hndshk && inh_DC2)
994        WRITETEST("\021");        /* default, DC1 handshake  */
995
996     else if(inh_hndshk && !inh_DC2) {  /* DC1-DC2-DC1 handshake */
997           ;
998
999     }
1000     else if(inh_hndshk && inh_DC2)
1001        ;                               /* NO hand shake */
1002     else
1003        MODULE_ERR("ERROR, illegal combination of hand shake parameters."); 
1004 #endif
1005
1006
1007     /* Determine termination character for read statements.              */
1008     /* Currently just work with auto line feed or not.                   */
1009 /*
1010     if(autolf_mode)
1011       terminator="\n";
1012     else
1013       terminator="\r";
1014 */
1015
1016
1017     /* Read in data form /dev/tty. Input_Terminator is set globally */
1018     /* Read til get terminating char.                               */
1019     c=in(fd_test,STR1, sizeof(STR1), terminator);
1020     if(autolf_mode)
1021         STR1[(int) strlen(STR1) - 2] = '\0';   /* remove "CR and new line  */         
1022     else
1023         STR1[(int) strlen(STR1) - 1] = '\0';   /* just remove terminating char */
1024     return(STR1);
1025 }
1026
1027 /* Reference terminal not supported. */
1028 Static char * 
1029 READREF()
1030 {
1031 ;
1032 }
1033
1034
1035 /*Static */char * 
1036 READTEST(char *Terminator)
1037 {  
1038     char *tmp;
1039     char STR[BUFSIZ];
1040     
1041     tmp = READ_COM(fd_test, Terminator);
1042     strcpy(STR,tmp);
1043
1044     if(__Log_Every_Thing)
1045       LOG_IT(STR, sizeof(STR),'R');
1046     return STR;  
1047 }
1048
1049
1050 Static short
1051 STRCOMP(Char *S1, Char *S2)
1052 {
1053     short I, J;
1054     boolean Still_The_Same;
1055
1056     if (!strcmp(S1, S2)) {
1057         return 0;
1058     }
1059     else {
1060         I = (int) strlen(S1);
1061         if ((int) strlen(S2) < I)
1062             I = (int) strlen(S2);
1063         J = 1;
1064         Still_The_Same = true;
1065         while (J <= I && Still_The_Same) {
1066             if (S1[J - 1] != S2[J - 1])
1067                 Still_The_Same = false;
1068             else
1069                 J++;
1070         }
1071         return J;
1072     }
1073 }
1074
1075 /* set termio flag ECHO based on user input from test script */
1076 /* Variable "Com" is not used, it is left in to keep from modifying */
1077 /* most tests.                                                       */
1078
1079 /* Currently, this function only supports a test terminal (no reference
1080    terminal). If reference terminal is to be supported, the correct 
1081    termios structure will have to be passed in.    
1082 */
1083
1084
1085 /* ECHO_COM  used to return void, but to keep compiler happy, I
1086    changed to return type of int.
1087    Error msg was: Inconsistent type declaration: ECHO_COM          */
1088 int
1089 ECHO_COM(char *S_)
1090 {   
1091     if(!strcmp(S_,"ON"))
1092       termio_test.c_lflag |= ECHO;
1093     else
1094       termio_test.c_lflag &= ~ECHO;
1095
1096    
1097     /* set new terminal control attributes */
1098     if(tcsetattr(fd_test,TCSADRAIN,&termio_test) < 0) {
1099       (void) perror("tcsetattr: ECHO ");
1100       (void) exit(1);
1101     } 
1102
1103 }
1104
1105
1106 Static void
1107 INTERM_COM(uchar Com, Char *S)
1108 {
1109    strcpy(Input_Terminator, S);
1110
1111 }
1112
1113
1114 Static void
1115 INTRIG_COM(uchar Com, Char *S)
1116 {
1117     strcpy(Input_Trigger,S);
1118
1119 }
1120
1121
1122 void
1123 _ECHO(char *S__)
1124 {
1125     uchar I=0;       /* "I" is a dummy var */ 
1126     ECHO_COM(S__);   
1127  
1128 }
1129
1130
1131 Static void
1132 INTERM(Char *S)
1133 {
1134     short I=0;
1135     INTERM_COM(I,S);
1136
1137 /*   not set up for more than 1 terminal
1138     for (I = 1; I <= 4; I++)
1139         INTERM_COM(I, S);
1140 */
1141 }
1142
1143
1144 Static void
1145 INTRIG(Char *S)
1146 {
1147     short I=0;
1148     INTRIG_COM(I,S);
1149
1150 /*   not set up for more than 1 terminal
1151     for (I = 1; I <= 4; I++)
1152         INTRIG_COM(I, S);
1153 */
1154 }
1155
1156
1157 Static void
1158 LOGMSG(Char *S)
1159 {
1160     if (__Log_Msg) {  /*$I-*/
1161         _SETIO(fprintf(__Message_File, "%s\n", S) >= 0, FileWriteError);
1162         if (P_ioresult != 0)
1163             MODULE_ERR("Error writing to Message File. Disk may be full");
1164     }
1165     puts(S);
1166 }
1167
1168
1169 Local boolean
1170 GET_PARITY(Char *S_, uchar Com)
1171 {
1172 ;
1173 }
1174
1175
1176 Static void
1177 PARITY_COM(struct termios *term, Char *Par)
1178 {
1179   switch (Par[0]) {
1180
1181       case '0':
1182         term->c_cflag |= (PARENB | PARODD);
1183         break;
1184
1185       case '1':
1186         term->c_cflag |= PARENB;
1187         term->c_cflag &= ~(PARODD);
1188         break;
1189
1190       case '2':
1191         term->c_cflag |= PARENB;
1192         term->c_cflag &= ~(PARODD);
1193         break;
1194
1195       case '3':
1196         term->c_cflag |= (PARENB | PARODD);
1197         break;
1198
1199       case '4':
1200         term->c_cflag &= ~(PARENB);
1201         break;
1202     }
1203     if (Par[0] == '4')
1204         term->c_cflag |= CS8;
1205     else
1206         term->c_cflag |= CS7;
1207
1208     /* set new terminal control attributes */
1209     if(tcsetattr(fd_test,TCSADRAIN,&termio_test) < 0) {
1210       (void) perror("tcsetattr: attempting to set parity and data bits.");
1211     }
1212
1213 }
1214
1215
1216 Static void
1217 PARITYREF(Char *Par)
1218 {
1219 ;
1220 }
1221
1222
1223 /* PARITYTEST used to return void, but to keep compiler happy, I
1224    changed to return type of int.
1225    Error msg was: Inconsistent type declaration: PARITYTEST        */
1226 int
1227 PARITYTEST(Char *Par)
1228 {
1229     PARITY_COM(&termio_test, Par);
1230
1231     return 1;
1232 }
1233
1234
1235 Static void
1236 GET_BAUD(Char *S_, uchar Com, short *Code)
1237 {
1238 ;
1239
1240 }
1241
1242
1243 Static void
1244 SPEED_COM(struct termios *term, speed_t sp)
1245 {
1246
1247     if(cfsetospeed(term,sp) < 0) {
1248       (void) perror("cfsetospeed: illegal baud rate");
1249     }
1250     if(cfsetispeed(term,sp) < 0) {
1251       (void) perror("cfsetispeed: illegal baud rate");
1252     } 
1253
1254     /* set new terminal control attributes */
1255     if(tcsetattr(fd_test,TCSADRAIN,&termio_test)) {
1256       (void) perror("tcsetattr: attempting to set baud rate");
1257     }
1258
1259 }
1260
1261
1262 Static void
1263 SPEEDREF(speed_t S)
1264
1265 ;
1266
1267 }
1268
1269
1270 /* SPEEDTEST used to return void, but to keep compiler happy, I
1271    changed to return type of int.
1272    Error msg was: Inconsistent type declaration: SPEEDTEST         */
1273 int
1274 SPEEDTEST(speed_t S)
1275 {
1276    
1277    SPEED_COM(&termio_test,S);
1278    return 1;
1279  
1280 }
1281
1282
1283 Static void
1284 TIMEOUT_COM(uchar Com, Char *S)
1285 {
1286 ;
1287
1288 }
1289
1290
1291 Static void
1292 TIMEOUT(Char *S)
1293 {
1294 ;
1295
1296 }
1297
1298
1299 Static void
1300 WRITE_COM(FILE *f, Char *S)
1301 {
1302     if(fputs(S,f) < 0) {
1303       MODULE_ERR("WRITE ERROR,fputs");
1304       perror("fputs");
1305      exit(1);
1306     }
1307
1308 }
1309
1310
1311 Static void
1312 WRITEREF(Char *S_)
1313 {
1314 ;  /* refernece terminal not supported */
1315
1316 }
1317
1318 /* WRITETEST used to return void, but to keep compiler happy, I
1319    changed to return type of int. 
1320    Error msg was: Inconsistent type declaration: WRITETEST         */
1321 int 
1322 WRITETEST(Char *S_)
1323 {
1324     WRITE_COM(f_test, S_);
1325     if(__Log_Every_Thing)
1326       LOG_IT(S_,sizeof(buffer),'W');
1327     return 1;
1328 }
1329
1330
1331 /* HANDSHAKE_COM used to return void, but to keep compiler happy, I
1332    changed to return type of int.
1333    Error msg was: Inconsistent type declaration: HANDSHAKE_COM       */
1334 /* Not used functionally */
1335 int
1336 HANDSHAKE_COM(char *S)
1337 /*  HANDSHAKE_COM(uchar Com, char *S) */
1338 {
1339     if (toupper(S[0]) == 'N' || toupper(S[0]) == 'B' ||
1340          toupper(S[0]) == 'X' || toupper(S[0]) == 'E')
1341         HAND_SHAKE = toupper(S[0]);
1342     else
1343         MODULE_ERR("Bad handshaking driver type in HandShake_Com");
1344
1345     return 1;
1346
1347 }
1348
1349
1350 Static void
1351 IOCONFIG(Char *S)
1352 {
1353 ;
1354
1355 }
1356
1357
1358 Static void
1359 DATACOMM_COM(uchar Com, Char *Baud, Char *Time_Out, Char *Hand,
1360              Char *Echo_Var, Char *Interm_Var, Char *Intrig_Var)
1361 {
1362 ;
1363
1364 }
1365
1366
1367 Static void
1368 DATACOMM(Char *Baud, Char *Time_Out, Char *Hand, Char *Echo_Var,
1369          Char *Interm_Var, Char *Intrig_Var, boolean Refpres)
1370 {
1371 ;
1372
1373 }
1374
1375
1376 Static void
1377 INITINFO(Char *S)
1378 {
1379     strcpy(S, __Command_Line);
1380 }
1381
1382
1383 Static void
1384 __setstrlen(Char *s, short l)
1385 {
1386     s[l] = '\0';
1387 }
1388
1389
1390 void ding()
1391 {
1392
1393 /* if (debug)
1394         (void) fputs(">> ding!!\n", log);
1395 */
1396     return;
1397 }
1398
1399 void timeout(int sig)
1400 {
1401     /* reset the signal handler... */
1402     if (sig)
1403         (void) signal(sig, timeout);
1404
1405     (void) fprintf(stderr, "timeout!\n");
1406     (void) cleanup();
1407 }
1408
1409
1410 /* Shutdown orderly and restore terminal back to original condition. */
1411 void cleanup(int sign)
1412 {
1413     /* reset the signal handler... */
1414     if (sign)
1415         (void) signal(sign, cleanup);
1416     (void)fflush(__Message_File);
1417     
1418     /* restore terminal terimo... */
1419     if (fd_test >= 0) {
1420       if(tcsetattr(fd_test,TCSAFLUSH,&termio_orig) < 0) {
1421         (void) perror("tcsetattr Cleanup");
1422         return;
1423       }
1424     }
1425
1426
1427  #if 0
1428    /* restore terminal configuration... */
1429     if (f_test) {
1430         (void) fputs("\033X", f_test);  /* turn off format mode.. */
1431         (void) fputs("\033&k0B", f_test);    /* turn off block mode.  */
1432         (void) fputs("\033&k0A", f_test);    /* turn off autolf mode. */
1433     }
1434  #endif 
1435
1436     return;
1437 }
1438
1439
1440 /* Reads from stream until the terminating char is found.  */
1441 char *
1442 in(int fd, char *buffer, int bufsiz, char *term)
1443 {
1444     static char holdbuffer[BUFSIZ];
1445     static int holdbufsiz = 0;
1446     char *c;
1447     int i;
1448
1449     c = buffer;
1450     /* copy over the hold buffer... */
1451
1452 #ifdef NOCODE                /* not required */
1453     if (holdbufsiz > 0) {
1454         /* copy it over... */
1455         (void) memcpy(buffer, holdbuffer, holdbufsiz);
1456
1457         /* set it's length... */
1458         i = holdbufsiz;
1459
1460         /* clear it... */
1461         holdbufsiz = 0;
1462     } else {
1463         i = 0;
1464     }
1465 #endif
1466     
1467     i=0;
1468     while (bufsiz > 0) {
1469         for (; i > 0; i--, c++, bufsiz--) {
1470             /* look for a valid terminalter... */
1471             if (strchr(term, *c)) {
1472                 /* found a terminator... */
1473                 /* move over 1 character... */
1474                 (void) c++;
1475                 (void) i--;
1476
1477                 /* copy the rest of the string into the hold buffer... */
1478                 if (i > 0) {
1479                     (void) memcpy(holdbuffer, c, i);
1480                     holdbufsiz = i;
1481                 }
1482
1483                 /* null out the next character... */
1484                 *c = '\0';
1485
1486                 /* and return string... */
1487                 strcat(buffer, term);
1488                 return(buffer);
1489             }
1490         }
1491         if ((i = read(fd, c, bufsiz)) < 0) {
1492             (void) perror("read");
1493             (void) cleanup(0);
1494         }
1495
1496     }
1497 }
1498
1499
1500
1501
1502
1503 /*  prints out all invisible and visible chars */
1504 char
1505 *vis(char *buf)  
1506 {
1507  static char visbuffer[BUFSIZ];
1508     char *c;
1509
1510     for (c = visbuffer; *buf; ) {
1511         if (*buf < 0x20) {
1512             *c++ = '^';
1513             *c++ = '@' + *buf++;
1514         } else if (*buf == '\\') {
1515             *c++ = *buf;
1516             *c++ = *buf++;
1517         } else if (*buf < 0x7f) {
1518             *c++ = *buf++;
1519         } else {
1520             *c++ = '\\';
1521             *c++ = '\0' + (*((unsigned char *) buf) >> 6) & 07;
1522             *c++ = '\0' + (*((unsigned char *) buf) >> 3) & 07;
1523             *c++ = '\0' + (*((unsigned char *) buf++) >> 0) & 07;
1524         }
1525     }
1526
1527     /* null out end of buffer... */
1528     *c = '\0';
1529
1530     return(visbuffer);
1531 }
1532
1533
1534
1535 void FLUSHTEST()
1536 {
1537    fflush(f_test);
1538 }
1539
1540 #endif