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