Mercurial > pidgin
diff plugins/zephyr/ZParseNot.c @ 1700:1e0fa7e130d0
[gaim-migrate @ 1710]
Zephyr.
committer: Tailor Script <tailor@pidgin.im>
author | Eric Warmenhoven <eric@warmenhoven.org> |
---|---|
date | Thu, 12 Apr 2001 09:21:16 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/zephyr/ZParseNot.c Thu Apr 12 09:21:16 2001 +0000 @@ -0,0 +1,293 @@ +/* This file is part of the Project Athena Zephyr Notification System. + * It contains source for the ZParseNotice function. + * + * Created by: Robert French + * + * $Source$ + * $Author: warmenhoven $ + * + * Copyright (c) 1987,1991 by the Massachusetts Institute of Technology. + * For copying and distribution information, see the file + * "mit-copyright.h". + */ +/* $Header$ */ + +#ifndef lint +static char rcsid_ZParseNotice_c[] = + "$Zephyr: /mit/zephyr/src/lib/RCS/ZParseNotice.c,v 1.22 91/03/29 03:34:46 raeburn Exp $"; +#endif + +#include <internal.h> + +/* Assume that strlen is efficient on this machine... */ +#define next_field(ptr) ptr += strlen (ptr) + 1 + +#if defined (__GNUC__) && defined (__vax__) +#undef next_field +static __inline__ char * Istrend (char *str) { + /* + * This should be faster on VAX models outside the 2 series. Don't + * use it if you are using MicroVAX 2 servers. If you are using a + * VS2 server, use something like + * #define next_field(ptr) while(*ptr++) + * instead of this code. + * + * This requires use of GCC to get the optimized code, but + * everybody uses GCC, don't they? :-) + */ + register char *str2 asm ("r1"); + /* Assumes that no field is longer than 64K.... */ + asm ("locc $0,$65535,(%1)" : "=r" (str2) : "r" (str) : "r0"); + return str2; +} +#define next_field(ptr) ptr = Istrend (ptr) + 1 +#endif + +#ifdef mips +#undef next_field +/* + * The compiler doesn't optimize this macro as well as it does the + * following function. + */ +#define next_fieldXXX(ptr) do{register unsigned c1,c2;c1= *ptr; \ + while((ptr++,c2= *ptr,c1)&&(ptr++,c1= *ptr,c2));}while(0) +static char *next_field_1 (s) char *s; { + /* + * Calling overhead is still present, but this routine is faster + * than strlen, and doesn't bother with some of the other math + * that we'd just have to undo later anyways. + */ + register unsigned c1 = *s, c2; + while (1) { + s++; c2 = *s; if (c1 == 0) break; + s++; c1 = *s; if (c2 == 0) break; + s++; c2 = *s; if (c1 == 0) break; + s++; c1 = *s; if (c2 == 0) break; + } + return s; +} +#define next_field(ptr) ptr=next_field_1(ptr) +#endif + +Code_t ZParseNotice(buffer, len, notice) + char *buffer; + int len; + ZNotice_t *notice; +{ + char *ptr, *end; + unsigned long temp; + int maj, numfields, i; + +#ifdef __LINE__ + int lineno; + /* Note: This definition of BAD eliminates lint and compiler + * complains about the "while (0)", but require that the macro not + * be used as the "then" part of an "if" statement that also has + * an "else" clause. + */ +#define BAD_PACKET {lineno=__LINE__;goto badpkt;} + /* This one gets lint/compiler complaints. */ +/*#define BAD do{lineno=__LINE__;goto badpkt;}while(0)*/ +#else +#define BAD_PACKET goto badpkt +#endif + + (void) memset((char *)notice, 0, sizeof(ZNotice_t)); + + ptr = buffer; + end = buffer+len; + + notice->z_packet = buffer; + + notice->z_version = ptr; + if (strncmp(ptr, ZVERSIONHDR, sizeof(ZVERSIONHDR) - 1)) + return (ZERR_VERS); + ptr += sizeof(ZVERSIONHDR) - 1; + if (!*ptr) { +#ifdef Z_DEBUG + Z_debug ("ZParseNotice: null version string"); +#endif + return ZERR_BADPKT; + } + maj = atoi(ptr); + if (maj != ZVERSIONMAJOR) + return (ZERR_VERS); + next_field (ptr); + + if (ZReadAscii32(ptr, end-ptr, &temp) == ZERR_BADFIELD) + BAD_PACKET; + numfields = temp; + next_field (ptr); + + /*XXX 3 */ + numfields -= 2; /* numfields, version, and checksum */ + if (numfields < 0) { +#ifdef __LINE__ + lineno = __LINE__; + badpkt: +#ifdef Z_DEBUG + Z_debug ("ZParseNotice: bad packet from %s/%d (line %d)", + inet_ntoa (notice->z_uid.zuid_addr.s_addr), + notice->z_port, lineno); +#endif +#else + badpkt: +#ifdef Z_DEBUG + Z_debug ("ZParseNotice: bad packet from %s/%d", + inet_ntoa (notice->z_uid.zuid_addr.s_addr), + notice->z_port); +#endif +#endif + return ZERR_BADPKT; + } + + if (numfields) { + if (ZReadAscii32(ptr, end-ptr, &temp) == ZERR_BADFIELD) + BAD_PACKET; + notice->z_kind = temp; + numfields--; + next_field (ptr); + } + else + BAD_PACKET; + + if (numfields) { + if (ZReadAscii(ptr, end-ptr, (unsigned char *)¬ice->z_uid, + sizeof(ZUnique_Id_t)) == ZERR_BADFIELD) + BAD_PACKET; + notice->z_time.tv_sec = ntohl((u_long) notice->z_uid.tv.tv_sec); + notice->z_time.tv_usec = ntohl((u_long) notice->z_uid.tv.tv_usec); + numfields--; + next_field (ptr); + } + else + BAD_PACKET; + + if (numfields) { + if (ZReadAscii16(ptr, end-ptr, ¬ice->z_port) == ZERR_BADFIELD) + BAD_PACKET; + notice->z_port = htons(notice->z_port); + numfields--; + next_field (ptr); + } + else + BAD_PACKET; + + if (numfields) { + if (ZReadAscii32(ptr, end-ptr, &temp) == ZERR_BADFIELD) + BAD_PACKET; + notice->z_auth = temp; + numfields--; + next_field (ptr); + } + else + BAD_PACKET; + notice->z_checked_auth = ZAUTH_UNSET; + + if (numfields) { + if (ZReadAscii32(ptr, end-ptr, &temp) == ZERR_BADFIELD) + BAD_PACKET; + notice->z_authent_len = temp; + numfields--; + next_field (ptr); + } + else + BAD_PACKET; + + if (numfields) { + notice->z_ascii_authent = ptr; + numfields--; + next_field (ptr); + } + else + BAD_PACKET; + + if (numfields) { + notice->z_class = ptr; + numfields--; + next_field (ptr); + } + else + notice->z_class = ""; + + if (numfields) { + notice->z_class_inst = ptr; + numfields--; + next_field (ptr); + } + else + notice->z_class_inst = ""; + + if (numfields) { + notice->z_opcode = ptr; + numfields--; + next_field (ptr); + } + else + notice->z_opcode = ""; + + if (numfields) { + notice->z_sender = ptr; + numfields--; + next_field (ptr); + } + else + notice->z_sender = ""; + + if (numfields) { + notice->z_recipient = ptr; + numfields--; + next_field (ptr); + } + else + notice->z_recipient = ""; + + if (numfields) { + notice->z_default_format = ptr; + numfields--; + next_field (ptr); + } + else + notice->z_default_format = ""; + +/*XXX*/ + if (ZReadAscii32(ptr, end-ptr, &temp) == ZERR_BADFIELD) + BAD_PACKET; + notice->z_checksum = temp; + numfields--; + next_field (ptr); + + if (numfields) { + notice->z_multinotice = ptr; + numfields--; + next_field (ptr); + } + else + notice->z_multinotice = ""; + + if (numfields) { + if (ZReadAscii(ptr, end-ptr, (unsigned char *)¬ice->z_multiuid, + sizeof(ZUnique_Id_t)) == ZERR_BADFIELD) + BAD_PACKET; + notice->z_time.tv_sec = ntohl((u_long) notice->z_multiuid.tv.tv_sec); + notice->z_time.tv_usec = ntohl((u_long) notice->z_multiuid.tv.tv_usec); + numfields--; + next_field (ptr); + } + else + notice->z_multiuid = notice->z_uid; + + for (i=0;i<Z_MAXOTHERFIELDS && numfields;i++,numfields--) { + notice->z_other_fields[i] = ptr; + next_field (ptr); + } + notice->z_num_other_fields = i; + + for (i=0;i<numfields;i++) + next_field (ptr); + + notice->z_message = (caddr_t) ptr; + notice->z_message_len = len-(ptr-buffer); + + return (ZERR_NONE); +}