1 /* This file is part of the Project Athena Zephyr Notification System.
2 * It contains source for the ZSubscribeTo, ZUnsubscribeTo, and
3 * ZCancelSubscriptions functions.
5 * Created by: Robert French
8 * $Author: warmenhoven $
10 * Copyright (c) 1987,1988 by the Massachusetts Institute of Technology.
11 * For copying and distribution information, see the file
19 static const char rcsid_ZSubscriptions_c
[] = "$Id: ZSubs.c 2432 2001-10-03 19:38:28Z warmenhoven $";
22 static Code_t Z_Subscriptions
__P((register ZSubscription_t
*sublist
,
23 int nitems
, unsigned int port
,
24 char *opcode
, int authit
));
25 static Code_t subscr_sendoff
__P((ZNotice_t
*notice
, char **lyst
, int num
,
28 Code_t
ZSubscribeTo(sublist
, nitems
, port
)
29 ZSubscription_t
*sublist
;
33 return (Z_Subscriptions(sublist
, nitems
, port
, CLIENT_SUBSCRIBE
, 1));
36 Code_t
ZSubscribeToSansDefaults(sublist
, nitems
, port
)
37 ZSubscription_t
*sublist
;
41 return (Z_Subscriptions(sublist
, nitems
, port
, CLIENT_SUBSCRIBE_NODEFS
,
45 Code_t
ZUnsubscribeTo(sublist
, nitems
, port
)
46 ZSubscription_t
*sublist
;
50 return (Z_Subscriptions(sublist
, nitems
, port
, CLIENT_UNSUBSCRIBE
, 1));
53 Code_t
ZCancelSubscriptions(port
)
56 return (Z_Subscriptions((ZSubscription_t
*)0, 0, port
,
57 CLIENT_CANCELSUB
, 0));
61 * This routine must do its own fragmentation. Subscriptions must
62 * not be broken across packet boundaries, or else the server will
67 Z_Subscriptions(sublist
, nitems
, port
, opcode
, authit
)
68 register ZSubscription_t
*sublist
;
77 char header
[Z_MAXHEADERLEN
];
80 int size_avail
= Z_MAXPKTLEN
-Z_FRAGFUDGE
; /* space avail for data,
82 int size
, start
, numok
;
84 /* nitems = 0 means cancel all subscriptions; still need to allocate a */
85 /* array for one item so we can cancel, however. */
87 list
= (char **)malloc((unsigned)((nitems
==0)?1:nitems
)*3*sizeof(char *));
91 (void) memset((char *)¬ice
, 0, sizeof(notice
));
92 notice
.z_kind
= ACKED
;
94 notice
.z_class
= ZEPHYR_CTL_CLASS
;
95 notice
.z_class_inst
= ZEPHYR_CTL_CLIENT
;
96 notice
.z_opcode
= opcode
;
98 notice
.z_recipient
= "";
99 notice
.z_default_format
= "";
100 notice
.z_message_len
= 0;
102 /* format the header to figure out how long it is */
103 retval
= Z_FormatHeader(¬ice
, header
, sizeof(header
), &hdrlen
, ZAUTH
);
104 if (retval
!= ZERR_NONE
&& !authit
)
105 retval
= Z_FormatHeader(¬ice
, header
, sizeof(header
),
107 if (retval
!= ZERR_NONE
) {
112 /* compute amount of room left */
113 size_avail
-= hdrlen
;
116 /* assemble subs into an array of pointers */
117 for (i
=0;i
<nitems
;i
++) {
118 list
[i
*3] = sublist
[i
].zsub_class
;
119 list
[i
*3+1] = sublist
[i
].zsub_classinst
;
120 if (sublist
[i
].zsub_recipient
&& *sublist
[i
].zsub_recipient
&&
121 *sublist
[i
].zsub_recipient
!= '*')
122 list
[i
*3+2] = ZGetSender();
131 /* there aren't really any, but we need to xmit anyway */
132 retval
= subscr_sendoff(¬ice
, list
, 0, authit
);
142 if ((j
= strlen(list
[i
*3])
143 + strlen(list
[i
*3+1])
144 + strlen(list
[i
*3+2]) + 3) <= size
) {
145 /* it will fit in this packet */
151 if (!numok
) { /* a single subscription won't
152 fit into one packet */
154 return(ZERR_FIELDLEN
);
156 retval
= subscr_sendoff(¬ice
, &list
[start
*3], numok
, authit
);
164 retval
= subscr_sendoff(¬ice
, &list
[start
*3], numok
, authit
);
170 subscr_sendoff(notice
, lyst
, num
, authit
)
176 register Code_t retval
;
179 retval
= ZSendList(notice
, lyst
, num
*3, ZAUTH
);
180 if (retval
!= ZERR_NONE
&& !authit
)
181 retval
= ZSendList(notice
, lyst
, num
*3, ZNOAUTH
);
183 if (retval
!= ZERR_NONE
)
185 if ((retval
= ZIfNotice(&retnotice
, (struct sockaddr_in
*)0,
186 ZCompareUIDPred
, (char *)¬ice
->z_uid
)) !=
189 if (retnotice
.z_kind
== SERVNAK
) {
190 ZFreeNotice(&retnotice
);
191 return (ZERR_SERVNAK
);
193 if (retnotice
.z_kind
!= SERVACK
) {
194 ZFreeNotice(&retnotice
);
195 return (ZERR_INTERNAL
);
197 ZFreeNotice(&retnotice
);