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: }