]> andersk Git - moira.git/blame - clients/cluster/cluster.c
Diane Delgado's changes for a fixed table-locking order
[moira.git] / clients / cluster / cluster.c
CommitLineData
c9104dd4 1/* $Header$ */
2
3#include <stdio.h>
2ddfd00a 4#include <Wc/WcCreate.h>
c9104dd4 5#include <X11/StringDefs.h>
6#include <X11/Xaw/Text.h>
2ddfd00a 7#include <netdb.h>
8#include "MList.h"
c9104dd4 9#include <moira.h>
10#include <moira_site.h>
2ddfd00a 11#include <strings.h>
c9104dd4 12
13extern void AriRegisterAthena();
2ddfd00a 14extern int errno;
c9104dd4 15
16typedef struct _ClusterResources {
17 char *server;
18} ClusterResources;
19
20static XrmOptionDescRec options[] = {
21 {"-server", "*moiraServer", XrmoptionSepArg, NULL},
22};
23
24#define Offset(field) (XtOffset(ClusterResources *, field))
25
26static XtResource my_resources[] = {
27 {"moiraServer", XtCString, XtRString, sizeof(String),
28 Offset(server), XtRImmediate, "" },
29};
30
31#undef Offset
32
2ddfd00a 33char *substr();
34void localErrorHandler(), mr_x_input(), inputDone(), Help(), popup_error_hook();
35void getClusters(), getClusterMachine();
36void selectClusters(), selectClusterMachine(), selectClusterData();
37void deselectClusters(), clearClusters();
38void getMachines(), getMachineCluster();
39void selectMachines(), selectMachineCluster();
40void deselectMachines(), clearMachines(), getMachineTypes();
41void selectMachineType(), selectMachineSubnet(), getClusterServer();
42void addMachineCluster(), removeMachineCluster(), removeMachineAllCluster();
43void selectAllCluster(), selectAllMachine();
44void saveCluster(), saveMachine();
c9104dd4 45
46XtActionsRec actions[] = {
2ddfd00a 47 { "inputDone", inputDone },
48};
49
50XtActionsRec callbacks[] = {
51 { "HelpCB", Help },
c9104dd4 52 { "getClusters", getClusters },
2ddfd00a 53 { "getClusterMachine", getClusterMachine },
54 { "selectClusters", selectClusters },
55 { "selectClusterData", selectClusterData },
56 { "selectAllCluster", selectAllCluster },
57 { "selectClusterMachine", selectClusterMachine },
58 { "deselectClusters", deselectClusters },
59 { "clearClusters", clearClusters },
60 { "getClusterServer", getClusterServer },
c9104dd4 61 { "getMachines", getMachines },
2ddfd00a 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 },
c9104dd4 76};
77
2ddfd00a 78char *moira_help = "Moira is the Athena configuration management system.";
79
80char *program_help =
81"This program allows you to manipulate machine/cluster mappings. To\n\
82create or delete machines or clusters, use one of the other moira\n\
83clients.\n\
84\n\
85You can fetch from the database clusters and machines, which will be\n\
86listed in the two scrolling windows. They may be fetched by name\n\
87(wildcards are allowed), machine<->cluster mappings, or fileservers\n\
88used.\n\
89\n\
90The machines and clusters you are going to change must be selected.\n\
91You can do this by mousing on them or using operations similar ton\n\
92those that fetched them from the database. Then you can use the\n\
93commands in the Mappings menu.";
94char *author_help = "Written by Mark Rosenstein <mar@MIT.EDU>, MIT Project Athena.";
95char *unknown_help = "Sorry, help is not available on that topic.";
96
97#define MACHLEN 32
98#define CLULEN 16
99
100typedef struct _mattr {
101 char type[9];
102 long addr;
103} mattr;
104
105Widget appShell, clist, mlist;
c9104dd4 106ClusterResources resources;
107Display *dpy;
108char *program_name;
2ddfd00a 109char *clusters[256], *machines[1000];
110mattr machattr[1000];
c9104dd4 111int nclusters = 0, nmachines = 0;
2ddfd00a 112int suppress_updates = 0;
113
c9104dd4 114
115void
116main(argc, argv)
117int argc;
118char* argv[];
119{
2ddfd00a 120 int status, i;
c9104dd4 121 char *motd;
122 XtAppContext app;
123
2ddfd00a 124/* setenv("XFILESEARCHPATH", "/afs/athena/system/moira/lib/%N", 1); */
125 setenv("XFILESEARCHPATH", "/afs/athena/astaff/project/moiradev/src/clients/cluster/%N", 1);
c9104dd4 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);
2ddfd00a 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 */
c9104dd4 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);
2ddfd00a 181 clist = WcFullNameToWidget(appShell, "*clusterlist");
182 XawMListChange(clist, clusters, 0, 0, False);
183 mlist = WcFullNameToWidget(appShell, "*machinelist");
184 XawMListChange(mlist, machines, 0, 0, False);
c9104dd4 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);
2ddfd00a 191 set_com_err_hook(popup_error_hook);
c9104dd4 192 XtMainLoop();
193}
194
195
196int collect(argc, argv, sq)
197int argc;
198char **argv;
199struct save_queue *sq;
200{
2ddfd00a 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);
c9104dd4 210 return(MR_CONT);
211}
212
2ddfd00a 213
214void 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
226void clearClusters()
227{
228 nclusters = 0;
229 deselectClusters();
230 clusters[0] = NULL;
231 XawMListChange(clist, clusters, 0, 0, False);
232}
233
234
235void addCluster(clu)
236char *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
299void selectCluster(clu)
300char *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
c9104dd4 313void getClusters()
314{
2ddfd00a 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
337void 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
361void 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
388void selectClusterMachine()
389{
390 char mach[64], **argv, *qargv[2];
c9104dd4 391 struct save_queue *sq;
392 int status;
393
394 sq = sq_create();
2ddfd00a 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);
c9104dd4 399 if (status)
400 com_err(program_name, status, " while fetching clusters");
2ddfd00a 401 free(qargv[0]);
402
403 suppress_updates = 1;
c9104dd4 404 while (sq_get_data(sq, &argv)) {
2ddfd00a 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
415void 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
460void 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
472void selectAllCluster()
473{
474 int i;
475
476 for (i = 0; i < nclusters; i++)
477 XawMListHighlight(clist, i);
478}
479
480
481void 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
493void clearMachines()
494{
495 nmachines = 0;
496 deselectMachines();
497 machines[0] = NULL;
498 XawMListChange(mlist, machines, 0, 0, False);
499}
500
501
502void addMachine(mach, type)
503char *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];
c9104dd4 545 }
2ddfd00a 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
565void selectMachine(mach, type)
566char *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 }
c9104dd4 576}
577
578void getMachines()
579{
2ddfd00a 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;
c9104dd4 601}
602
2ddfd00a 603
604void 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
631void 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
667void 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
703void 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
739void 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
753void 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
770void selectAllMachine()
771{
772 int i;
773
774 for (i = 0; i < nmachines; i++)
775 XawMListHighlight(mlist, i);
776}
777
778
779void 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
808void 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
837void 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
869void 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
888void 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
c9104dd4 907/* Called from within the toolkit */
908void localErrorHandler(s)
909String s;
910{
911 fprintf(stderr, "Moira X error: %s\n", s);
912 exit(1);
913}
914
915
916void mr_x_input()
917{
918 XEvent event;
919
920 XtAppNextEvent(_XtDefaultAppContext(), &event);
921 XtDispatchEvent(&event);
922}
923
924
925int MoiraQuery(query, argc, argv, callback, data)
926char *query;
927int argc;
928char **argv;
929int (*callback)();
930caddr_t data;
931{
932 int status;
933
2ddfd00a 934 MakeWatchCursor(appShell);
c9104dd4 935 status = mr_query(query, argc, argv, callback, data);
936 if (status != MR_ABORTED && status != MR_NOT_CONNECTED) {
2ddfd00a 937 MakeNormalCursor(appShell);
c9104dd4 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);
2ddfd00a 944 MakeNormalCursor(appShell);
c9104dd4 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();
2ddfd00a 952 MakeNormalCursor(appShell);
c9104dd4 953 return(MR_ABORTED);
954 }
955 status = mr_query(query, argc, argv, callback, data);
2ddfd00a 956 MakeNormalCursor(appShell);
c9104dd4 957 return(status);
958}
959
960
2ddfd00a 961MakeWatchCursor(w) {}
962MakeNormalCursor(w) {}
963
964static input_done_flag = 0;
965
966void inputDone()
967{
968 input_done_flag = 1;
969}
970
971
972PromptUser(msg, buf, bufsiz)
973char *msg, *buf;
974int bufsiz;
c9104dd4 975{
976 XawTextBlock tb;
c9104dd4 977 Arg args[2];
2ddfd00a 978 XEvent e;
979 char *data;
c9104dd4 980
c9104dd4 981 tb.firstPos = 0;
2ddfd00a 982 tb.ptr = msg;
983 tb.length = 0;
c9104dd4 984 tb.format = FMT8BIT;
2ddfd00a 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"));
c9104dd4 1007}
1008
2ddfd00a 1009
1010void Help(w, s, unused)
1011Widget w;
1012char *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
1035free_argv(argv)
1036char **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
1051int strmcmp(s1, s2)
1052char *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
1070char *substr(f, s)
1071char *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
1085void popup_error_hook(who, code, fmt, arg1, arg2, arg3, arg4, arg5)
1086char *who;
1087long code;
1088char *fmt;
1089caddr_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.212538 seconds and 5 git commands to generate.