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>
22 static const char *rcsid_zctl_c = "$Id: zctl.c,v 1.28.4.1 1997/01/06 01:40:24 marc Exp $";
27 #define USERS_SUBS "/.zephyr.subs"
28 #define OLD_SUBS "/.subscriptions"
34 void add_file(char *fn, char *galaxy, short wgport, ZSubscription_t *subs,
36 void del_file(char *fn, char *galaxy, short wgport, ZSubscription_t *subs,
41 char subsname[BUFSIZ];
43 extern ss_request_table zctl_cmds;
50 char ssline[BUFSIZ],oldsubsname[BUFSIZ],*envptr,*tty = NULL;
52 #ifdef HAVE_SYS_UTSNAME
56 if ((retval = ZInitialize()) != ZERR_NONE) {
57 com_err(argv[0],retval,"while initializing");
61 /* Set hostname and tty for locations. If we support X, use the
62 * DISPLAY environment variable for the tty name. */
63 #ifndef X_DISPLAY_MISSING
64 tty = getenv("DISPLAY");
66 if ((retval = ZInitLocationInfo(NULL, tty)) != ZERR_NONE)
67 com_err(argv[0], retval, "initializing location information");
69 envptr = getenv("ZEPHYR_SUBS");
71 strcpy(subsname,envptr);
73 envptr = getenv("HOME");
75 strcpy(subsname,envptr);
77 if (!(pwd = getpwuid((int) getuid()))) {
78 fprintf(stderr,"Who are you?\n");
82 strcpy(subsname,pwd->pw_dir);
84 strcpy(oldsubsname,subsname);
85 strcat(oldsubsname,OLD_SUBS);
86 strcat(subsname,USERS_SUBS);
87 if (!access(oldsubsname,F_OK) && access(subsname, F_OK)) {
88 /* only if old one exists and new one does not exist */
89 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");
90 if (rename(oldsubsname,subsname))
91 com_err(argv[0], errno, "renaming .subscriptions");
95 sci_idx = ss_create_invocation("zctl","",0,&zctl_cmds,&code);
97 ss_perror(sci_idx,code,"while creating invocation");
104 (void) sprintf(ssline+strlen(ssline),"%s ",argv[i]);
105 ssline[strlen(ssline)-1] = '\0';
106 code = ss_execute_line(sci_idx,ssline);
108 fprintf (stderr, "%s: %s: %s\n",
109 argv[0], error_message (code), ssline);
113 printf("ZCTL $Revision: 1.28.4.1 $ (Protocol %s%d.%d) - Type '?' for a list of commands.\n\n",
115 ZVERSIONMAJOR,ZVERSIONMINOR_GALAXY);
117 code = ss_listen(sci_idx);
127 fprintf(stderr,"Usage: %s filename\n",argv[0]);
132 printf("Current file: %s\n",subsname);
134 (void) strcpy(subsname,argv[1]);
138 flush_locations(argc,argv)
147 fprintf(stderr,"Usage: %s [galaxy]\n",argv[0]);
151 galaxy = (argc > 1)?argv[1]:NULL;
153 if (galaxy && strcmp(galaxy, "*") == 0) {
154 if (retval = ZGetGalaxyCount(&cnt)) {
155 ss_perror(sci_idx, retval, "while getting galaxy count");
159 for (i=0; i<cnt; i++) {
160 if (retval = ZGetGalaxyName(i, &galaxy)) {
161 ss_perror(sci_idx, retval, "while getting galaxy name");
165 if ((retval = ZFlushMyLocations(galaxy)) != ZERR_NONE) {
166 ss_perror(sci_idx, retval, "while flushing locations");
171 if ((retval = ZFlushMyLocations(galaxy)) != ZERR_NONE) {
172 ss_perror(sci_idx, retval, "while flushing locations");
179 wgc_control(argc,argv)
186 fprintf(stderr,"Usage: %s\n",argv[0]);
190 if (!strcmp(argv[0],"wg_read")) {
191 retval = send_wgc_control(USER_REREAD, NULL, 0);
192 } else if (!strcmp(argv[0],"wg_shutdown")) {
193 retval = send_wgc_control(USER_SHUTDOWN, NULL, 0);
194 } else if (!strcmp(argv[0],"wg_startup")) {
195 retval = send_wgc_control(USER_STARTUP, NULL, 0);
196 } else if (!strcmp(argv[0],"wg_exit")) {
197 retval = send_wgc_control(USER_EXIT, NULL, 0);
200 "unknown WindowGram client control command %s\n",
206 ss_perror(sci_idx, retval,
207 "while sending WindowGram control message");
211 hm_control(argc,argv)
221 fprintf(stderr,"Usage: %s [galaxy]\n",argv[0]);
225 galaxy = (argc > 1)?argv[1]:NULL;
227 (void) memset((char *)¬ice, 0, sizeof(notice));
228 notice.z_kind = HMCTL;
230 notice.z_class = HM_CTL_CLASS;
231 notice.z_class_inst = HM_CTL_CLIENT;
233 if (!strcmp(argv[0],"hm_flush"))
234 notice.z_opcode = CLIENT_FLUSH;
235 if (!strcmp(argv[0],"new_server"))
236 notice.z_opcode = CLIENT_NEW_SERVER;
237 if (!notice.z_opcode) {
238 fprintf(stderr, "unknown HostManager control command %s\n",
243 notice.z_recipient = "";
244 notice.z_default_format = "";
245 notice.z_message_len = 0;
247 if (galaxy && strcmp(galaxy, "*") == 0) {
248 if (retval = ZGetGalaxyCount(&cnt)) {
249 ss_perror(sci_idx, retval, "while getting galaxy count");
253 for (i=0; i<cnt; i++) {
254 if (retval = ZGetGalaxyName(i, &galaxy)) {
255 ss_perror(sci_idx, retval, "while getting galaxy name");
259 notice.z_dest_galaxy = galaxy;
261 if ((retval = ZSendNotice(¬ice,ZNOAUTH)) != ZERR_NONE) {
262 ss_perror(sci_idx,retval,"while sending notice");
267 if ((retval = ZSendNotice(¬ice,ZNOAUTH)) != ZERR_NONE) {
268 ss_perror(sci_idx,retval,"while sending notice");
283 fprintf(stderr,"Usage: %s <varname> <varname> ...\n",argv[0]);
287 for (i=1;i<argc;i++) {
288 value = ZGetVariable(argv[i]);
290 printf("%s: %s\n",argv[i],value);
292 printf("%s: not defined\n",argv[i]);
299 register char **argv;
301 int retval,setting_exp,i;
306 fprintf(stderr,"Usage: %s <varname> [value]\n",
313 if (strncasecmp(argv[1],"exposure",8) == 0) {
316 fprintf(stderr, "An exposure setting must be specified.\n");
319 if (strlen(argv[1]) == 8) {
320 galaxy = NULL; /* the default */
321 } else if ((strlen(argv[1]) == 9) ||
322 (ZGetRhs(argv[1]+9) == NULL)) {
323 fprintf(stderr, "The exposure variable's galaxy name was empty or invalid.\nUse a variable of the form exposure-GALAXYNAME.\n");
331 retval = ZSetVariable(argv[1],"");
333 (void) strcpy(varcat,argv[2]);
334 for (i=3;i<argc;i++) {
335 (void) strcat(varcat," ");
336 (void) strcat(varcat,argv[i]);
338 retval = ZSetVariable(argv[1],varcat);
341 if (retval != ZERR_NONE) {
342 ss_perror(sci_idx,retval,"while setting variable value");
346 /* Side-effects? Naw, us? */
349 set_exposure(galaxy?galaxy:"*", argv[2]);
363 fprintf(stderr, "Usage: %s [galaxy]\n",argv[0]);
367 if (strcmp(argv[0], "unhide") == 0) {
368 exp_level = ZGetVariable("exposure");
370 exp_level = ZParseExposureLevel(exp_level);
372 exp_level = EXPOSE_REALMVIS;
374 exp_level = EXPOSE_OPSTAFF;
377 galaxy = (argc > 1)?argv[1]:NULL;
379 if (code = set_exposure(galaxy, exp_level)) {
380 ss_perror(sci_idx, code, "while setting exposures");
393 fprintf(stderr,"Usage: %s <varname> [<varname> ... ]\n",
399 if ((retval = ZUnsetVariable(argv[i])) != ZERR_NONE)
400 ss_perror(sci_idx,retval,
401 "while unsetting variable value");
405 cancel_subs(argc,argv)
415 fprintf(stderr,"Usage: %s [galaxy]\n",argv[0]);
419 if ((wgport = ZGetWGPort()) == -1) {
420 ss_perror(sci_idx,errno,"while finding WindowGram port");
424 galaxy = (argc > 1)?argv[1]:NULL;
426 if (galaxy && strcmp(galaxy, "*") == 0) {
427 if (retval = ZGetGalaxyCount(&cnt)) {
428 ss_perror(sci_idx, retval, "while getting galaxy count");
432 for (i=0; i<cnt; i++) {
433 if (retval = ZGetGalaxyName(i, &galaxy)) {
434 ss_perror(sci_idx, retval, "while getting galaxy name");
438 if ((retval = ZCancelSubscriptions(galaxy, (u_short)wgport))
440 ss_perror(sci_idx,retval,"while cancelling subscriptions");
445 if ((retval = ZCancelSubscriptions(galaxy, (u_short)wgport))
447 ss_perror(sci_idx,retval,"while cancelling subscriptions");
460 ZSubscription_t sub,sub2;
464 if (argc > 5 || argc < 3) {
465 fprintf(stderr,"Usage: %s class instance [* [galaxy]]\n",
470 if (strncmp(argv[0], "sub", 3) == 0) {
472 } else if (strncmp(argv[0], "unsub", 5) == 0) {
474 } else if ((strncmp(argv[0], "punt", 4) == 0) ||
475 (strncmp(argv[0], "sup", 3) == 0)) {
477 } else if ((strncmp(argv[0], "unpunt", 6) == 0) ||
478 (strncmp(argv[0], "unsup", 5) == 0)) {
481 ss_perror(sci_idx, 0, "internal error in subscribe");
485 sub.zsub_class = argv[1];
486 sub.zsub_classinst = argv[2];
487 sub.zsub_recipient = (argc > 3)?argv[3]:
488 (((mode == PUNT) || (mode == UNPUNT))?"":ZGetSender());
489 galaxy = (argc > 4)?argv[4]:NULL;
491 fix_macros(&sub,&sub2,1);
493 if ((wgport = ZGetWGPort()) == -1) {
494 ss_perror(sci_idx,errno,"while finding WindowGram port");
500 if (retval = ZSubscribeTo(galaxy, &sub2, 1, (u_short) wgport))
501 ss_perror(sci_idx, retval, "while subscribing");
504 if (retval = ZUnsubscribeTo(galaxy, &sub2, 1, (u_short) wgport))
505 ss_perror(sci_idx, retval, "while subscribing");
508 if (retval = xpunt(sub2.zsub_class, sub2.zsub_classinst,
509 sub2.zsub_recipient, PUNT))
510 ss_perror(sci_idx, retval, "while suppressing");
513 if (retval = xpunt(sub2.zsub_class, sub2.zsub_classinst,
514 sub2.zsub_recipient, UNPUNT))
515 ss_perror(sci_idx, retval, "while unsuppressing");
528 char *arggalaxy, *galaxy;
533 if (argc > 5 || argc < 3) {
534 fprintf(stderr,"Usage: %s class instance [* [galaxy]]\n",
539 if (!strcmp(argv[0],"add")) {
542 } else if (!strcmp(argv[0],"add_unsubscription") ||
543 !strcmp(argv[0],"add_un")) {
546 } else if (!strcmp(argv[0],"add_suppression") ||
547 !strcmp(argv[0],"add_punt")) {
550 } else if (!strcmp(argv[0],"delete") ||
551 !strcmp(argv[0],"del") ||
552 !strcmp(argv[0],"dl")) {
555 } else if (!strcmp(argv[0],"delete_unsubscription") ||
556 !strcmp(argv[0],"del_un")) {
559 } else if (!strcmp(argv[0],"delete_suppression") ||
560 !strcmp(argv[0],"del_punt")) {
564 ss_perror(sci_idx,0,"unknown command name");
567 if (argv[1][0] == '!') {
568 ss_perror(sci_idx,0, (mode == UNSUB)?
569 "Do not use `!' as the first character of a class.\n\tIt is automatically added before modifying the subscription file." :
570 "Do not use `!' as the first character of a class.\n\tIt is reserved for internal use with un-subscriptions.");
572 } else if (argv[1][0] == '-') {
573 ss_perror(sci_idx,0, (mode == PUNT)?
574 "Do not use `-' as the first character of a class.\n\tIt is automatically added before modifying the subscription file." :
575 "Do not use `-' as the first character of a class.\n\tIt is reserved for internal use with suppressions.");
579 sub.zsub_class = argv[1];
580 sub.zsub_classinst = argv[2];
581 sub.zsub_recipient = (argc > 3)?argv[3]:
582 (((mode == PUNT) || (mode == UNPUNT))?"":TOKEN_ME);
583 arggalaxy = (argc > 4)?argv[4]:NULL;
586 if (retval = ZGetGalaxyCount(&cnt)) {
587 ss_perror(sci_idx, retval, "while getting galaxy count");
591 for (i=0; i<cnt; i++) {
592 if (retval = ZGetGalaxyName(i, &galaxy)) {
593 ss_perror(sci_idx, retval, "while getting galaxy name");
597 if (strcasecmp(galaxy, arggalaxy) == 0)
602 ss_perror(sci_idx, 0,
603 "unknown galaxy specified while modifying subscripion file");
607 galaxy = ZGetDefaultGalaxy();
610 if ((wgport = ZGetWGPort()) == -1) {
611 ss_perror(sci_idx,errno,"while finding WindowGram port");
615 strcpy(fn, subsname);
619 if (!strcmp(argv[0],"add")) {
620 add_file(fn, galaxy, wgport, &sub, SUB);
621 } else if (!strcmp(argv[0],"add_unsubscription") ||
622 !strcmp(argv[0],"add_un")) {
623 add_file(fn, galaxy, wgport, &sub, UNSUB);
624 } else if (!strcmp(argv[0],"add_suppression") ||
625 !strcmp(argv[0],"add_punt")) {
626 add_file(fn, galaxy, wgport, &sub, PUNT);
627 } else if (!strcmp(argv[0],"delete") ||
628 !strcmp(argv[0],"del") ||
629 !strcmp(argv[0],"dl")) {
630 del_file(fn, galaxy, wgport, &sub, SUB);
631 } else if (!strcmp(argv[0],"delete_unsubscription") ||
632 !strcmp(argv[0],"del_un")) {
633 del_file(fn, galaxy, wgport, &sub, UNSUB);
634 } else if (!strcmp(argv[0],"delete_suppression") ||
635 !strcmp(argv[0],"del_punt")) {
636 del_file(fn, galaxy, wgport, &sub, PUNT);
638 ss_perror(sci_idx,0,"unknown command name");
644 add_file(fn,galaxy,wgport,subs,mode)
648 ZSubscription_t *subs;
653 ZSubscription_t sub2;
656 (void) purge_subs(fn,subs,ALL); /* remove copies in the subs file */
657 if (!(fp = fopen(fn,"a"))) {
658 (void) sprintf(errbuf,"while opening %s for append", fn);
659 ss_perror(sci_idx,errno,errbuf);
662 fprintf(fp,"%s%s,%s,%s\n",
663 ((mode == UNSUB) ? "!" :
664 ((mode == PUNT) ? "*" :
666 subs->zsub_class, subs->zsub_classinst, subs->zsub_recipient);
667 if (fclose(fp) == EOF) {
668 (void) sprintf(errbuf, "while closing %s", subsname);
669 ss_perror(sci_idx, errno, errbuf);
672 fix_macros(subs,&sub2,1);
674 if (retval = ZUnsubscribeTo(galaxy, &sub2,1,(u_short)wgport))
675 ss_perror(sci_idx, retval, "while subscribing");
676 } else if (mode == PUNT) {
677 if (retval = xpunt(sub2.zsub_class, sub2.zsub_classinst,
678 sub2.zsub_recipient, PUNT))
679 ss_perror(sci_idx, retval, "while unsubscribing");
681 if (retval = ZSubscribeTo(galaxy, &sub2,1,(u_short)wgport))
682 ss_perror(sci_idx, retval, "while suppressing");
689 del_file(fn,galaxy,wgport,subs,mode)
693 ZSubscription_t *subs;
696 ZSubscription_t sub2;
699 retval = purge_subs(fn, subs, mode);
702 if (retval == NOT_REMOVED)
704 "Couldn't find %sclass %s instance %s recipient %s in\n\tfile %s\n",
705 ((mode == UNSUB) ? "un-subscription " :
706 ((mode == PUNT) ? "suppression " :
708 subs->zsub_class, subs->zsub_classinst,
709 subs->zsub_recipient, subsname);
710 fix_macros(subs,&sub2,1);
712 if (retval = xpunt(sub2.zsub_class, sub2.zsub_classinst,
713 sub2.zsub_recipient, UNPUNT))
714 ss_perror(sci_idx,retval,"while unsuppressing");
715 } else if ((retval = ZUnsubscribeTo(galaxy, &sub2,1,(u_short)wgport)) !=
717 ss_perror(sci_idx,retval,"while unsubscribing");
722 purge_subs(fn, subs, mode)
724 register ZSubscription_t *subs;
728 char errbuf[BUFSIZ],subline[BUFSIZ];
729 char backup[BUFSIZ],ourline[BUFSIZ];
730 int delflag = NOT_REMOVED;
740 ss_perror(sci_idx,0,"internal error in purge_subs");
744 (void) sprintf(ourline,"%s,%s,%s",
746 subs->zsub_classinst,
747 subs->zsub_recipient);
749 if (!(fp = fopen(fn,"r"))) {
751 /* if the filw doesn't exist, then the sub
754 (void) sprintf(errbuf,"while opening %s for read", fn);
755 ss_perror(sci_idx,errno,errbuf);
758 (void) strcpy(backup, fn);
759 (void) strcat(backup, ".temp");
760 (void) unlink(backup);
761 if (!(fpout = fopen(backup,"w"))) {
762 (void) sprintf(errbuf,"while opening %s for writing",backup);
763 ss_perror(sci_idx,errno,errbuf);
768 if (!fgets(subline,sizeof subline,fp))
771 subline[strlen(subline)-1] = '\0'; /* nuke newline */
774 purge = (strcmp(subline,ourline) == 0);
777 purge = (*subline == '!' &&
778 (strcmp(subline+1,ourline) == 0));
781 purge = (*subline == '-' &&
782 (strcmp(subline+1,ourline) == 0));
785 purge = ((strcmp(subline,ourline) == 0) ||
786 (((*subline == '!') || (*subline == '-')) &&
787 (strcmp(subline+1, ourline) == 0)));
793 fputs(subline, fpout);
794 if (ferror(fpout) || (fputc('\n', fpout) == EOF)) {
795 (void) sprintf(errbuf, "while writing to %s",
797 ss_perror(sci_idx, errno, errbuf);
801 (void) fclose(fp); /* open read-only, ignore errs */
802 if (fclose(fpout) == EOF) {
803 (void) sprintf(errbuf, "while closing %s",backup);
804 ss_perror(sci_idx, errno, errbuf);
807 if (rename(backup, fn) == -1) {
808 (void) sprintf(errbuf,"while renaming %s to %s\n",
810 ss_perror(sci_idx,errno,errbuf);
823 char *arggalaxy, *galaxy;
827 fprintf(stderr,"Usage: %s [file [galaxy]]\n",argv[0]);
833 else if (!strcmp(argv[0],"list") || !strcmp(argv[0],"ls"))
838 file = (argc > 1)?argv[1]:subsname;
839 arggalaxy = (argc > 2)?argv[2]:NULL;
842 if (code = ZGetGalaxyCount(&cnt)) {
843 ss_perror(sci_idx, code, "while getting galaxy count");
847 for (i=0; i<cnt; i++) {
848 if (code = ZGetGalaxyName(i, &galaxy)) {
849 ss_perror(sci_idx, code, "while getting galaxy name");
853 if (strcasecmp(galaxy, arggalaxy) == 0)
858 ss_perror(sci_idx, 0,
859 "unknown galaxy specified while loading subscription file");
866 if (code = load_sub_file(type, file, galaxy))
867 ss_perror(sci_idx, code,
868 "while loading subscription file");
883 fprintf(stderr,"Usage: %s\n",argv[0]);
887 if (!strcmp(argv[0],"list") || !strcmp(argv[0],"ls"))
892 load_all_sub_files(type, subsname);
902 ZSubscription_t subs;
903 int i,nsubs,retval,save,one,defs;
905 char *galaxy, *file, backup[BUFSIZ];
910 if (!strcmp(argv[0],"save"))
912 else if (!strcmp(argv[0], "defaults") || !strcmp(argv[0], "defs"))
917 fprintf(stderr,"Usage: %s [filename [galaxy]]\n",
921 file = (argc > 1)?argv[1]:subsname;
922 galaxy = (argc > 2)?argv[2]:NULL;
926 fprintf(stderr,"Usage: %s [galaxy]\n",argv[0]);
929 galaxy = (argc > 1)?argv[1]:NULL;
934 if ((wgport = ZGetWGPort()) == -1) {
935 ss_perror(sci_idx,errno,
936 "while finding WindowGram port");
941 retval = ZRetrieveDefaultSubscriptions(galaxy, &nsubs);
943 retval = ZRetrieveSubscriptions(galaxy,(u_short)wgport,&nsubs);
945 if (retval == ZERR_TOOMANYSUBS) {
946 fprintf(stderr,"Too many subscriptions -- some have not been returned.\n");
948 fprintf(stderr,"Save aborted.\n");
953 if (retval != ZERR_NONE) {
954 ss_perror(sci_idx,retval,"retrieving subscriptions");
959 (void) strcpy(backup,file);
960 (void) strcat(backup,".temp");
961 if (!(fp = fopen(backup,"w"))) {
962 (void) sprintf(errbuf,"while opening %s for write",
964 ss_perror(sci_idx,errno,errbuf);
969 for (i=0;i<nsubs;i++) {
971 if ((retval = ZGetSubscriptions(&subs,&one)) != ZERR_NONE) {
972 ss_perror(sci_idx,retval,"while getting subscription");
974 fprintf(stderr,"Subscriptions file not modified\n");
976 (void) unlink(backup);
981 fprintf(fp,"%s,%s,%s\n",subs.zsub_class,
982 subs.zsub_classinst, subs.zsub_recipient);
984 printf("Class %s Instance %s Recipient %s\n",
985 subs.zsub_class, subs.zsub_classinst,
986 subs.zsub_recipient);
990 if (fclose(fp) == EOF) {
991 (void) sprintf(errbuf, "while closing %s", backup);
992 ss_perror(sci_idx, errno, errbuf);
995 if (rename(backup,file) == -1) {
996 (void) sprintf(errbuf,"while renaming %s to %s",
998 ss_perror(sci_idx,retval,errbuf);
999 (void) unlink(backup);