1 /* This file is part of the Project Athena Zephyr Notification System.
2 * It contains code for the "zctl" command.
4 * Created by: Robert French
6 * $Source: /afs/athena/astaff/project/zephyr/attic2/repository/zephyr/clients/zctl/zctl.c,v $
9 * Copyright (c) 1987,1988 by the Massachusetts Institute of Technology.
10 * For copying and distribution information, see the file
15 #include <zephyr/zephyr.h>
19 # ifdef HAVE_KRB5_SS_H
28 static const char *rcsid_zctl_c = "$Id: zctl.c,v 1.28.4.1 1997/01/06 01:40:24 marc Exp $";
33 #define USERS_SUBS "/.zephyr.subs"
34 #define OLD_SUBS "/.subscriptions"
40 void add_file(char *fn, char *galaxy, short wgport, ZSubscription_t *subs,
42 void del_file(char *fn, char *galaxy, short wgport, ZSubscription_t *subs,
47 char subsname[BUFSIZ];
49 extern ss_request_table zctl_cmds;
56 char ssline[BUFSIZ],oldsubsname[BUFSIZ],*envptr,*tty = NULL;
58 #ifdef HAVE_SYS_UTSNAME
62 if ((retval = ZInitialize()) != ZERR_NONE) {
63 com_err(argv[0],retval,"while initializing");
67 /* Set hostname and tty for locations. If we support X, use the
68 * DISPLAY environment variable for the tty name. */
69 #ifndef X_DISPLAY_MISSING
70 tty = getenv("DISPLAY");
72 if ((retval = ZInitLocationInfo(NULL, tty)) != ZERR_NONE)
73 com_err(argv[0], retval, "initializing location information");
75 envptr = getenv("ZEPHYR_SUBS");
77 strcpy(subsname,envptr);
79 envptr = getenv("HOME");
81 strcpy(subsname,envptr);
83 if (!(pwd = getpwuid((int) getuid()))) {
84 fprintf(stderr,"Who are you?\n");
88 strcpy(subsname,pwd->pw_dir);
90 strcpy(oldsubsname,subsname);
91 strcat(oldsubsname,OLD_SUBS);
92 strcat(subsname,USERS_SUBS);
93 if (!access(oldsubsname,F_OK) && access(subsname, F_OK)) {
94 /* only if old one exists and new one does not exist */
95 printf("The .subscriptions file in your home directory is now being used as\n.zephyr.subs . I will rename it to .zephyr.subs for you.\n");
96 if (rename(oldsubsname,subsname))
97 com_err(argv[0], errno, "renaming .subscriptions");
101 sci_idx = ss_create_invocation("zctl","",0,&zctl_cmds,&code);
103 ss_perror(sci_idx,code,"while creating invocation");
110 (void) sprintf(ssline+strlen(ssline),"%s ",argv[i]);
111 ssline[strlen(ssline)-1] = '\0';
112 code = ss_execute_line(sci_idx,ssline);
114 fprintf (stderr, "%s: %s: %s\n",
115 argv[0], error_message (code), ssline);
119 printf("ZCTL $Revision: 1.28.4.1 $ (Protocol %s%d.%d) - Type '?' for a list of commands.\n\n",
121 ZVERSIONMAJOR,ZVERSIONMINOR_GALAXY);
123 code = ss_listen(sci_idx);
133 fprintf(stderr,"Usage: %s filename\n",argv[0]);
138 printf("Current file: %s\n",subsname);
140 (void) strcpy(subsname,argv[1]);
144 flush_locations(argc,argv)
153 fprintf(stderr,"Usage: %s [galaxy]\n",argv[0]);
157 galaxy = (argc > 1)?argv[1]:NULL;
159 if (galaxy && strcmp(galaxy, "*") == 0) {
160 if (retval = ZGetGalaxyCount(&cnt)) {
161 ss_perror(sci_idx, retval, "while getting galaxy count");
165 for (i=0; i<cnt; i++) {
166 if (retval = ZGetGalaxyName(i, &galaxy)) {
167 ss_perror(sci_idx, retval, "while getting galaxy name");
171 if ((retval = ZFlushMyLocations(galaxy)) != ZERR_NONE) {
172 ss_perror(sci_idx, retval, "while flushing locations");
177 if ((retval = ZFlushMyLocations(galaxy)) != ZERR_NONE) {
178 ss_perror(sci_idx, retval, "while flushing locations");
185 wgc_control(argc,argv)
192 fprintf(stderr,"Usage: %s\n",argv[0]);
196 if (!strcmp(argv[0],"wg_read")) {
197 retval = send_wgc_control(USER_REREAD, NULL, 0);
198 } else if (!strcmp(argv[0],"wg_shutdown")) {
199 retval = send_wgc_control(USER_SHUTDOWN, NULL, 0);
200 } else if (!strcmp(argv[0],"wg_startup")) {
201 retval = send_wgc_control(USER_STARTUP, NULL, 0);
202 } else if (!strcmp(argv[0],"wg_exit")) {
203 retval = send_wgc_control(USER_EXIT, NULL, 0);
206 "unknown WindowGram client control command %s\n",
212 ss_perror(sci_idx, retval,
213 "while sending WindowGram control message");
217 hm_control(argc,argv)
227 fprintf(stderr,"Usage: %s [galaxy]\n",argv[0]);
231 galaxy = (argc > 1)?argv[1]:NULL;
233 (void) memset((char *)¬ice, 0, sizeof(notice));
234 notice.z_kind = HMCTL;
236 notice.z_class = HM_CTL_CLASS;
237 notice.z_class_inst = HM_CTL_CLIENT;
239 if (!strcmp(argv[0],"hm_flush"))
240 notice.z_opcode = CLIENT_FLUSH;
241 if (!strcmp(argv[0],"new_server"))
242 notice.z_opcode = CLIENT_NEW_SERVER;
243 if (!notice.z_opcode) {
244 fprintf(stderr, "unknown HostManager control command %s\n",
249 notice.z_recipient = "";
250 notice.z_default_format = "";
251 notice.z_message_len = 0;
253 if (galaxy && strcmp(galaxy, "*") == 0) {
254 if (retval = ZGetGalaxyCount(&cnt)) {
255 ss_perror(sci_idx, retval, "while getting galaxy count");
259 for (i=0; i<cnt; i++) {
260 if (retval = ZGetGalaxyName(i, &galaxy)) {
261 ss_perror(sci_idx, retval, "while getting galaxy name");
265 notice.z_dest_galaxy = galaxy;
267 if ((retval = ZSendNotice(¬ice,ZNOAUTH)) != ZERR_NONE) {
268 ss_perror(sci_idx,retval,"while sending notice");
273 if ((retval = ZSendNotice(¬ice,ZNOAUTH)) != ZERR_NONE) {
274 ss_perror(sci_idx,retval,"while sending notice");
289 fprintf(stderr,"Usage: %s <varname> <varname> ...\n",argv[0]);
293 for (i=1;i<argc;i++) {
294 value = ZGetVariable(argv[i]);
296 printf("%s: %s\n",argv[i],value);
298 printf("%s: not defined\n",argv[i]);
305 register char **argv;
307 int retval,setting_exp,i;
312 fprintf(stderr,"Usage: %s <varname> [value]\n",
319 if (strncasecmp(argv[1],"exposure",8) == 0) {
322 fprintf(stderr, "An exposure setting must be specified.\n");
325 if (strlen(argv[1]) == 8) {
326 galaxy = NULL; /* the default */
327 } else if ((strlen(argv[1]) == 9) ||
328 (ZGetRhs(argv[1]+9) == NULL)) {
329 fprintf(stderr, "The exposure variable's galaxy name was empty or invalid.\nUse a variable of the form exposure-GALAXYNAME.\n");
337 retval = ZSetVariable(argv[1],"");
339 (void) strcpy(varcat,argv[2]);
340 for (i=3;i<argc;i++) {
341 (void) strcat(varcat," ");
342 (void) strcat(varcat,argv[i]);
344 retval = ZSetVariable(argv[1],varcat);
347 if (retval != ZERR_NONE) {
348 ss_perror(sci_idx,retval,"while setting variable value");
352 /* Side-effects? Naw, us? */
355 set_exposure(galaxy?galaxy:"*", argv[2]);
369 fprintf(stderr, "Usage: %s [galaxy]\n",argv[0]);
373 if (strcmp(argv[0], "unhide") == 0) {
374 exp_level = ZGetVariable("exposure");
376 exp_level = ZParseExposureLevel(exp_level);
378 exp_level = EXPOSE_REALMVIS;
380 exp_level = EXPOSE_OPSTAFF;
383 galaxy = (argc > 1)?argv[1]:NULL;
385 if (code = set_exposure(galaxy, exp_level)) {
386 ss_perror(sci_idx, code, "while setting exposures");
399 fprintf(stderr,"Usage: %s <varname> [<varname> ... ]\n",
405 if ((retval = ZUnsetVariable(argv[i])) != ZERR_NONE)
406 ss_perror(sci_idx,retval,
407 "while unsetting variable value");
411 cancel_subs(argc,argv)
421 fprintf(stderr,"Usage: %s [galaxy]\n",argv[0]);
425 if ((wgport = ZGetWGPort()) == -1) {
426 ss_perror(sci_idx,errno,"while finding WindowGram port");
430 galaxy = (argc > 1)?argv[1]:NULL;
432 if (galaxy && strcmp(galaxy, "*") == 0) {
433 if (retval = ZGetGalaxyCount(&cnt)) {
434 ss_perror(sci_idx, retval, "while getting galaxy count");
438 for (i=0; i<cnt; i++) {
439 if (retval = ZGetGalaxyName(i, &galaxy)) {
440 ss_perror(sci_idx, retval, "while getting galaxy name");
444 if ((retval = ZCancelSubscriptions(galaxy, (u_short)wgport))
446 ss_perror(sci_idx,retval,"while cancelling subscriptions");
451 if ((retval = ZCancelSubscriptions(galaxy, (u_short)wgport))
453 ss_perror(sci_idx,retval,"while cancelling subscriptions");
466 ZSubscription_t sub,sub2;
470 if (argc > 5 || argc < 3) {
471 fprintf(stderr,"Usage: %s class instance [* [galaxy]]\n",
476 if (strncmp(argv[0], "sub", 3) == 0) {
478 } else if (strncmp(argv[0], "unsub", 5) == 0) {
480 } else if ((strncmp(argv[0], "punt", 4) == 0) ||
481 (strncmp(argv[0], "sup", 3) == 0)) {
483 } else if ((strncmp(argv[0], "unpunt", 6) == 0) ||
484 (strncmp(argv[0], "unsup", 5) == 0)) {
487 ss_perror(sci_idx, 0, "internal error in subscribe");
491 sub.zsub_class = argv[1];
492 sub.zsub_classinst = argv[2];
493 sub.zsub_recipient = (argc > 3)?argv[3]:
494 (((mode == PUNT) || (mode == UNPUNT))?"":ZGetSender());
495 galaxy = (argc > 4)?argv[4]:NULL;
497 fix_macros(&sub,&sub2,1);
499 if ((wgport = ZGetWGPort()) == -1) {
500 ss_perror(sci_idx,errno,"while finding WindowGram port");
506 if (retval = ZSubscribeTo(galaxy, &sub2, 1, (u_short) wgport))
507 ss_perror(sci_idx, retval, "while subscribing");
510 if (retval = ZUnsubscribeTo(galaxy, &sub2, 1, (u_short) wgport))
511 ss_perror(sci_idx, retval, "while subscribing");
514 if (retval = xpunt(sub2.zsub_class, sub2.zsub_classinst,
515 sub2.zsub_recipient, PUNT))
516 ss_perror(sci_idx, retval, "while suppressing");
519 if (retval = xpunt(sub2.zsub_class, sub2.zsub_classinst,
520 sub2.zsub_recipient, UNPUNT))
521 ss_perror(sci_idx, retval, "while unsuppressing");
534 char *arggalaxy, *galaxy;
539 if (argc > 5 || argc < 3) {
540 fprintf(stderr,"Usage: %s class instance [* [galaxy]]\n",
545 if (!strcmp(argv[0],"add")) {
548 } else if (!strcmp(argv[0],"add_unsubscription") ||
549 !strcmp(argv[0],"add_un")) {
552 } else if (!strcmp(argv[0],"add_suppression") ||
553 !strcmp(argv[0],"add_punt")) {
556 } else if (!strcmp(argv[0],"delete") ||
557 !strcmp(argv[0],"del") ||
558 !strcmp(argv[0],"dl")) {
561 } else if (!strcmp(argv[0],"delete_unsubscription") ||
562 !strcmp(argv[0],"del_un")) {
565 } else if (!strcmp(argv[0],"delete_suppression") ||
566 !strcmp(argv[0],"del_punt")) {
570 ss_perror(sci_idx,0,"unknown command name");
573 if (argv[1][0] == '!') {
574 ss_perror(sci_idx,0, (mode == UNSUB)?
575 "Do not use `!' as the first character of a class.\n\tIt is automatically added before modifying the subscription file." :
576 "Do not use `!' as the first character of a class.\n\tIt is reserved for internal use with un-subscriptions.");
578 } else if (argv[1][0] == '-') {
579 ss_perror(sci_idx,0, (mode == PUNT)?
580 "Do not use `-' as the first character of a class.\n\tIt is automatically added before modifying the subscription file." :
581 "Do not use `-' as the first character of a class.\n\tIt is reserved for internal use with suppressions.");
585 sub.zsub_class = argv[1];
586 sub.zsub_classinst = argv[2];
587 sub.zsub_recipient = (argc > 3)?argv[3]:
588 (((mode == PUNT) || (mode == UNPUNT))?"":TOKEN_ME);
589 arggalaxy = (argc > 4)?argv[4]:NULL;
592 if (retval = ZGetGalaxyCount(&cnt)) {
593 ss_perror(sci_idx, retval, "while getting galaxy count");
597 for (i=0; i<cnt; i++) {
598 if (retval = ZGetGalaxyName(i, &galaxy)) {
599 ss_perror(sci_idx, retval, "while getting galaxy name");
603 if (strcasecmp(galaxy, arggalaxy) == 0)
608 ss_perror(sci_idx, 0,
609 "unknown galaxy specified while modifying subscripion file");
613 galaxy = ZGetDefaultGalaxy();
616 if ((wgport = ZGetWGPort()) == -1) {
617 ss_perror(sci_idx,errno,"while finding WindowGram port");
621 strcpy(fn, subsname);
625 if (!strcmp(argv[0],"add")) {
626 add_file(fn, galaxy, wgport, &sub, SUB);
627 } else if (!strcmp(argv[0],"add_unsubscription") ||
628 !strcmp(argv[0],"add_un")) {
629 add_file(fn, galaxy, wgport, &sub, UNSUB);
630 } else if (!strcmp(argv[0],"add_suppression") ||
631 !strcmp(argv[0],"add_punt")) {
632 add_file(fn, galaxy, wgport, &sub, PUNT);
633 } else if (!strcmp(argv[0],"delete") ||
634 !strcmp(argv[0],"del") ||
635 !strcmp(argv[0],"dl")) {
636 del_file(fn, galaxy, wgport, &sub, SUB);
637 } else if (!strcmp(argv[0],"delete_unsubscription") ||
638 !strcmp(argv[0],"del_un")) {
639 del_file(fn, galaxy, wgport, &sub, UNSUB);
640 } else if (!strcmp(argv[0],"delete_suppression") ||
641 !strcmp(argv[0],"del_punt")) {
642 del_file(fn, galaxy, wgport, &sub, PUNT);
644 ss_perror(sci_idx,0,"unknown command name");
650 add_file(fn,galaxy,wgport,subs,mode)
654 ZSubscription_t *subs;
659 ZSubscription_t sub2;
662 (void) purge_subs(fn,subs,ALL); /* remove copies in the subs file */
663 if (!(fp = fopen(fn,"a"))) {
664 (void) sprintf(errbuf,"while opening %s for append", fn);
665 ss_perror(sci_idx,errno,errbuf);
668 fprintf(fp,"%s%s,%s,%s\n",
669 ((mode == UNSUB) ? "!" :
670 ((mode == PUNT) ? "*" :
672 subs->zsub_class, subs->zsub_classinst, subs->zsub_recipient);
673 if (fclose(fp) == EOF) {
674 (void) sprintf(errbuf, "while closing %s", subsname);
675 ss_perror(sci_idx, errno, errbuf);
678 fix_macros(subs,&sub2,1);
680 if (retval = ZUnsubscribeTo(galaxy, &sub2,1,(u_short)wgport))
681 ss_perror(sci_idx, retval, "while subscribing");
682 } else if (mode == PUNT) {
683 if (retval = xpunt(sub2.zsub_class, sub2.zsub_classinst,
684 sub2.zsub_recipient, PUNT))
685 ss_perror(sci_idx, retval, "while unsubscribing");
687 if (retval = ZSubscribeTo(galaxy, &sub2,1,(u_short)wgport))
688 ss_perror(sci_idx, retval, "while suppressing");
695 del_file(fn,galaxy,wgport,subs,mode)
699 ZSubscription_t *subs;
702 ZSubscription_t sub2;
705 retval = purge_subs(fn, subs, mode);
708 if (retval == NOT_REMOVED)
710 "Couldn't find %sclass %s instance %s recipient %s in\n\tfile %s\n",
711 ((mode == UNSUB) ? "un-subscription " :
712 ((mode == PUNT) ? "suppression " :
714 subs->zsub_class, subs->zsub_classinst,
715 subs->zsub_recipient, subsname);
716 fix_macros(subs,&sub2,1);
718 if (retval = xpunt(sub2.zsub_class, sub2.zsub_classinst,
719 sub2.zsub_recipient, UNPUNT))
720 ss_perror(sci_idx,retval,"while unsuppressing");
721 } else if ((retval = ZUnsubscribeTo(galaxy, &sub2,1,(u_short)wgport)) !=
723 ss_perror(sci_idx,retval,"while unsubscribing");
728 purge_subs(fn, subs, mode)
730 register ZSubscription_t *subs;
734 char errbuf[BUFSIZ],subline[BUFSIZ];
735 char backup[BUFSIZ],ourline[BUFSIZ];
736 int delflag = NOT_REMOVED;
746 ss_perror(sci_idx,0,"internal error in purge_subs");
750 (void) sprintf(ourline,"%s,%s,%s",
752 subs->zsub_classinst,
753 subs->zsub_recipient);
755 if (!(fp = fopen(fn,"r"))) {
757 /* if the filw doesn't exist, then the sub
760 (void) sprintf(errbuf,"while opening %s for read", fn);
761 ss_perror(sci_idx,errno,errbuf);
764 (void) strcpy(backup, fn);
765 (void) strcat(backup, ".temp");
766 (void) unlink(backup);
767 if (!(fpout = fopen(backup,"w"))) {
768 (void) sprintf(errbuf,"while opening %s for writing",backup);
769 ss_perror(sci_idx,errno,errbuf);
774 if (!fgets(subline,sizeof subline,fp))
777 subline[strlen(subline)-1] = '\0'; /* nuke newline */
780 purge = (strcmp(subline,ourline) == 0);
783 purge = (*subline == '!' &&
784 (strcmp(subline+1,ourline) == 0));
787 purge = (*subline == '-' &&
788 (strcmp(subline+1,ourline) == 0));
791 purge = ((strcmp(subline,ourline) == 0) ||
792 (((*subline == '!') || (*subline == '-')) &&
793 (strcmp(subline+1, ourline) == 0)));
799 fputs(subline, fpout);
800 if (ferror(fpout) || (fputc('\n', fpout) == EOF)) {
801 (void) sprintf(errbuf, "while writing to %s",
803 ss_perror(sci_idx, errno, errbuf);
807 (void) fclose(fp); /* open read-only, ignore errs */
808 if (fclose(fpout) == EOF) {
809 (void) sprintf(errbuf, "while closing %s",backup);
810 ss_perror(sci_idx, errno, errbuf);
813 if (rename(backup, fn) == -1) {
814 (void) sprintf(errbuf,"while renaming %s to %s\n",
816 ss_perror(sci_idx,errno,errbuf);
829 char *arggalaxy, *galaxy;
833 fprintf(stderr,"Usage: %s [file [galaxy]]\n",argv[0]);
839 else if (!strcmp(argv[0],"list") || !strcmp(argv[0],"ls"))
844 file = (argc > 1)?argv[1]:subsname;
845 arggalaxy = (argc > 2)?argv[2]:NULL;
848 if (code = ZGetGalaxyCount(&cnt)) {
849 ss_perror(sci_idx, code, "while getting galaxy count");
853 for (i=0; i<cnt; i++) {
854 if (code = ZGetGalaxyName(i, &galaxy)) {
855 ss_perror(sci_idx, code, "while getting galaxy name");
859 if (strcasecmp(galaxy, arggalaxy) == 0)
864 ss_perror(sci_idx, 0,
865 "unknown galaxy specified while loading subscription file");
872 if (code = load_sub_file(type, file, galaxy))
873 ss_perror(sci_idx, code,
874 "while loading subscription file");
889 fprintf(stderr,"Usage: %s\n",argv[0]);
893 if (!strcmp(argv[0],"list") || !strcmp(argv[0],"ls"))
898 load_all_sub_files(type, subsname);
908 ZSubscription_t subs;
909 int i,nsubs,retval,save,one,defs;
911 char *galaxy, *file, backup[BUFSIZ];
916 if (!strcmp(argv[0],"save"))
918 else if (!strcmp(argv[0], "defaults") || !strcmp(argv[0], "defs"))
923 fprintf(stderr,"Usage: %s [filename [galaxy]]\n",
927 file = (argc > 1)?argv[1]:subsname;
928 galaxy = (argc > 2)?argv[2]:NULL;
932 fprintf(stderr,"Usage: %s [galaxy]\n",argv[0]);
935 galaxy = (argc > 1)?argv[1]:NULL;
940 if ((wgport = ZGetWGPort()) == -1) {
941 ss_perror(sci_idx,errno,
942 "while finding WindowGram port");
947 retval = ZRetrieveDefaultSubscriptions(galaxy, &nsubs);
949 retval = ZRetrieveSubscriptions(galaxy,(u_short)wgport,&nsubs);
951 if (retval == ZERR_TOOMANYSUBS) {
952 fprintf(stderr,"Too many subscriptions -- some have not been returned.\n");
954 fprintf(stderr,"Save aborted.\n");
959 if (retval != ZERR_NONE) {
960 ss_perror(sci_idx,retval,"retrieving subscriptions");
965 (void) strcpy(backup,file);
966 (void) strcat(backup,".temp");
967 if (!(fp = fopen(backup,"w"))) {
968 (void) sprintf(errbuf,"while opening %s for write",
970 ss_perror(sci_idx,errno,errbuf);
975 for (i=0;i<nsubs;i++) {
977 if ((retval = ZGetSubscriptions(&subs,&one)) != ZERR_NONE) {
978 ss_perror(sci_idx,retval,"while getting subscription");
980 fprintf(stderr,"Subscriptions file not modified\n");
982 (void) unlink(backup);
987 fprintf(fp,"%s,%s,%s\n",subs.zsub_class,
988 subs.zsub_classinst, subs.zsub_recipient);
990 printf("Class %s Instance %s Recipient %s\n",
991 subs.zsub_class, subs.zsub_classinst,
992 subs.zsub_recipient);
996 if (fclose(fp) == EOF) {
997 (void) sprintf(errbuf, "while closing %s", backup);
998 ss_perror(sci_idx, errno, errbuf);
1001 if (rename(backup,file) == -1) {
1002 (void) sprintf(errbuf,"while renaming %s to %s",
1004 ss_perror(sci_idx,retval,errbuf);
1005 (void) unlink(backup);