<*+M2EXTENSIONS *> <*-CHECKDIV *> <*-CHECKRANGE *> <*-COVERFLOW *> <*-IOVERFLOW*> <*+NOPTRALIAS*> <*CPU="PENTIUM"*> <*COMPILERHEAP="100000000"*> <*-CHECKNIL *> <*-DOREORDER*> <*-CHECKINDEX*> <*-CHECKSET*> <* IF __GEN_C__ THEN *> <*+COMMENT*> <*-GENCTYPES*> <*-GENDEBUG*> <*-LINENO*> <*-GENHISTORY*> <*-GENDATE*> <*+NOHEADER*> <*+GENCDIV*> <*-GENKRC*> <*+NOOPTIMIZE*> <*-GENSIZE*> <*-ASSERT*> <*GENWIDTH="240"*> <* ELSE *> <*-PROCINLINE*> <*-GENDEBUG*> <*-LINENO*> <*-GENHISTORY*> <* END *> MODULE ttytee; (* read serial port send to unbreakable pipe(s) *) IMPORT udp; FROM osi IMPORT OpenNONBLOCK, OpenWrite, NextArg, WrInt, WrCard, ALLOCATE, WrLn, WrStr, WrStrLn, OpenRead, WrBin, RdBin, setttybaudraw, OpenRW, usleep, Close, IsFifo, Werr, WerrLn; FROM signal IMPORT signal, SIGTERM, SIGINT, SIGPIPE, sighandler_t; FROM aprsstr IMPORT Assign; TYPE SET16=SET OF [0..15]; SET8 =SET OF [0..7]; pPIPE=POINTER TO PIPE; PIPE=RECORD next:pPIPE; pipename:ARRAY[0..1023] OF CHAR; pipefd:INTEGER; END; VAR outpipes:pPIPE; dat, ttynamee:ARRAY[0..1023] OF CHAR; verb, usbrobust:BOOLEAN; datlen, tty:INTEGER; baud:CARDINAL; PROCEDURE Error(text:ARRAY OF CHAR); BEGIN Werr("ttytee: "); Werr(text); WerrLn(" error abort"); HALT END Error; PROCEDURE SetComMode(fd:INTEGER; baud:CARDINAL); VAR res : INTEGER; BEGIN IF setttybaudraw(fd, baud)<0 THEN IF verb THEN WerrLn("cannot config tty") END; END; END SetComMode; PROCEDURE opentty; BEGIN LOOP tty:=OpenRW(ttynamee); IF tty>=0 THEN SetComMode(tty, baud); EXIT ELSIF NOT usbrobust THEN Error("tty open") ELSIF verb THEN WerrLn("tty open error") END; usleep(1000000); END; END opentty; PROCEDURE testtty(len:INTEGER); BEGIN IF len<=0 THEN Close(tty); usleep(1000000); opentty; END; END testtty; PROCEDURE GetNum(h-:ARRAY OF CHAR; eot:CHAR; VAR p,n:CARDINAL):BOOLEAN; BEGIN n:=0; WHILE (h[p]>="0") & (h[p]<="9") DO n:=n*10+ORD(h[p])-ORD("0"); INC(p); END; RETURN h[p]=eot END GetNum; PROCEDURE Parms; VAR err:BOOLEAN; h:ARRAY[0..1023] OF CHAR; p:pPIPE; i:CARDINAL; BEGIN err:=FALSE; LOOP NextArg(h); IF h[0]=0C THEN EXIT END; IF (h[0]="-") & (h[1]<>0C) & (h[2]=0C) THEN IF h[1]="u" THEN usbrobust:=FALSE ELSIF h[1]="p" THEN NextArg(h); ALLOCATE(p, SIZE(p^)); IF p=NIL THEN Error("out of memory") END; Assign(p^.pipename, h); p^.pipefd:=-1; p^.next:=outpipes; outpipes:=p; ELSIF h[1]="t" THEN NextArg(h); i:=0; WHILE (h[i]<>0C) & (h[i]<>":") & (i0C THEN INC(i); IF NOT GetNum(h, 0C, i, baud) THEN Error("need ttydevice:baud") END; END; ELSIF h[1]="v" THEN verb:=TRUE ELSIF h[1]="h" THEN WrLn; WrStrLn("Read (unbreakable USB) serial port and send to unbreakable pipe(s)"); WrStrLn(" -h this"); WrStrLn(" -p may be repeatet"); WrStrLn(" -t : (/dev/ttyS0:4800)"); WrStrLn(" -u abort, not retry until open removable USB tty"); WrStrLn(" -v verbous"); WrLn; WrStrLn('before use make pipes with "mknod p"'); WrStrLn('for data on stdout as "tee" does, append "-p /dev/stdout"'); WrLn; HALT ELSE err:=TRUE END; ELSE err:=TRUE END; IF err THEN EXIT END; END; IF err THEN WrStr(">"); WrStr(h); WrStrLn("< use -h"); HALT END; END Parms; PROCEDURE ["C"] pipebroken(signum:INTEGER); BEGIN WrStr("got signal "); WrInt(signum,0); WrStrLn("!"); END pipebroken; VAR p:pPIPE; BEGIN signal(SIGPIPE, pipebroken); verb:=FALSE; usbrobust:=TRUE; baud:=4800; ttynamee:="/dev/ttyS0"; outpipes:=NIL; Parms; opentty; LOOP datlen:=RdBin(tty, dat, SIZE(dat)); testtty(datlen); p:=outpipes; WHILE p<>NIL DO WITH p^ DO IF pipename[0]<>0C THEN IF pipefd<0 THEN pipefd:=OpenNONBLOCK(pipename); IF verb & (pipefd>=0) & NOT IsFifo(pipefd) THEN WerrLn(""); Werr("warning: ");Werr(pipename); WerrLn(" is not a fifo!"); END; -- IF pipefd<0 THEN pipefd:=OpenWrite(pipename) END; END; END; IF pipefd>=0 THEN WrBin(pipefd, dat, datlen) END; END; p:=p^.next; END; END; END ttytee.