1: static char sccsid[]="@(#)pk1.c	4.1  6/27/83  uucp-4.2BSD";
   2: extern  char    *malloc();
   3: 
   4: #define USER    1
   5: #include <stdio.h>
   6: #ifdef SYSIII
   7: #include <sys/types.h>
   8: #endif
   9: #include "pk.p"
  10: #include <sys/param.h>
  11: #include "pk.h"
  12: #include <sys/buf.h>
  13: #include <setjmp.h>
  14: #include <signal.h>
  15: 
  16: 
  17: #define PKMAXSTMSG 40
  18: #define PKTIME  25
  19: extern int Errorrate;
  20: int Connodata = 0;
  21: int Ntimeout = 0;
  22: #define CONNODATA 10
  23: #define NTIMEOUT 50
  24: /*
  25:  * packet driver support routines
  26:  *
  27:  */
  28: 
  29: struct pack *pklines[NPLINES];
  30: 
  31: /*
  32:  * start initial synchronization.
  33:  */
  34: 
  35: struct pack *
  36: pkopen(ifn, ofn)
  37: int ifn, ofn;
  38: {
  39:     register struct pack *pk;
  40:     register char **bp;
  41:     register int i;
  42: 
  43:     if (++pkactive >= NPLINES)
  44:         return(NULL);
  45:     if ((pk = (struct pack *) malloc(sizeof (struct pack))) == NULL)
  46:         return(NULL);
  47:     pkzero((caddr_t) pk, sizeof (struct pack));
  48:     pk->p_ifn = ifn;
  49:     pk->p_ofn = ofn;
  50:     pk->p_xsize = pk->p_rsize = PACKSIZE;
  51:     pk->p_rwindow = pk->p_swindow = WINDOWS;
  52:     /*  allocate input windows */
  53:     for (i = 0; i < pk->p_rwindow; i++) {
  54:         if ((bp = (char **) GETEPACK) == NULL)
  55:             break;
  56:         *bp = (char *) pk->p_ipool;
  57:         pk->p_ipool = bp;
  58:     }
  59:     if (i == 0)
  60:         return(NULL);
  61:     pk->p_rwindow = i;
  62: 
  63:     /* start synchronization */
  64:     pk->p_msg = pk->p_rmsg = M_INITA;
  65:     for (i = 0; i < NPLINES; i++) {
  66:         if (pklines[i] == NULL) {
  67:             pklines[i] = pk;
  68:             break;
  69:         }
  70:     }
  71:     if (i >= NPLINES)
  72:         return(NULL);
  73:     pkoutput(pk);
  74: 
  75:     for (i = 0; i < PKMAXSTMSG; i++) {
  76:         PKGETPKT(pk);
  77:         if ((pk->p_state & LIVE) != 0)
  78:             break;
  79:     }
  80:     if (i >= PKMAXSTMSG)
  81:         return(NULL);
  82: 
  83:     pkreset(pk);
  84:     return(pk);
  85: }
  86: 
  87: 
  88: /*
  89:  * input framing and block checking.
  90:  * frame layout for most devices is:
  91:  *
  92:  *	S|K|X|Y|C|Z|  ... data ... |
  93:  *
  94:  *	where 	S	== initial synch byte
  95:  *		K	== encoded frame size (indexes pksizes[])
  96:  *		X, Y	== block check bytes
  97:  *		C	== control byte
  98:  *		Z	== XOR of header (K^X^Y^C)
  99:  *		data	== 0 or more data bytes
 100:  *
 101:  */
 102: 
 103: int pksizes[] = {
 104:     1, 32, 64, 128, 256, 512, 1024, 2048, 4096, 1
 105: };
 106: 
 107: #define GETRIES 5
 108: /*
 109:  * Pseudo-dma byte collection.
 110:  */
 111: 
 112: pkgetpack(ipk)
 113: struct pack *ipk;
 114: {
 115:     int ret, k, tries;
 116:     register char *p;
 117:     register struct pack *pk;
 118:     register struct header *h;
 119:     unsigned short sum;
 120:     int ifn;
 121:     char **bp;
 122:     char hdchk;
 123: 
 124:     pk = PADDR;
 125:     if ((pk->p_state & DOWN) ||
 126:       Connodata > CONNODATA /* || Ntimeout > NTIMEOUT */)
 127:         pkfail();
 128:     ifn = pk->p_ifn;
 129: 
 130:     /* find HEADER */
 131:     for (tries = 0; tries < GETRIES; ) {
 132:         p = (caddr_t) &pk->p_ihbuf;
 133:         if ((ret = pkcget(ifn, p, 1)) < 0) {
 134:             /* set up retransmit or REJ */
 135:             tries++;
 136:             pk->p_msg |= pk->p_rmsg;
 137:             if (pk->p_msg == 0)
 138:                 pk->p_msg |= M_RR;
 139:             if ((pk->p_state & LIVE) == LIVE)
 140:                 pk->p_state |= RXMIT;
 141:             pkoutput(pk);
 142:             continue;
 143:         }
 144:         if (*p != SYN)
 145:             continue;
 146:         p++;
 147:         ret = pkcget(ifn, p, HDRSIZ - 1);
 148:         if (ret == -1)
 149:             continue;
 150:         break;
 151:     }
 152:     if (tries >= GETRIES) {
 153:         PKDEBUG(4, "tries = %d\n", tries);
 154:         pkfail();
 155:     }
 156: 
 157:     Connodata++;
 158:     h = (struct header * ) &pk->p_ihbuf;
 159:     p = (caddr_t) h;
 160:     hdchk = p[1] ^ p[2] ^ p[3] ^ p[4];
 161:     p += 2;
 162:     sum = (unsigned) *p++ & 0377;
 163:     sum |= (unsigned) *p << 8;
 164:     h->sum = sum;
 165:     PKDEBUG(7, "rec h->cntl %o\n", (unsigned) h->cntl);
 166:     k = h->ksize;
 167:     if (hdchk != h->ccntl) {
 168:         /* bad header */
 169:         PKDEBUG(7, "bad header %o,", hdchk);
 170:         PKDEBUG(7, "h->ccntl %o\n", h->ccntl);
 171:         return;
 172:     }
 173:     if (k == 9) {
 174:         if (((h->sum + h->cntl) & 0xffff) == CHECK) {
 175:             pkcntl(h->cntl, pk);
 176:             PKDEBUG(7, "state - %o\n", pk->p_state);
 177:         }
 178:         else {
 179:             /*  bad header */
 180:             PKDEBUG(7, "bad header (k==9) %o\n", h->cntl);
 181:             pk->p_state |= BADFRAME;
 182:         }
 183:         return;
 184:     }
 185:     if (k && pksizes[k] == pk->p_rsize) {
 186:         pk->p_rpr = h->cntl & MOD8;
 187:         pksack(pk);
 188:         Connodata = 0;
 189:         bp = pk->p_ipool;
 190:         pk->p_ipool = (char **) *bp;
 191:         if (bp == NULL) {
 192:             PKDEBUG(7, "bp NULL %s\n", "");
 193:         return;
 194:         }
 195:     }
 196:     else {
 197:         return;
 198:     }
 199:     ret = pkcget(pk->p_ifn, (char *) bp, pk->p_rsize);
 200:     if (ret == 0)
 201:         pkdata(h->cntl, h->sum, pk, (char **) bp);
 202:     return;
 203: }
 204: 
 205: 
 206: pkdata(c, sum, pk, bp)
 207: char c;
 208: unsigned short sum;
 209: register struct pack *pk;
 210: char **bp;
 211: {
 212: register x;
 213: int t;
 214: char m;
 215: 
 216:     if (pk->p_state & DRAINO || !(pk->p_state & LIVE)) {
 217:         pk->p_msg |= pk->p_rmsg;
 218:         pkoutput(pk);
 219:         goto drop;
 220:     }
 221:     t = next[pk->p_pr];
 222:     for(x=pk->p_pr; x!=t; x = (x-1)&7) {
 223:         if (pk->p_is[x] == 0)
 224:             goto slot;
 225:     }
 226: drop:
 227:     *bp = (char *)pk->p_ipool;
 228:     pk->p_ipool = bp;
 229:     return;
 230: 
 231: slot:
 232:     m = mask[x];
 233:     pk->p_imap |= m;
 234:     pk->p_is[x] = c;
 235:     pk->p_isum[x] = sum;
 236:     pk->p_ib[x] = (char *)bp;
 237:     return;
 238: }
 239: 
 240: 
 241: 
 242: /*
 243:  * setup input transfers
 244:  */
 245: pkrstart(pk)
 246: {}
 247: 
 248: #define PKMAXBUF 128
 249: /*
 250:  * Start transmission on output device associated with pk.
 251:  * For asynch devices (t_line==1) framing is
 252:  * imposed.  For devices with framing and crc
 253:  * in the driver (t_line==2) the transfer is
 254:  * passed on to the driver.
 255:  */
 256: pkxstart(pk, cntl, x)
 257: register struct pack *pk;
 258: char cntl;
 259: register x;
 260: {
 261:     register char *p;
 262:     int ret;
 263:     short checkword;
 264:     char hdchk;
 265: 
 266:     p = (caddr_t) &pk->p_ohbuf;
 267:     *p++ = SYN;
 268:     if (x < 0) {
 269:         *p++ = hdchk = 9;
 270:         checkword = cntl;
 271:     }
 272:     else {
 273:         *p++ = hdchk = pk->p_lpsize;
 274:         checkword = pk->p_osum[x] ^ (unsigned)(cntl & 0377);
 275:     }
 276:     checkword = CHECK - checkword;
 277:     *p = checkword;
 278:     hdchk ^= *p++;
 279:     *p = checkword>>8;
 280:     hdchk ^= *p++;
 281:     *p = cntl;
 282:     hdchk ^= *p++;
 283:     *p = hdchk;
 284:  /*  writes  */
 285: PKDEBUG(7, "send %o\n", (unsigned) cntl);
 286:     p = (caddr_t) & pk->p_ohbuf;
 287:     if (x < 0) {
 288: #ifdef PROTODEBUG
 289:         GENERROR(p, HDRSIZ);
 290: #endif
 291:         ret = write(pk->p_ofn, p, HDRSIZ);
 292:         PKASSERT(ret == HDRSIZ, "PKXSTART ret", "", ret);
 293:     }
 294:     else {
 295:         char buf[PKMAXBUF + HDRSIZ], *b;
 296:         int i;
 297:         for (i = 0, b = buf; i < HDRSIZ; i++)
 298:             *b++ = *p++;
 299:         for (i = 0, p = pk->p_ob[x]; i < pk->p_xsize; i++)
 300:             *b++ = *p++;
 301: #ifdef PROTODEBUG
 302:         GENERROR(buf, pk->p_xsize + HDRSIZ);
 303: #endif
 304:         ret = write(pk->p_ofn, buf, pk->p_xsize + HDRSIZ);
 305:         PKASSERT(ret == pk->p_xsize + HDRSIZ,
 306:           "PKXSTART ret", "", ret);
 307:         Connodata = 0;
 308:     }
 309:     if (pk->p_msg)
 310:         pkoutput(pk);
 311:     return;
 312: }
 313: 
 314: 
 315: pkmove(p1, p2, count, flag)
 316: char *p1, *p2;
 317: int count, flag;
 318: {
 319:     register char *s, *d;
 320:     register int i;
 321: 
 322:     if (flag == B_WRITE) {
 323:         s = p2;
 324:         d = p1;
 325:     }
 326:     else {
 327:         s = p1;
 328:         d = p2;
 329:     }
 330:     for (i = 0; i < count; i++)
 331:         *d++ = *s++;
 332:     return;
 333: }
 334: 
 335: 
 336: /***
 337:  *	pkcget(fn, b, n)	get n characters from input
 338:  *	char *b;		- buffer for characters
 339:  *	int fn;			- file descriptor
 340:  *	int n;			- requested number of characters
 341:  *
 342:  *	return codes:
 343:  *		n - number of characters returned
 344:  *		0 - end of file
 345:  */
 346: 
 347: jmp_buf Getjbuf;
 348: cgalarm() { longjmp(Getjbuf, 1); }
 349: 
 350: pkcget(fn, b, n)
 351: int fn, n;
 352: register char *b;
 353: {
 354:     register int nchars, ret;
 355: 
 356:     if (setjmp(Getjbuf)) {
 357:         Ntimeout++;
 358:         PKDEBUG(4, "alarm %d\n", Ntimeout);
 359:         return(-1);
 360:     }
 361:     signal(SIGALRM, cgalarm);
 362: 
 363:     alarm(PKTIME);
 364:     for (nchars = 0; nchars < n; nchars += ret) {
 365:         ret = read(fn, b, n - nchars);
 366:         if (ret == 0) {
 367:             alarm(0);
 368:             return(-1);
 369:         }
 370:         PKASSERT(ret > 0, "PKCGET READ", "", ret);
 371:         b += ret;
 372:     }
 373:     alarm(0);
 374:     return(0);
 375: }
 376: 
 377: 
 378: #ifdef PROTODEBUG
 379: generror(p, s)
 380: char *p;
 381: int s;
 382: {
 383:     int r;
 384:     if (Errorrate != 0 && (rand() % Errorrate) == 0) {
 385:         r = rand() % s;
 386: fprintf(stderr, "gen err at %o, (%o), ", r, (unsigned) *(p + r));
 387:         *(p + r) += 1;
 388:     }
 389:     return;
 390: }
 391: 
 392: 
 393: #endif

Defined functions

cgalarm defined in line 348; used 1 times
generror defined in line 379; never used
pkcget defined in line 350; used 3 times
pkdata defined in line 206; used 1 times
pkgetpack defined in line 112; never used
pkmove defined in line 315; never used
pkopen defined in line 35; never used
pkrstart defined in line 245; never used
pkxstart defined in line 256; never used

Defined variables

Connodata defined in line 20; used 4 times
Getjbuf defined in line 347; used 2 times
Ntimeout defined in line 21; used 2 times
pklines defined in line 29; used 2 times
pksizes defined in line 103; used 1 times
sccsid defined in line 1; never used

Defined macros

CONNODATA defined in line 22; used 1 times
GETRIES defined in line 107; used 2 times
NTIMEOUT defined in line 23; never used
PKMAXBUF defined in line 248; used 1 times
PKMAXSTMSG defined in line 17; used 2 times
PKTIME defined in line 18; used 1 times
USER defined in line 4; never used
Last modified: 1983-06-30
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 966
Valid CSS Valid XHTML 1.0 Strict