From a323589383be38de2f76b564c5edc493bf7f9ec2 Mon Sep 17 00:00:00 2001 From: Jeffrey Hutzelman Date: Sat, 23 Feb 2013 15:00:54 -0500 Subject: zctl flush_subs Provide a new zctl subcommand, flush_subs, to flush all subscriptions for a specified recipient. This is implemented using a new library function, ZFlushUserSubscriptions(). This is the client side of #103 --- clients/zctl/zctl.1.in | 6 ++++++ clients/zctl/zctl.c | 19 +++++++++++++++++++ clients/zctl/zctl_cmds.ct | 3 +++ h/zephyr/zephyr.h | 1 + lib/ZSubs.c | 39 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 68 insertions(+) diff --git a/clients/zctl/zctl.1.in b/clients/zctl/zctl.1.in index ec9dbf0..5b73b6e 100644 --- a/clients/zctl/zctl.1.in +++ b/clients/zctl/zctl.1.in @@ -73,6 +73,12 @@ should only be used to remove any incorrect data that may have been left after a system crash. Note that only Operations staff may flush location information associated with another user. .TP +.B flush_subs \fR[ \fIrecipient\fR ] +Tell the Zephyr servers to flush all of \fIrecipient\fR's subscriptions, +This differs from the cancel command in that it affects subscriptions for +all of \fIrecipient\fR's clients. Note that only Operations staff may flush +the subscriptions of another user. +.TP .B hide Hide your location as maintained by the Zephyr server. This does not affect the value of the exposure variable (see below, under diff --git a/clients/zctl/zctl.c b/clients/zctl/zctl.c index 1dfa792..f18df10 100644 --- a/clients/zctl/zctl.c +++ b/clients/zctl/zctl.c @@ -75,6 +75,7 @@ void current(int argc, char *argv[]); void do_hide(int argc, char *argv[]); void do_punt(int argc, char *argv[]); void flush_locations(int argc, char *argv[]); +void flush_subscr(int argc, char *argv[]); void hm_control(int argc, char *argv[]); void list_punts(int argc, char *argv[]); void load_subs(int argc, char *argv[]); @@ -231,6 +232,22 @@ flush_locations(int argc, com_err(whoami, retval, "while flushing locations"); } +void +flush_subscr(int argc, + char *argv[]) +{ + int retval; + + if (argc > 2) { + fprintf(stderr,"Usage: %s [recipient]\n",argv[0]); + return; + } + + retval = ZFlushUserSubscriptions((argc > 1) ? argv[1] : NULL); + if (retval != ZERR_NONE) + com_err(whoami, retval, "while flushing subscriptions"); +} + void wgc_control(int argc, char *argv[]) @@ -1306,6 +1323,8 @@ static const struct { { "new_server" } }, { flush_locations, "Flush all location information.", { "flush_locs" } }, + { flush_subscr, "Flush all subscription information.", + { "flush_subs" } }, { do_hide, "Hide your location.", { "hide" } }, { do_hide, "Show (un-hide) your location.", diff --git a/clients/zctl/zctl_cmds.ct b/clients/zctl/zctl_cmds.ct index 761572c..00b799c 100644 --- a/clients/zctl/zctl_cmds.ct +++ b/clients/zctl/zctl_cmds.ct @@ -73,6 +73,9 @@ request flush_locations, "Flush all location information.", flush_locs; + request flush_subscr, "Flush all subscription information.", + flush_subs; + request do_hide, "Hide your location.", hide; diff --git a/h/zephyr/zephyr.h b/h/zephyr/zephyr.h index 78b4139..207624b 100644 --- a/h/zephyr/zephyr.h +++ b/h/zephyr/zephyr.h @@ -244,6 +244,7 @@ Code_t ZSubscribeToSansDefaults(ZSubscription_t *sublist, int nitems, Code_t ZUnsubscribeTo(ZSubscription_t *sublist, int nitems, unsigned int port); Code_t ZCancelSubscriptions(unsigned int port); +Code_t ZFlushUserSubscriptions(char *recip); int ZPending(void); Code_t ZReceiveNotice(ZNotice_t *notice, struct sockaddr_in *from); const char *ZGetCharsetString(char *charset); diff --git a/lib/ZSubs.c b/lib/ZSubs.c index 3a241db..5e05f20 100644 --- a/lib/ZSubs.c +++ b/lib/ZSubs.c @@ -205,3 +205,42 @@ subscr_sendoff(ZNotice_t *notice, 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); +} -- cgit v1.2.3