/* This file is part of the Project Athena Zephyr Notification System. * It contains source for the ZSubscribeTo, ZUnsubscribeTo, and * ZCancelSubscriptions functions. * * Created by: Robert French * * $Source: /cvsroot/gaim/gaim/src/protocols/zephyr/ZSubs.c,v $ * $Author: chipx86 $ * * Copyright (c) 1987,1988 by the Massachusetts Institute of Technology. * For copying and distribution information, see the file * "mit-copyright.h". */ /* $Header: /cvsroot/gaim/gaim/src/protocols/zephyr/ZSubs.c,v 1.4 2004/04/24 09:02:28 chipx86 Exp $ */ #include "internal.h" #ifndef lint static const char rcsid_ZSubscriptions_c[] = "$Id: ZSubs.c,v 1.4 2004/04/24 09:02:28 chipx86 Exp $"; #endif static Code_t Z_Subscriptions __P((register ZSubscription_t *sublist, int nitems, unsigned int port, char *opcode, int authit)); static Code_t subscr_sendoff __P((ZNotice_t *notice, char **lyst, int num, int authit)); Code_t ZSubscribeTo(sublist, nitems, port) ZSubscription_t *sublist; int nitems; unsigned int port; { return (Z_Subscriptions(sublist, nitems, port, CLIENT_SUBSCRIBE, 1)); } Code_t ZSubscribeToSansDefaults(sublist, nitems, port) ZSubscription_t *sublist; int nitems; unsigned int port; { return (Z_Subscriptions(sublist, nitems, port, CLIENT_SUBSCRIBE_NODEFS, 1)); } Code_t ZUnsubscribeTo(sublist, nitems, port) ZSubscription_t *sublist; int nitems; unsigned int port; { return (Z_Subscriptions(sublist, nitems, port, CLIENT_UNSUBSCRIBE, 1)); } Code_t ZCancelSubscriptions(port) unsigned int port; { return (Z_Subscriptions((ZSubscription_t *)0, 0, port, CLIENT_CANCELSUB, 0)); } /* * This routine must do its own fragmentation. Subscriptions must * not be broken across packet boundaries, or else the server will * mis-interpret them. */ static Code_t Z_Subscriptions(sublist, nitems, port, opcode, authit) register ZSubscription_t *sublist; int nitems; unsigned int port; char *opcode; int authit; { register int i, j; int retval; ZNotice_t notice; char header[Z_MAXHEADERLEN]; char **list; char *recip; int hdrlen; int size_avail = Z_MAXPKTLEN-Z_FRAGFUDGE; /* space avail for data, adjusted below */ int size, start, numok; /* nitems = 0 means cancel all subscriptions; still need to allocate a */ /* array for one item so we can cancel, however. */ list = (char **)malloc((unsigned)((nitems==0)?1:nitems)*3*sizeof(char *)); if (!list) return (ENOMEM); (void) memset((char *)¬ice, 0, sizeof(notice)); notice.z_kind = ACKED; notice.z_port = port; notice.z_class = ZEPHYR_CTL_CLASS; notice.z_class_inst = ZEPHYR_CTL_CLIENT; notice.z_opcode = opcode; notice.z_sender = 0; notice.z_recipient = ""; notice.z_default_format = ""; notice.z_message_len = 0; /* format the header to figure out how long it is */ retval = Z_FormatHeader(¬ice, header, sizeof(header), &hdrlen, ZAUTH); if (retval != ZERR_NONE && !authit) retval = Z_FormatHeader(¬ice, header, sizeof(header), &hdrlen, ZNOAUTH); if (retval != ZERR_NONE) { free((char *)list); return(retval); } /* compute amount of room left */ size_avail -= hdrlen; size = size_avail; /* assemble subs into an array of pointers */ for (i=0;iz_uid)) != ZERR_NONE) return (retval); if (retnotice.z_kind == SERVNAK) { ZFreeNotice(&retnotice); return (ZERR_SERVNAK); } if (retnotice.z_kind != SERVACK) { ZFreeNotice(&retnotice); return (ZERR_INTERNAL); } ZFreeNotice(&retnotice); return (ZERR_NONE); }