|
|
1.1 ! root 1: /* ! 2: * Routines for closing an SPP connection ! 3: */ ! 4: ! 5: /* ! 6: $Log: sppclose.c,v $ ! 7: * Revision 2.0 85/11/21 07:22:21 jqj ! 8: * 4.3BSD standard release ! 9: * ! 10: * Revision 1.3 85/03/11 16:37:50 jqj ! 11: * *** empty log message *** ! 12: * ! 13: * Revision 1.3 85/03/11 16:37:50 jqj ! 14: * Public alpha-test version, released 11 March 1985 ! 15: * ! 16: * Revision 1.2 85/01/27 07:37:52 jqj ! 17: * finished but undebugged version ! 18: * ! 19: */ ! 20: ! 21: #ifndef lint ! 22: static char rcsid[] = "$Header: sppclose.c,v 2.0 85/11/21 07:22:21 jqj Exp $"; ! 23: #endif ! 24: ! 25: /* #include <stdio.h> */ ! 26: #include <sys/types.h> /* for ns.h */ ! 27: #include <sys/socket.h> ! 28: #include <sys/time.h> ! 29: #include <netns/ns.h> /* for misc. constants */ ! 30: #include <netns/sp.h> /* for spphdr */ ! 31: #include "courier.h" ! 32: ! 33: #ifndef SPPMAXDATA ! 34: #define SPPMAXDATA 534 ! 35: #endif ! 36: ! 37: #ifndef TRUE ! 38: #define TRUE (1) ! 39: #define FALSE (0) ! 40: #define NULL ((char*)0) ! 41: #endif ! 42: ! 43: int ! 44: sppclose(s) ! 45: /* try to close an SPP connection by sending an END packet. */ ! 46: /* return TRUE on normal close, FALSE on abnormal close */ ! 47: int s; ! 48: { ! 49: int fdmask; ! 50: static struct timeval timeout = {15,0}; ! 51: struct { ! 52: struct sphdr hdr; ! 53: char data[SPPMAXDATA]; ! 54: } packbuf; ! 55: ! 56: /* streamtype=254, EOM=FALSE, Attn=FALSE */ ! 57: packbuf.hdr.sp_dt = SPPSST_END; ! 58: packbuf.hdr.sp_cc = 0; ! 59: fdmask = 1<<s; ! 60: if (write(s, &packbuf, sizeof(packbuf.hdr)) >= 0 ! 61: && select(s+1,&fdmask,(int*)NULL,(int*)NULL,&timeout) > 0 ! 62: && read(s,(char*)&packbuf,sizeof(packbuf)) > 0) { ! 63: if (packbuf.hdr.sp_dt == SPPSST_ENDREPLY) { ! 64: /* normal close */ ! 65: /* SetSPPoptions(s, SPPSST_ENDREPLY, 0, 0); ! 66: /* streamtype=255, EOM=FALSE, Attn=FALSE */ ! 67: packbuf.hdr.sp_dt = SPPSST_ENDREPLY; ! 68: packbuf.hdr.sp_cc = 0; ! 69: if (write(s, &packbuf, sizeof(packbuf.hdr)) >= 0 ! 70: && shutdown(s,0) >= 0) { ! 71: /* don't read any more, but */ ! 72: /* try to get ENDREPLY out */ ! 73: (void) close(s); ! 74: return(TRUE); ! 75: } ! 76: /* fall out of if to abnormal close */ ! 77: } ! 78: else if (packbuf.hdr.sp_dt == SPPSST_END) { ! 79: /* simultaneous close */ ! 80: return(sppclosereply(s)); ! 81: } ! 82: /* else must have been a data packet -- abnormal close */ ! 83: /* fall through */ ! 84: } ! 85: /* timer expired, data packet arrived, or write failed */ ! 86: (void) shutdown(s,2); /* throw away all data */ ! 87: (void) close(s); ! 88: return(FALSE); ! 89: } ! 90: ! 91: int ! 92: sppclosereply(s) ! 93: /* handle receipt of a packet of type END, by closing down the SPP ! 94: * connection. Returns TRUE on normal close, FALSE otherwise. ! 95: */ ! 96: int s; /* spp socket */ ! 97: { ! 98: int fdmask; ! 99: static struct timeval timeout = {10,0}; ! 100: struct { ! 101: struct sphdr hdr; ! 102: char data[SPPMAXDATA]; ! 103: } packbuf; ! 104: ! 105: fdmask = 1<<s; ! 106: /* SetSPPoptions(s, SPPSST_ENDREPLY, 0, 0); ! 107: /* streamtype=255, EOM=FALSE, Attn=FALSE */ ! 108: packbuf.hdr.sp_dt = SPPSST_ENDREPLY; ! 109: packbuf.hdr.sp_cc = 0; ! 110: if (write(s, &packbuf, sizeof(packbuf.hdr)) ! 111: && select(s+1, &fdmask, (int*)NULL, (int*)NULL, &timeout) > 0 ! 112: && read(s, (char*)&packbuf, sizeof(packbuf)) > 0 ! 113: && shutdown(s,2) == 0) { ! 114: close(s); ! 115: return(packbuf.hdr.sp_dt == SPPSST_ENDREPLY); ! 116: } ! 117: /* write failed, timeout expired, or error occured */ ! 118: (void) shutdown(s,2); /* throw away any data */ ! 119: (void) close(s); ! 120: return(FALSE); ! 121: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.