]> asedeno.scripts.mit.edu Git - 1ts-debian.git/blob - zephyr/clients/zctl/zctl.c
This commit was generated by cvs2svn to compensate for changes in r127,
[1ts-debian.git] / zephyr / clients / zctl / zctl.c
1 /* This file is part of the Project Athena Zephyr Notification System.
2  * It contains code for the "zctl" command.
3  *
4  *      Created by:     Robert French
5  *
6  *      $Source: /afs/athena/astaff/project/zephyr/attic2/repository/zephyr/clients/zctl/zctl.c,v $
7  *      $Author: marc $
8  *
9  *      Copyright (c) 1987,1988 by the Massachusetts Institute of Technology.
10  *      For copying and distribution information, see the file
11  *      "mit-copyright.h". 
12  */
13
14 #include <sysdep.h>
15 #include <zephyr/zephyr.h>
16 #include <ss/ss.h>
17 #include <com_err.h>
18 #include <pwd.h>
19 #include <netdb.h>
20 #include <errno.h>
21 #ifndef lint
22 static const char *rcsid_zctl_c = "$Id: zctl.c,v 1.28.4.1 1997/01/06 01:40:24 marc Exp $";
23 #endif
24
25 #include "zutils.h"
26
27 #define USERS_SUBS "/.zephyr.subs"
28 #define OLD_SUBS "/.subscriptions"
29
30 #define ERR             (-1)
31 #define NOT_REMOVED     0
32 #define REMOVED         1
33 int purge_subs();
34 void add_file(char *fn, char *galaxy, short wgport, ZSubscription_t *subs,
35               int mode);
36 void del_file(char *fn, char *galaxy, short wgport, ZSubscription_t *subs,
37               int mode);
38
39
40 int sci_idx;
41 char subsname[BUFSIZ];
42
43 extern ss_request_table zctl_cmds;
44
45 main(argc,argv)
46         int argc;
47         char *argv[];
48 {
49         struct passwd *pwd;
50         char ssline[BUFSIZ],oldsubsname[BUFSIZ],*envptr,*tty = NULL;
51         int retval,code,i;
52 #ifdef HAVE_SYS_UTSNAME
53         struct utsname name;
54 #endif
55
56         if ((retval = ZInitialize()) != ZERR_NONE) {
57                 com_err(argv[0],retval,"while initializing");
58                 exit (1);
59         }
60
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");
65 #endif  
66         if ((retval = ZInitLocationInfo(NULL, tty)) != ZERR_NONE)
67             com_err(argv[0], retval, "initializing location information");
68
69         envptr = getenv("ZEPHYR_SUBS");
70         if (envptr)
71                 strcpy(subsname,envptr);
72         else {
73                 envptr = getenv("HOME");
74                 if (envptr)
75                         strcpy(subsname,envptr);
76                 else {
77                         if (!(pwd = getpwuid((int) getuid()))) {
78                                 fprintf(stderr,"Who are you?\n");
79                                 exit (1);
80                         }
81
82                         strcpy(subsname,pwd->pw_dir);
83                 }
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");
92                 }
93         }
94
95         sci_idx = ss_create_invocation("zctl","",0,&zctl_cmds,&code);
96         if (code) {
97                 ss_perror(sci_idx,code,"while creating invocation");
98                 exit(1);
99         }
100
101         if (argc > 1) {
102                 *ssline = '\0';
103                 for (i=1;i<argc;i++)
104                         (void) sprintf(ssline+strlen(ssline),"%s ",argv[i]);
105                 ssline[strlen(ssline)-1] = '\0';
106                 code = ss_execute_line(sci_idx,ssline);
107                 if (code)
108                     fprintf (stderr, "%s: %s: %s\n",
109                              argv[0], error_message (code), ssline);
110                 exit((code != 0));
111         } 
112
113         printf("ZCTL $Revision: 1.28.4.1 $ (Protocol %s%d.%d) - Type '?' for a list of commands.\n\n",
114                ZVERSIONHDR,
115                ZVERSIONMAJOR,ZVERSIONMINOR_GALAXY);
116         
117         code = ss_listen(sci_idx);
118         exit(0);
119 }
120
121 void
122 set_file(argc,argv)
123         int argc;
124         char *argv[];
125 {
126         if (argc > 2) {
127                 fprintf(stderr,"Usage: %s filename\n",argv[0]);
128                 return;
129         }
130
131         if (argc == 1)
132                 printf("Current file: %s\n",subsname);
133         else
134                 (void) strcpy(subsname,argv[1]);
135 }
136
137 void
138 flush_locations(argc,argv)
139         int argc;
140         char *argv[];
141 {
142     int retval;
143     char *galaxy;
144     int cnt, i;
145         
146     if (argc > 2) {
147         fprintf(stderr,"Usage: %s [galaxy]\n",argv[0]);
148         return;
149     }
150
151     galaxy = (argc > 1)?argv[1]:NULL;
152
153     if (galaxy && strcmp(galaxy, "*") == 0) {
154         if (retval = ZGetGalaxyCount(&cnt)) {
155             ss_perror(sci_idx, retval, "while getting galaxy count");
156             return;
157         }
158
159         for (i=0; i<cnt; i++) {
160             if (retval = ZGetGalaxyName(i, &galaxy)) {
161                 ss_perror(sci_idx, retval, "while getting galaxy name");
162                 return;
163             }
164
165             if ((retval = ZFlushMyLocations(galaxy)) != ZERR_NONE) {
166                 ss_perror(sci_idx, retval, "while flushing locations");
167                 return;
168             }
169         }
170     } else {
171         if ((retval = ZFlushMyLocations(galaxy)) != ZERR_NONE) {
172             ss_perror(sci_idx, retval, "while flushing locations");
173             return;
174         }
175     }
176 }
177
178 void
179 wgc_control(argc,argv)
180         int argc;
181         char *argv[];
182 {
183         Code_t retval;
184
185         if (argc > 1) {
186                 fprintf(stderr,"Usage: %s\n",argv[0]);
187                 return;
188         }
189
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);
198         } else {
199                 fprintf(stderr,
200                         "unknown WindowGram client control command %s\n",
201                         argv[0]);
202                 return;
203         }
204
205         if (retval)
206                 ss_perror(sci_idx, retval,
207                           "while sending WindowGram control message");
208 }
209
210 void
211 hm_control(argc,argv)
212         int argc;
213         char *argv[];
214 {
215     int retval;
216     ZNotice_t notice;
217     char *galaxy;
218     int cnt, i;
219
220     if (argc > 2) {
221         fprintf(stderr,"Usage: %s [galaxy]\n",argv[0]);
222         return;
223     }
224         
225     galaxy = (argc > 1)?argv[1]:NULL;
226
227     (void) memset((char *)&notice, 0, sizeof(notice));
228     notice.z_kind = HMCTL;
229     notice.z_port = 0;
230     notice.z_class = HM_CTL_CLASS;
231     notice.z_class_inst = HM_CTL_CLIENT;
232
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",
239                 argv[0]);
240         return;
241     }
242     notice.z_sender = 0;
243     notice.z_recipient = "";
244     notice.z_default_format = "";
245     notice.z_message_len = 0;
246
247     if (galaxy && strcmp(galaxy, "*") == 0) {
248         if (retval = ZGetGalaxyCount(&cnt)) {
249             ss_perror(sci_idx, retval, "while getting galaxy count");
250             return;
251         }
252
253         for (i=0; i<cnt; i++) {
254             if (retval = ZGetGalaxyName(i, &galaxy)) {
255                 ss_perror(sci_idx, retval, "while getting galaxy name");
256                 return;
257             }
258
259             notice.z_dest_galaxy = galaxy;
260
261             if ((retval = ZSendNotice(&notice,ZNOAUTH)) != ZERR_NONE) {
262                 ss_perror(sci_idx,retval,"while sending notice");
263                 return;
264             }
265         }
266     } else {
267         if ((retval = ZSendNotice(&notice,ZNOAUTH)) != ZERR_NONE) {
268             ss_perror(sci_idx,retval,"while sending notice");
269             return;
270         }
271     }
272
273
274 void
275 show_var(argc,argv)
276         int argc;
277         char *argv[];
278 {
279         int i;
280         char *value;
281         
282         if (argc < 2) {
283                 fprintf(stderr,"Usage: %s <varname> <varname> ...\n",argv[0]);
284                 return;
285         }
286
287         for (i=1;i<argc;i++) {
288                 value = ZGetVariable(argv[i]);
289                 if (value)
290                         printf("%s: %s\n",argv[i],value);
291                 else
292                         printf("%s: not defined\n",argv[i]);
293         }
294 }
295
296 void
297 set_var(argc,argv)
298         int argc;
299         register char **argv;
300 {
301     int retval,setting_exp,i;
302     char *galaxy;
303     char varcat[BUFSIZ];
304         
305     if (argc < 2) {
306         fprintf(stderr,"Usage: %s <varname> [value]\n",
307                 argv[0]);
308         return;
309     }
310
311     setting_exp = 0;
312
313     if (strncasecmp(argv[1],"exposure",8) == 0) {
314         setting_exp = 1;
315         if (argc != 3) {
316             fprintf(stderr, "An exposure setting must be specified.\n");
317             return;
318         }
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");
324             return;
325         } else {
326             galaxy = argv[1]+9;
327         }
328     } 
329
330     if (argc == 2)
331         retval = ZSetVariable(argv[1],"");
332     else {
333         (void) strcpy(varcat,argv[2]);
334         for (i=3;i<argc;i++) {
335             (void) strcat(varcat," ");
336             (void) strcat(varcat,argv[i]);
337         } 
338         retval = ZSetVariable(argv[1],varcat);
339     } 
340
341     if (retval != ZERR_NONE) {
342         ss_perror(sci_idx,retval,"while setting variable value");
343         return;
344     }
345
346     /* Side-effects?  Naw, us? */
347         
348     if (setting_exp)
349         set_exposure(galaxy?galaxy:"*", argv[2]);
350 }
351
352 void
353 do_hide(argc,argv)
354         int argc;
355         char *argv[];
356 {
357     char *exp_level;
358     char *galaxy;
359     int cnt, i;
360     Code_t code;
361
362     if (argc > 2) {
363         fprintf(stderr, "Usage: %s [galaxy]\n",argv[0]);
364         return;
365     }
366
367     if (strcmp(argv[0], "unhide") == 0) {
368         exp_level = ZGetVariable("exposure");
369         if (exp_level)
370             exp_level = ZParseExposureLevel(exp_level);
371         if (!exp_level)
372             exp_level = EXPOSE_REALMVIS;
373     } else {
374         exp_level = EXPOSE_OPSTAFF;
375     }
376
377     galaxy = (argc > 1)?argv[1]:NULL;
378
379     if (code = set_exposure(galaxy, exp_level)) {
380         ss_perror(sci_idx, code, "while setting exposures");
381         return;
382     }
383 }
384
385 void
386 unset_var(argc,argv)
387         int argc;
388         char *argv[];
389 {
390         int retval,i;
391         
392         if (argc < 2) {
393                 fprintf(stderr,"Usage: %s <varname> [<varname> ... ]\n",
394                         argv[0]);
395                 return;
396         }
397
398         for (i=1;i<argc;i++)
399                 if ((retval = ZUnsetVariable(argv[i])) != ZERR_NONE)
400                         ss_perror(sci_idx,retval,
401                                   "while unsetting variable value");
402 }
403         
404 void
405 cancel_subs(argc,argv)
406         int argc;
407         char *argv[];
408 {
409     int retval;
410     short wgport;
411     int i, cnt;
412     char *galaxy;
413
414     if (argc > 2) {
415         fprintf(stderr,"Usage: %s [galaxy]\n",argv[0]);
416         return;
417     }
418
419     if ((wgport = ZGetWGPort()) == -1) {
420         ss_perror(sci_idx,errno,"while finding WindowGram port");
421         return;
422     } 
423
424     galaxy = (argc > 1)?argv[1]:NULL;
425
426     if (galaxy && strcmp(galaxy, "*") == 0) {
427         if (retval = ZGetGalaxyCount(&cnt)) {
428             ss_perror(sci_idx, retval, "while getting galaxy count");
429             return;
430         }
431
432         for (i=0; i<cnt; i++) {
433             if (retval = ZGetGalaxyName(i, &galaxy)) {
434                 ss_perror(sci_idx, retval, "while getting galaxy name");
435                 return;
436             }
437
438             if ((retval = ZCancelSubscriptions(galaxy, (u_short)wgport))
439                 != ZERR_NONE) {
440                 ss_perror(sci_idx,retval,"while cancelling subscriptions");
441                 return;
442             }
443         }
444     } else {
445         if ((retval = ZCancelSubscriptions(galaxy, (u_short)wgport))
446             != ZERR_NONE) {
447             ss_perror(sci_idx,retval,"while cancelling subscriptions");
448             return;
449         }
450     }
451 }
452
453 void
454 subscribe(argc,argv)
455         int argc;
456         char *argv[];
457 {
458         int retval;
459         short wgport;
460         ZSubscription_t sub,sub2;
461         char *galaxy;
462         int mode;
463         
464         if (argc > 5 || argc < 3) {
465                 fprintf(stderr,"Usage: %s class instance [* [galaxy]]\n",
466                         argv[0]);
467                 return;
468         }
469         
470         if (strncmp(argv[0], "sub", 3) == 0) {
471                 mode = SUB;
472         } else if (strncmp(argv[0], "unsub", 5) == 0) {
473                 mode = UNSUB;
474         } else if ((strncmp(argv[0], "punt", 4) == 0) ||
475                    (strncmp(argv[0], "sup", 3) == 0)) {
476                 mode = PUNT;
477         } else if ((strncmp(argv[0], "unpunt", 6) == 0) ||
478                    (strncmp(argv[0], "unsup", 5) == 0)) {
479                 mode = UNPUNT;
480         } else {
481                 ss_perror(sci_idx, 0, "internal error in subscribe");
482                 exit(1);
483         }
484
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;
490
491         fix_macros(&sub,&sub2,1);
492         
493         if ((wgport = ZGetWGPort()) == -1) {
494                 ss_perror(sci_idx,errno,"while finding WindowGram port");
495                 return;
496         } 
497
498         switch (mode) {
499         case SUB:
500                 if (retval = ZSubscribeTo(galaxy, &sub2, 1, (u_short) wgport))
501                         ss_perror(sci_idx, retval, "while subscribing");
502                 break;
503         case UNSUB:
504                 if (retval = ZUnsubscribeTo(galaxy, &sub2, 1, (u_short) wgport))
505                         ss_perror(sci_idx, retval, "while subscribing");
506                 break;
507         case PUNT:
508                 if (retval = xpunt(sub2.zsub_class, sub2.zsub_classinst,
509                                   sub2.zsub_recipient, PUNT))
510                         ss_perror(sci_idx, retval, "while suppressing");
511                 break;
512         case UNPUNT:
513                 if (retval = xpunt(sub2.zsub_class, sub2.zsub_classinst,
514                                     sub2.zsub_recipient, UNPUNT))
515                         ss_perror(sci_idx, retval, "while unsuppressing");
516                 break;
517         }
518
519
520 void
521 sub_file(argc,argv)
522         int argc;
523         char *argv[];
524 {
525         ZSubscription_t sub;
526         short wgport;
527         char fn[MAXPATHLEN];
528         char *arggalaxy, *galaxy;
529         int cnt, i;
530         Code_t retval;
531         int del, mode;
532
533         if (argc > 5 || argc < 3) {
534                 fprintf(stderr,"Usage: %s class instance [* [galaxy]]\n",
535                         argv[0]);
536                 return;
537         }
538
539         if (!strcmp(argv[0],"add")) {
540                 del = 0;
541                 mode = SUB;
542         } else if (!strcmp(argv[0],"add_unsubscription") ||
543                    !strcmp(argv[0],"add_un")) {
544                 del = 0;
545                 mode = UNSUB;
546         } else if (!strcmp(argv[0],"add_suppression") ||
547                    !strcmp(argv[0],"add_punt")) {
548                 del = 0;
549                 mode = PUNT;
550         } else if (!strcmp(argv[0],"delete") ||
551                    !strcmp(argv[0],"del") ||
552                    !strcmp(argv[0],"dl")) {
553                 del = 1;
554                 mode = SUB;
555         } else if (!strcmp(argv[0],"delete_unsubscription") ||
556                    !strcmp(argv[0],"del_un")) {
557                 del = 1;
558                 mode = UNSUB;
559         } else if (!strcmp(argv[0],"delete_suppression") ||
560                    !strcmp(argv[0],"del_punt")) {
561                 del = 1;
562                 mode = PUNT;
563         } else {
564                 ss_perror(sci_idx,0,"unknown command name");
565         }
566
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.");
571                 return;
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.");
576                 return;
577         }
578
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;
584
585         if (arggalaxy) {
586             if (retval = ZGetGalaxyCount(&cnt)) {
587                 ss_perror(sci_idx, retval, "while getting galaxy count");
588                 return;
589             }
590
591             for (i=0; i<cnt; i++) {
592                 if (retval = ZGetGalaxyName(i, &galaxy)) {
593                     ss_perror(sci_idx, retval, "while getting galaxy name");
594                     return;
595                 }
596
597                 if (strcasecmp(galaxy, arggalaxy) == 0)
598                     break;
599             }
600
601             if (i == cnt) {
602                 ss_perror(sci_idx, 0,
603                           "unknown galaxy specified while modifying subscripion file");
604                 return;
605             }
606         } else {
607             galaxy = ZGetDefaultGalaxy();
608         }
609
610         if ((wgport = ZGetWGPort()) == -1) {
611                 ss_perror(sci_idx,errno,"while finding WindowGram port");
612                 return;
613         } 
614
615         strcpy(fn, subsname);
616         strcat(fn, "-");
617         strcat(fn, galaxy);
618
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);
637         } else {
638                 ss_perror(sci_idx,0,"unknown command name");
639         }
640         return;
641 }
642
643 void
644 add_file(fn,galaxy,wgport,subs,mode)
645      char *fn;
646      char *galaxy;
647      short wgport;
648      ZSubscription_t *subs;
649      int mode;
650 {
651         FILE *fp;
652         char errbuf[BUFSIZ];
653         ZSubscription_t sub2;
654         Code_t retval;
655
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);
660                 return;
661         } 
662         fprintf(fp,"%s%s,%s,%s\n",
663                 ((mode == UNSUB) ? "!" : 
664                  ((mode == PUNT) ? "*" :
665                   "")),
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);
670                 return;
671         }
672         fix_macros(subs,&sub2,1);
673         if (mode == UNSUB) {
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");
680         } else {
681                 if (retval = ZSubscribeTo(galaxy, &sub2,1,(u_short)wgport))
682                         ss_perror(sci_idx, retval, "while suppressing");
683         }
684
685         return;
686 }
687
688 void
689 del_file(fn,galaxy,wgport,subs,mode)
690      char *fn;
691      char *galaxy;
692      short wgport;
693      ZSubscription_t *subs;
694      int mode;
695 {
696         ZSubscription_t sub2;
697         int retval;
698         
699         retval = purge_subs(fn, subs, mode);
700         if (retval == ERR)
701                 return;
702         if (retval == NOT_REMOVED)
703                 fprintf(stderr,
704                         "Couldn't find %sclass %s instance %s recipient %s in\n\tfile %s\n",
705                         ((mode == UNSUB) ? "un-subscription " : 
706                          ((mode == PUNT) ? "suppression " :
707                           "")),
708                         subs->zsub_class, subs->zsub_classinst,
709                         subs->zsub_recipient, subsname);
710         fix_macros(subs,&sub2,1);
711         if (mode == PUNT) {
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)) !=
716                    ZERR_NONE) {
717                 ss_perror(sci_idx,retval,"while unsubscribing");
718         }
719 }
720
721 int
722 purge_subs(fn, subs, mode)
723      char *fn;
724      register ZSubscription_t *subs;
725      int mode;
726 {
727         FILE *fp,*fpout;
728         char errbuf[BUFSIZ],subline[BUFSIZ];
729         char backup[BUFSIZ],ourline[BUFSIZ];
730         int delflag = NOT_REMOVED;
731         int purge;
732
733         switch (mode) {
734         case SUB:
735         case UNSUB:
736         case PUNT:
737         case ALL:
738                 break;
739         default:
740                 ss_perror(sci_idx,0,"internal error in purge_subs");
741                 return(ERR);
742         }
743
744         (void) sprintf(ourline,"%s,%s,%s",
745                        subs->zsub_class,
746                        subs->zsub_classinst,
747                        subs->zsub_recipient);
748
749         if (!(fp = fopen(fn,"r"))) {
750                 if (errno == ENOENT)
751                         /* if the filw doesn't exist, then the sub
752                            is clearly purged */
753                         return(delflag);
754                 (void) sprintf(errbuf,"while opening %s for read", fn);
755                 ss_perror(sci_idx,errno,errbuf);
756                 return(ERR);
757         } 
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);
764                 (void) fclose(fp);
765                 return(ERR);
766         } 
767         for (;;) {
768                 if (!fgets(subline,sizeof subline,fp))
769                         break;
770                 if (*subline)
771                         subline[strlen(subline)-1] = '\0'; /* nuke newline */
772                 switch (mode) {
773                 case SUB:
774                         purge = (strcmp(subline,ourline) == 0);
775                         break;
776                 case UNSUB:
777                         purge = (*subline == '!' &&
778                                  (strcmp(subline+1,ourline) == 0));
779                         break;
780                 case PUNT:
781                         purge = (*subline == '-' &&
782                                  (strcmp(subline+1,ourline) == 0));
783                         break;
784                 case ALL:
785                         purge = ((strcmp(subline,ourline) == 0) ||
786                                  (((*subline == '!') || (*subline == '-')) &&
787                                   (strcmp(subline+1, ourline) == 0)));
788                         break;
789                 }
790                 if (purge) {
791                         delflag = REMOVED;
792                 } else {
793                         fputs(subline, fpout);
794                         if (ferror(fpout) || (fputc('\n', fpout) == EOF)) {
795                                 (void) sprintf(errbuf, "while writing to %s",
796                                                backup);
797                                 ss_perror(sci_idx, errno, errbuf);
798                         }
799                 }
800         }
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);
805                 return(ERR);
806         }
807         if (rename(backup, fn) == -1) {
808                 (void) sprintf(errbuf,"while renaming %s to %s\n",
809                                backup, fn);
810                 ss_perror(sci_idx,errno,errbuf);
811                 return(ERR);
812         }
813         return(delflag);
814 }
815
816 void
817 load_subs(argc,argv)
818         int argc;
819         char *argv[];
820 {
821         int type, cnt, i;
822         char *file;
823         char *arggalaxy, *galaxy;
824         Code_t code;
825
826         if (argc > 3) {
827                 fprintf(stderr,"Usage: %s [file [galaxy]]\n",argv[0]);
828                 return;
829         }
830
831         if (*argv[0] == 'u')
832                 type = UNSUB;
833         else if (!strcmp(argv[0],"list") || !strcmp(argv[0],"ls"))
834                 type = LIST;
835         else
836                 type = SUB;
837
838         file = (argc > 1)?argv[1]:subsname;
839         arggalaxy = (argc > 2)?argv[2]:NULL;
840
841         if (arggalaxy) {
842             if (code = ZGetGalaxyCount(&cnt)) {
843                 ss_perror(sci_idx, code, "while getting galaxy count");
844                 return;
845             }
846
847             for (i=0; i<cnt; i++) {
848                 if (code = ZGetGalaxyName(i, &galaxy)) {
849                     ss_perror(sci_idx, code, "while getting galaxy name");
850                     return;
851                 }
852
853                 if (strcasecmp(galaxy, arggalaxy) == 0)
854                     break;
855             }
856
857             if (i == cnt) {
858                 ss_perror(sci_idx, 0,
859                           "unknown galaxy specified while loading subscription file");
860                 return;
861             }
862         } else {
863             galaxy = NULL;
864         }
865
866         if (code = load_sub_file(type, file, galaxy))
867             ss_perror(sci_idx, code,
868                       "while loading subscription file");
869
870 }
871
872 void
873 loadall(argc,argv)
874         int argc;
875         char *argv[];
876 {       
877     int retval;
878     char *galaxy;
879     int type, cnt, i;
880     char fn[MAXPATHLEN];
881         
882     if (argc > 1) {
883         fprintf(stderr,"Usage: %s\n",argv[0]);
884         return;
885     }
886
887     if (!strcmp(argv[0],"list") || !strcmp(argv[0],"ls"))
888         type = LIST;
889     else
890         type = SUB;
891
892     load_all_sub_files(type, subsname);
893 }
894
895 void
896 current(argc,argv)
897         int argc;
898         char *argv[];
899 {
900         FILE *fp;
901         char errbuf[BUFSIZ];
902         ZSubscription_t subs;
903         int i,nsubs,retval,save,one,defs;
904         short wgport;
905         char *galaxy, *file, backup[BUFSIZ];
906         
907         save = 0;
908         defs = 0;
909
910         if (!strcmp(argv[0],"save"))
911                 save = 1;
912         else if (!strcmp(argv[0], "defaults") || !strcmp(argv[0], "defs"))
913                 defs = 1;
914
915         if (save) {
916                 if (argc > 3) {
917                         fprintf(stderr,"Usage: %s [filename [galaxy]]\n",
918                                 argv[0]);
919                         return;
920                 } else {
921                         file = (argc > 1)?argv[1]:subsname;
922                         galaxy = (argc > 2)?argv[2]:NULL;
923                 }
924         } else {
925                 if (argc > 2) {
926                         fprintf(stderr,"Usage: %s [galaxy]\n",argv[0]);
927                         return;
928                 } else {
929                         galaxy = (argc > 1)?argv[1]:NULL;
930                 }
931         }
932
933         if (!defs)
934                 if ((wgport = ZGetWGPort()) == -1) {
935                         ss_perror(sci_idx,errno,
936                                   "while finding WindowGram port");
937                         return;
938                 } 
939
940         if (defs)
941                 retval = ZRetrieveDefaultSubscriptions(galaxy, &nsubs);
942         else
943                 retval = ZRetrieveSubscriptions(galaxy,(u_short)wgport,&nsubs);
944
945         if (retval == ZERR_TOOMANYSUBS) {
946                 fprintf(stderr,"Too many subscriptions -- some have not been returned.\n");
947                 if (save) {
948                         fprintf(stderr,"Save aborted.\n");
949                         return;
950                 }
951         }
952         else
953                 if (retval != ZERR_NONE) {
954                         ss_perror(sci_idx,retval,"retrieving subscriptions");
955                         return;
956                 }
957
958         if (save) {
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",
963                                        backup);
964                         ss_perror(sci_idx,errno,errbuf);
965                         return;
966                 }
967         }
968         
969         for (i=0;i<nsubs;i++) {
970                 one = 1;
971                 if ((retval = ZGetSubscriptions(&subs,&one)) != ZERR_NONE) {
972                         ss_perror(sci_idx,retval,"while getting subscription");
973                         if (save) {
974                                 fprintf(stderr,"Subscriptions file not modified\n");
975                                 (void) fclose(fp);
976                                 (void) unlink(backup);
977                         }
978                         return;
979                 } 
980                 if (save)
981                         fprintf(fp,"%s,%s,%s\n",subs.zsub_class,
982                                 subs.zsub_classinst, subs.zsub_recipient);
983                 else
984                         printf("Class %s Instance %s Recipient %s\n",
985                                subs.zsub_class, subs.zsub_classinst,
986                                subs.zsub_recipient);
987         }
988
989         if (save) {
990                 if (fclose(fp) == EOF) {
991                         (void) sprintf(errbuf, "while closing %s", backup);
992                         ss_perror(sci_idx, errno, errbuf);
993                         return;
994                 }
995                 if (rename(backup,file) == -1) {
996                         (void) sprintf(errbuf,"while renaming %s to %s",
997                                        backup,file);
998                         ss_perror(sci_idx,retval,errbuf);
999                         (void) unlink(backup);
1000                 }
1001         }
1002 }