Mercurial > pidgin
annotate src/protocols/zephyr/ZParseNot.c @ 13561:104fbbfc91fb
[gaim-migrate @ 15940]
beta3 for the RPM spec file too
committer: Tailor Script <tailor@pidgin.im>
| author | Stu Tomlinson <stu@nosnilmot.com> |
|---|---|
| date | Sat, 25 Mar 2006 15:17:15 +0000 |
| parents | 64895571248f |
| children |
| 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 * 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 | |
|
8792
43d6c08d7e96
[gaim-migrate @ 9554]
Christian Hammond <chipx86@chipx86.com>
parents:
7475
diff
changeset
|
11 #include "internal.h" |
| 2086 | 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; | |
| 7475 | 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); | |
| 2086 | 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; | |
| 7475 | 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); | |
| 2086 | 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 | |
| 7475 | 280 notice->z_message = (void *)ptr; |
| 2086 | 281 notice->z_message_len = len-(ptr-buffer); |
| 282 | |
| 283 return (ZERR_NONE); | |
| 284 } |
