1: #if !defined(lint) && defined(DOSCCS)
   2: static char sccsid[] = "@(#)pk1.c	5.9.2 (2.11BSD) 1997/10/2";
   3: #endif
   4: 
   5: #include <signal.h>
   6: #include "uucp.h"
   7: #include "pk.h"
   8: #include <setjmp.h>
   9: #include <errno.h>
  10: #include <string.h>
  11: #ifdef BSD4_2
  12: #include <sys/time.h>
  13: #endif BSD4_2
  14: 
  15: #ifdef VMS
  16: #include <eunice/eunice.h>
  17: #include <vms/iodef.h>
  18: #include <vms/ssdef.h>
  19: int iomask[2];
  20: #endif VMS
  21: 
  22: #define PKMAXSTMSG 40
  23: #define MAXPKTIME 32    /* was 16 */
  24: #define CONNODATA 10
  25: #define MAXTIMEOUT 32
  26: 
  27: extern int Retries;
  28: extern jmp_buf Sjbuf;
  29: 
  30: int Connodata = 0;
  31: int Ntimeout = 0;
  32: int pktimeout = 4;
  33: int pktimeskew = 2;
  34: /*
  35:  * packet driver support routines
  36:  *
  37:  */
  38: 
  39: extern struct pack *pklines[];
  40: 
  41: /*
  42:  * start initial synchronization.
  43:  */
  44: 
  45: struct pack *
  46: pkopen(ifn, ofn)
  47: int ifn, ofn;
  48: {
  49:     register struct pack *pk;
  50:     register char **bp;
  51:     register int i;
  52: 
  53:     if ((pk = (struct pack *) malloc(sizeof (struct pack))) == NULL)
  54:         return NULL;
  55:     bzero((caddr_t) pk, sizeof (struct pack));
  56:     pk->p_ifn = ifn;
  57:     pk->p_ofn = ofn;
  58:     pk->p_xsize = pk->p_rsize = PACKSIZE;
  59:     pk->p_rwindow = pk->p_swindow = WINDOWS;
  60:     /*  allocate input windows */
  61:     for (i = 0; i < pk->p_rwindow; i++) {
  62:         if ((bp = (char **) malloc((unsigned)pk->p_xsize)) == NULL)
  63:             break;
  64:         *bp = (char *) pk->p_ipool;
  65:         pk->p_ipool = bp;
  66:     }
  67:     if (i == 0) {
  68:         DEBUG(1, "pkopen: can't malloc i = 0\n", CNULL);
  69:         return NULL;
  70:     }
  71:     pk->p_rwindow = i;
  72: 
  73:     /* start synchronization */
  74:     pk->p_msg = pk->p_rmsg = M_INITA;
  75:     for (i = 0; i < NPLINES; i++) {
  76:         if (pklines[i] == NULL) {
  77:             pklines[i] = pk;
  78:             break;
  79:         }
  80:     }
  81:     if (i >= NPLINES) {
  82:         DEBUG(1,"pkopen: i>=NPLINES\n", CNULL);
  83:         return NULL;
  84:     }
  85:     pkoutput(pk);
  86: 
  87:     for (i = 0; i < PKMAXSTMSG; i++) {
  88:         pkgetpack(pk);
  89:         if ((pk->p_state & LIVE) != 0)
  90:             break;
  91:     }
  92:     if (i >= PKMAXSTMSG) {
  93:         DEBUG(1, "pkopen: i>= PKMAXSTMSG\n", CNULL);
  94:         return NULL;
  95:     }
  96: 
  97:     pkreset(pk);
  98:     return pk;
  99: }
 100: 
 101: 
 102: /*
 103:  * input framing and block checking.
 104:  * frame layout for most devices is:
 105:  *
 106:  *	S|K|X|Y|C|Z|  ... data ... |
 107:  *
 108:  *	where 	S	== initial synch byte
 109:  *		K	== encoded frame size (indexes pksizes[])
 110:  *		X, Y	== block check bytes
 111:  *		C	== control byte
 112:  *		Z	== XOR of header (K^X^Y^C)
 113:  *		data	== 0 or more data bytes
 114:  *
 115:  */
 116: 
 117: int pksizes[] = {
 118:     1, 32, 64, 128, 256, 512, 1024, 2048, 4096, 1
 119: };
 120: 
 121: #define GETRIES 10
 122: /*
 123:  * Pseudo-dma byte collection.
 124:  */
 125: 
 126: pkgetpack(pk)
 127: register struct pack *pk;
 128: {
 129:     int k, tries, noise;
 130:     register char *p;
 131:     register struct header *h;
 132:     unsigned short sum;
 133:     int ifn;
 134:     char **bp;
 135:     char hdchk;
 136: 
 137:     if ((pk->p_state & DOWN) || Connodata > CONNODATA || Ntimeout > MAXTIMEOUT)
 138:         pkfail();
 139:     ifn = pk->p_ifn;
 140: 
 141:     /* find HEADER */
 142:     for (tries = 0, noise = 0; tries < GETRIES; ) {
 143:         p = (caddr_t) &pk->p_ihbuf;
 144:         if (pkcget(ifn, p, 1) == SUCCESS) {
 145:             if (*p++ == SYN) {
 146:                 if (pkcget(ifn, p, HDRSIZ-1) == SUCCESS)
 147:                     break;
 148:             } else {
 149:                 if (noise++ < 10 || noise < (3*pk->p_rsize))
 150:                     continue;
 151:             }
 152:             DEBUG(4, "Noisy line - set up RXMIT\n", CNULL);
 153:             noise = 0;
 154:         }
 155:         /* set up retransmit or REJ */
 156:         tries++;
 157:         Retries++;
 158:         pk->p_msg |= pk->p_rmsg;
 159:         if (pk->p_msg == 0)
 160:             pk->p_msg |= M_RR;
 161:         if ((pk->p_state & LIVE) == LIVE)
 162:             pk->p_state |= RXMIT;
 163:         pkoutput(pk);
 164:     }
 165:     if (tries >= GETRIES) {
 166:         DEBUG(4, "tries = %d\n", tries);
 167:         pkfail();
 168:     }
 169: 
 170:     Connodata++;
 171:     h = (struct header *) &pk->p_ihbuf;
 172:     p = (caddr_t) h;
 173:     hdchk = p[1] ^ p[2] ^ p[3] ^ p[4];
 174:     p += 2;
 175:     sum = (unsigned) *p++ & 0377;
 176:     sum |= (unsigned) *p << 8;
 177:     h->sum = sum;
 178:     DEBUG(7, "rec h->cntl 0%o\n", h->cntl&0xff);
 179:     k = h->ksize;
 180:     if (hdchk != h->ccntl) {
 181:         /* bad header */
 182:         DEBUG(7, "bad header 0%o,", hdchk&0xff);
 183:         DEBUG(7, "h->ccntl 0%o\n", h->ccntl&0xff);
 184:         return;
 185:     }
 186:     if (k == 9) {
 187:         if (((h->sum + h->cntl) & 0xffff) == CHECK) {
 188:             pkcntl(h->cntl, pk);
 189:             DEBUG(7, "state - 0%o\n", pk->p_state);
 190:         } else {
 191:             /*  bad header */
 192:             pk->p_state |= BADFRAME;
 193:             DEBUG(7, "bad header (k==9) 0%o\n", h->cntl&0xff);
 194:         }
 195:         return;
 196:     }
 197:     if (k && pksizes[k] == pk->p_rsize) {
 198:         pk->p_rpr = h->cntl & MOD8;
 199:         DEBUG(7, "end pksack 0%o\n", pk->p_rpr);
 200:         pksack(pk);
 201:         bp = pk->p_ipool;
 202:         if (bp == NULL) {
 203:             DEBUG(7, "bp NULL %s\n", "");
 204:             return;
 205:         }
 206:         pk->p_ipool = (char **) *bp;
 207:         Connodata = 0;
 208:     } else
 209:         return;
 210: 
 211:     if (pkcget(pk->p_ifn, (char *) bp, pk->p_rsize) == SUCCESS) {
 212:         pkdata(h->cntl, h->sum, pk, (char **) bp);
 213:     } else {
 214:         *bp = (char *)pk->p_ipool;
 215:         pk->p_ipool = bp;
 216:     }
 217: }
 218: 
 219: pkdata(c, sum, pk, bp)
 220: char c;
 221: unsigned short sum;
 222: register struct pack *pk;
 223: char **bp;
 224: {
 225:     register x;
 226:     int t;
 227:     char m;
 228: 
 229:     if (pk->p_state & DRAINO || !(pk->p_state & LIVE)) {
 230:         pk->p_msg |= pk->p_rmsg;
 231:         pkoutput(pk);
 232:         goto drop;
 233:     }
 234:     t = next[pk->p_pr];
 235:     for(x=pk->p_pr; x!=t; x = (x-1)&7) {
 236:         if (pk->p_is[x] == 0)
 237:             goto slot;
 238:     }
 239: drop:
 240:     *bp = (char *)pk->p_ipool;
 241:     pk->p_ipool = bp;
 242:     return;
 243: 
 244: slot:
 245:     m = mask[x];
 246:     pk->p_imap |= m;
 247:     pk->p_is[x] = c;
 248:     pk->p_isum[x] = sum;
 249:     pk->p_ib[x] = (char *)bp;
 250: }
 251: 
 252: /*
 253:  * setup input transfers
 254:  */
 255: #define PKMAXBUF 128
 256: /*
 257:  * Start transmission on output device associated with pk.
 258:  * For asynch devices (t_line==1) framing is
 259:  * imposed.  For devices with framing and crc
 260:  * in the driver (t_line==2) the transfer is
 261:  * passed on to the driver.
 262:  */
 263: pkxstart(pk, cntl, x)
 264: register struct pack *pk;
 265: char cntl;
 266: register x;
 267: {
 268:     register char *p;
 269:     short checkword;
 270:     char hdchk;
 271: 
 272:     p = (caddr_t) &pk->p_ohbuf;
 273:     *p++ = SYN;
 274:     if (x < 0) {
 275:         *p++ = hdchk = 9;
 276:         checkword = cntl;
 277:     } else {
 278:         *p++ = hdchk = pk->p_lpsize;
 279:         checkword = pk->p_osum[x] ^ (unsigned)(cntl & 0377);
 280:     }
 281:     checkword = CHECK - checkword;
 282:     *p = checkword;
 283:     hdchk ^= *p++;
 284:     *p = checkword>>8;
 285:     hdchk ^= *p++;
 286:     *p = cntl;
 287:     hdchk ^= *p++;
 288:     *p = hdchk;
 289:     /*  writes  */
 290:     DEBUG(7, "send 0%o\n", cntl&0xff);
 291:     p = (caddr_t) & pk->p_ohbuf;
 292:     if (x < 0) {
 293:         if(write(pk->p_ofn, p, HDRSIZ) != HDRSIZ) {
 294:             alarm(0);
 295:             logent("PKXSTART write failed", strerror(errno));
 296:             longjmp(Sjbuf, 4);
 297:         }
 298:     } else {
 299:         char buf[PKMAXBUF + HDRSIZ + TAILSIZE], *b;
 300:         int i;
 301:         for (i = 0, b = buf; i < HDRSIZ; i++)
 302:             *b++ = *p++;
 303:         for (i = 0, p = pk->p_ob[x]; i < pk->p_xsize; i++)
 304:             *b++ = *p++;
 305: #if TAILSIZE != 0
 306:         for (i = 0; i < TAILSIZE; i++)
 307:             *b++ = '\0';
 308: #endif TAILSIZE
 309:         if (write(pk->p_ofn, buf, pk->p_xsize + HDRSIZ + TAILSIZE)
 310:             != (HDRSIZ + TAILSIZE + pk->p_xsize)) {
 311:             alarm(0);
 312:             logent("PKXSTART write failed", strerror(errno));
 313:             longjmp(Sjbuf, 5);
 314:         }
 315:         Connodata = 0;
 316:     }
 317:     if (pk->p_msg)
 318:         pkoutput(pk);
 319: }
 320: 
 321: 
 322: pkmove(p1, p2, count, flag)
 323: char *p1, *p2;
 324: int count, flag;
 325: {
 326:     register char *s, *d;
 327:     register int i;
 328: 
 329:     if (flag == B_WRITE) {
 330:         s = p2;
 331:         d = p1;
 332:     } else {
 333:         s = p1;
 334:         d = p2;
 335:     }
 336:     for (i = 0; i < count; i++)
 337:         *d++ = *s++;
 338: }
 339: 
 340: 
 341: /*
 342:  *	get n characters from input
 343:  *
 344:  *	return codes:
 345:  *		n - number of characters returned
 346:  *		0 - end of file
 347:  */
 348: 
 349: jmp_buf Getjbuf;
 350: cgalarm()
 351: {
 352:     longjmp(Getjbuf, 1);
 353: }
 354: 
 355: pkcget(fn, b, n)
 356: int fn;
 357: register char *b;
 358: register int n;
 359: {
 360:     register int ret;
 361:     extern int linebaudrate;
 362: #ifdef BSD4_2
 363:     long r, itime = 100000L; /* guess it's been 1/10th second since we
 364: 				    last read the line */
 365:     struct timeval tv;
 366: #endif BSD4_2
 367: #ifdef VMS
 368:     short iosb[4];
 369:     int SYS$QioW(); /* use this for long reads on vms */
 370: #endif VMS
 371: 
 372:     if (setjmp(Getjbuf)) {
 373:         Ntimeout++;
 374:         DEBUG(4, "pkcget: alarm %d\n", pktimeout * 1000 + Ntimeout);
 375:         pktimeout += pktimeskew;
 376:         if (pktimeout > MAXPKTIME)
 377:             pktimeout = MAXPKTIME;
 378:         return FAIL;
 379:     }
 380:     signal(SIGALRM, cgalarm);
 381: 
 382:     alarm(pktimeout);
 383:     while (n > 0) {
 384: #ifdef BSD4_2
 385:         if (linebaudrate > 0) {
 386:             r = n  * 100000L;
 387:             r = r / linebaudrate;
 388:             r = (r * 100) - itime;
 389:             itime = 0;
 390:             /* we predict that more than 1/50th of a
 391: 			   second will go by before the read will
 392: 			   give back all that we want. */
 393:             if (r > 20000) {
 394:                 tv.tv_sec = r / 1000000L;
 395:                 tv.tv_usec = r % 1000000L;
 396:                 DEBUG(11, "PKCGET stall for %d", tv.tv_sec);
 397:                 DEBUG(11, ".%06d sec\n", tv.tv_usec);
 398:                 (void) select (0, (int *)0, (int *)0, (int *)0, &tv);
 399:             }
 400:         }
 401: #endif BSD4_2
 402: #ifndef VMS
 403:         ret = read(fn, b, n);
 404: #else VMS
 405:         _$Cancel_IO_On_Signal = FD_FAB_Pointer[fn];
 406:         ret = SYS$QioW(_$EFN,(FD_FAB_Pointer[fn]->fab).fab$l_stv,
 407:                 IO$_READVBLK|IO$M_NOFILTR|IO$M_NOECHO,
 408:                 iosb,0,0,b,n,0,
 409:                 iomask,0,0);
 410:         _$Cancel_IO_On_Signal = 0;
 411:         if (ret == SS$_NORMAL)
 412:             ret = iosb[1]+iosb[3];   /* get length of transfer */
 413:         else
 414:             ret = 0;
 415: #endif VMS
 416:         if (ret == 0) {
 417:             alarm(0);
 418:             return FAIL;
 419:         }
 420:         if (ret <= 0) {
 421:             alarm(0);
 422:             logent(strerror(errno),"FAILED pkcget Read");
 423:             longjmp(Sjbuf, 6);
 424:         }
 425:         b += ret;
 426:         n -= ret;
 427:     }
 428:     alarm(0);
 429:     return SUCCESS;
 430: }

Defined functions

cgalarm defined in line 350; used 1 times
pkcget defined in line 355; used 3 times
pkdata defined in line 219; used 1 times
pkgetpack defined in line 126; used 4 times
pkmove defined in line 322; used 2 times
pkopen defined in line 45; used 2 times
pkxstart defined in line 263; used 2 times

Defined variables

Connodata defined in line 30; used 4 times
Getjbuf defined in line 349; used 2 times
Ntimeout defined in line 31; used 5 times
iomask defined in line 19; used 1 times
pksizes defined in line 117; used 3 times
pktimeout defined in line 32; used 7 times
pktimeskew defined in line 33; used 3 times
sccsid defined in line 2; never used

Defined macros

CONNODATA defined in line 24; used 1 times
GETRIES defined in line 121; used 2 times
MAXPKTIME defined in line 23; used 2 times
MAXTIMEOUT defined in line 25; used 1 times
PKMAXBUF defined in line 255; used 1 times
PKMAXSTMSG defined in line 22; used 2 times
Last modified: 1997-10-03
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3729
Valid CSS Valid XHTML 1.0 Strict