]> andersk Git - moira.git/blob - clients/cluster/cluster.c
Diane Delgado's changes for a fixed table-locking order
[moira.git] / clients / cluster / cluster.c
1 /* $Header$ */
2
3 #include <stdio.h>
4 #include <Wc/WcCreate.h>
5 #include <X11/StringDefs.h>
6 #include <X11/Xaw/Text.h>
7 #include <netdb.h>
8 #include "MList.h"
9 #include <moira.h>
10 #include <moira_site.h>
11 #include <strings.h>
12
13 extern void AriRegisterAthena();
14 extern int errno;
15
16 typedef struct _ClusterResources {
17     char *server;
18 } ClusterResources;
19
20 static XrmOptionDescRec options[] = {
21     {"-server", "*moiraServer",         XrmoptionSepArg,        NULL},
22 };
23
24 #define Offset(field) (XtOffset(ClusterResources *, field))
25
26 static XtResource my_resources[] = {
27     {"moiraServer", XtCString, XtRString, sizeof(String),
28        Offset(server), XtRImmediate, "" },
29 };
30
31 #undef Offset
32
33 char *substr();
34 void localErrorHandler(), mr_x_input(), inputDone(), Help(), popup_error_hook();
35 void getClusters(), getClusterMachine();
36 void selectClusters(), selectClusterMachine(), selectClusterData();
37 void deselectClusters(), clearClusters();
38 void getMachines(), getMachineCluster();
39 void selectMachines(), selectMachineCluster();
40 void deselectMachines(), clearMachines(), getMachineTypes();
41 void selectMachineType(), selectMachineSubnet(), getClusterServer();
42 void addMachineCluster(), removeMachineCluster(), removeMachineAllCluster();
43 void selectAllCluster(), selectAllMachine();
44 void saveCluster(), saveMachine();
45
46 XtActionsRec actions[] = {
47     { "inputDone", inputDone },
48 };
49
50 XtActionsRec callbacks[] = {
51     { "HelpCB", Help },
52     { "getClusters", getClusters },
53     { "getClusterMachine", getClusterMachine },
54     { "selectClusters", selectClusters },
55     { "selectClusterData", selectClusterData },
56     { "selectAllCluster", selectAllCluster },
57     { "selectClusterMachine", selectClusterMachine },
58     { "deselectClusters", deselectClusters },
59     { "clearClusters", clearClusters },
60     { "getClusterServer", getClusterServer },
61     { "getMachines", getMachines },
62     { "getMachineCluster", getMachineCluster },
63     { "selectMachines", selectMachines },
64     { "selectAllMachine", selectAllMachine },
65     { "selectMachineCluster", selectMachineCluster },
66     { "deselectMachines", deselectMachines },
67     { "clearMachines", clearMachines },
68     { "getMachineTypes", getMachineTypes },
69     { "selectMachineType", selectMachineType },
70     { "selectMachineSubnet", selectMachineSubnet },
71     { "addMachineCluster", addMachineCluster },
72     { "removeMachineCluster", removeMachineCluster },
73     { "removeMachineAllCluster", removeMachineAllCluster },
74     { "saveCluster", saveCluster },
75     { "saveMachine", saveMachine },
76 };
77
78 char *moira_help = "Moira is the Athena configuration management system.";
79
80 char *program_help = 
81 "This program allows you to manipulate machine/cluster mappings.  To\n\
82 create or delete machines or clusters, use one of the other moira\n\
83 clients.\n\
84 \n\
85 You can fetch from the database clusters and machines, which will be\n\
86 listed in the two scrolling windows.  They may be fetched by name\n\
87 (wildcards are allowed), machine<->cluster mappings, or fileservers\n\
88 used.\n\
89 \n\
90 The machines and clusters you are going to change must be selected.\n\
91 You can do this by mousing on them or using operations similar ton\n\
92 those that fetched them from the database.  Then you can use the\n\
93 commands in the Mappings menu.";
94 char *author_help = "Written by Mark Rosenstein <mar@MIT.EDU>, MIT Project Athena.";
95 char *unknown_help = "Sorry, help is not available on that topic.";
96
97 #define MACHLEN 32
98 #define CLULEN 16
99
100 typedef struct _mattr {
101         char    type[9];
102         long    addr;
103 } mattr;
104
105 Widget appShell, clist, mlist;
106 ClusterResources resources;
107 Display *dpy;
108 char *program_name;
109 char *clusters[256], *machines[1000];
110 mattr machattr[1000];
111 int nclusters = 0, nmachines = 0;
112 int suppress_updates = 0;
113
114
115 void
116 main(argc, argv)
117 int argc;
118 char* argv[];
119 {   
120     int status, i;
121     char *motd;
122     XtAppContext app;
123
124 /*    setenv("XFILESEARCHPATH", "/afs/athena/system/moira/lib/%N", 1); */
125     setenv("XFILESEARCHPATH", "/afs/athena/astaff/project/moiradev/src/clients/cluster/%N", 1);
126     if ((program_name = rindex(argv[0], '/')) == NULL)
127       program_name = argv[0];
128     else
129       program_name++;
130     program_name = strsave(program_name);
131
132     /*
133      *  Intialize Toolkit creating the application shell, and get
134      *  application resources.
135      */
136     appShell = XtInitialize("cluster", "Cluster",
137                             options, XtNumber(options),
138                             &argc, argv);
139     app = XtWidgetToApplicationContext(appShell);
140     XtAppSetErrorHandler(app, localErrorHandler);
141     dpy = XtDisplay(appShell);
142     XtAppAddActions(app, actions, XtNumber(actions));
143     XtGetApplicationResources(appShell, (caddr_t) &resources, 
144                               my_resources, XtNumber(my_resources),
145                               NULL, (Cardinal) 0);
146     for (i = 0; i < sizeof(callbacks)/sizeof(XtActionsRec); i++)
147       WcRegisterCallback(app, callbacks[i].string, callbacks[i].proc, NULL);
148     /* Register all Motif widget classes */
149     AriRegisterAthena(app);
150
151     status = mr_connect(resources.server);
152     if (status) {
153         com_err(program_name, status, " connecting to server");
154         exit(1);
155     }
156
157     status = mr_motd(&motd);
158     if (status) {
159         com_err(program_name, status, " connecting to server");
160         exit(1);
161     }
162     if (motd) {
163         fprintf(stderr, "The Moira server is currently unavailable:\n%s\n",
164                 motd);
165         mr_disconnect();
166         exit(1);
167     }
168
169     status = mr_auth("cluster");
170     if (status == MR_USER_AUTH) {
171         char buf[BUFSIZ];
172         com_err(program_name, status, "\nPress [RETURN] to continue");
173         gets(buf);
174     } else if (status) {
175         com_err(program_name, status, "; authorization failed - may need to run kinit");
176         exit(1);
177     }
178
179     /* Create widget tree below toplevel shell using Xrm database */
180     WcWidgetCreation(appShell);
181     clist = WcFullNameToWidget(appShell, "*clusterlist");
182     XawMListChange(clist, clusters, 0, 0, False);
183     mlist = WcFullNameToWidget(appShell, "*machinelist");
184     XawMListChange(mlist, machines, 0, 0, False);
185     /*
186      *  Realize the widget tree, finish up initializing,
187      *  and enter the main application loop
188      */
189     XtRealizeWidget(appShell);
190     mr_set_alternate_input(ConnectionNumber(dpy), mr_x_input);
191     set_com_err_hook(popup_error_hook);
192     XtMainLoop();
193 }
194
195
196 int collect(argc, argv, sq)
197 int argc;
198 char **argv;
199 struct save_queue *sq;
200 {
201     char **argv_copy;
202     int i, n;
203
204     argv_copy = (char **)malloc((argc + 1) * sizeof (char *));
205     for (i = 0; i < argc; i++)
206       argv_copy[i] = strsave(argv[i]);
207     argv_copy[i] = NULL;
208
209     sq_save_data(sq, (char *)argv_copy);
210     return(MR_CONT);
211 }
212
213
214 void deselectClusters()
215 {
216     XawMListReturnStruct *ret;
217     int count;
218
219     ret = XawMListShowCurrent(clist, &count);
220     for (count--; count >= 0; count--)
221       XawMListUnhighlight(clist, ret[count].list_index);
222     free(ret);
223 }
224
225
226 void clearClusters()
227 {
228     nclusters = 0;
229     deselectClusters();
230     clusters[0] = NULL;
231     XawMListChange(clist, clusters, 0, 0, False);
232 }
233
234
235 void addCluster(clu)
236 char *clu;
237 {
238     XawMListReturnStruct *ret;
239     int count, i, j, new, status;
240     char *argv[3], **nargv, buf[BUFSIZ], buf1[BUFSIZ];
241     struct save_queue *sq;
242
243     /* Get cluster data and assemble line */
244     sq = sq_create();
245     argv[0] = clu;
246     argv[1] = "*";
247     status = MoiraQuery("get_cluster_data", 2, argv, collect, sq);
248     if (status)
249       com_err(program_name, status, " while fetching cluster data");
250     if (status == MR_SUCCESS) {
251         sq_get_data(sq, &nargv);
252         sprintf(buf, "%-16s %s %s", clu, nargv[1], nargv[2]);
253         free_argv(nargv);
254         while (sq_get_data(sq, &nargv)) {
255             sprintf(buf1, "%s; %s %s", buf, nargv[1], nargv[2]);
256             strcpy(buf, buf1);
257             free_argv(nargv);
258         }
259     } else
260       strcpy(buf, clu);
261     sq_destroy(sq);
262
263     /* find out where in sorted list new item will go */
264     for (new = 0; new < nclusters; new++) {
265         if ((i = strmcmp(clusters[new], clu)) > 0)
266           break;
267         if (i == 0) {
268             free(clusters[new]);
269             clusters[new] = strsave(buf);
270             return;
271         }
272     }
273
274     /* unselect everything in list */
275     ret = XawMListShowCurrent(clist, &count);
276     for (i = 0; i < count; i++)
277       XawMListUnhighlight(clist, ret[i].list_index);
278
279     /* insert new item */
280     for (i = nclusters; i > new; i--)
281       clusters[i + 1] = clusters[i];
282
283     clusters[new] = strsave(buf);
284     nclusters++;
285     if (suppress_updates)
286       suppress_updates++;
287     else
288       XawMListChange(clist, clusters, nclusters, 0, True);
289
290     /* re-highlight (possibly moved) items */
291     for (i = 0; i < count; i++)
292       for (j = 0; j < nclusters; j++)
293         if (!strmcmp(ret[i].string, clusters[j]))
294           XawMListHighlight(clist, j);
295     free(ret);
296 }
297
298
299 void selectCluster(clu)
300 char *clu;
301 {
302     int i;
303
304     addCluster(clu);
305     for (i = 0; i < nclusters; i++)
306       if (!strmcmp(clusters[i], clu)) {
307           XawMListHighlight(clist, i);
308           return;
309       }
310 }
311
312
313 void getClusters()
314 {
315     char clu[64], **argv, *p;
316     struct save_queue *sq;
317     int status;
318
319     sq = sq_create();
320     PromptUser("Cluster name:", clu, sizeof(clu));
321     p = clu;
322     status = MoiraQuery("get_cluster", 1, &p, collect, sq);
323     if (status)
324       com_err(program_name, status, " while fetching clusters");
325
326     suppress_updates = 1;
327     while (sq_get_data(sq, &argv)) {
328         addCluster(strsave(argv[0]));
329         free_argv(argv);
330     }
331     sq_destroy(sq);
332     if (suppress_updates > 1)
333       XawMListChange(clist, clusters, nclusters, 0, True);
334     suppress_updates = 0;
335 }
336
337 void selectClusters()
338 {
339     char clu[64], **argv, *p;
340     struct save_queue *sq;
341     int status;
342
343     sq = sq_create();
344     PromptUser("Cluster name:", clu, sizeof(clu));
345     p = clu;
346     status = MoiraQuery("get_cluster", 1, &p, collect, sq);
347     if (status)
348       com_err(program_name, status, " while fetching clusters");
349
350     suppress_updates = 1;
351     while (sq_get_data(sq, &argv)) {
352         selectCluster(strsave(argv[0]));
353         free_argv(argv);
354     }
355     sq_destroy(sq);
356     if (suppress_updates > 1)
357       XawMListChange(clist, clusters, nclusters, 0, True);
358     suppress_updates = 0;
359 }
360
361 void getClusterMachine()
362 {
363     char mach[64], **argv, *qargv[2];
364     struct save_queue *sq;
365     int status;
366
367     sq = sq_create();
368     PromptUser("Machine name:", mach, sizeof(mach));
369     qargv[0] = canonicalize_hostname(strsave(mach));
370     qargv[1] = "*";
371     status = MoiraQuery("get_machine_to_cluster_map", 2, qargv, collect, sq);
372     if (status)
373       com_err(program_name, status, " while fetching clusters");
374     free(qargv[0]);
375
376     suppress_updates = 1;
377     while (sq_get_data(sq, &argv)) {
378         addCluster(strsave(argv[1]));
379         free_argv(argv);
380     }
381     sq_destroy(sq);
382     if (suppress_updates > 1)
383       XawMListChange(clist, clusters, nclusters, 0, True);
384     suppress_updates = 0;
385 }
386
387
388 void selectClusterMachine()
389 {
390     char mach[64], **argv, *qargv[2];
391     struct save_queue *sq;
392     int status;
393
394     sq = sq_create();
395     PromptUser("Machine name:", mach, sizeof(mach));
396     qargv[0] = canonicalize_hostname(strsave(mach));
397     qargv[1] = "*";
398     status = MoiraQuery("get_machine_to_cluster_map", 2, qargv, collect, sq);
399     if (status)
400       com_err(program_name, status, " while fetching clusters");
401     free(qargv[0]);
402
403     suppress_updates = 1;
404     while (sq_get_data(sq, &argv)) {
405         selectCluster(strsave(argv[1]));
406         free_argv(argv);
407     }
408     sq_destroy(sq);
409     if (suppress_updates > 1)
410       XawMListChange(clist, clusters, nclusters, 0, True);
411     suppress_updates = 0;
412 }
413
414
415 void getClusterServer()
416 {
417     char buf[64], *mach, **argv, *qargs[3];
418     struct save_queue *fsq, *cluq, *sq;
419     int status;
420
421     fsq = sq_create();
422     PromptUser("Server name:", buf, sizeof(buf));
423     mach = canonicalize_hostname(strsave(buf));
424     status = MoiraQuery("get_filesys_by_machine", 1, &mach, collect, fsq);
425     if (status) {
426         com_err(program_name, status, " while fetching filesystems");
427         return;
428     }
429     free(mach);
430     cluq = sq_create();
431     qargs[0] = "*";
432     qargs[1] = "syslib";
433     status = MoiraQuery("get_cluster_data", 2, qargs, collect, cluq);
434     if (status) {
435         com_err(program_name, status, " while fetching cluster data");
436         return;
437     }
438     suppress_updates = 1;
439     while (sq_get_data(cluq, &argv)) {
440         mach = index(argv[2], ' ');
441         if (mach) *mach = 0;
442         printf("Searching for filsys %s\n", argv[2]);
443         for (sq = fsq->q_next; sq != fsq; sq = sq->q_next)
444           if (!strcmp(argv[2], ((char **)sq->q_data)[0]))
445             addCluster(strsave(argv[0]));
446         free_argv(argv);
447     }
448     if (suppress_updates > 1)
449       XawMListChange(clist, clusters, nclusters, 0, True);
450     suppress_updates = 0;
451     while (sq_get_data(fsq, &argv)) {
452         printf("filsys %s\n", argv[0]);
453         free_argv(argv);
454     }
455     sq_destroy(fsq);
456     sq_destroy(cluq);
457 }
458
459
460 void selectClusterData()
461 {
462     char buf[64];
463     int i;
464
465     PromptUser("Data:", buf, sizeof(buf));
466
467     for (i = 0; i < nclusters; i++)
468       if (substr(buf, &clusters[i][CLULEN]))
469         XawMListHighlight(clist, i);
470 }
471
472 void selectAllCluster()
473 {
474     int i;
475
476     for (i = 0; i < nclusters; i++)
477       XawMListHighlight(clist, i);
478 }
479
480
481 void deselectMachines()
482 {
483     XawMListReturnStruct *ret;
484     int count;
485
486     ret = XawMListShowCurrent(mlist, &count);
487     for (count--; count >= 0; count--)
488       XawMListUnhighlight(mlist, ret[count].list_index);
489     free(ret);
490 }
491
492
493 void clearMachines()
494 {
495     nmachines = 0;
496     deselectMachines();
497     machines[0] = NULL;
498     XawMListChange(mlist, machines, 0, 0, False);
499 }
500
501
502 void addMachine(mach, type)
503 char *mach, *type;
504 {
505     XawMListReturnStruct *ret;
506     int count, i, j, new, addr;
507     char buf[BUFSIZ];
508     struct hostent *he;
509
510     he = gethostbyname(mach);
511     if (he)
512       addr = *(int *)he->h_addr_list[0];
513     else
514       addr = 0L;
515     sprintf(buf, "%-32s %-8s %s", mach, type, inet_ntoa(addr));
516
517     /* find out where in sorted list new item will go */
518     for (new = 0; new < nmachines; new++) {
519         if ((i = strmcmp(machines[new], mach)) > 0)
520           break;
521         if (i == 0) {
522             if (strlen(mach) > strlen(machines[new])) {
523                 free(machines[new]);
524                 machines[new] = strsave(buf);
525                 strcpy(machattr[new].type, type);
526                 machattr[new].addr = addr;
527             }
528             if (suppress_updates)
529               suppress_updates++;
530             else
531               XawMListChange(mlist, machines, nmachines, 0, True);
532             return;
533         }
534     }
535
536     /* unselect everything in list */
537     ret = XawMListShowCurrent(mlist, &count);
538     for (i = 0; i < count; i++)
539       XawMListUnhighlight(mlist, ret[i].list_index);
540
541     /* insert new item */
542     for (i = nmachines; i > new; i--) {
543         machines[i] = machines[i - 1];
544         machattr[i] = machattr[i - 1];
545     }
546
547     machines[new] = strsave(buf);
548     strcpy(machattr[new].type, type);
549     machattr[new].addr = addr;
550     nmachines++;
551     if (suppress_updates)
552       suppress_updates++;
553     else
554       XawMListChange(mlist, machines, nmachines, 0, True);
555
556     /* re-highlight (possibly moved) items */
557     for (i = 0; i < count; i++)
558       for (j = 0; j < nmachines; j++)
559         if (!strmcmp(ret[i].string, machines[j]))
560           XawMListHighlight(mlist, j);
561     free(ret);
562 }
563
564
565 void selectMachine(mach, type)
566 char *mach, *type;
567 {
568     int i;
569
570     addMachine(mach, type);
571     for (i = 0; i < nmachines; i++)
572       if (!strmcmp(machines[i], mach)) {
573           XawMListHighlight(mlist, i);
574           return;
575       }
576 }
577
578 void getMachines()
579 {
580     char *mach, **argv, buf[BUFSIZ];
581     struct save_queue *sq;
582     int status;
583
584     sq = sq_create();
585     PromptUser("Machine name:", buf, sizeof(buf));
586     mach = canonicalize_hostname(strsave(buf));
587     status = MoiraQuery("get_machine", 1, &mach, collect, sq);
588     if (status)
589       com_err(program_name, status, " while fetching machines");
590     free(mach);
591
592     suppress_updates = 1;
593     while (sq_get_data(sq, &argv)) {
594         addMachine(argv[0], argv[1]);
595         free_argv(argv);
596     }
597     sq_destroy(sq);
598     if (suppress_updates > 1)
599       XawMListChange(mlist, machines, nmachines, 0, True);
600     suppress_updates = 0;
601 }
602
603
604 void selectMachines()
605 {
606     char *mach, **argv, buf[BUFSIZ];
607     struct save_queue *sq;
608     int status;
609
610     sq = sq_create();
611     PromptUser("Machine name:", buf, sizeof(buf));
612     mach = canonicalize_hostname(strsave(buf));
613     status = MoiraQuery("get_machine", 1, &mach, collect, sq);
614     if (status)
615       com_err(program_name, status, " while fetching machines");
616     free(mach);
617
618     suppress_updates = 1;
619     while (sq_get_data(sq, &argv)) {
620         selectMachine(argv[0], argv[1]);
621         free_argv(argv);
622     }
623     sq_destroy(sq);
624     if (suppress_updates > 1)
625       XawMListChange(mlist, machines, nmachines, 0, True);
626     suppress_updates = 0;
627
628 }
629
630
631 void getMachineCluster()
632 {
633     char **argv, **argv1, *qargv[2], buf[256];
634     struct save_queue *sq, *sq1;
635     int status;
636
637     sq = sq_create();
638     qargv[0] = "*";
639     PromptUser("Cluster name:", buf, sizeof(buf));
640     qargv[1] = buf;
641     status = MoiraQuery("get_machine_to_cluster_map", 2, qargv, collect, sq);
642     if (status)
643       com_err(program_name, status, " while fetching clusters");
644
645     suppress_updates = 1;
646     while (sq_get_data(sq, &argv)) {
647         addMachine(strsave(argv[0]), "");
648 #ifdef MACHTYPE
649         sq1 = sq_create();
650         status = MoiraQuery("get_machine", 1, argv, collect, sq1);
651         if (status)
652           com_err(program_name, status, " while fetching machine type");
653         sq_get_data(sq1, &argv1);
654         addMachine(argv1[0], argv1[1]);
655         sq_destroy(sq1);
656         free_argv(argv1);
657 #endif
658         free_argv(argv);
659     }
660     sq_destroy(sq);
661     if (suppress_updates > 1)
662       XawMListChange(mlist, machines, nmachines, 0, True);
663     suppress_updates = 0;
664 }
665
666
667 void selectMachineCluster()
668 {
669     char **argv, **argv1, *qargv[2], buf[256];
670     struct save_queue *sq, *sq1;
671     int status;
672
673     sq = sq_create();
674     qargv[0] = "*";
675     PromptUser("Cluster name:", buf, sizeof(buf));
676     qargv[1] = buf;
677     status = MoiraQuery("get_machine_to_cluster_map", 2, qargv, collect, sq);
678     if (status)
679       com_err(program_name, status, " while fetching clusters");
680
681     suppress_updates = 1;
682     while (sq_get_data(sq, &argv)) {
683         selectMachine(strsave(argv[0]), "");
684 #ifdef MACHTYPE
685         sq1 = sq_create();
686         status = MoiraQuery("get_machine", 1, argv, collect, sq1);
687         if (status)
688           com_err(program_name, status, " while fetching machine type");
689         sq_get_data(sq1, &argv1);
690         selectMachine(argv1[0], argv1[1]);
691         free_argv(argv1);
692         sq_destroy(sq1);
693 #endif
694         free_argv(argv);
695     }
696     sq_destroy(sq);
697     if (suppress_updates > 1)
698       XawMListChange(mlist, machines, nmachines, 0, True);
699     suppress_updates = 0;
700 }
701
702
703 void getMachineTypes()
704 {
705     char *mach, **argv, buf[256], *p;
706     int i, changed = 0, status, addr;
707     struct save_queue *sq;
708     struct hostent *he;
709     sq = sq_create();
710
711     for (i = 0; i < nmachines; i++) {
712         if (strlen(machattr[i].type) == 0) {
713             mach = machines[i];
714             p = index(mach, ' ');
715             if (p) *p = 0;
716             status = MoiraQuery("get_machine", 1, &mach, collect, sq);
717             if (status)
718               com_err(program_name, status, " while fetching machine type");
719             sq_get_data(sq, &argv);
720             strcpy(machattr[i].type, argv[1]);
721             he = gethostbyname(mach);
722             if (he)
723               addr = *(int *)he->h_addr_list[0];
724             else
725               addr = 0L;
726             sprintf(buf, "%-32s %-8s %s", mach, argv[1], inet_ntoa(addr));
727             machines[i] = strsave(buf);
728             machattr[i].addr = addr;
729             free_argv(argv);
730             changed++;
731         }
732     }
733     if (changed)
734       XawMListChange(mlist, machines, nmachines, 0, True);
735     sq_destroy(sq);
736 }
737
738
739 void selectMachineType()
740 {
741     char type[16];
742     int i;
743
744     PromptUser("Machine type:", type, sizeof(type));
745     getMachineTypes();
746
747     for (i = 0; i < nmachines; i++)
748       if (!strcasecmp(type, machattr[i].type))
749         XawMListHighlight(mlist, i);
750 }
751
752
753 void selectMachineSubnet()
754 {
755     char buf[BUFSIZ];
756     int i, subnet;
757     struct hostent *he;
758
759     PromptUser("Machine's subnet:", buf, sizeof(buf));
760     subnet = atoi(buf);
761
762     for (i = 0; i < nmachines; i++) {
763         /* Here we go hardcoding the subnet mask.... */
764         if (subnet == ((ntohl(machattr[i].addr) >> 16) & 0xff))
765           XawMListHighlight(mlist, i);
766     }
767 }
768
769
770 void selectAllMachine()
771 {
772     int i;
773
774     for (i = 0; i < nmachines; i++)
775       XawMListHighlight(mlist, i);
776 }
777
778
779 void addMachineCluster()
780 {
781     XawMListReturnStruct *machs, *clus;
782     int mcount, ccount, status, c, m;
783     char *argv[2], *p;
784
785     machs = XawMListShowCurrent(mlist, &mcount);
786     clus = XawMListShowCurrent(clist, &ccount);
787     for (c = 0; c < ccount; c++) {
788         for (m = 0; m < mcount; m++) {
789             argv[0] = strsave(machines[machs[m].list_index]);
790             p = index(argv[0], ' ');
791             if (p) *p = 0;
792             argv[1] = strsave(clusters[clus[c].list_index]);
793             p = index(argv[1], ' ');
794             if (p) *p = 0;
795             status = MoiraQuery("add_machine_to_cluster", 2, argv,
796                                 collect, NULL);
797             if (status)
798               com_err(program_name, status, " while adding machines to clusters");
799             free(argv[0]);
800             free(argv[1]);
801         }
802     }
803     free(machs);
804     free(clus);
805 }
806
807
808 void removeMachineCluster()
809 {
810     XawMListReturnStruct *machs, *clus;
811     int mcount, ccount, status, c, m;
812     char *argv[2], *p;
813
814     machs = XawMListShowCurrent(mlist, &mcount);
815     clus = XawMListShowCurrent(clist, &ccount);
816     for (c = 0; c < ccount; c++) {
817         for (m = 0; m < mcount; m++) {
818             argv[0] = strsave(machs[m].string);
819             p = index(argv[0], ' ');
820             if (p) *p = 0;
821             argv[1] = strsave(clus[c].string);
822             p = index(argv[1], ' ');
823             if (p) *p = 0;
824             status = MoiraQuery("delete_machine_from_cluster", 2, argv,
825                                 collect, NULL);
826             if (status)
827               com_err(program_name, status, " while deleting machines from clusters");
828             free(argv[0]);
829             free(argv[1]);
830         }
831     }
832     free(machs);
833     free(clus);
834 }
835
836
837 void removeMachineAllCluster()
838 {
839     XawMListReturnStruct *machs;
840     int mcount, ccount, status, c, m;
841     char *argv[2], *p, **args;
842     struct save_queue *sq;
843
844     machs = XawMListShowCurrent(mlist, &mcount);
845
846     for (m = 0; m < mcount; m++) {
847         sq = sq_create();
848         argv[0] = strsave(machs[m].string);
849         p = index(argv[0], ' ');
850         if (p) *p = 0;
851         argv[1] = "*";
852         status = MoiraQuery("get_machine_to_cluster_map", 2, argv,
853                             collect, sq);
854         if (status)
855           com_err(program_name, status, " while getting cluster mapping");
856         free(argv[0]);
857
858         while (sq_get_data(sq, &args)) {
859             status = MoiraQuery("delete_machine_from_cluster", 2, args,
860                                 collect, NULL);
861             if (status)
862               com_err(program_name, status, " while deleting machines from clusters");
863         }
864         sq_destroy(sq);
865     }
866 }
867
868
869 void saveCluster()
870 {
871     char buf[512];
872     FILE *out;
873     int i;
874
875     PromptUser("Filename:", buf, sizeof(buf));
876     out = fopen(buf, "w");
877     if (out == NULL) {
878         com_err(program_name, errno, " while opening output file \"%s\"", buf);
879         return;
880     }
881     for (i = 0; i < nclusters; i++)
882       fprintf(out, "%s\n", clusters[i]);
883     if (fclose(out))
884       com_err(program_name, errno, " while closing output file \"%s\"", buf);
885 }
886
887
888 void saveMachine()
889 {
890     char buf[512];
891     FILE *out;
892     int i;
893
894     PromptUser("Filename:", buf, sizeof(buf));
895     out = fopen(buf, "w");
896     if (out == NULL) {
897         com_err(program_name, errno, " while opening output file \"%s\"", buf);
898         return;
899     }
900     for (i = 0; i < nmachines; i++)
901       fprintf(out, "%s\n", machines[i]);
902     if (fclose(out))
903       com_err(program_name, errno, " while closing output file \"%s\"", buf);
904 }
905
906
907 /* Called from within the toolkit */
908 void localErrorHandler(s)
909 String s;
910 {
911     fprintf(stderr, "Moira X error: %s\n", s);
912     exit(1);
913 }
914
915
916 void mr_x_input()
917 {
918     XEvent event;
919
920     XtAppNextEvent(_XtDefaultAppContext(), &event);
921     XtDispatchEvent(&event);
922 }
923
924
925 int MoiraQuery(query, argc, argv, callback, data)
926 char *query;
927 int argc;
928 char **argv;
929 int (*callback)();
930 caddr_t data;
931 {
932     int status;
933
934     MakeWatchCursor(appShell);
935     status = mr_query(query, argc, argv, callback, data);
936     if (status != MR_ABORTED && status != MR_NOT_CONNECTED) {
937         MakeNormalCursor(appShell);
938         return(status);
939     }
940     status = mr_connect(resources.server);
941     if (status) {
942         com_err(program_name, status, " while re-connecting to server %s",
943                 resources.server);
944         MakeNormalCursor(appShell);
945         return(MR_ABORTED);
946     }
947     status = mr_auth("mmoira");
948     if (status) {
949         com_err(program_name, status, " while re-authenticating to server %s",
950                 resources.server);
951         mr_disconnect();
952         MakeNormalCursor(appShell);
953         return(MR_ABORTED);
954     }
955     status = mr_query(query, argc, argv, callback, data);
956     MakeNormalCursor(appShell);
957     return(status);
958 }
959
960
961 MakeWatchCursor(w) {}
962 MakeNormalCursor(w) {}
963
964 static input_done_flag = 0;
965
966 void inputDone()
967 {
968     input_done_flag = 1;
969 }
970
971
972 PromptUser(msg, buf, bufsiz)
973 char *msg, *buf;
974 int bufsiz;
975 {
976     XawTextBlock tb;
977     Arg args[2];
978     XEvent e;
979     char *data;
980
981     tb.firstPos = 0;
982     tb.ptr = msg;
983     tb.length = 0;
984     tb.format = FMT8BIT;
985
986     XtSetArg(args[0], XtNlabel, msg);
987     XtSetValues(WcFullNameToWidget(appShell, "*query*prompt"), args, 1);
988
989     XawTextReplace(WcFullNameToWidget(appShell, "*query*input"),
990                    0, 65536, &tb);
991
992     XtManageChild(WcFullNameToWidget(appShell, "*query"));
993     XRaiseWindow(dpy, XtWindow(WcFullNameToWidget(appShell, "*query")));
994
995     /* repeat main_loop here so we can check status & return */
996     input_done_flag = 0;
997     while (!input_done_flag) {
998         XtAppNextEvent(_XtDefaultAppContext(), &e);
999         XtDispatchEvent(&e);
1000     }
1001
1002     XtSetArg(args[0], XtNstring, &data);
1003     XtGetValues(WcFullNameToWidget(appShell, "*query*input"), args, 1);
1004     strncpy(buf, data, bufsiz);
1005
1006     XtUnmanageChild(WcFullNameToWidget(appShell, "*query"));
1007 }
1008
1009
1010 void Help(w, s, unused)
1011 Widget w;
1012 char *s;
1013 {
1014     XawTextBlock tb;
1015
1016     if (!strcmp(s, "moira"))
1017       tb.ptr = moira_help;
1018     else if (!strcmp(s, "program"))
1019       tb.ptr = program_help;
1020     else if (!strcmp(s, "author"))
1021       tb.ptr = author_help;
1022     else tb.ptr = unknown_help;
1023
1024     tb.firstPos = 0;
1025     tb.length = strlen(tb.ptr);
1026     tb.format = FMT8BIT;
1027
1028     XawTextReplace(WcFullNameToWidget(appShell, "*msg"),
1029                    0, 65536, &tb);
1030
1031     XtPopup(WcFullNameToWidget(appShell, "*help"), XtGrabNone);
1032 }
1033
1034
1035 free_argv(argv)
1036 char **argv;
1037 {
1038     int i;
1039
1040     for (i = 0; argv[i]; i++)
1041       free(argv[i]);
1042     free(argv);
1043 }
1044
1045
1046 /* compare machine strings.  This is a separate routine instead of strcmp()
1047  * so that we can deal with the optional machine type after the space
1048  * padding.  Usage is just like strcmp().
1049  */
1050
1051 int strmcmp(s1, s2)
1052 char *s1, *s2;
1053 {
1054     if ((*s1 == ' ' || *s1 == 0) &&
1055         (*s2 == ' ' || *s2 == 0))
1056       return(0);
1057     if (*s1 == *s2)
1058       return(strmcmp(s1+1, s2+1));
1059     if (*s1 < *s2)
1060       return(-1);
1061     return(1);
1062 }
1063
1064
1065 /* search for a substring.  Will scan string s looking for substring
1066  * f contained within it.  Will return a pointer to the start of the
1067  * contained substring, or NULL if not found.
1068  */
1069
1070 char *substr(f, s)
1071 char *f, *s;
1072 {
1073     char *p;
1074
1075     while (p = index(s, *f)) {
1076         if (!strncmp(f, p, strlen(f)))
1077           return(p);
1078         s++;
1079     }
1080     return(NULL);
1081 }
1082
1083
1084
1085 void popup_error_hook(who, code, fmt, arg1, arg2, arg3, arg4, arg5)
1086 char *who;
1087 long code;
1088 char *fmt;
1089 caddr_t arg1, arg2, arg3, arg4, arg5;
1090 {
1091     char buf[BUFSIZ], *cp;
1092     XawTextBlock tb;
1093     XEvent e;
1094
1095     (void) strcpy(buf, who);
1096     for (cp = buf; *cp; cp++);
1097     *cp++ = ':';
1098     *cp++ = ' ';
1099     if (code) {
1100         (void) strcpy(cp, error_message(code));
1101         while (*cp)
1102             cp++;
1103     }
1104     sprintf(cp, fmt, arg1, arg2, arg3, arg4, arg5);
1105
1106     tb.firstPos = 0;
1107     tb.ptr = buf;
1108     tb.length = strlen(tb.ptr);
1109     tb.format = FMT8BIT;
1110
1111     XawTextReplace(WcFullNameToWidget(appShell, "*errmsg"),
1112                    0, 65536, &tb);
1113     XtCallActionProc(WcFullNameToWidget(appShell, "*errmsg"),
1114                      "form-paragraph", &e, NULL, 0);
1115
1116     XtPopup(WcFullNameToWidget(appShell, "*error"), XtGrabNone);
1117 }
This page took 0.127563 seconds and 5 git commands to generate.