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 * Copyright (c) 1987,1991 by the Massachusetts Institute of Technology.
7 * For copying and distribution information, see the file
13 /* Assume that strlen is efficient on this machine... */
14 #define next_field(ptr) ptr += strlen (ptr) + 1
16 #if defined (__GNUC__) && defined (__vax__)
18 static __inline__
char * Istrend (char *str
) {
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.
26 * This requires use of GCC to get the optimized code, but
27 * everybody uses GCC, don't they? :-)
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");
34 #define next_field(ptr) ptr = Istrend (ptr) + 1
40 * The compiler doesn't optimize this macro as well as it does the
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
; {
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.
51 register unsigned c1
= *s
, c2
;
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;
60 #define next_field(ptr) ptr=next_field_1(ptr)
63 Code_t
ZParseNotice(buffer
, len
, notice
)
70 int maj
, numfields
, i
;
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
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)*/
83 #define BAD_PACKET goto badpkt
86 (void) memset((char *)notice
, 0, sizeof(ZNotice_t
));
91 notice
->z_packet
= buffer
;
93 notice
->z_version
= ptr
;
94 if (strncmp(ptr
, ZVERSIONHDR
, sizeof(ZVERSIONHDR
) - 1))
96 ptr
+= sizeof(ZVERSIONHDR
) - 1;
99 Z_debug ("ZParseNotice: null version string");
104 if (maj
!= ZVERSIONMAJOR
)
108 if (ZReadAscii32(ptr
, end
-ptr
, &temp
) == ZERR_BADFIELD
)
114 numfields
-= 2; /* numfields, version, and checksum */
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
);
124 /* We won't use lineno anywhere else, so let's silence a warning. */
130 Z_debug ("ZParseNotice: bad packet from %s/%d",
131 inet_ntoa (notice
->z_uid
.zuid_addr
.s_addr
),
139 if (ZReadAscii32(ptr
, end
-ptr
, &temp
) == ZERR_BADFIELD
)
141 notice
->z_kind
= temp
;
149 if (ZReadAscii(ptr
, end
-ptr
, (unsigned char *)¬ice
->z_uid
,
150 sizeof(ZUnique_Id_t
)) == ZERR_BADFIELD
)
152 notice
->z_time
.tv_sec
= ntohl((unsigned long) notice
->z_uid
.tv
.tv_sec
);
153 notice
->z_time
.tv_usec
= ntohl((unsigned long) notice
->z_uid
.tv
.tv_usec
);
161 if (ZReadAscii16(ptr
, end
-ptr
, ¬ice
->z_port
) == ZERR_BADFIELD
)
163 notice
->z_port
= htons(notice
->z_port
);
171 if (ZReadAscii32(ptr
, end
-ptr
, &temp
) == ZERR_BADFIELD
)
173 notice
->z_auth
= temp
;
179 notice
->z_checked_auth
= ZAUTH_UNSET
;
182 if (ZReadAscii32(ptr
, end
-ptr
, &temp
) == ZERR_BADFIELD
)
184 notice
->z_authent_len
= temp
;
192 notice
->z_ascii_authent
= ptr
;
200 notice
->z_class
= ptr
;
205 notice
->z_class
= "";
208 notice
->z_class_inst
= ptr
;
213 notice
->z_class_inst
= "";
216 notice
->z_opcode
= ptr
;
221 notice
->z_opcode
= "";
224 notice
->z_sender
= ptr
;
229 notice
->z_sender
= "";
232 notice
->z_recipient
= ptr
;
237 notice
->z_recipient
= "";
240 notice
->z_default_format
= ptr
;
245 notice
->z_default_format
= "";
248 if (ZReadAscii32(ptr
, end
-ptr
, &temp
) == ZERR_BADFIELD
)
250 notice
->z_checksum
= temp
;
255 notice
->z_multinotice
= ptr
;
260 notice
->z_multinotice
= "";
263 if (ZReadAscii(ptr
, end
-ptr
, (unsigned char *)¬ice
->z_multiuid
,
264 sizeof(ZUnique_Id_t
)) == ZERR_BADFIELD
)
266 notice
->z_time
.tv_sec
= ntohl((unsigned long) notice
->z_multiuid
.tv
.tv_sec
);
267 notice
->z_time
.tv_usec
= ntohl((unsigned long) notice
->z_multiuid
.tv
.tv_usec
);
272 notice
->z_multiuid
= notice
->z_uid
;
274 for (i
=0;i
<Z_MAXOTHERFIELDS
&& numfields
;i
++,numfields
--) {
275 notice
->z_other_fields
[i
] = ptr
;
278 notice
->z_num_other_fields
= i
;
280 for (i
=0;i
<numfields
;i
++)
283 notice
->z_message
= (void *)ptr
;
284 notice
->z_message_len
= len
-(ptr
-buffer
);