Mercurial > pidgin
comparison libpurple/protocols/zephyr/ZParseNot.c @ 15373:5fe8042783c1
Rename gtk/ and libgaim/ to pidgin/ and libpurple/
author | Sean Egan <seanegan@gmail.com> |
---|---|
date | Sat, 20 Jan 2007 02:32:10 +0000 |
parents | |
children | a8cc50c2279f |
comparison
equal
deleted
inserted
replaced
15372:f79e0f4df793 | 15373:5fe8042783c1 |
---|---|
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 } |