source: trunk/athena/bin/discuss/usp/block.c @ 201

Revision 201, 5.3 KB checked in by spook, 38 years ago (diff)
Added netinet/in.h for machines that AREN'T backwards.
Line 
1/* UNIX Unified Stream Protocol
2
3   Copyright 1986 by the Massachusetts Institute of Technology
4   See permission and disclaimer notice in file "notice.h"
5*/
6
7#include <sys/types.h>
8#include <stdio.h>
9#include "gen.h"
10#include "usp.h"
11#include <netinet/in.h>
12
13char *error_message();
14/* USP block operations */
15
16int usp_internal_errno = 0;
17char usp_internal_string[256];
18
19char *usp_setup_errlist[] = {
20    "foreign name unknown",
21    "service identifier unknown",
22    "host down",
23    "service not supported on host",
24    "service not currently available",
25    "protocol conversion not available"};
26
27char *usp_during_errlist[] = {
28    "transport failure",
29    "transport timeout",
30    "foreign client failure",
31    "path transformation impossible"};
32
33USP_rcv_blk(us, bt)
34
35USPStream   *us;
36USPCardinal *bt;
37{
38    errno = 0;
39
40    /* get block type */
41   
42    if(get_from_net(us, (char *) bt, sizeof(USPCardinal)) == ERROR) {
43        return(ERROR);
44    }
45    *bt = ntohs(*bt);
46    us->us_in_receiving_p = TRUE;
47    us->us_nunread_sub_block_bytes = 0;
48    if(get_sub_block_header(us) == ERROR) {
49        return(ERROR);
50    }
51
52    /* sneak a look at the block type.  If CONNECTION-ERROR,
53       intercept it, parse the reason and return an error to
54       the client */
55
56    if(*bt == CONNECTION_ERROR) {
57        USPCardinal what_error, who_reported;
58        USPString   info, module_name;
59        char        what_string[256], who_string[65];
60       
61        errno = UEINTERNAL;
62        if(USP_get_cardinal(us, &what_error) == ERROR) {
63            USP_flush_block(us);
64            strcpy(usp_internal_string, "CONNECTION-ERROR block read error");
65            return(ERROR);
66        }
67        switch(what_error) {
68          case CE_UNKNOWN:
69            strcpy(what_string, "unknown internal error");
70            break;
71          case CE_NAME_UNKNOWN:
72          case CE_SERVICE_UNKNOWN:
73          case CE_HOST_DOWN:
74          case CE_SERVICE_UNSUPPORTED:
75          case CE_SERVICE_UNAVAILABLE:
76          case CE_CONVERSION_UNAVAILABLE:
77            strcpy(what_string, usp_setup_errlist[what_error - CE_NAME_UNKNOWN]);
78            break;
79          case CE_TRANSPORT_FAILURE:
80          case CE_TRANSPORT_TIMEOUT:
81          case CE_CLIENT_FAILURE:
82          case CE_PATH_TRANSLATION:
83            strcpy(what_string, usp_during_errlist[what_error - CE_TRANSPORT_FAILURE]);
84            break;
85          default:
86            sprintf(what_string, "(unknown internal error code %u)", what_error);
87            break;
88        }
89        if(USP_get_string(us, &info) == ERROR) {
90            USP_flush_block(us);
91            strcpy(usp_internal_string, "CONNECTION-ERROR block read error");
92            return(ERROR);
93        }
94        if(USP_get_cardinal(us, &who_reported) == ERROR) {
95            USP_flush_block(us);
96            strcpy(usp_internal_string, "CONNECTION-ERROR block read error");
97            return(ERROR);
98        }
99        switch(who_reported) {
100          case FOREIGN_DETECT:
101            strcpy(who_string, "foreign client");
102            break;
103          case TRANSPORT_DETECT:
104            strcpy(who_string, "transport layer");
105            break;
106          case INTERMEDIATE_DETECT:
107            strcpy(who_string, "protocol converter");
108            break;
109          default:
110            strcpy(who_string, "[unknown]");
111        }
112        if(USP_get_string(us, &module_name) == ERROR) {
113            USP_flush_block(us);
114            strcpy(usp_internal_string, "CONNECTION-ERROR block read error");
115            return(ERROR);
116        }
117        sprintf(usp_internal_string, "Internal error \"%s\" (%s), detected by %s \"%s\"",
118                what_string, info, who_string, module_name);
119        cfree((char *) info);
120        cfree((char *) module_name);
121        return(ERROR);
122    }
123
124    /* if other end wishes to shut down, fine... */
125
126    else if(*bt == CONNECTION_END) {
127        if(USP_begin_block(us, CONNECTION_END_REPLY))
128          ;
129        if(USP_end_block(us) == ERROR)
130          ;
131        return(CLOSED);
132    }
133
134    /* if other end is sending an OPEN block, ignore it and get the next
135       block.  Note that we might recurse indefinitely if the other end
136       never sends anything but CONNECTION-OPEN blocks... */
137
138    else if(*bt == CONNECTION_OPEN) {
139        USP_flush_block(us);
140        return(USP_rcv_blk(us, bt));
141    }
142    return(SUCCESS);
143}
144
145USP_begin_block(us, bt)
146
147USPStream   *us;
148USPCardinal bt;
149{
150    errno = 0;
151    if(us->us_out_sending_p) {          /* already sending a block! */
152        errno = UECBNOTENDED;
153        return(ERROR);
154    }
155    bt = htons(bt);
156    if(put_onto_net(us, (char *) &bt, sizeof(USPCardinal), FALSE) == ERROR) {
157        return(ERROR);
158    }
159    us->us_out_sending_p = TRUE;
160    us->us_nsent_sub_block_bytes = 0;                                   
161    return(SUCCESS);
162}
163
164/* end block and flush buffer */
165
166USP_end_block(us)
167
168USPStream    *us;
169{
170    errno = 0;
171    if(! us->us_out_sending_p) {
172        errno = UENOTSENDING;
173        return(ERROR);
174    }
175    if(send_sub_block(us, TRUE) == ERROR) { /* force send of last sub-block */
176        return(ERROR);
177    }
178    us->us_out_sending_p = FALSE;
179    return(SUCCESS);
180}
181
182/* skip to end of block (does nothing if already there) */
183
184USP_flush_block(us)
185
186USPStream    *us;
187{
188    errno = 0;
189    if(! us->us_in_receiving_p) {               /* already there? */
190        return;
191    }
192    while(! us->us_last_sub_block_p) {         
193        if(skip_sub_block(us) == ERROR) {
194            return;
195        }
196        if(get_sub_block_header(us) == ERROR) {
197            return;
198        }
199    }
200
201    /* and skip over the last sub-block */
202
203    if(skip_sub_block(us) == ERROR) {
204        return;
205    }
206    us->us_in_receiving_p = FALSE;
207}
208
209
210Boolean USP_end_of_block_p(us)
211
212USPStream       *us;
213{
214    return(((us->us_nunread_sub_block_bytes == 0) && us->us_last_sub_block_p) ?
215           TRUE : FALSE);
216}
217
218
219
220char *usp_error(errnum)
221
222int errnum;
223{
224    if(errnum == UEINTERNAL) {
225        return(usp_internal_string);
226    }
227    else {
228        return(error_message(errnum));
229    }
230}
Note: See TracBrowser for help on using the repository browser.