14192
|
1 /* This file is part of the Project Athena Zephyr Notification System.
|
|
2 * It contains source for the ZParseNotice function.
|
|
3 *
|
|
4 * Created by: Robert French
|
|
5 *
|
|
6 * Copyright (c) 1987,1991 by the Massachusetts Institute of Technology.
|
|
7 * For copying and distribution information, see the file
|
|
8 * "mit-copyright.h".
|
|
9 */
|
|
10
|
|
11 #include "internal.h"
|
|
12
|
|
13 /* Assume that strlen is efficient on this machine... */
|
|
14 #define next_field(ptr) ptr += strlen (ptr) + 1
|
|
15
|
|
16 #if defined (__GNUC__) && defined (__vax__)
|
|
17 #undef next_field
|
|
18 static __inline__ char * Istrend (char *str) {
|
|
19 /*
|
|
20 * This should be faster on VAX models outside the 2 series. Don't
|
|
21 * use it if you are using MicroVAX 2 servers. If you are using a
|
|
22 * VS2 server, use something like
|
|
23 * #define next_field(ptr) while(*ptr++)
|
|
24 * instead of this code.
|
|
25 *
|
|
26 * This requires use of GCC to get the optimized code, but
|
|
27 * everybody uses GCC, don't they? :-)
|
|
28 */
|
|
29 register char *str2 asm ("r1");
|
|
30 /* Assumes that no field is longer than 64K.... */
|
|
31 asm ("locc $0,$65535,(%1)" : "=r" (str2) : "r" (str) : "r0");
|
|
32 return str2;
|
|
33 }
|
|
34 #define next_field(ptr) ptr = Istrend (ptr) + 1
|
|
35 #endif
|
|
36
|
|
37 #ifdef mips
|
|
38 #undef next_field
|
|
39 /*
|
|
40 * The compiler doesn't optimize this macro as well as it does the
|
|
41 * following function.
|
|
42 */
|
|
43 #define next_fieldXXX(ptr) do{register unsigned c1,c2;c1= *ptr; \
|
|
44 while((ptr++,c2= *ptr,c1)&&(ptr++,c1= *ptr,c2));}while(0)
|
|
45 static char *next_field_1 (s) char *s; {
|
|
46 /*
|
|
47 * Calling overhead is still present, but this routine is faster
|
|
48 * than strlen, and doesn't bother with some of the other math
|
|
49 * that we'd just have to undo later anyways.
|
|
50 */
|
|
51 register unsigned c1 = *s, c2;
|
|
52 while (1) {
|
|
53 s++; c2 = *s; if (c1 == 0) break;
|
|
54 s++; c1 = *s; if (c2 == 0) break;
|
|
55 s++; c2 = *s; if (c1 == 0) break;
|
|
56 s++; c1 = *s; if (c2 == 0) break;
|
|
57 }
|
|
58 return s;
|
|
59 }
|
|
60 #define next_field(ptr) ptr=next_field_1(ptr)
|
|
61 #endif
|
|
62
|
|
63 Code_t ZParseNotice(buffer, len, notice)
|
|
64 char *buffer;
|
|
65 int len;
|
|
66 ZNotice_t *notice;
|
|
67 {
|
|
68 char *ptr, *end;
|
|
69 unsigned long temp;
|
|
70 int maj, numfields, i;
|
|
71
|
|
72 #ifdef __LINE__
|
|
73 int lineno;
|
|
74 /* Note: This definition of BAD eliminates lint and compiler
|
|
75 * complains about the "while (0)", but require that the macro not
|
|
76 * be used as the "then" part of an "if" statement that also has
|
|
77 * an "else" clause.
|
|
78 */
|
|
79 #define BAD_PACKET {lineno=__LINE__;goto badpkt;}
|
|
80 /* This one gets lint/compiler complaints. */
|
|
81 /*#define BAD do{lineno=__LINE__;goto badpkt;}while(0)*/
|
|
82 #else
|
|
83 #define BAD_PACKET goto badpkt
|
|
84 #endif
|
|
85
|
|
86 (void) memset((char *)notice, 0, sizeof(ZNotice_t));
|
|
87
|
|
88 ptr = buffer;
|
|
89 end = buffer+len;
|
|
90
|
|
91 notice->z_packet = buffer;
|
|
92
|
|
93 notice->z_version = ptr;
|
|
94 if (strncmp(ptr, ZVERSIONHDR, sizeof(ZVERSIONHDR) - 1))
|
|
95 return (ZERR_VERS);
|
|
96 ptr += sizeof(ZVERSIONHDR) - 1;
|
|
97 if (!*ptr) {
|
|
98 #ifdef Z_DEBUG
|
|
99 Z_debug ("ZParseNotice: null version string");
|
|
100 #endif
|
|
101 return ZERR_BADPKT;
|
|
102 }
|
|
103 maj = atoi(ptr);
|
|
104 if (maj != ZVERSIONMAJOR)
|
|
105 return (ZERR_VERS);
|
|
106 next_field (ptr);
|
|
107
|
|
108 if (ZReadAscii32(ptr, end-ptr, &temp) == ZERR_BADFIELD)
|
|
109 BAD_PACKET;
|
|
110 numfields = temp;
|
|
111 next_field (ptr);
|
|
112
|
|
113 /*XXX 3 */
|
|
114 numfields -= 2; /* numfields, version, and checksum */
|
|
115 if (numfields < 0) {
|
|
116 #ifdef __LINE__
|
|
117 lineno = __LINE__;
|
|
118 badpkt:
|
|
119 #ifdef Z_DEBUG
|
|
120 Z_debug ("ZParseNotice: bad packet from %s/%d (line %d)",
|
|
121 inet_ntoa (notice->z_uid.zuid_addr.s_addr),
|
|
122 notice->z_port, lineno);
|
|
123 #endif
|
|
124 #else
|
|
125 badpkt:
|
|
126 #ifdef Z_DEBUG
|
|
127 Z_debug ("ZParseNotice: bad packet from %s/%d",
|
|
128 inet_ntoa (notice->z_uid.zuid_addr.s_addr),
|
|
129 notice->z_port);
|
|
130 #endif
|
|
131 #endif
|
|
132 return ZERR_BADPKT;
|
|
133 }
|
|
134
|
|
135 if (numfields) {
|
|
136 if (ZReadAscii32(ptr, end-ptr, &temp) == ZERR_BADFIELD)
|
|
137 BAD_PACKET;
|
|
138 notice->z_kind = temp;
|
|
139 numfields--;
|
|
140 next_field (ptr);
|
|
141 }
|
|
142 else
|
|
143 BAD_PACKET;
|
|
144
|
|
145 if (numfields) {
|
|
146 if (ZReadAscii(ptr, end-ptr, (unsigned char *)¬ice->z_uid,
|
|
147 sizeof(ZUnique_Id_t)) == ZERR_BADFIELD)
|
|
148 BAD_PACKET;
|
|
149 notice->z_time.tv_sec = ntohl((unsigned long) notice->z_uid.tv.tv_sec);
|
|
150 notice->z_time.tv_usec = ntohl((unsigned long) notice->z_uid.tv.tv_usec);
|
|
151 numfields--;
|
|
152 next_field (ptr);
|
|
153 }
|
|
154 else
|
|
155 BAD_PACKET;
|
|
156
|
|
157 if (numfields) {
|
|
158 if (ZReadAscii16(ptr, end-ptr, ¬ice->z_port) == ZERR_BADFIELD)
|
|
159 BAD_PACKET;
|
|
160 notice->z_port = htons(notice->z_port);
|
|
161 numfields--;
|
|
162 next_field (ptr);
|
|
163 }
|
|
164 else
|
|
165 BAD_PACKET;
|
|
166
|
|
167 if (numfields) {
|
|
168 if (ZReadAscii32(ptr, end-ptr, &temp) == ZERR_BADFIELD)
|
|
169 BAD_PACKET;
|
|
170 notice->z_auth = temp;
|
|
171 numfields--;
|
|
172 next_field (ptr);
|
|
173 }
|
|
174 else
|
|
175 BAD_PACKET;
|
|
176 notice->z_checked_auth = ZAUTH_UNSET;
|
|
177
|
|
178 if (numfields) {
|
|
179 if (ZReadAscii32(ptr, end-ptr, &temp) == ZERR_BADFIELD)
|
|
180 BAD_PACKET;
|
|
181 notice->z_authent_len = temp;
|
|
182 numfields--;
|
|
183 next_field (ptr);
|
|
184 }
|
|
185 else
|
|
186 BAD_PACKET;
|
|
187
|
|
188 if (numfields) {
|
|
189 notice->z_ascii_authent = ptr;
|
|
190 numfields--;
|
|
191 next_field (ptr);
|
|
192 }
|
|
193 else
|
|
194 BAD_PACKET;
|
|
195
|
|
196 if (numfields) {
|
|
197 notice->z_class = ptr;
|
|
198 numfields--;
|
|
199 next_field (ptr);
|
|
200 }
|
|
201 else
|
|
202 notice->z_class = "";
|
|
203
|
|
204 if (numfields) {
|
|
205 notice->z_class_inst = ptr;
|
|
206 numfields--;
|
|
207 next_field (ptr);
|
|
208 }
|
|
209 else
|
|
210 notice->z_class_inst = "";
|
|
211
|
|
212 if (numfields) {
|
|
213 notice->z_opcode = ptr;
|
|
214 numfields--;
|
|
215 next_field (ptr);
|
|
216 }
|
|
217 else
|
|
218 notice->z_opcode = "";
|
|
219
|
|
220 if (numfields) {
|
|
221 notice->z_sender = ptr;
|
|
222 numfields--;
|
|
223 next_field (ptr);
|
|
224 }
|
|
225 else
|
|
226 notice->z_sender = "";
|
|
227
|
|
228 if (numfields) {
|
|
229 notice->z_recipient = ptr;
|
|
230 numfields--;
|
|
231 next_field (ptr);
|
|
232 }
|
|
233 else
|
|
234 notice->z_recipient = "";
|
|
235
|
|
236 if (numfields) {
|
|
237 notice->z_default_format = ptr;
|
|
238 numfields--;
|
|
239 next_field (ptr);
|
|
240 }
|
|
241 else
|
|
242 notice->z_default_format = "";
|
|
243
|
|
244 /*XXX*/
|
|
245 if (ZReadAscii32(ptr, end-ptr, &temp) == ZERR_BADFIELD)
|
|
246 BAD_PACKET;
|
|
247 notice->z_checksum = temp;
|
|
248 numfields--;
|
|
249 next_field (ptr);
|
|
250
|
|
251 if (numfields) {
|
|
252 notice->z_multinotice = ptr;
|
|
253 numfields--;
|
|
254 next_field (ptr);
|
|
255 }
|
|
256 else
|
|
257 notice->z_multinotice = "";
|
|
258
|
|
259 if (numfields) {
|
|
260 if (ZReadAscii(ptr, end-ptr, (unsigned char *)¬ice->z_multiuid,
|
|
261 sizeof(ZUnique_Id_t)) == ZERR_BADFIELD)
|
|
262 BAD_PACKET;
|
|
263 notice->z_time.tv_sec = ntohl((unsigned long) notice->z_multiuid.tv.tv_sec);
|
|
264 notice->z_time.tv_usec = ntohl((unsigned long) notice->z_multiuid.tv.tv_usec);
|
|
265 numfields--;
|
|
266 next_field (ptr);
|
|
267 }
|
|
268 else
|
|
269 notice->z_multiuid = notice->z_uid;
|
|
270
|
|
271 for (i=0;i<Z_MAXOTHERFIELDS && numfields;i++,numfields--) {
|
|
272 notice->z_other_fields[i] = ptr;
|
|
273 next_field (ptr);
|
|
274 }
|
|
275 notice->z_num_other_fields = i;
|
|
276
|
|
277 for (i=0;i<numfields;i++)
|
|
278 next_field (ptr);
|
|
279
|
|
280 notice->z_message = (void *)ptr;
|
|
281 notice->z_message_len = len-(ptr-buffer);
|
|
282
|
|
283 return (ZERR_NONE);
|
|
284 }
|