1 /* This file is part of the Project Athena Zephyr Notification System.
2 * It contains source for the ZParseNotice function.
4 * Created by: Robert French
6 * $Id: ZParseNot.c,v 1.29 1999/08/13 00:19:44 danw Exp $
8 * Copyright (c) 1987,1991 by the Massachusetts Institute of Technology.
9 * For copying and distribution information, see the file
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 $";
20 /* Assume that strlen is efficient on this machine... */
21 #define next_field(ptr) ptr += strlen (ptr) + 1
23 #if defined (__GNUC__) && defined (__vax__)
25 static __inline__ char * Istrend (char *str) {
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.
33 * This requires use of GCC to get the optimized code, but
34 * everybody uses GCC, don't they? :-)
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");
41 #define next_field(ptr) ptr = Istrend (ptr) + 1
47 * The compiler doesn't optimize this macro as well as it does the
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; {
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.
58 register unsigned c1 = *s, c2;
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;
67 #define next_field(ptr) ptr=next_field_1(ptr)
70 Code_t ZParseNotice(buffer, len, notice)
77 int maj, numfields, i;
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
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)*/
90 #define BAD_PACKET goto badpkt
93 (void) memset((char *)notice, 0, sizeof(ZNotice_t));
98 notice->z_packet = buffer;
100 notice->z_version = ptr;
101 if (strncmp(ptr, ZVERSIONHDR, sizeof(ZVERSIONHDR) - 1))
103 ptr += sizeof(ZVERSIONHDR) - 1;
106 Z_debug ("ZParseNotice: null version string");
111 if (maj != ZVERSIONMAJOR)
115 if (ZReadAscii32(ptr, end-ptr, &temp) == ZERR_BADFIELD)
121 numfields -= 2; /* numfields, version, and checksum */
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);
134 Z_debug ("ZParseNotice: bad packet from %s/%d",
135 inet_ntoa (notice->z_uid.zuid_addr.s_addr),
143 if (ZReadAscii32(ptr, end-ptr, &temp) == ZERR_BADFIELD)
145 notice->z_kind = (ZNotice_Kind_t)temp;
153 if (ZReadAscii(ptr, end-ptr, (unsigned char *)¬ice->z_uid,
154 sizeof(ZUnique_Id_t)) == ZERR_BADFIELD)
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);
165 if (ZReadAscii16(ptr, end-ptr, ¬ice->z_port) == ZERR_BADFIELD)
167 notice->z_port = htons(notice->z_port);
175 if (ZReadAscii32(ptr, end-ptr, &temp) == ZERR_BADFIELD)
177 notice->z_auth = temp;
183 notice->z_checked_auth = ZAUTH_UNSET;
186 if (ZReadAscii32(ptr, end-ptr, &temp) == ZERR_BADFIELD)
188 notice->z_authent_len = temp;
196 notice->z_ascii_authent = ptr;
204 notice->z_class = ptr;
209 notice->z_class = "";
212 notice->z_class_inst = ptr;
217 notice->z_class_inst = "";
220 notice->z_opcode = ptr;
225 notice->z_opcode = "";
228 notice->z_sender = ptr;
233 notice->z_sender = "";
236 notice->z_recipient = ptr;
241 notice->z_recipient = "";
244 notice->z_default_format = ptr;
249 notice->z_default_format = "";
252 if (ZReadAscii32(ptr, end-ptr, &temp) == ZERR_BADFIELD)
254 notice->z_checksum = temp;
259 notice->z_multinotice = ptr;
264 notice->z_multinotice = "";
267 if (ZReadAscii(ptr, end-ptr, (unsigned char *)¬ice->z_multiuid,
268 sizeof(ZUnique_Id_t)) == ZERR_BADFIELD)
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);
276 notice->z_multiuid = notice->z_uid;
278 for (i=0;i<Z_MAXOTHERFIELDS && numfields;i++,numfields--) {
279 notice->z_other_fields[i] = ptr;
282 notice->z_num_other_fields = i;
284 for (i=0;i<numfields;i++)
287 notice->z_message = (caddr_t) ptr;
288 notice->z_message_len = len-(ptr-buffer);