Mercurial > pidgin
annotate src/protocols/zephyr/ZParseNot.c @ 10607:bf4c9ce533ab
[gaim-migrate @ 12043]
fix a segfault, fix an idiocy from other clients (that was already applied to oldstatus)
committer: Tailor Script <tailor@pidgin.im>
author | Nathan Walp <nwalp@pidgin.im> |
---|---|
date | Thu, 17 Feb 2005 03:31:06 +0000 |
parents | 43d6c08d7e96 |
children | 64895571248f |
rev | line source |
---|---|
2086 | 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 * $Source$ | |
8792
43d6c08d7e96
[gaim-migrate @ 9554]
Christian Hammond <chipx86@chipx86.com>
parents:
7475
diff
changeset
|
7 * $Author: chipx86 $ |
2086 | 8 * |
9 * Copyright (c) 1987,1991 by the Massachusetts Institute of Technology. | |
10 * For copying and distribution information, see the file | |
11 * "mit-copyright.h". | |
12 */ | |
13 /* $Header$ */ | |
14 | |
15 #ifndef lint | |
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 $"; | |
18 #endif | |
19 | |
8792
43d6c08d7e96
[gaim-migrate @ 9554]
Christian Hammond <chipx86@chipx86.com>
parents:
7475
diff
changeset
|
20 #include "internal.h" |
2086 | 21 |
22 /* Assume that strlen is efficient on this machine... */ | |
23 #define next_field(ptr) ptr += strlen (ptr) + 1 | |
24 | |
25 #if defined (__GNUC__) && defined (__vax__) | |
26 #undef next_field | |
27 static __inline__ char * Istrend (char *str) { | |
28 /* | |
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. | |
34 * | |
35 * This requires use of GCC to get the optimized code, but | |
36 * everybody uses GCC, don't they? :-) | |
37 */ | |
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"); | |
41 return str2; | |
42 } | |
43 #define next_field(ptr) ptr = Istrend (ptr) + 1 | |
44 #endif | |
45 | |
46 #ifdef mips | |
47 #undef next_field | |
48 /* | |
49 * The compiler doesn't optimize this macro as well as it does the | |
50 * following function. | |
51 */ | |
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; { | |
55 /* | |
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. | |
59 */ | |
60 register unsigned c1 = *s, c2; | |
61 while (1) { | |
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; | |
66 } | |
67 return s; | |
68 } | |
69 #define next_field(ptr) ptr=next_field_1(ptr) | |
70 #endif | |
71 | |
72 Code_t ZParseNotice(buffer, len, notice) | |
73 char *buffer; | |
74 int len; | |
75 ZNotice_t *notice; | |
76 { | |
77 char *ptr, *end; | |
78 unsigned long temp; | |
79 int maj, numfields, i; | |
80 | |
81 #ifdef __LINE__ | |
82 int lineno; | |
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 | |
86 * an "else" clause. | |
87 */ | |
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)*/ | |
91 #else | |
92 #define BAD_PACKET goto badpkt | |
93 #endif | |
94 | |
95 (void) memset((char *)notice, 0, sizeof(ZNotice_t)); | |
96 | |
97 ptr = buffer; | |
98 end = buffer+len; | |
99 | |
100 notice->z_packet = buffer; | |
101 | |
102 notice->z_version = ptr; | |
103 if (strncmp(ptr, ZVERSIONHDR, sizeof(ZVERSIONHDR) - 1)) | |
104 return (ZERR_VERS); | |
105 ptr += sizeof(ZVERSIONHDR) - 1; | |
106 if (!*ptr) { | |
107 #ifdef Z_DEBUG | |
108 Z_debug ("ZParseNotice: null version string"); | |
109 #endif | |
110 return ZERR_BADPKT; | |
111 } | |
112 maj = atoi(ptr); | |
113 if (maj != ZVERSIONMAJOR) | |
114 return (ZERR_VERS); | |
115 next_field (ptr); | |
116 | |
117 if (ZReadAscii32(ptr, end-ptr, &temp) == ZERR_BADFIELD) | |
118 BAD_PACKET; | |
119 numfields = temp; | |
120 next_field (ptr); | |
121 | |
122 /*XXX 3 */ | |
123 numfields -= 2; /* numfields, version, and checksum */ | |
124 if (numfields < 0) { | |
125 #ifdef __LINE__ | |
126 lineno = __LINE__; | |
127 badpkt: | |
128 #ifdef Z_DEBUG | |
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); | |
132 #endif | |
133 #else | |
134 badpkt: | |
135 #ifdef Z_DEBUG | |
136 Z_debug ("ZParseNotice: bad packet from %s/%d", | |
137 inet_ntoa (notice->z_uid.zuid_addr.s_addr), | |
138 notice->z_port); | |
139 #endif | |
140 #endif | |
141 return ZERR_BADPKT; | |
142 } | |
143 | |
144 if (numfields) { | |
145 if (ZReadAscii32(ptr, end-ptr, &temp) == ZERR_BADFIELD) | |
146 BAD_PACKET; | |
147 notice->z_kind = temp; | |
148 numfields--; | |
149 next_field (ptr); | |
150 } | |
151 else | |
152 BAD_PACKET; | |
153 | |
154 if (numfields) { | |
155 if (ZReadAscii(ptr, end-ptr, (unsigned char *)¬ice->z_uid, | |
156 sizeof(ZUnique_Id_t)) == ZERR_BADFIELD) | |
157 BAD_PACKET; | |
7475 | 158 notice->z_time.tv_sec = ntohl((unsigned long) notice->z_uid.tv.tv_sec); |
159 notice->z_time.tv_usec = ntohl((unsigned long) notice->z_uid.tv.tv_usec); | |
2086 | 160 numfields--; |
161 next_field (ptr); | |
162 } | |
163 else | |
164 BAD_PACKET; | |
165 | |
166 if (numfields) { | |
167 if (ZReadAscii16(ptr, end-ptr, ¬ice->z_port) == ZERR_BADFIELD) | |
168 BAD_PACKET; | |
169 notice->z_port = htons(notice->z_port); | |
170 numfields--; | |
171 next_field (ptr); | |
172 } | |
173 else | |
174 BAD_PACKET; | |
175 | |
176 if (numfields) { | |
177 if (ZReadAscii32(ptr, end-ptr, &temp) == ZERR_BADFIELD) | |
178 BAD_PACKET; | |
179 notice->z_auth = temp; | |
180 numfields--; | |
181 next_field (ptr); | |
182 } | |
183 else | |
184 BAD_PACKET; | |
185 notice->z_checked_auth = ZAUTH_UNSET; | |
186 | |
187 if (numfields) { | |
188 if (ZReadAscii32(ptr, end-ptr, &temp) == ZERR_BADFIELD) | |
189 BAD_PACKET; | |
190 notice->z_authent_len = temp; | |
191 numfields--; | |
192 next_field (ptr); | |
193 } | |
194 else | |
195 BAD_PACKET; | |
196 | |
197 if (numfields) { | |
198 notice->z_ascii_authent = ptr; | |
199 numfields--; | |
200 next_field (ptr); | |
201 } | |
202 else | |
203 BAD_PACKET; | |
204 | |
205 if (numfields) { | |
206 notice->z_class = ptr; | |
207 numfields--; | |
208 next_field (ptr); | |
209 } | |
210 else | |
211 notice->z_class = ""; | |
212 | |
213 if (numfields) { | |
214 notice->z_class_inst = ptr; | |
215 numfields--; | |
216 next_field (ptr); | |
217 } | |
218 else | |
219 notice->z_class_inst = ""; | |
220 | |
221 if (numfields) { | |
222 notice->z_opcode = ptr; | |
223 numfields--; | |
224 next_field (ptr); | |
225 } | |
226 else | |
227 notice->z_opcode = ""; | |
228 | |
229 if (numfields) { | |
230 notice->z_sender = ptr; | |
231 numfields--; | |
232 next_field (ptr); | |
233 } | |
234 else | |
235 notice->z_sender = ""; | |
236 | |
237 if (numfields) { | |
238 notice->z_recipient = ptr; | |
239 numfields--; | |
240 next_field (ptr); | |
241 } | |
242 else | |
243 notice->z_recipient = ""; | |
244 | |
245 if (numfields) { | |
246 notice->z_default_format = ptr; | |
247 numfields--; | |
248 next_field (ptr); | |
249 } | |
250 else | |
251 notice->z_default_format = ""; | |
252 | |
253 /*XXX*/ | |
254 if (ZReadAscii32(ptr, end-ptr, &temp) == ZERR_BADFIELD) | |
255 BAD_PACKET; | |
256 notice->z_checksum = temp; | |
257 numfields--; | |
258 next_field (ptr); | |
259 | |
260 if (numfields) { | |
261 notice->z_multinotice = ptr; | |
262 numfields--; | |
263 next_field (ptr); | |
264 } | |
265 else | |
266 notice->z_multinotice = ""; | |
267 | |
268 if (numfields) { | |
269 if (ZReadAscii(ptr, end-ptr, (unsigned char *)¬ice->z_multiuid, | |
270 sizeof(ZUnique_Id_t)) == ZERR_BADFIELD) | |
271 BAD_PACKET; | |
7475 | 272 notice->z_time.tv_sec = ntohl((unsigned long) notice->z_multiuid.tv.tv_sec); |
273 notice->z_time.tv_usec = ntohl((unsigned long) notice->z_multiuid.tv.tv_usec); | |
2086 | 274 numfields--; |
275 next_field (ptr); | |
276 } | |
277 else | |
278 notice->z_multiuid = notice->z_uid; | |
279 | |
280 for (i=0;i<Z_MAXOTHERFIELDS && numfields;i++,numfields--) { | |
281 notice->z_other_fields[i] = ptr; | |
282 next_field (ptr); | |
283 } | |
284 notice->z_num_other_fields = i; | |
285 | |
286 for (i=0;i<numfields;i++) | |
287 next_field (ptr); | |
288 | |
7475 | 289 notice->z_message = (void *)ptr; |
2086 | 290 notice->z_message_len = len-(ptr-buffer); |
291 | |
292 return (ZERR_NONE); | |
293 } |