Amiga-Request@cs.odu.edu (Amiga Sources/Binaries Moderator) (06/28/90)
Submitted-by: Matt Dillon <@uunet.uu.net:overload!dillon> Posting-number: Volume 90, Issue 186 Archive-name: unix/uucp-1.06d/part08 #!/bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 8 (of 12)." # Contents: uucp2/src/getty/getty.c uucp2/src/uucico/gio.c # Wrapped by tadguy@xanth on Thu Jun 28 08:21:31 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'uucp2/src/getty/getty.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'uucp2/src/getty/getty.c'\" else echo shar: Extracting \"'uucp2/src/getty/getty.c'\" \(20766 characters\) sed "s/^X//" >'uucp2/src/getty/getty.c' <<'END_OF_FILE' X X/* X * GETTY.C X * X * $Header: Beta:src/uucp/src/getty/RCS/getty.c,v 1.1 90/02/02 12:13:30 dillon Exp Locker: dillon $ X * X * (C)Copyright 1989, Matthew Dillon, All Rights Reserved X * X * Uses: X * GETTY:PASSWD X * GETTY:LOGFILE X * GETTY:Getty-Header X * X * GETTY <options> <modem-commands> X * X * -Sdevicenam Tells GETTY which serial.device to use, default X * serial.device X * X * -Uunitnum Tells GETTY which unit number to use, default 0 X * X * -A Always talk to the modem at the first baud X * rate in the -B list and ignore the baud rate X * in the CONNECT message. X * X * -7 use SERF_7WIRE while online. X * X * -Bn Set baud rate. If specified multiple times the X * first one is the default and remaining ones X * switched to when a BREAK is received after a X * connect. Also determines how CONNECT messages X * are interpreted. A CONNECT with no number uses X * the first -B entry while CONNECTs with numbers X * use those numbers regardless of any -B entries. X * X * -Mc Set modem type: X * c = m = multimodem X * h = hays X * d = dumb (no AT or +++ cmds are ever sent), X * normally used with only one specified X * baud rate. X * X * -m1 Turn on the modem speaker during dialing/connect X * (default is -m0) X * X * -h0 Ignore CD (carrier detect), default is to use X * carrier detect. X * X * -c0 Ignore CONNECT message (i.e. you are not connected X * to a modem, usually combined with -h0). Default is X * to expect a CONNECT message. X * X * -d0 do not use DTR to drop connection. Default is X * to drop DTR to drop a connection. If this option X * is chosen the +++ and ATH0 sequence will be used X * to drop a connection. X * X * -xn Set debug level. Also causes log output to go X * to stdout instead of GETTY:LOGFILE X * X * -0 QUIT - Kills any running getty for the specified X * port. X * X * Any fields specified without a '-' are considered modem commands X * used to initialize/reinitialize the modem. Up to 16 fields may X * be specified (each is sent to the modem in 1 second intervals) X */ X X#include <exec/types.h> X#include <exec/lists.h> X#include <exec/devices.h> X#include <devices/timer.h> X#include <devices/serial.h> X#include <libraries/dos.h> X#include <libraries/dosextens.h> X#include <hardware/cia.h> X#include <stdio.h> X#include <stdlib.h> X#include "protos.h" X#include <pwd.h> X#include "version.h" X X#include "log.h" X XIDENT(".02"); X X#ifndef IO_STATF_READBREAK X#define IO_STATF_READBREAK (IOSTF_READBREAK<<8) X#endif X X#define arysize(ary) (sizeof(ary)/sizeof((ary)[0])) X X#define ST_WAITCD 0 X#define ST_CONNECT 1 X#define ST_LOGIN 2 X#define ST_PASSWD 3 X#define ST_RUN 4 X Xtypedef struct IORequest IOR; Xtypedef struct timerequest IOT; Xtypedef struct IOExtSer IOSER; Xtypedef struct MsgPort PORT; Xtypedef struct List LIST; Xtypedef struct Node NODE; Xtypedef struct Message MSG; Xtypedef void (*FPTR)(); X Xtypedef struct GMsg { X struct Message Msg; X short Cmd; X long Data1; X void *Data2; X} GMsg; X Xextern struct ProcID *RunPasswdEntry(); X Xchar *CopyRight = "(c)Copyright 1989, Matthew Dillon, All Rights Reserved\r\n"; Xchar *ComPortName; X Xchar *DeviceName = "serial.device"; Xlong DeviceUnit = 0; Xlong NullFH; Xchar SpeakerLevel = 0; Xchar AnswerRing = 2; /* default, answer on second ring */ Xchar SpeakerOpt = 0; Xchar IgnoreCD = 0; Xchar IgnoreConnect = 0; Xchar IgnoreDTR = 0; Xchar BaudAdjust = 0; Xchar DropOnExit = 1; Xchar ModemType = 'h'; Xchar ZeroOption = 0; Xchar Wire7 = 0; /* use 7 wire while online */ Xchar Locked = 0; /* serial port is lcked */ Xlong Bauds[16] = { 9600 }; /* up 16 baud rates */ Xchar *AtFields[16]; X XPORT *ComPort; XPORT *IoSink; /* Sink for IO reqs. */ Xlong IoSinkMask; Xlong ComPortMask; X XIOT Iot; /* check-carrier */ XIOSER Iosr; /* serial read-req */ XIOSER Iosw; /* serial write-req */ X Xchar IotIP; /* Iot0 in progress */ Xchar IosrIP; X Xchar ScrBuf[256]; Xchar ConnectBuf[64]; Xchar LoginBuf[32]; Xchar PasswdBuf[32]; Xchar RxBuf[32]; Xchar HaveConnectMsg; Xchar HaveLogin; Xchar HavePasswd; X Xshort State; Xshort Index; Xshort BIndex; X Xshort CountDown; Xshort GotOffPort; X Xvoid SerPuts(); Xvoid Set7Wire(); Xvoid xexit(); Xvoid Disconnect(); Xvoid ClearRecv(); Xvoid InitModem(); Xvoid SetParams(); Xvoid DoOptions(); Xvoid SerialOff(); Xvoid InterceptDeviceVector(); Xvoid RestoreDeviceVector(); X Xbrk() X{ X return(0); X} X Xmain(ac, av) Xchar *av[]; X{ X extern int IAmGetty; X char termCr = 1; X char termLf = 1; X X IAmGetty = 1; /* for LockSerialPort()/UnLockSerialPort() */ X X puts(CopyRight); X fflush(stdout); X onbreak(brk); X X LogProgram = "Getty"; X LogWho = LoginBuf; X LogFile = "Getty:LOGFILE"; X PasswdFile = "Getty:Passwd"; X X DoOptions(ac, av); X X IoSink = CreatePort(NULL, 0); X IoSinkMask = 1 << IoSink->mp_SigBit; X X ComPortName = malloc(strlen(DeviceName) + 20); X sprintf(ComPortName, "Getty.%s.%ld", DeviceName, DeviceUnit); X X Forbid(); X if (ComPort = FindPort(ComPortName)) { X GMsg msg; X msg.Cmd = 'O'; X msg.Data1 = ac; X msg.Data2 = (void *)av; X msg.Msg.mn_ReplyPort = IoSink; X PutMsg(ComPort, &msg.Msg); X WaitPort(IoSink); X Remove(&msg.Msg.mn_Node); X Permit(); X puts("Options updated"); X xexit(0); X } X ComPort = CreatePort(ComPortName, 0L); X Permit(); X X ComPortMask = 1L << ComPort->mp_SigBit; X X NullFH = Open("NULL:", 1006); X if (NullFH == NULL) { X ulog(-1, "GETTY REQUIRES NULL: HANDLER!"); X puts("Requires NULL: handler!"); X xexit(1); X } X if (LogToStdout == 0) { X freopen("NULL:", "r", stdin); X freopen("NULL:", "w", stdout); X freopen("NULL:", "w", stderr); X } X X X /* X * Timer Device X */ X X Iot.tr_node.io_Message.mn_ReplyPort = IoSink; X if (OpenDevice("timer.device", UNIT_VBLANK, &Iot, 0L)) { X Iot.tr_node.io_Device = NULL; X xexit(20); X } X Iot.tr_node.io_Command = TR_ADDREQUEST; X X /* X * SERIAL.DEVICE X */ X X Iosr.IOSer.io_Message.mn_ReplyPort = IoSink; X Iosr.io_SerFlags = SERF_XDISABLED | SERF_7WIRE | SERF_RAD_BOOGIE | SERF_SHARED; X if (OpenDevice(DeviceName, DeviceUnit, &Iosr, 0L)) { X Iosr.IOSer.io_Device = NULL; X xexit(21); X } X X InterceptDeviceVector(Iosr.IOSer.io_Device); X X Iosw = Iosr; X X Iosw.io_SerFlags = SERF_XDISABLED | SERF_RAD_BOOGIE | SERF_SHARED; X Iosw.io_ExtFlags = 0; X Iosw.io_Baud = Bauds[0]; X Iosw.io_ReadLen = 8; X Iosw.io_WriteLen = 8; X Iosw.io_StopBits = 1; X X SetParams(&Iosw); X X /* X * Run Operation X */ X X State = ST_WAITCD; X Iot.tr_time.tv_secs = 1; X Iot.tr_time.tv_micro= 0; X IotIP = 1; X SendIO(&Iot); X X InitModem(); X X Signal(FindTask(NULL), IoSinkMask); X X for (;;) { X long mask; X IOR *ior; X GMsg *msg; X mask = Wait(SIGBREAKF_CTRL_C | IoSinkMask | ComPortMask); X X ulog(2, "State = %d", State); X X if (mask & SIGBREAKF_CTRL_C) X break; X X if (msg = (GMsg *)GetMsg(ComPort)) { X do { X switch(msg->Cmd) { X case 'O': X DoOptions(msg->Data1, msg->Data2); X break; X } X ReplyMsg((MSG *)msg); X if (ZeroOption) X xexit(0); X } while (msg = (GMsg *)GetMsg(ComPort)); X if (State == ST_WAITCD && !GotOffPort) X Disconnect(0); X } X X while (ior = (IOR *)GetMsg(IoSink)) { X if (ior == (IOR *)&Iot) { X short diu; X X IotIP = 0; X Iot.tr_time.tv_secs = 1; X Iot.tr_time.tv_micro= 0; X X /* X * If OpenCnt > 1, disable all processing. X * X * When returns to <= 1 reset serial port. X */ X X diu = DeviceInUse(); X if (diu) { X if (GotOffPort == 0) { X ulog(-1, "Device in use"); X if (Locked) X ulog(-1, "getting off port"); X SerialOff(); X GotOffPort = 1; X State = ST_WAITCD; X } X SendIO(&Iot); X IotIP = 1; X continue; X } X if (GotOffPort) { X if (Locked == 0) { X LockSerialPort(DeviceName, DeviceUnit); X Locked = 1; X } X GotOffPort = 0; X ulog(-1, "Getty resetting"); X SendIO(&Iot); X IotIP = 1; X Disconnect(1); X continue; X } X if (State == ST_WAITCD) X SerialOff(); X X if (State != ST_WAITCD && IosrIP == 0) { X if (Locked == 0) X LockSerialPort(DeviceName, DeviceUnit); X Locked = 1; X ulog(-1, "Serial Port Locked"); X X Iosr.IOSer.io_Command = CMD_READ; X Iosr.IOSer.io_Data = (APTR)RxBuf; X Iosr.IOSer.io_Length = 1; X SendIO(&Iosr); X IosrIP = 1; X ulog(1, "Carrier, Getty getting on port"); X } X X Iosw.IOSer.io_Command = SDCMD_QUERY; X DoIO(&Iosw); X if (IgnoreCD) X Iosw.io_Status &= ~CIAF_COMCD; X X /* X * If state connected and we loose carrier, disconnect. X * X * If state connected and timeout occurs disconnect. X */ X X if (State != ST_WAITCD) { X if ((Iosw.io_Status & CIAF_COMCD) != 0) { X ulog(1, "Getty, Carrier lost"); X Disconnect(0); X } else { X if (--CountDown == 0) { X ulog(1, "Getty, Timeout, Disconnecting"); X Disconnect(1); X Iosw.io_Status |= CIAF_COMCD; /* for below */ X } X } X } X X switch(State) { X case ST_WAITCD: X if ((Iosw.io_Status & CIAF_COMCD) == 0) { X State = ST_CONNECT; X CountDown = 60; /* allow 60 seconds */ X ulog(-1, "Carrier Detect"); X } else { X Iot.tr_time.tv_secs = 2; X } X break; X case ST_CONNECT: X /* X * Wait for CONNECT message, then send Login: X */ X X if (IgnoreConnect && HaveConnectMsg == 0) { X if (Wire7) X Set7Wire(&Iosw); X HaveConnectMsg = 1; X ulog(-1, "Connect"); X } X X if (HaveConnectMsg) { X FILE *fi; X X Delay(50); X ClearRecv(); X if (fi = fopen("Getty:Getty-Header", "r")) { X while (fgets(ScrBuf, sizeof(ScrBuf), fi)) { X SerPuts(ScrBuf); X SerPuts("\r"); X } X fclose(fi); X } X termCr = termLf = 1; X SerPuts("Login: "); X ulog(-1, "Getty, Connect, Login"); X State = ST_LOGIN; X Index = 0; X HaveLogin = 0; X LoginBuf[0] = 0; X } X break; X case ST_LOGIN: /* wait Login: response */ X if (HaveLogin) { X if (LoginBuf[0] == 0) { X State = ST_CONNECT; X break; X } X ClearRecv(); X PasswdBuf[0] = 0; X X /* X * If no password required, else request X * password. X */ X X if (CheckLoginAndPassword()) { X HavePasswd = 1; X Index = 0; X State = ST_PASSWD; X } else { X SerPuts("Password: "); X ulog(1, "Getty, Passwd"); X State = ST_PASSWD; X HavePasswd = 0; X Index = 0; X } X } X break; X case ST_PASSWD: /* wait Password: response */ X if (HavePasswd) { X if (CheckLoginAndPassword()) { X ulog(-1, "login %s", LoginBuf); X X /* X * Disable read requests but leave serial X * port locked. X */ X X if (IosrIP) { X AbortIO(&Iosr); X WaitIO(&Iosr); X IosrIP = 0; X } X X /* X * If run successful, leave read req and X * timer disabled. X */ X X RunPasswdEntry(); X X if (DropOnExit) X Disconnect(1); X else X State = ST_CONNECT; X ulog(-1, "disconnect"); X } else { X SerPuts("Login Failed.\r\n\n"); X State = ST_CONNECT; X ulog(-1, "LoginFailed user=%s pass=%s", LoginBuf, PasswdBuf); X } X HaveLogin = 0; X HavePasswd= 0; X LoginBuf[0] = 0; X } X break; X } X X /* X * Make no read requests while running 3rd party X * program, else resend read request. X */ X X if (IotIP == 0) { X IotIP = 1; X SendIO(&Iot); X } X } X X /* X * RECEIVED SERIAL READ DATA X */ X X if (ior == (IOR *)&Iosr) { X IosrIP = 0; X X Iosw.IOSer.io_Command = SDCMD_QUERY; X DoIO(&Iosw); X if (IgnoreCD) X Iosw.io_Status &= ~CIAF_COMCD; X X /* X * BREAK used to switch baud rates between allowed X * values X */ X X if (Iosw.io_Status & IO_STATF_READBREAK) { X if (BaudAdjust == 0 && (State == ST_LOGIN || State == ST_PASSWD)) { X if (++BIndex == arysize(Bauds)) X BIndex = 0; X if (Bauds[BIndex] == 0) X BIndex = 0; X Iosw.io_Baud = Bauds[BIndex]; X SetParams(&Iosw); X if (Wire7) X Set7Wire(&Iosw); X ulog(1, "<BREAK> to %d baud", Iosw.io_Baud); X Delay(100); X ClearRecv(); X Index = 0; X State = ST_CONNECT; X } X } else X if (Iosr.IOSer.io_Actual == 1) { X char *ptr; X UBYTE c = (UBYTE)RxBuf[0]; X X ulog(2, "Rx %02x %c", c, (c < 32) ? ' ' : c); X c &= 0x7F; X X switch(State) { X case ST_WAITCD: /* looking for CONNECT msg */ X case ST_CONNECT: /* looking for CONNECT msg */ X ptr = ConnectBuf; X break; X case ST_LOGIN: /* looking for login name */ X ptr = LoginBuf; X break; X case ST_PASSWD: /* looking for password */ X ptr = PasswdBuf; X break; X } X if (State == ST_LOGIN && HaveLogin) X c = 0; X if (State == ST_PASSWD && HavePasswd) X c = 0; X X switch(c) { X case 0: X break; X case 8: X if (State == ST_LOGIN && HaveLogin) X break; X if (Index) { X if (State == ST_LOGIN) X SerPuts("\010 \010"); X --Index; X } X break; X case 10: X if (termLf == 0) X break; X termCr = 0; X case 13: X if (c == 13) { X if (termCr == 0) X break; X else X termLf = 0; X } X ptr[Index] = 0; X Index = 0; X switch(State) { X case ST_WAITCD: X case ST_CONNECT: X if (strncmp(ptr, "CONNECT", 7)) { X ulog(1, "Looking for CONNECT, got '%s'", ptr); X break; X } X Delay(50); X HaveConnectMsg = 1; X if (BaudAdjust) { X ulog(-1, "Connect Auto-Baud %d", Iosw.io_Baud); X } else { X char *str = ptr + 7; X while (*str && (*str == 9 || *str == ' ')) X ++str; X if (*str >= '0' && *str <= '9') X Iosw.io_Baud = atoi(str); X else X Iosw.io_Baud = Bauds[0]; X SetParams(&Iosw); X ulog(-1, "Connect at %d baud", Iosw.io_Baud); X } X if (Wire7) X Set7Wire(&Iosw); X break; X case ST_LOGIN: X HaveLogin = 1; X SerPuts("\r\n"); X ulog(1, "Login: %s", ptr); X break; X case ST_PASSWD: X HavePasswd = 1; X SerPuts("\r\n"); X ulog(1, "Password: %s", ptr); X break; X } X break; X default: X if (Index == 31) X break; X if (State == ST_LOGIN) { X char cc[2]; X cc[0] = c; X cc[1] = 0; X SerPuts(cc); X } X ptr[Index++] = c; X break; X } X } X if (IosrIP == 0) { X Iosr.IOSer.io_Command = CMD_READ; X Iosr.IOSer.io_Data = (APTR)RxBuf; X Iosr.IOSer.io_Length = 1; X SendIO(&Iosr); X IosrIP = 1; X } X } X } X } X xexit(0); X} X Xvoid XSerialOff() X{ X if (IosrIP) { X AbortIO(&Iosr); X WaitIO(&Iosr); X IosrIP = 0; X } X if (Locked) { X UnLockSerialPort(DeviceName, DeviceUnit); X Locked = 0; X ulog(1, "Serial Port UnLocked"); X } X} X Xvoid Xxexit(code) X{ X if (ComPortMask) { X GMsg *msg; X Forbid(); X while (msg = (GMsg *)GetMsg(ComPort)) X ReplyMsg((MSG *)msg); X DeletePort(ComPort); X Permit(); X } X if (IotIP) { X AbortIO(&Iot); X WaitIO(&Iot); X } X if (Iot.tr_node.io_Device) X CloseDevice(&Iot); X X if (IosrIP) { X AbortIO(&Iosr); X WaitIO(&Iosr); X } X if (Iosr.IOSer.io_Device) { X RestoreDeviceVector(Iosr.IOSer.io_Device); X CloseDevice(&Iosr); X } X X if (IoSink) X DeletePort(IoSink); X X if (NullFH) X Close(NullFH); X X if (Locked) X UnLockSerialPort(DeviceName, DeviceUnit); X X exit(code); X} X Xvoid XSerPuts(str) Xchar *str; X{ X Iosw.IOSer.io_Command = CMD_WRITE; X Iosw.IOSer.io_Data = (APTR)str; X Iosw.IOSer.io_Length = strlen(str); X DoIO(&Iosw); X} X Xstatic short RxDisableIP; X Xvoid XRxDisable() X{ X RxDisableIP = IosrIP; X if (IosrIP) { X AbortIO(&Iosr); X WaitIO(&Iosr); X IosrIP = 0; X } X} X Xvoid XRxEnable() X{ X if (RxDisableIP && IosrIP == 0) { X Iosr.IOSer.io_Command = CMD_READ; X Iosr.IOSer.io_Data = (APTR)RxBuf; X Iosr.IOSer.io_Length = 1; X SendIO(&Iosr); X IosrIP = 1; X } X} X Xvoid XClearRecv() X{ X RxDisable(); X ulog(1, "Clear beg"); X for (;;) { X Iosr.IOSer.io_Command = SDCMD_QUERY; X DoIO(&Iosr); X if ((Iosr.IOSer.io_Length = Iosr.IOSer.io_Actual) <= 0) X break; X if (Iosr.IOSer.io_Length > sizeof(RxBuf)) X Iosr.IOSer.io_Length = sizeof(RxBuf); X Iosr.IOSer.io_Data = (APTR)RxBuf; X Iosr.IOSer.io_Command = CMD_READ; X DoIO(&Iosr); X } X ulog(1, "Clear end"); X RxEnable(); X} X Xvoid XSetParams(ior) XIOSER *ior; X{ X int error; X X if (IosrIP) X AbortIO(&Iosr); X ior->IOSer.io_Command = SDCMD_SETPARAMS; X error = DoIO(ior); X if (error) X printf("SetParams, error %d\n", error); X} X Xvoid XSet7Wire(ior) XIOSER *ior; X{ X short error; X X if (IosrIP) X AbortIO(&Iosr); X ior->IOSer.io_Command = SDCMD_SETPARAMS; X ior->io_SerFlags |= SERF_7WIRE; X error = DoIO(ior); X ior->io_SerFlags &= ~SERF_7WIRE; X if (error) X printf("SetParams, error %d\n", error); X} X Xvoid XDisconnect(dropdtr) X{ X short retry = (IgnoreDTR) ? 2 : 10; X X ulog(1, "Disconnect drop=%d", dropdtr); X HaveConnectMsg = 0; X HaveLogin = 0; X HavePasswd = 0; X LoginBuf[0] = 0; X PasswdBuf[0] = 0; X Index = 0; X State = ST_WAITCD; X X while (dropdtr && DeviceInUse() == 0) { X short i; X X RxDisable(); X X if (IgnoreDTR) { X if (ModemType != 'd') { X Delay(70); X SerPuts("+++"); X Delay(70); X SerPuts("\010\010\r"); X Delay(10); X SerPuts("ATH0\r"); X Delay(120); X } X } else { X CloseDevice(&Iosr); X Iosr.IOSer.io_Device = NULL; /* so xexit doesn't reclose */ X for (i = 0; i < 5; ++i) { /* 5 seconds */ X Delay(50); X if (SetSignal(SIGBREAKF_CTRL_C, 0) & SIGBREAKF_CTRL_C) X xexit(23); X } X X /* X * Use Iosr to re-open serial device so we don't loose X * our config. X */ X X if (OpenDevice(DeviceName, DeviceUnit, &Iosr, 0)) { X Iosr.IOSer.io_Device = NULL; X xexit(22); X } X Iosw.IOSer.io_Device = Iosr.IOSer.io_Device; X Iosw.IOSer.io_Unit = Iosr.IOSer.io_Unit; X SetParams(&Iosw); X } X X /* X * Loop until carrier lost X */ X X Iosw.IOSer.io_Command = SDCMD_QUERY; X DoIO(&Iosw); X if (IgnoreCD) X Iosw.io_Status &= ~CIAF_COMCD; X X RxEnable(); X X if ((Iosw.io_Status & CIAF_COMCD) != 0) X break; X if (--retry == 0) { X if (IgnoreDTR == 0) X puts("Getty: unable to disconnect!"); X break; X } X } X if (DeviceInUse() == 0) X InitModem(); X} X Xvoid XInitModem() X{ X char buf[64]; X short i; X X RxDisable(); X ulog(1, "Init Modem"); X Iosw.io_Baud = Bauds[0]; /* reset baud rate */ X BIndex = 0; X SetParams(&Iosw); X RxEnable(); X X switch(ModemType) { X case 'm': /* Multi Modem */ X SerPuts("\010\010\r"); X Delay(10); X SerPuts("AT\r"); X Delay(50); X sprintf(buf, "ATM%dS0=%dX4$BA%d&E%d\r", X SpeakerLevel, X AnswerRing, X !BaudAdjust, X (Wire7) ? 4 : 3 X ); X SerPuts(buf); X break; X case 'h': X SerPuts("\010\010\r"); X Delay(10); X SerPuts("ATZ\r"); X Delay(120); X strcpy(buf, "AT"); X if (SpeakerOpt) X sprintf(buf + strlen(buf), "M%d", SpeakerLevel); X sprintf(buf + strlen(buf), "S0=%d", AnswerRing); X strcat(buf, "\r"); X SerPuts(buf); X break; X case 'd': X SerPuts("\010\010\r"); X break; X } X for (i = 0; i < arysize(AtFields) && AtFields[i]; ++i) { X Delay(50); X SerPuts(AtFields[i]); X SerPuts("\r"); X } X Delay(20); X ClearRecv(); X Index = 0; X} X Xvoid XDoOptions(ac, av) Xchar *av[]; X{ X short i; X short bi = 0; X short fi = 0; X long v; X X for (i = 1; i < ac; ++i) { X char *ptr = av[i]; X if (*ptr != '-') { X if (fi != arysize(AtFields)) X AtFields[fi++] = ptr; X else X puts("AT field overflow"); X continue; X } X if (*++ptr) /* skip - */ X ++ptr; /* and option */ X v = atoi(ptr); X switch(ptr[-1]) { X case '0': X ZeroOption = 1; X break; X case '7': X Wire7 = 1; X break; X case 'S': X DeviceName = ptr; X break; X case 'U': X DeviceUnit = v; X break; X case 'M': X ModemType = *ptr; X break; X case 'A': X BaudAdjust = 1; X break; X case 'B': X if (bi != arysize(Bauds)) X Bauds[bi++] = v; X else X puts("-B field overflow"); X break; X case 'm': X SpeakerOpt = 1; X SpeakerLevel = v; X break; X case 'r': X AnswerRing = v; X break; X case 'h': X IgnoreCD = !v; X break; X case 'c': X IgnoreConnect = !v; X break; X case 'd': X IgnoreDTR = !v; X break; X case 'x': X LogLevel = v; X LogToStdout = (v >= 0); X break; X default: X printf("Warning, Bad option: -%s\n", ptr); X break; X } X } X if (fi && fi != arysize(AtFields)) X AtFields[fi] = NULL; X if (bi && bi != arysize(Bauds)) X Bauds[bi] = 0; X} X XDeviceInUse() X{ X return(Iosr.IOSer.io_Device->dd_Library.lib_OpenCnt > 1); X} X X/* X * Device Vector Intercept, used to force SERF_SHARED on device open. X */ X Xextern void AsmIntercept(); Xextern void AsmRoute(); XFPTR OldVector; X Xvoid XInterceptDeviceVector(dev) Xstruct Device *dev; X{ X OldVector = SetFunction((struct Library *)dev, LIB_OPEN, AsmIntercept); X AsmRoute(OldVector); X} X Xvoid XRestoreDeviceVector(dev) Xstruct Device *dev; X{ X SetFunction((struct Library *)dev, LIB_OPEN, OldVector); X} X X END_OF_FILE if test 20766 -ne `wc -c <'uucp2/src/getty/getty.c'`; then echo shar: \"'uucp2/src/getty/getty.c'\" unpacked with wrong size! fi # end of 'uucp2/src/getty/getty.c' fi if test -f 'uucp2/src/uucico/gio.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'uucp2/src/uucico/gio.c'\" else echo shar: Extracting \"'uucp2/src/uucico/gio.c'\" \(18871 characters\) sed "s/^X//" >'uucp2/src/uucico/gio.c' <<'END_OF_FILE' X X/* X * GIO.C WINDOWED G PROTOCOL X * X * written from scratch, except the checksum routine which was X * rewritten but based on the old one. X * X * WINDOW SIZE: When changing the window size be sure there X * are enough buffers available for pending txs. X * X * GIO.C (c)Copyright 1989, Matthew Dillon, All Rights Reserved X * extended to window size of 7 by Jack J. Rouse X */ X X#include "includes.h" X Xtypedef unsigned char ubyte; Xtypedef unsigned short uword; X Xtypedef struct { X ubyte Dle; /* Literal ASCII DLE */ X ubyte K; /* data size 2^(K+4) except K=0 means no data */ X ubyte CL,CH; /* MAGIC - chksum(data) ^ C */ X ubyte C; X ubyte X; /* K ^ C0 ^ C1 ^ C */ X} Frame; X Xtypedef struct { X ubyte CType; /* bits 7-6 of C */ X ubyte CCmd; /* bits 5-3 of C */ X ubyte CSeq; /* bits 2-0 of C */ X ubyte PLen; /* pre-data (2 bytes) for SHORTDATA type */ X ubyte *Data; /* implies CType=LONGDATA or SHORTDATA */ X uword DLen; /* length of data */ X} Packet; X XPrototype int gwrdata(FILE *); XPrototype int gwrmsg(char *); XPrototype int grddata(FILE *); XPrototype int grdmsg(char *, int); XPrototype int gturnon(int); XPrototype int gturnoff(void); XPrototype void ResetGIO(void); X XLocal char *GetTxBuf(void); XLocal int SendDataPacket(unsigned char *, int); XLocal int RecvDataPacket(char **); XLocal int GetData(int, Packet *); XLocal int RecvdAck(char); XLocal int WriteCtlPacket(int); XLocal int WritePacket(Packet *, int); XLocal int ReadPacket(Packet *, int); XLocal int CheckSum(unsigned char *, int); XLocal void FrameToPacket(Frame *, Packet *, unsigned char *); XLocal int LenToK(unsigned short); X Xextern int debug; Xextern int WindowOne; X X#define SUCCESS 0 X#define FAIL 1 X X#define MAGIC 0125252 X#define DLE 0x10 X#define WINDOWSIZE 7 X#define SEGSIZEK 2 /* 64 bytes ?? */ X X#define SUB1(var) (((var)-1)&7) X X X#define CT_CONTROL (0 << 6) X#define CT_ALTCHN (1 << 6) X#define CT_LONGDATA (2 << 6) X#define CT_SHORTDATA (3 << 6) X#define CT_MASK (3 << 6) X X#define CC_CLOSE (1 << 3) X#define CC_RJ (2 << 3) X#define CC_SRJ (3 << 3) X#define CC_RR (4 << 3) X#define CC_INITC (5 << 3) X#define CC_INITB (6 << 3) X#define CC_INITA (7 << 3) X#define CC_MASK (7 << 3) X X#define SEQ_MASK 7 X X#define WAIT_ACK 1 X#define WAIT_DATA 2 X#define WAIT_CONTROL 3 X X#define MaxPktSize 4096 X Xchar RxBuf[MaxPktSize+4]; Xchar *TxBuf[8]; X X /* TRANSMIT STAGE */ Xchar TxSeq = 0; /* Last send packet */ Xchar TxPend= 0; /* hasn't been acked yet */ Xuword TxWinSize; /* 1 or 2 (max 7) */ Xuword TxSegSize; /* maximum segment size */ Xchar TxSegK; /* K for TxSegSize */ XPacket TxPacket[8]; /* contents of last packet */ X X /* RECEIVE STAGE */ Xchar RxSeq = 0; /* Last valid recv pkt */ Xchar RxRdy = 0; /* Has come in.. */ Xchar RxRetry = 8; Xchar RxNotAcked = 0; /* We have yet to ack it */ XPacket RxPacket; /* The packet that has come in */ X Xvoid XResetGIO() X{ X TxSeq = 0; X TxPend= 0; X TxWinSize = 0; X TxSegSize = 0; X TxSegK = 0; X RxSeq = 0; X RxRdy = 0; X RxRetry = 8; X RxNotAcked = 0; X} X X/* X * Get Transmit Buffer. Note that some space to the left is available X */ X XLocal Xchar * XGetTxBuf() X{ X static int index = 0; X X if (++index > TxWinSize) X index = 0; X if (TxBuf[index] == NULL X && (TxBuf[index] = (char *)malloc(MaxPktSize+4)) == NULL) X { X printf("Out of memory in GetTxBuf."); X /* could handle this case better, but it should be rare */ X xexit(1); X } X return(TxBuf[index] + 2); X} X Xint Xgwrdata(fi) XFILE *fi; X{ X int bytes; X X if (debug > 7) X printf("GWRDATA: "); X X for (;;) { X char *buf = GetTxBuf(); X if ((bytes = fread(buf, 1, TxSegSize, fi)) <= 0) X break; X if (SendDataPacket(buf, bytes) != SUCCESS) { X if (debug > 7) X printf("GWR Failed\n"); X return(FAIL); X } X if (debug > 7) X printf("\nGWROK "); X } X { X char *buf = GetTxBuf(); X if (SendDataPacket(buf, 0) != SUCCESS) { X if (debug > 7) X printf("GWR Failed (last)\n"); X return(FAIL); X } X } X if (debug > 7) X printf("\nGWFile Last Ack\n"); X while (TxPend) { X if (GetData(WAIT_ACK, NULL) == FAIL) X return(FAIL); X } X if (debug > 7) X printf("success\n"); X return (SUCCESS); X} X X/* X * Write message to the other guy. X * X * NOTE: LONGDATA packets used exclusively and \0 fill to end. X */ X Xint Xgwrmsg(str) Xchar *str; X{ X int len = strlen(str) + 1; /* type + str + \0 */ X X if (debug > 7) X printf("GWRMSG: %s\n", str); X X while (len > TxSegSize) { X char *buf = GetTxBuf(); X movmem(str, buf, TxSegSize); X if (debug > 7) X printf("GWR-SEND %d\n", TxSegSize); X if (SendDataPacket(buf, TxSegSize) != SUCCESS) X return(FAIL); X len -= TxSegSize; X str += TxSegSize; X } X X /* X * Find optimal packet size (remember, we must force LONGDATA X * X * Apparently packet sizes less than the agreed upon size are X * not allowed ??? X */ X X { X short siz = TxSegSize; X char *buf = GetTxBuf(); X#ifdef NOTDEF X short k = TxSegK; X X while (k > 1 && (siz >> 1) >= len) { X --k; X siz >>= 1; X } X#endif X if (debug > 7) X printf("GWR-FNL %d %d\n", len, siz); X X movmem(str, buf, len); X setmem(buf + len, siz - len, 0); X if (SendDataPacket(buf, siz) != SUCCESS) { X if (debug > 7) X printf("GWR-FAIL\n"); X return(FAIL); X } X } X if (debug > 7) X printf("GWR Last Ack\n"); X while (TxPend) { X if (GetData(WAIT_ACK, NULL) == FAIL) X return(FAIL); X } X if (debug > 7) X printf("success\n"); X return (SUCCESS); X} X Xint Xgrddata(fi) XFILE *fi; X{ X int bytes; X char *buf; X X if (debug > 7) X printf("GRDDATA\n"); X while ((bytes = RecvDataPacket(&buf)) > 0) { X if (debug > 7) X printf("GRDDATA blk %d\n", bytes); X fwrite(buf, 1, bytes, fi); X } X if (debug > 7) X printf("GRDDATA end %d\n", bytes); X if (bytes < 0) X return(FAIL); X else X return(SUCCESS); X} X Xint Xgrdmsg(buf, maxlen) Xchar *buf; X{ X short i; X short n; X short slen; X char *ptr; X X i = 0; X if (debug > 7) X printf("GRDMSG\n"); X while ((n = RecvDataPacket(&ptr)) > 0) { X ptr[n] = 0; X slen = strlen(ptr); X if (slen > maxlen - 1) { X printf("GRDMSG: Buffer overflow!\n"); X return (FAIL); X } X movmem(ptr, buf + i, slen); X buf[i + slen] = 0; X if (slen != n) X break; X i += slen; X maxlen -= slen; X } X if (debug > 7) X printf("GRDMSGEND %d (%d) %s\n", n, i, buf); X if (n < 0) { X buf[0] = 0; X return(FAIL); X } X return(SUCCESS); X} X XLocal Xint XSendDataPacket(buf, bytes) Xubyte *buf; Xint bytes; X{ X Packet P; X X /* X * If window exhausted we must wait for at least one ack. X */ X X while (TxPend == TxWinSize) { X if (GetData(WAIT_ACK, NULL) == FAIL) X return(FAIL); X } X X TxSeq = (TxSeq + 1) & 7; /* next Tx packet */ X X /* X * Figure out best fit packet size. Apparently packets smaller X * then the agreed upon size are not allowed ??? X */ X X#ifdef NOTDEF X { X short k = TxSegK; X P.DLen = TxSegSize; X while (k > 1 && P.DLen && (P.DLen >> 1) >= bytes) { X --k; X P.DLen >>= 1; X } X } X#else X P.DLen = TxSegSize; X#endif X X if (bytes < P.DLen) { X uword extra = P.DLen - bytes; X setmem(buf + bytes, extra, 0); X if (extra <= 127) { X P.PLen = 1; X buf[-1] = extra; X } else { X P.PLen = 2; X buf[-2] = 0x80 | extra; X buf[-1] = (extra >> 7); X } X P.CType = CT_SHORTDATA; X } else { X P.PLen = 0; X P.CType = CT_LONGDATA; X } X P.CCmd = TxSeq << 3; /* transmit sequence number */ X P.CSeq = RxSeq; /* last valid received pkt */ X P.Data = buf; X X if (debug > 7) X printf("WRITE DATA PACKET txseq=%d rxack=%d\n", TxSeq, P.CSeq); X X RxNotAcked = 0; /* We've acked the rx packet */ X X TxPacket[TxSeq] = P; X ++TxPend; X X WritePacket(&TxPacket[TxSeq], 1); X X return(SUCCESS); X} X XLocal Xint XRecvDataPacket(pbuf) Xchar **pbuf; X{ X if (RxRdy == 0) { X if (GetData(WAIT_DATA, NULL) != SUCCESS) X return(-1); X } X *pbuf = RxPacket.Data; X RxRdy = 0; X return((int)RxPacket.DLen); X} X Xint Xgturnon(master) Xint master; X{ X Packet P; X short retry = 5; X short windowsize = WINDOWSIZE; /* our prefered window size */ X short segsize = SEGSIZEK; /* our prefered segment size */ X X if (WindowOne) X windowsize = 1; X X if (master) { X while (retry > 0) { X WriteCtlPacket(CC_INITA | windowsize); X if (GetData(WAIT_CONTROL, &P) == SUCCESS && P.CCmd == CC_INITA) { X if (P.CSeq && P.CSeq < windowsize) X windowsize = P.CSeq; X break; X } X --retry; X } X while (retry > 0) { X WriteCtlPacket(CC_INITB | (segsize - 1)); X if (GetData(WAIT_CONTROL, &P) == SUCCESS && P.CCmd == CC_INITB) { X if (P.CSeq < segsize - 1) X segsize = P.CSeq + 1; X break; X } X --retry; X } X while (retry > 0) { X WriteCtlPacket(CC_INITC | windowsize); X if (GetData(WAIT_CONTROL, &P) == SUCCESS && P.CCmd == CC_INITC) { X if (P.CSeq && P.CSeq < windowsize) X windowsize = P.CSeq; X break; X } X --retry; X } X } else { X while (retry > 0) { X if (GetData(WAIT_CONTROL, &P) == SUCCESS && P.CCmd == CC_INITA) { X WriteCtlPacket(CC_INITA | windowsize); X if (P.CSeq && windowsize > P.CSeq) X windowsize = P.CSeq; X break; X } X --retry; X } X while (retry > 0) { X if (GetData(WAIT_CONTROL, &P) == SUCCESS && P.CCmd == CC_INITB) { X WriteCtlPacket(CC_INITB | (segsize - 1)); X if (P.CSeq < segsize - 1) X segsize = P.CSeq + 1; X break; X } X --retry; X } X while (retry > 0) { X if (GetData(WAIT_CONTROL, &P) == SUCCESS && P.CCmd == CC_INITC) { X WriteCtlPacket(CC_INITC | windowsize); X if (P.CSeq && windowsize > P.CSeq) X windowsize = P.CSeq; X break; X } X --retry; X } X } X TxSegK = segsize; X TxSegSize = 1 << (TxSegK + 4); X TxWinSize = windowsize; X if (debug > 0) X printf("Window Size is %d\n", TxWinSize); X if (retry == 0) X return(FAIL); X return(SUCCESS); X} X Xint Xgturnoff() X{ X Packet P; X X WriteCtlPacket(CC_CLOSE); X if (GetData(WAIT_CONTROL, &P) == SUCCESS && P.CCmd == CC_CLOSE) { X WriteCtlPacket(CC_RR | RxSeq); X return (SUCCESS); X } X return (FAIL); X} X X/* X * GetData() X * X * This is the core of the packet protocol. As soon as we get a satisfactory X * terminating condition we return. However, on unsatisfactory conditions X * such as having to send a reject, we attempt to drain any pending data X * (i.e. multiple returned rejects) so we do not do multiple resends. X * X * The resend flag only applies on a failure return. X */ X XLocal Xint XGetData(waitfor, p) Xint waitfor; XPacket *p; X{ X Packet P; X short timeout; X short drainmode = 0; X X /* X * If we haven't acked the last packet we received we must do X * so now before we can expect to receive another one! X */ X X if (debug > 7) X printf("Get-Data waitfor %s\n", (waitfor == WAIT_ACK) ? "WAIT_ACK" : "WAIT_DATA"); X if (waitfor == WAIT_ACK) X timeout = 5; X else if (waitfor == WAIT_DATA) X timeout = 20; X else X timeout = 20; X X for (;;) { X if (RxNotAcked) { /* good, send ack for rx'd pkt */ X WriteCtlPacket(CC_RR | RxSeq); X RxNotAcked = 0; X } /* bad, timeout on read */ X if (ReadPacket(&P, (drainmode) ? 0 : timeout) == FAIL) { X drainmode = 0; X X /* X * If we have timed out waiting for data then send a reject X */ X X if (waitfor == WAIT_DATA) { X if (RxRetry) { X --RxRetry; X if (debug > 7) X printf("\nWAIT-DATA, TIMEOUT, SEND RJ\n"); X WriteCtlPacket(CC_RJ | RxSeq); X continue; X } X } X X /* X * If we have timed out waiting for an ack send the entire X * window. We must send the window sometime and it might as X * well be now. X */ X X if (waitfor == WAIT_ACK) { X if (RxRetry) { X int i; X X if (debug > 7) X printf("RESEND %d packets\n", TxPend); X for (i = 1; i <= TxPend; ++i) { X Packet *p = &TxPacket[(TxSeq - TxPend + i) & 7]; X p->CSeq = RxSeq; X WritePacket(p, 1); X } X --RxRetry; X continue; X } X } X if (debug > 7) X printf("COMPLETE FAILURE RxRetry = %d\n", RxRetry); X return(FAIL); X } X X /* X * valid packet, terminating condition? X */ X X RxRetry = 8; X switch(P.CType) { X case CT_CONTROL: X switch(P.CCmd) { X case CC_CLOSE: /* End of communication ... not an ACK! */ X if (waitfor == WAIT_CONTROL) { X *p = P; X return(SUCCESS); X } X return(FAIL); X case CC_RJ: /* Reject packet (P.CSeq == last good packet) */ X (void)RecvdAck(P.CSeq); X drainmode = 1; X break; X case CC_SRJ: /* Selective Reject (P.CSeq == bad packet # ) */ X return(FAIL); X case CC_RR: /* Ack to packet (P.CSeq == packet # acked) */ X#ifdef NOTDEF X if (P.CSeq == ((TxSeq - TxPend) & 7)) { X /* X * The CSeq packet was previously acknowledged X * The receiver apparently has not seen anything since. X * This is the same as a rejection. X */ X goto resend; X } X#endif X if (RecvdAck(P.CSeq) == SUCCESS && waitfor == WAIT_ACK) X return(SUCCESS); X break; X case CC_INITC: X case CC_INITB: X case CC_INITA: X if (waitfor == WAIT_CONTROL) { X *p = P; X return(SUCCESS); X } X return(FAIL); X } X break; X case CT_ALTCHN: X printf("ALTCHN packet ??\n"); X break; X case CT_LONGDATA: X case CT_SHORTDATA: X { X char rxseq = P.CCmd >> 3; X char txack = P.CSeq; X X if (RxRdy == 1) { X printf("Got two receive packets without me acking!\n"); X } X X if (rxseq == RxSeq) { /* already got this packet */ X RxNotAcked = 1; X continue; X /* expected packet? */ X } else if (rxseq != ((RxSeq + 1) & 7)) { X drainmode = 1; X printf("Received sequence %d, expected %d\n", rxseq, (RxSeq + 1) & 7); X break; X } X if (debug > 6) X printf("RECV SEQUENCE %d\n", rxseq); X X RecvdAck(txack); /* woa */ X X /* X * Delay sending the ACK back in case we can combine X * it with the next transmitted packet. X */ X X RxNotAcked = 1; /* we haven't ack'd the rx packet */ X X RxSeq = (RxSeq + 1) & 7; X RxRdy = 1; X RxPacket = P; X if (waitfor == WAIT_DATA) X return(SUCCESS); X if (TxPend == 0 && waitfor == WAIT_ACK) X return(SUCCESS); X } X break; X } X } X} X XLocal Xint XRecvdAck(seq) Xchar seq; X{ X short i; X X /* X * which packet was acked? X */ X X for (i = 0; i < TxPend; ++i) { X if (seq == ((TxSeq - i) & 7)) X break; X } X if (i && i == TxPend) { X if (seq != ((TxSeq - TxPend) & 7)) X printf("He acked the wrong packet! %d expected %d\n", seq, TxSeq); X return(FAIL); X } X if (debug > 7) X printf("TxPend %d -> %d\n", TxPend, i); X TxPend = i; X return(SUCCESS); X} X XLocal Xint XWriteCtlPacket(cc) Xint cc; X{ X Packet pk; X X pk.CType = CT_CONTROL; X pk.CCmd = cc & CC_MASK; X pk.CSeq = cc & SEQ_MASK; X pk.PLen = 0; X pk.DLen = 0; X WritePacket(&pk, 0); X return(SUCCESS); X} X XLocal Xint XWritePacket(pk, async) XPacket *pk; Xint async; X{ X Frame F; X uword sum; X X F.Dle = DLE; X F.C = pk->CType | pk->CCmd | pk->CSeq; X F.K = 9; X X if (pk->CType == CT_SHORTDATA || pk->CType == CT_LONGDATA) X F.K = LenToK(pk->DLen); X else X pk->DLen = 0; X X sum = MAGIC - (CheckSum(pk->Data - pk->PLen, pk->DLen) ^ F.C); X X F.CH = sum >> 8; X F.CL = sum; X F.X = F.K ^ F.CH ^ F.CL ^ F.C; X X if (debug > 7) X printf("WritePacket: F.K = %d F.C = %d.%d.%d\n", F.K, F.C >> 6, (F.C >> 3) & 7, F.C & 7); X X if (async) X xwritea(&F, sizeof(F)); X else X xwrite(&F, sizeof(F)); /* write header */ X if (pk->DLen) { /* write data */ X if (async) X xwritea(pk->Data - pk->PLen, pk->DLen); X else X xwrite(pk->Data - pk->PLen, pk->DLen); X } X return(SUCCESS); X} X XLocal Xint XReadPacket(pk, timeout) XPacket *pk; Xint timeout; X{ X Frame F; X short c; X short i = 0; X X pk->Data = RxBuf; X pk->CType = 0xFF; X pk->CCmd = 0; X pk->CSeq = 0; X X if (debug > 7) X printf("ReadPacket\n"); X while ((c = xgetc(timeout)) != EOF) { X if (debug > 8) X printf("RP %d %02x\n", i, c); X X switch(i) { X case 0: X if (c == DLE) { X F.Dle = c; X ++i; X if (timeout == 0) X timeout = 1; X } X break; X case 1: X F.K = c; X ++i; X if (c == DLE) { /* K only valid 1-9 */ X F.Dle = c; X i = 1; X } X else if (c == 0 || c > 9) X i = 0; X break; X case 2: X F.CL = c; X ++i; X break; X case 3: X F.CH = c; X ++i; X break; X case 4: X F.C = c; X ++i; X break; X case 5: X F.X = c; X if (F.X != (F.K ^ F.CH ^ F.CL ^ F.C)) { X printf("F.X failed: %02x %02x\n", F.X, (F.K ^ F.CH ^ F.CL ^ F.C)); X i = 0; X } else { /* get data segment if any */ X ++i; X } X break; X } X if (i == 6) X break; X } X if (debug > 7) { X if (i) X printf("RP Hdr i = %d, F.K = %d F.C = %d.%d.%d\n", i, F.K, F.C >> 6, (F.C >> 3) & 7, F.C & 7); X else X printf("RP Hdr <rx timeout>\n"); X } X X if (i == 6) { /* Receive Data Portion */ X uword pktsize = 1 << (F.K + 4); X uword n; X X if (F.K == 9) X pktsize = 0; X X if (pktsize > MaxPktSize) { X printf("Protocol failure pktsize %d/%d/%d\n", pktsize, TxSegSize, MaxPktSize); X return (FAIL); X } X for (n = 0; n < pktsize; ++n) { X if ((c = xgetc(4)) == EOF) X break; X pk->Data[n] = c; X } X if (c != EOF) { X uword hissum; X uword oursum; X hissum = (F.CH << 8) | F.CL; X oursum = MAGIC - (CheckSum(pk->Data, pktsize) ^ F.C); X if (debug > 7) X printf("Got Data, checking: %04x %04x\n", hissum, oursum); X if (hissum == oursum) { X FrameToPacket(&F, pk, pk->Data); X return (SUCCESS); X } X } else { X FrameToPacket(&F, pk, pk->Data); /* mainly for pk->CType */ X return (FAIL); X } X } X /* X * Timeout, retry? X */ X return (FAIL); X} X XLocal Xint XCheckSum(s, n) Xubyte *s; Xint n; X{ X uword sum; X uword x; X uword t; X X if (n == 0) X return(0); X sum = -1; X x = 0; X X while (n) { X if (sum & 0x8000) X sum = (sum << 1) | 1; X else X sum = (sum << 1); X X t = sum; X sum += *s++; X x += sum ^ n; X if (sum <= t) X sum ^= x; X --n; X } X return((int)sum); X} X XLocal Xvoid XFrameToPacket(fr, pk, data) XFrame *fr; XPacket *pk; Xubyte *data; X{ X pk->CType = fr->C & CT_MASK; X pk->CCmd = fr->C & CC_MASK; X pk->CSeq = fr->C & SEQ_MASK; X switch(pk->CType) { X case CT_LONGDATA: X pk->DLen = 1 << (fr->K + 4); X break; X case CT_SHORTDATA: X pk->DLen = 1 << (fr->K + 4); X if (pk->Data[0] & 0x80) { X pk->DLen -= (pk->Data[0] & 0x7F) | (pk->Data[1] << 7); X if (pk->DLen < 0) { X printf("DLEN ERROR %d\n", pk->DLen); X pk->DLen = 0; X } X pk->Data += 2; X } else { X pk->DLen -= *pk->Data; X ++pk->Data; X } X break; X default: X pk->DLen = 0; X break; X } X} X XLocal Xint XLenToK(bytes) Xuword bytes; X{ X uword n = 32; X uword k = 1; X X while (n < bytes) { X n <<= 1; X ++k; X } X if (k > 8) { X printf("Soft error, LenToK: %d %d %d\n", bytes, n, k); X k = 8; X } X return((int)k); X} X END_OF_FILE if test 18871 -ne `wc -c <'uucp2/src/uucico/gio.c'`; then echo shar: \"'uucp2/src/uucico/gio.c'\" unpacked with wrong size! fi # end of 'uucp2/src/uucico/gio.c' fi echo shar: End of archive 8 \(of 12\). cp /dev/null ark8isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 12 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 12 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Mail submissions (sources or binaries) to <amiga@cs.odu.edu>. Mail comments to the moderator at <amiga-request@cs.odu.edu>. Post requests for sources, and general discussion to comp.sys.amiga.