summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jeffrey Hutzelman <jhutz@cmu.edu>2013-02-23 15:00:54 -0500
committerGravatar Karl Ramm <kcr@1ts.org>2013-02-26 23:01:10 -0500
commita323589383be38de2f76b564c5edc493bf7f9ec2 (patch)
tree6547a2080c31a0fee4866f7d42196d52999fa58f
parent0fb2236580debdd37eeac27a5e0ae81d160400b4 (diff)
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
-rw-r--r--clients/zctl/zctl.1.in6
-rw-r--r--clients/zctl/zctl.c19
-rw-r--r--clients/zctl/zctl_cmds.ct3
-rw-r--r--h/zephyr/zephyr.h1
-rw-r--r--lib/ZSubs.c39
5 files changed, 68 insertions, 0 deletions
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[]);
@@ -232,6 +233,22 @@ flush_locations(int argc,
}
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 *)&notice, 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(&notice, ZAUTH)) != ZERR_NONE)
+ return (retval);
+
+ if ((retval = ZIfNotice(&retnotice, (struct sockaddr_in *)0,
+ ZCompareUIDPred, (char *)&notice.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);
+}