|
|
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.