/* 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 * * $Id$ * * Copyright (c) 1987,1988 by the Massachusetts Institute of Technology. * For copying and distribution information, see the file * "mit-copyright.h". */ #include #ifndef lint static const char rcsid_ZSubscriptions_c[] = "$Id$"; #endif static Code_t Z_Subscriptions(register ZSubscription_t *sublist, int nitems, unsigned int port, char *opcode, int authit); static Code_t subscr_sendoff(ZNotice_t *notice, char **lyst, int num, int authit); #ifdef CMU_ZCTL_PUNT Code_t ZPunt(ZSubscription_t *sublist, int nitems, unsigned int port) { return (Z_Subscriptions(sublist, nitems, port, "SUPPRESS", 1)); } #endif Code_t ZSubscribeTo(ZSubscription_t *sublist, int nitems, unsigned int port) { return (Z_Subscriptions(sublist, nitems, port, CLIENT_SUBSCRIBE, 1)); } Code_t ZSubscribeToSansDefaults(ZSubscription_t *sublist, int nitems, unsigned int port) { return (Z_Subscriptions(sublist, nitems, port, CLIENT_SUBSCRIBE_NODEFS, 1)); } Code_t ZUnsubscribeTo(ZSubscription_t *sublist, int nitems, unsigned int port) { return (Z_Subscriptions(sublist, nitems, port, CLIENT_UNSUBSCRIBE, 1)); } Code_t ZCancelSubscriptions(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(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); } Code_t ZFlushUserSubscriptions(char *recip) { register Code_t retval; ZNotice_t notice, retnotice; (void)memset((char *)¬ice, 0, sizeof(notice)); notice.z_kind = ACKED; notice.z_class = ZEPHYR_CTL_CLASS; notice.z_class_inst = ZEPHYR_CTL_CLIENT; notice.z_opcode = CLIENT_FLUSHSUBS; notice.z_recipient = ""; notice.z_default_format = ""; if (recip) { notice.z_message = recip; notice.z_message_len = strlen(recip) + 1; } else { notice.z_message_len = 0; } if ((retval = ZSendNotice(¬ice, ZAUTH)) != ZERR_NONE) return (retval); if ((retval = ZIfNotice(&retnotice, (struct sockaddr_in *)0, ZCompareUIDPred, (char *)¬ice.z_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); }