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
7 * $Author: warmenhoven $
9 * Copyright (c) 1987,1991 by the Massachusetts Institute of Technology.
10 * For copying and distribution information, see the file
16 static char rcsid_ZParseNotice_c
[] =
17 "$Zephyr: /mit/zephyr/src/lib/RCS/ZParseNotice.c,v 1.22 91/03/29 03:34:46 raeburn Exp $";
22 /* Assume that strlen is efficient on this machine... */
23 #define next_field(ptr) ptr += strlen (ptr) + 1
25 #if defined (__GNUC__) && defined (__vax__)
27 static __inline__
char * Istrend (char *str
) {
29 * This should be faster on VAX models outside the 2 series. Don't
30 * use it if you are using MicroVAX 2 servers. If you are using a
31 * VS2 server, use something like
32 * #define next_field(ptr) while(*ptr++)
33 * instead of this code.
35 * This requires use of GCC to get the optimized code, but
36 * everybody uses GCC, don't they? :-)
38 register char *str2
asm ("r1");
39 /* Assumes that no field is longer than 64K.... */
40 asm ("locc $0,$65535,(%1)" : "=r" (str2
) : "r" (str
) : "r0");
43 #define next_field(ptr) ptr = Istrend (ptr) + 1
49 * The compiler doesn't optimize this macro as well as it does the
52 #define next_fieldXXX(ptr) do{register unsigned c1,c2;c1= *ptr; \
53 while((ptr++,c2= *ptr,c1)&&(ptr++,c1= *ptr,c2));}while(0)
54 static char *next_field_1 (s
) char *s
; {
56 * Calling overhead is still present, but this routine is faster
57 * than strlen, and doesn't bother with some of the other math
58 * that we'd just have to undo later anyways.
60 register unsigned c1
= *s
, c2
;
62 s
++; c2
= *s
; if (c1
== 0) break;
63 s
++; c1
= *s
; if (c2
== 0) break;
64 s
++; c2
= *s
; if (c1
== 0) break;
65 s
++; c1
= *s
; if (c2
== 0) break;
69 #define next_field(ptr) ptr=next_field_1(ptr)
72 Code_t
ZParseNotice(buffer
, len
, notice
)
79 int maj
, numfields
, i
;
83 /* Note: This definition of BAD eliminates lint and compiler
84 * complains about the "while (0)", but require that the macro not
85 * be used as the "then" part of an "if" statement that also has
88 #define BAD_PACKET {lineno=__LINE__;goto badpkt;}
89 /* This one gets lint/compiler complaints. */
90 /*#define BAD do{lineno=__LINE__;goto badpkt;}while(0)*/
92 #define BAD_PACKET goto badpkt
95 (void) memset((char *)notice
, 0, sizeof(ZNotice_t
));
100 notice
->z_packet
= buffer
;
102 notice
->z_version
= ptr
;
103 if (strncmp(ptr
, ZVERSIONHDR
, sizeof(ZVERSIONHDR
) - 1))
105 ptr
+= sizeof(ZVERSIONHDR
) - 1;
108 Z_debug ("ZParseNotice: null version string");
113 if (maj
!= ZVERSIONMAJOR
)
117 if (ZReadAscii32(ptr
, end
-ptr
, &temp
) == ZERR_BADFIELD
)
123 numfields
-= 2; /* numfields, version, and checksum */
129 Z_debug ("ZParseNotice: bad packet from %s/%d (line %d)",
130 inet_ntoa (notice
->z_uid
.zuid_addr
.s_addr
),
131 notice
->z_port
, lineno
);
136 Z_debug ("ZParseNotice: bad packet from %s/%d",
137 inet_ntoa (notice
->z_uid
.zuid_addr
.s_addr
),
145 if (ZReadAscii32(ptr
, end
-ptr
, &temp
) == ZERR_BADFIELD
)
147 notice
->z_kind
= temp
;
155 if (ZReadAscii(ptr
, end
-ptr
, (unsigned char *)¬ice
->z_uid
,
156 sizeof(ZUnique_Id_t
)) == ZERR_BADFIELD
)
158 notice
->z_time
.tv_sec
= ntohl((u_long
) notice
->z_uid
.tv
.tv_sec
);
159 notice
->z_time
.tv_usec
= ntohl((u_long
) notice
->z_uid
.tv
.tv_usec
);
167 if (ZReadAscii16(ptr
, end
-ptr
, ¬ice
->z_port
) == ZERR_BADFIELD
)
169 notice
->z_port
= htons(notice
->z_port
);
177 if (ZReadAscii32(ptr
, end
-ptr
, &temp
) == ZERR_BADFIELD
)
179 notice
->z_auth
= temp
;
185 notice
->z_checked_auth
= ZAUTH_UNSET
;
188 if (ZReadAscii32(ptr
, end
-ptr
, &temp
) == ZERR_BADFIELD
)
190 notice
->z_authent_len
= temp
;
198 notice
->z_ascii_authent
= ptr
;
206 notice
->z_class
= ptr
;
211 notice
->z_class
= "";
214 notice
->z_class_inst
= ptr
;
219 notice
->z_class_inst
= "";
222 notice
->z_opcode
= ptr
;
227 notice
->z_opcode
= "";
230 notice
->z_sender
= ptr
;
235 notice
->z_sender
= "";
238 notice
->z_recipient
= ptr
;
243 notice
->z_recipient
= "";
246 notice
->z_default_format
= ptr
;
251 notice
->z_default_format
= "";
254 if (ZReadAscii32(ptr
, end
-ptr
, &temp
) == ZERR_BADFIELD
)
256 notice
->z_checksum
= temp
;
261 notice
->z_multinotice
= ptr
;
266 notice
->z_multinotice
= "";
269 if (ZReadAscii(ptr
, end
-ptr
, (unsigned char *)¬ice
->z_multiuid
,
270 sizeof(ZUnique_Id_t
)) == ZERR_BADFIELD
)
272 notice
->z_time
.tv_sec
= ntohl((u_long
) notice
->z_multiuid
.tv
.tv_sec
);
273 notice
->z_time
.tv_usec
= ntohl((u_long
) notice
->z_multiuid
.tv
.tv_usec
);
278 notice
->z_multiuid
= notice
->z_uid
;
280 for (i
=0;i
<Z_MAXOTHERFIELDS
&& numfields
;i
++,numfields
--) {
281 notice
->z_other_fields
[i
] = ptr
;
284 notice
->z_num_other_fields
= i
;
286 for (i
=0;i
<numfields
;i
++)
289 notice
->z_message
= (caddr_t
) ptr
;
290 notice
->z_message_len
= len
-(ptr
-buffer
);