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
7 * Copyright (c) 1987,1988 by the Massachusetts Institute of Technology.
8 * For copying and distribution information, see the file
14 static Code_t
Z_Subscriptions(register ZSubscription_t
*sublist
, int nitems
,
15 unsigned int port
, char *opcode
, int authit
);
16 static Code_t
subscr_sendoff(ZNotice_t
*notice
, char **lyst
, int num
,
19 Code_t
ZSubscribeTo(sublist
, nitems
, port
)
20 ZSubscription_t
*sublist
;
24 return (Z_Subscriptions(sublist
, nitems
, port
, CLIENT_SUBSCRIBE
, 1));
27 Code_t
ZSubscribeToSansDefaults(sublist
, nitems
, port
)
28 ZSubscription_t
*sublist
;
32 return (Z_Subscriptions(sublist
, nitems
, port
, CLIENT_SUBSCRIBE_NODEFS
,
36 Code_t
ZUnsubscribeTo(sublist
, nitems
, port
)
37 ZSubscription_t
*sublist
;
41 return (Z_Subscriptions(sublist
, nitems
, port
, CLIENT_UNSUBSCRIBE
, 1));
44 Code_t
ZCancelSubscriptions(port
)
47 return (Z_Subscriptions((ZSubscription_t
*)0, 0, port
,
48 CLIENT_CANCELSUB
, 0));
52 * This routine must do its own fragmentation. Subscriptions must
53 * not be broken across packet boundaries, or else the server will
58 Z_Subscriptions(sublist
, nitems
, port
, opcode
, authit
)
59 register ZSubscription_t
*sublist
;
68 char header
[Z_MAXHEADERLEN
];
72 int size_avail
= Z_MAXPKTLEN
-Z_FRAGFUDGE
; /* space avail for data,
74 int size
, start
, numok
;
76 /* nitems = 0 means cancel all subscriptions; still need to allocate a */
77 /* array for one item so we can cancel, however. */
79 list
= (char **)malloc((unsigned)((nitems
==0)?1:nitems
)*3*sizeof(char *));
83 (void) memset((char *)¬ice
, 0, sizeof(notice
));
84 notice
.z_kind
= ACKED
;
86 notice
.z_class
= ZEPHYR_CTL_CLASS
;
87 notice
.z_class_inst
= ZEPHYR_CTL_CLIENT
;
88 notice
.z_opcode
= opcode
;
90 notice
.z_recipient
= "";
91 notice
.z_default_format
= "";
92 notice
.z_message_len
= 0;
94 /* format the header to figure out how long it is */
95 retval
= Z_FormatHeader(¬ice
, header
, sizeof(header
), &hdrlen
, ZAUTH
);
96 if (retval
!= ZERR_NONE
&& !authit
)
97 retval
= Z_FormatHeader(¬ice
, header
, sizeof(header
),
99 if (retval
!= ZERR_NONE
) {
104 /* compute amount of room left */
105 size_avail
-= hdrlen
;
108 /* assemble subs into an array of pointers */
109 for (i
=0;i
<nitems
;i
++) {
110 list
[i
*3] = sublist
[i
].zsub_class
;
111 list
[i
*3+1] = sublist
[i
].zsub_classinst
;
112 recip
= sublist
[i
].zsub_recipient
;
113 if (recip
&& *recip
== '*')
115 if (!recip
|| (*recip
!= 0 && *recip
!= '@'))
116 recip
= ZGetSender();
124 /* there aren't really any, but we need to xmit anyway */
125 retval
= subscr_sendoff(¬ice
, list
, 0, authit
);
135 if ((j
= strlen(list
[i
*3])
136 + strlen(list
[i
*3+1])
137 + strlen(list
[i
*3+2]) + 3) <= size
) {
138 /* it will fit in this packet */
144 if (!numok
) { /* a single subscription won't
145 fit into one packet */
147 return(ZERR_FIELDLEN
);
149 retval
= subscr_sendoff(¬ice
, &list
[start
*3], numok
, authit
);
157 retval
= subscr_sendoff(¬ice
, &list
[start
*3], numok
, authit
);
163 subscr_sendoff(notice
, lyst
, num
, authit
)
169 register Code_t retval
;
172 retval
= ZSendList(notice
, lyst
, num
*3, ZAUTH
);
173 if (retval
!= ZERR_NONE
&& !authit
)
174 retval
= ZSendList(notice
, lyst
, num
*3, ZNOAUTH
);
176 if (retval
!= ZERR_NONE
)
178 if ((retval
= ZIfNotice(&retnotice
, (struct sockaddr_in
*)0,
179 ZCompareUIDPred
, (char *)¬ice
->z_uid
)) !=
182 if (retnotice
.z_kind
== SERVNAK
) {
183 ZFreeNotice(&retnotice
);
184 return (ZERR_SERVNAK
);
186 if (retnotice
.z_kind
!= SERVACK
) {
187 ZFreeNotice(&retnotice
);
188 return (ZERR_INTERNAL
);
190 ZFreeNotice(&retnotice
);