]> andersk Git - moira.git/blob - clients/moira/cluster.c
sms -> moira
[moira.git] / clients / moira / cluster.c
1 #if (!defined(lint) && !defined(SABER))
2   static char rcsid_module_c[] = "$Header$";
3 #endif lint
4
5 /*      This is the file cluster.c for the MOIRA Client, which allows a nieve
6  *      user to quickly and easily maintain most parts of the MOIRA database.
7  *      It Contains: 
8  *      
9  *      Created:        4/22/88
10  *      By:             Chris D. Peterson
11  *
12  *      $Source$
13  *      $Author$
14  *      $Header$
15  *      
16  *      Copyright 1988 by the Massachusetts Institute of Technology.
17  *
18  *      For further information on copyright and distribution 
19  *      see the file mit-copyright.h
20  */
21
22 /* BTW: for anyone who cares MCD is short for Machine, Cluster, Data. */
23
24 #include <stdio.h>
25 #include <strings.h>
26 #include <moira.h>
27 #include <moira_site.h>
28 #include <menu.h>
29
30 #include "mit-copyright.h"
31 #include "defs.h"
32 #include "f_defs.h"
33 #include "globals.h"
34
35 #define MACHINE  0
36 #define CLUSTER  1
37 #define DATA     2
38 #define MAP      3
39
40 #define M_DEFAULT_TYPE     DEFAULT_NONE
41
42 #define C_DEFAULT_DESCRIPT DEFAULT_NONE
43 #define C_DEFAULT_LOCATION DEFAULT_NONE
44
45 #define CD_DEFAULT_LABEL   DEFAULT_NONE
46 #define CD_DEFAULT_DATA    DEFAULT_NONE
47
48 /* -------------------- Set Defaults -------------------- */
49
50 /*      Function Name: SetMachineDefaults
51  *      Description: sets machine defaults.
52  *      Arguments: info - an array to put the defaults into.
53  *                 name - Canonacalized name of the machine.
54  *      Returns: info - the array.
55  */
56
57 static char **
58 SetMachineDefaults(info, name)
59 char ** info, *name;
60 {
61     info[M_NAME] = Strsave(name);
62     info[M_TYPE] = Strsave(M_DEFAULT_TYPE);
63     info[M_MODBY] = info[M_MODTIME] = info[M_MODWITH] = info[M_END] = NULL;
64     return(info);
65 }
66
67 /*      Function Name: SetClusterDefaults
68  *      Description: sets Cluster defaults.
69  *      Arguments: info - an array to put the defaults into.
70  *                 name - name of the Cluster.
71  *      Returns: info - the array.
72  */
73
74 static char **
75 SetClusterDefaults(info, name)
76 char ** info, *name;
77 {
78     info[C_NAME] = Strsave(name);
79     info[C_DESCRIPT] = Strsave(C_DEFAULT_DESCRIPT);
80     info[C_LOCATION] = Strsave(C_DEFAULT_LOCATION);
81     info[C_MODBY] = info[C_MODTIME] = info[C_MODWITH] = info[C_END] = NULL;
82     return(info);
83 }
84
85 /* -------------------- General Functions -------------------- */
86
87 /*      Function Name: PrintMachInfo
88  *      Description: This function Prints out the Machine info in 
89  *                   a coherent form.
90  *      Arguments: info - array of information about a machine.
91  *      Returns: The name of the Machine
92  */
93
94 static char *
95 PrintMachInfo(info)
96 char ** info;
97 {
98     char buf[BUFSIZ];
99
100     Put_message("");
101     sprintf(buf, "Machine: %-30s Type: %s", info[M_NAME], info[M_TYPE]);
102     Put_message(buf);
103     sprintf(buf, MOD_FORMAT, info[M_MODBY], info[M_MODTIME], info[M_MODWITH]);
104     Put_message(buf);
105     return(info[M_NAME]);
106 }
107
108 /*      Function Name: PrintClusterInfo
109  *      Description: This function Prints out the cluster info 
110  *                   in a coherent form.
111  *      Arguments: info - array of information about a cluster.
112  *      Returns: The name of the cluster.
113  */
114
115 static char *
116 PrintClusterInfo(info)
117 char ** info;
118 {
119     char buf[BUFSIZ];
120
121     Put_message("");
122     sprintf(buf, "Cluster:     %s", info[C_NAME]);
123     Put_message(buf);
124     sprintf(buf, "Description: %s", info[C_DESCRIPT]);
125     Put_message(buf);
126     sprintf(buf, "Location:    %s", info[C_LOCATION]);
127     Put_message(buf);
128     sprintf(buf, MOD_FORMAT, info[C_MODBY], info[C_MODTIME], info[C_MODWITH]);
129     Put_message(buf);
130     return(info[C_NAME]);
131 }
132
133 /*      Function Name: PrintClusterData
134  *      Description: Prints the Data on a cluster
135  *      Arguments: info a pointer to the data array.
136  *      Returns: The name of the cluster.
137  */
138
139 static char *
140 PrintClusterData(info)
141 char ** info;
142 {
143     char buf[BUFSIZ];
144
145     Put_message("");
146     sprintf(buf, "Cluster: %-20s Label: %-15s Data: %s",
147             info[CD_NAME], info[CD_LABEL], info[CD_DATA]);
148     Put_message(buf);
149     return(info[CD_NAME]);
150 }
151
152 /*      Function Name: PrintMCMap
153  *      Description: Prints the data about a machine to cluster mapping.
154  *      Arguments: info a pointer to the data array.
155  *      Returns: none
156  */
157
158 static char *
159 PrintMCMap(info)
160 char ** info;
161 {
162     char buf[BUFSIZ];
163     sprintf(buf, "Cluster: %-30s Machine: %-20s",
164             info[MAP_CLUSTER], info[MAP_MACHINE]);
165     Put_message(buf);
166     return("");                 /* Used by QueryLoop(). */
167 }
168
169 /*      Function Name: GetMCInfo.
170  *      Description: This function stores info about a machine.
171  *                   type - type of data we are trying to retrieve.
172  *                   name1 - the name of argv[0] for the call.
173  *                   name2 - the name of argv[1] for the call.
174  *      Returns: the top element of a queue containing the data or NULL.
175  */
176
177 struct qelem *
178 GetMCInfo(type, name1, name2)
179 int type;
180 char * name1, *name2;
181 {
182
183     int stat;
184     struct qelem * elem = NULL;
185     char * args[2];
186
187     switch (type) {
188     case MACHINE:
189         if ( (stat = do_mr_query("get_machine", 1, &name1,
190                                   StoreInfo, (char *)&elem)) != 0) {
191             com_err(program_name, stat, " in get_machine.");
192             return(NULL);
193         }
194         break;
195     case CLUSTER:
196         if ( (stat = do_mr_query("get_cluster",  1, &name1,
197                                   StoreInfo, (char *)&elem)) != 0) {
198             com_err(program_name, stat, " in get_cluster.");
199             return(NULL);
200         }
201         break;
202     case MAP:
203         args[MAP_MACHINE] = name1;
204         args[MAP_CLUSTER] = name2;
205         if ( (stat = do_mr_query("get_machine_to_cluster_map", 2, args,
206                                   StoreInfo, (char *)&elem)) != 0) {
207             com_err(program_name, stat, " in get_machine_to_cluster_map.");
208             return(NULL);
209         }
210         break;
211     case DATA:
212         args[CD_NAME] = name1;
213         args[CD_LABEL] = name2;
214         if ( (stat = do_mr_query("get_cluster_data", 2, args,
215                                   StoreInfo, (char *)&elem)) != 0) {
216             com_err(program_name, stat, " in get_cluster_data.");
217             return(NULL);
218         }
219     }
220     return(QueueTop(elem));
221 }
222
223 /*      Function Name: AskMCDInfo.
224  *      Description: This function askes the user for information about a 
225  *                   machine and saves it into a structure.
226  *      Arguments: info - a pointer the information to ask about
227  *                 type - type of information - MACHINE
228  *                                              CLUSTER
229  *                                              DATA
230  *                 name - T/F : change the name of this type.
231  *      Returns: none.
232  */
233
234 char **
235 AskMCDInfo(info, type, name)
236 char ** info;
237 int type;
238 Bool name;
239 {
240     char temp_buf[BUFSIZ], *newname;
241
242     switch (type) {
243     case MACHINE:
244         sprintf(temp_buf, "Setting the information for the Machine %s.",
245                 info[M_NAME]);
246         break;
247     case CLUSTER:
248         sprintf(temp_buf, "Setting the information for the Cluster %s.",
249                 info[C_NAME]);
250         break;
251     case DATA:
252         sprintf(temp_buf, "Setting the Data for the Cluster %s.",
253                 info[CD_NAME]);
254         break;
255     }
256     Put_message(temp_buf);
257
258     if (name) {
259         switch (type) {
260         case MACHINE:
261             newname = Strsave(info[M_NAME]);
262             GetValueFromUser("The new name for this machine? ", &newname);
263             newname = canonicalize_hostname(newname);
264             break;
265         case CLUSTER:
266             newname = Strsave(info[C_NAME]);
267             GetValueFromUser("The new name for this cluster? ",
268                              &newname);
269             break;
270         default:
271             Put_message("Unknown type in AskMCDInfo, programmer botch");
272             return(NULL);
273         }
274     }
275
276     switch(type) {
277     case MACHINE:
278         GetTypeFromUser("Machine's Type", "mac_type", &info[M_TYPE]);
279         FreeAndClear(&info[M_MODTIME], TRUE);
280         FreeAndClear(&info[M_MODBY], TRUE);
281         FreeAndClear(&info[M_MODWITH], TRUE);
282         break;
283     case CLUSTER:
284         GetValueFromUser("Cluster's Description:", &info[C_DESCRIPT]);
285         GetValueFromUser("Cluster's Location:", &info[C_LOCATION]);
286         FreeAndClear(&info[C_MODTIME], TRUE);
287         FreeAndClear(&info[C_MODBY], TRUE);
288         FreeAndClear(&info[C_MODWITH], TRUE);
289         break;
290     case DATA:
291         GetValueFromUser("Label defining this data?", &info[CD_LABEL]);
292         GetValueFromUser("The data itself ? ", &info[CD_DATA]);
293         break;
294     }
295
296 /* 
297  * Slide the newname into the #2 slot, this screws up all future references 
298  * to this list.
299  */
300     if (name)                   
301         SlipInNewName(info, newname);
302
303     return(info);
304 }
305
306 /* -----------  Machine Menu ----------- */
307
308 /*      Function Name: ShowMachineInfo
309  *      Description: This function shows the information about a machine.
310  *      Arguments: argc, argv - the name of the machine in argv[1].
311  *      Returns: DM_NORMAL.
312  */
313
314 /* ARGSUSED */
315 int
316 ShowMachineInfo(argc, argv)
317 int argc;
318 char **argv;
319 {
320     struct qelem *top;
321     char *tmpname;
322
323     tmpname = canonicalize_hostname(strsave(argv[1]));
324     top = GetMCInfo(MACHINE, tmpname, (char *) NULL);
325     Loop(top, ( (void *) PrintMachInfo) );
326     FreeQueue(top);
327     return(DM_NORMAL);
328 }
329
330 /*      Function Name: AddMachine
331  *      Description: This function adds a new machine to the database.
332  *      Arguments: argc, argv - the name of the machine in argv[1].
333  *      Returns: DM_NORMAL.
334  */
335
336 /* ARGSUSED */
337 int
338 AddMachine(argc, argv)
339 int argc;
340 char **argv;
341 {
342     char **args, *info[MAX_ARGS_SIZE], *name;
343     int stat;
344
345     if (!ValidName(argv[1]))    /* Checks for wildcards. */
346         return(DM_NORMAL);
347 /* 
348  * Check to see if this machine already exists. 
349  */
350     name =  canonicalize_hostname(strsave(argv[1]));
351
352     if ( (stat = do_mr_query("get_machine", 1, &name, NullFunc, NULL)) == 0) {
353         Put_message("This machine already exists.");
354         free(name);
355         return(DM_NORMAL);
356     }
357     else if (stat != MR_NO_MATCH) {
358         com_err(program_name, stat, " in AddMachine.");
359         free(name);
360         return(DM_NORMAL);
361     }
362
363     args = AskMCDInfo(SetMachineDefaults(info, name), MACHINE, FALSE);
364
365 /*
366  * Actually create the new Machine.
367  */
368     
369     if ( (stat = do_mr_query("add_machine", CountArgs(args), 
370                               args, Scream, NULL)) != 0)
371         com_err(program_name, stat, " in AddMachine.");
372
373     FreeInfo(info);
374     free(name);
375     return(DM_NORMAL);
376 }
377
378 /*      Function Name: RealUpdateMachine
379  *      Description: Performs the actual update of the machine data.
380  *      Arguments: info - the information on the machine to update.
381  *                 junk - an UNUSED Boolean.
382  *      Returns: none.
383  */
384
385 /* ARGSUSED */
386 static void
387 RealUpdateMachine(info, junk)
388 char ** info;
389 Bool junk;
390 {
391     register int stat;
392     char ** args = AskMCDInfo(info, MACHINE, TRUE);
393     if ( (stat = do_mr_query("update_machine", CountArgs(args), 
394                               args, Scream, NULL)) != 0)
395         com_err(program_name, stat, " in UpdateMachine.");
396     else
397         Put_message("Machine sucessfully updated.");
398 }
399
400 /*      Function Name: UpdateMachine
401  *      Description: This function adds a new machine to the database.
402  *      Arguments: argc, argv - the name of the machine in argv[1].
403  *      Returns: DM_NORMAL.
404  */
405
406 /* ARGSUSED */
407 int
408 UpdateMachine(argc, argv)
409 int argc;
410 char **argv;
411 {
412     struct qelem *top;
413     char *tmpname;
414
415     tmpname = canonicalize_hostname(strsave(argv[1]));
416     top = GetMCInfo( MACHINE,  tmpname, (char *) NULL);
417     QueryLoop(top, NullPrint, RealUpdateMachine, "Update the machine");
418
419     FreeQueue(top);
420     free(tmpname);
421     return(DM_NORMAL);
422 }
423
424 /*      Function Name: CheckAndRemoveFromCluster
425  *      Description: This func tests to see if a machine is in a cluster.
426  *                   and if so then removes it
427  *      Arguments: name - name of the machine (already Canonocalized).
428  *                 ask_user- query the user before removing if from clusters?
429  *      Returns: MR_ERROR if machine left in a cluster, or mr_error.
430  */
431
432 int 
433 CheckAndRemoveFromCluster(name, ask_user)
434 char * name;
435 Bool ask_user;
436 {
437     register int stat, ret_value;
438     Bool delete_it;
439     char *args[10], temp_buf[BUFSIZ], *ptr;
440     struct qelem *top, *elem = NULL;
441     
442     ret_value = SUB_NORMAL;     /* initialize ret_value. */
443     args[0] = name;
444     args[1] = "*";
445     stat = do_mr_query("get_machine_to_cluster_map", 2, args, 
446                         StoreInfo, (char *)&elem);
447     if (stat && stat != MR_NO_MATCH) {
448         com_err(program_name, stat, " in get_machine_to_cluster_map.");
449         return(DM_NORMAL);
450     }
451     if (stat == MR_SUCCESS) {
452         elem = top = QueueTop(elem);
453         if (ask_user) {
454             sprintf(temp_buf, "%s is assigned to the following clusters.",
455                     name);
456             Put_message(temp_buf);
457             Loop(top, (void *) PrintMCMap);
458             ptr = "Remove this machine from ** ALL ** these clusters?";
459             if (YesNoQuestion(ptr, FALSE) == TRUE) /* may return -1. */
460                 delete_it = TRUE;
461             else {
462                 Put_message("Aborting...");
463                 FreeQueue(top);
464                 return(SUB_ERROR);
465             }
466         }
467         else
468             delete_it = TRUE;
469
470         if (delete_it) {
471             while (elem != NULL) {
472                 char **info = (char **) elem->q_data;
473                 if ( (stat = do_mr_query( "delete_machine_from_cluster",
474                                           2, info, Scream, NULL)) != 0) {
475                     ret_value = SUB_ERROR;
476                     com_err(program_name, stat, 
477                             " in delete_machine_from_cluster.");
478                     sprintf(temp_buf, 
479                             "Machine %s ** NOT ** removed from cluster %s.",
480                             info[MAP_MACHINE], info[MAP_CLUSTER]);
481                     Put_message(temp_buf);
482                 }
483                 elem = elem->q_forw;
484             }
485         }
486     }
487     return(ret_value);
488 }
489
490 /*      Function Name: RealDeleteMachine
491  *      Description: Actually Deletes the Machine.
492  *      Arguments: info - nescessary information stored as an array of char *'s
493  *                 one_machine - a boolean, true if there is only one item in
494  *                               the query.
495  *      Returns: none.
496  */
497
498 static void
499 RealDeleteMachine(info, one_machine)
500 char ** info;
501 Bool one_machine;
502 {
503     register int stat;
504     char temp_buf[BUFSIZ];
505
506     sprintf(temp_buf, "Are you sure you want to delete the machine %s (y/n)? ",
507             info[M_NAME]);
508     if(!one_machine || Confirm(temp_buf)) {
509         if (CheckAndRemoveFromCluster(info[M_NAME], TRUE) != SUB_ERROR) {
510             if ( (stat = do_mr_query("delete_machine", 1,
511                                       &info[M_NAME], Scream, NULL)) != 0) {
512                 com_err(program_name, stat, " in DeleteMachine.");
513                 sprintf(temp_buf, "%s ** NOT ** deleted.", 
514                         info[M_NAME]);
515                 Put_message(temp_buf);
516             }
517             else {
518                 sprintf(temp_buf, "%s successfully Deleted.", info[M_NAME]);
519                 Put_message(temp_buf);
520             }
521         }
522     }
523 }
524
525 /*      Function Name: DeleteMachine
526  *      Description: This function removes a machine from the data base.
527  *      Arguments: argc, argv - the machines name int argv[1].
528  *      Returns: DM_NORMAL.
529  */
530
531 /* Perhaps we should remove the cluster if it has no machine now. */
532
533 /* ARGSUSED */
534 int
535 DeleteMachine(argc, argv)
536 int argc;
537 char **argv;
538 {
539     struct qelem *top;
540     char *tmpname;
541
542     tmpname = canonicalize_hostname(strsave(argv[1]));
543     top = GetMCInfo(MACHINE, tmpname, (char *) NULL);
544     QueryLoop(top, PrintMachInfo, RealDeleteMachine, "Delete the machine");
545     FreeQueue(top);
546     free(tmpname);
547     return(DM_NORMAL);
548 }
549
550 /*      Function Name: AddMachineToCluster
551  *      Description: This function adds a machine to a cluster
552  *      Arguments: argc, argv - The machine name is argv[1].
553  *                              The cluster name in argv[2].
554  *      Returns: DM_NORMAL.
555  */
556
557 /* ARGSUSED */
558 int 
559 AddMachineToCluster(argc, argv)
560 int argc;
561 char ** argv;
562 {
563     int stat;
564     char *machine, *cluster, temp_buf[BUFSIZ], *args[10];
565     Bool add_it, one_machine, one_cluster;
566     struct qelem * melem, *mtop, *celem, *ctop;
567
568     machine = canonicalize_hostname(strsave(argv[1]));
569     cluster = argv[2];
570
571     celem = ctop = GetMCInfo(CLUSTER,  cluster, (char *) NULL);
572     melem = mtop = GetMCInfo(MACHINE,  machine, (char *) NULL);
573     free(machine);
574
575     one_machine = (QueueCount(mtop) == 1);
576     one_cluster = (QueueCount(ctop) == 1);
577
578     /* No good way to use QueryLoop() here, sigh */
579
580     while (melem != NULL) {
581         char ** minfo = (char **) melem->q_data;
582         while (celem != NULL) {
583             char ** cinfo = (char **) celem->q_data;
584             if (one_machine && one_cluster) 
585                 add_it = TRUE;
586             else {
587                 sprintf(temp_buf,"Add machine %s to cluster %s (y/n/q) ?",
588                         minfo[M_NAME], cinfo[C_NAME]);
589                 switch (YesNoQuitQuestion(temp_buf, FALSE)) {
590                 case TRUE:
591                     add_it = TRUE;
592                     break;
593                 case FALSE:
594                     add_it = FALSE;
595                     break;
596                 default:
597                     Put_message("Aborting...");
598                     FreeQueue(ctop);
599                     FreeQueue(mtop);
600                     return(DM_NORMAL);
601                 }
602             }
603             if (add_it) {
604                 args[0] = minfo[M_NAME];
605                 args[1] = cinfo[C_NAME];
606                 stat = do_mr_query("add_machine_to_cluster", 2, args,
607                                     Scream, NULL);
608                 switch (stat) {
609                 case MR_SUCCESS:
610                     break;
611                 case MR_EXISTS:
612                     sprintf(temp_buf, "%s is already in cluster %s",
613                             minfo[M_NAME], cinfo[C_NAME]);
614                     Put_message(temp_buf);
615                     break;
616                 default:
617                     com_err(program_name, stat, " in AddMachineToCluster.");
618                     break;
619                 }
620             }
621             celem = celem->q_forw;
622         }
623         celem = ctop;           /* reset cluster element. */
624         melem = melem->q_forw;
625     }
626     FreeQueue(ctop);
627     FreeQueue(mtop);                
628     return(DM_NORMAL);
629 }
630
631 /*      Function Name: RealRemoveMachineFromCluster
632  *      Description: This function actually removes the machine from its 
633  *                   cluster.
634  *      Arguments: info - all information nescessary to perform the removal.
635  *                 one_map - True if there is only one case, and we should
636  *                           confirm.
637  *      Returns: none.
638  */
639
640 static void
641 RealRemoveMachineFromCluster(info, one_map)
642 char ** info;
643 Bool one_map;
644 {
645     char temp_buf[BUFSIZ];
646     register int stat;
647
648     sprintf(temp_buf, "Remove %s from the cluster %s", 
649             info[MAP_MACHINE], info[MAP_CLUSTER]);
650     if (!one_map || Confirm(temp_buf)) {
651         if ( (stat = do_mr_query("delete_machine_from_cluster", 2, 
652                                   info, Scream, NULL)) != 0 )
653             com_err(program_name, stat, " in delete_machine_from_cluster");
654         else {
655             sprintf(temp_buf, "%s has been removed from the cluster %s.",
656                     info[MAP_MACHINE], info[MAP_CLUSTER]);
657             Put_message(temp_buf);
658         }
659     }
660     else
661         Put_message("Machine not removed.");
662 }
663
664 /*      Function Name: RemoveMachineFromCluster
665  *      Description: Removes this machine form a specific cluster.
666  *      Arguments: argc, argv - Name of machine in argv[1].
667  *                              Name of cluster in argv[2].
668  *      Returns: none.
669  */
670
671 /* ARGSUSED */
672 int
673 RemoveMachineFromCluster(argc, argv)
674 int argc;
675 char ** argv;
676 {
677     struct qelem *elem = NULL;
678     char buf[BUFSIZ], * args[10];
679     register int stat;
680
681     args[MAP_MACHINE] = canonicalize_hostname(strsave(argv[1]));
682     args[MAP_CLUSTER] = argv[2];
683     args[MAP_END] = NULL;
684
685     stat = do_mr_query("get_machine_to_cluster_map", CountArgs(args), args,
686                         StoreInfo, (char *)&elem);
687     if (stat == MR_NO_MATCH) {
688         sprintf(buf, "The machine %s is not is the cluster %s.",
689                 args[MAP_MACHINE], args[MAP_CLUSTER]);
690         Put_message(buf);
691         free(args[MAP_MACHINE]);
692         return(DM_NORMAL);
693     }
694     if (stat != MR_SUCCESS)
695         com_err(program_name, stat, " in delete_machine_from_cluster");
696
697     elem = QueueTop(elem);
698     QueryLoop(elem, PrintMCMap, RealRemoveMachineFromCluster,
699               "Remove this machine from this cluster");
700
701     FreeQueue(elem);
702     free(args[MAP_MACHINE]);
703     return(DM_NORMAL);
704 }
705
706 /* ---------- Cluster Menu -------- */
707
708 /*      Function Name: ShowClusterInfo
709  *      Description: Gets information about a cluser given its name.
710  *      Arguments: argc, argc - the name of the cluster in in argv[1].
711  *      Returns: DM_NORMAL.
712  */
713
714 /* ARGSUSED */
715 int
716 ShowClusterInfo(argc, argv)
717 int argc;
718 char ** argv;
719 {
720     struct qelem *top;
721
722     top = GetMCInfo(CLUSTER, argv[1], (char *) NULL);
723     Loop(top, (void *) PrintClusterInfo);
724     FreeQueue(top);
725     return(DM_NORMAL);
726 }
727
728 /*      Function Name: AddCluster
729  *      Description: Creates a new cluster.
730  *      Arguments: argc, argv - the name of the new cluster is argv[1].
731  *      Returns: DM_NORMAL.
732  */
733
734 /* ARGSUSED */
735 int
736 AddCluster(argc, argv)
737 int argc;
738 char ** argv;
739 {
740     char **args, *info[MAX_ARGS_SIZE], *name = argv[1];
741     int stat;
742 /* 
743  * Check to see if this cluster already exists. 
744  */
745     if (!ValidName(name))
746         return(DM_NORMAL);
747
748     if ( (stat = do_mr_query("get_cluster", 1, &name, 
749                               NullFunc, NULL)) == MR_SUCCESS) {
750         Put_message("This cluster already exists.");
751         return(DM_NORMAL);
752     }
753     else if (stat != MR_NO_MATCH) {
754         com_err(program_name, stat, " in AddCluster.");
755         return(DM_NORMAL);
756     }
757     args = AskMCDInfo(SetClusterDefaults(info, name), CLUSTER, FALSE);
758 /*
759  * Actually create the new Cluster.
760  */
761     if ( (stat = do_mr_query("add_cluster", CountArgs(args), 
762                               args, Scream, NULL)) != 0)
763         com_err(program_name, stat, " in AddCluster.");
764
765     FreeInfo(info);
766     return(DM_NORMAL);
767 }
768
769 /*      Function Name: RealUpdateCluster
770  *      Description: This function actually performs the cluster update.
771  *      Arguments: info - all information nesc. for updating the cluster.
772  *                 junk - an UNUSED boolean.
773  *      Returns: none.
774  */
775
776 /* ARGSUSED */
777 static void
778 RealUpdateCluster(info, junk)
779 char ** info;
780 Bool junk;
781 {
782     register int stat;
783     char ** args = AskMCDInfo(info, CLUSTER, TRUE);
784     if ( (stat = do_mr_query("update_cluster", CountArgs(args), 
785                               args, Scream, NULL)) != 0)
786         com_err(program_name, stat, " in UpdateCluster.");
787     else
788         Put_message("Cluster successfully updated.");
789 }
790
791 /*      Function Name: UpdateCluster
792  *      Description: This Function Updates a cluster
793  *      Arguments: name of the cluster in argv[1].
794  *      Returns: DM_NORMAL.
795  */
796
797 /* ARGSUSED */
798 int 
799 UpdateCluster(argc, argv)
800 int argc;
801 char ** argv;
802 {
803     struct qelem *top;    
804     top = GetMCInfo( CLUSTER, argv[1], (char *) NULL );
805     QueryLoop(top, NullPrint, RealUpdateCluster, "Update the cluster");
806
807     FreeQueue(top);
808     return(DM_NORMAL);
809 }
810
811 /*      Function Name: CheckAndRemoveMachine
812  *      Description: This function checks and removes all machines from a
813  *                   cluster.
814  *      Arguments: name - name of the cluster.
815  *                 ask_first - if TRUE, then we will query the user, before
816  *                             deletion.
817  *      Returns: SUB_ERROR if all machines not removed.
818  */
819
820 int
821 CheckAndRemoveMachines(name, ask_first)
822 char * name;
823 Bool ask_first;
824 {
825     register int stat, ret_value;
826     Bool delete_it;
827     char *args[10], temp_buf[BUFSIZ], *ptr;
828     struct qelem *top, *elem = NULL;
829     
830     ret_value = SUB_NORMAL;
831     args[MAP_MACHINE] = "*";
832     args[MAP_CLUSTER] = name;
833     stat = do_mr_query("get_machine_to_cluster_map", 2, args, 
834                         StoreInfo, (char *)&elem);
835     if (stat && stat != MR_NO_MATCH) {
836         com_err(program_name, stat, " in get_machine_to_cluster_map.");
837         return(DM_NORMAL);
838     }
839     if (stat == 0) {
840         elem = top = QueueTop(elem);
841         if (ask_first) {
842             sprintf(temp_buf,
843                     "The cluster %s has the following machines in it:",
844                     name);
845             Put_message(temp_buf);
846             while (elem != NULL) {
847                 char **info = (char **) elem->q_data;
848                 Print(1, &info[MAP_MACHINE], (char *) NULL);
849                 elem = elem->q_forw;
850             }
851             ptr = "Remove ** ALL ** these machines from this cluster?";
852
853             if (YesNoQuestion(ptr, FALSE) == TRUE) /* may return -1. */
854                 delete_it = TRUE;
855             else {
856                 Put_message("Aborting...");
857                 FreeQueue(top);
858                 return(SUB_ERROR);
859             }
860         }
861         else
862             delete_it = TRUE;
863
864         if (delete_it) {
865             elem = top;
866             while (elem != 0) {
867                 char **info = (char **) elem->q_data;
868                 if ( (stat = do_mr_query("delete_machine_from_cluster",
869                                           2, info, Scream, NULL)) != 0) {
870                     ret_value = SUB_ERROR;
871                     com_err(program_name, stat, 
872                             " in delete_machine_from_cluster.");
873                     sprintf(temp_buf, 
874                             "Machine %s ** NOT ** removed from cluster %s.",
875                             info[MAP_MACHINE], info[MAP_CLUSTER]);
876                     Put_message(temp_buf);
877                 }
878                 elem = elem->q_forw;
879             }
880         }
881     }
882     return(ret_value);
883 }
884
885 /*      Function Name: RealDeleteCluster
886  *      Description: Actually performs the cluster deletion.
887  *      Arguments: info - all information about this cluster.
888  *                 one_cluster - If true then there was only one cluster in
889  *                               the queue, and we should confirm.
890  *      Returns: none.
891  */
892
893 static void
894 RealDeleteCluster(info, one_cluster)
895 char ** info;
896 Bool one_cluster;
897 {
898     register int stat;
899     char temp_buf[BUFSIZ];
900     
901     sprintf(temp_buf, 
902             "Are you sure the you want to delete the cluster %s (y/n) ?", 
903             info[C_NAME]);
904     if (!one_cluster || Confirm(temp_buf)) {
905         if (CheckAndRemoveMachines(info[C_NAME], TRUE) != SUB_ERROR) {
906             if ( (stat = do_mr_query("delete_cluster", 1,
907                                       &info[C_NAME], Scream, NULL)) != 0) {
908                 com_err(program_name, stat, " in delete_cluster.");
909                 sprintf(temp_buf, "Cluster %s ** NOT ** deleted.", 
910                         info[C_NAME]);
911                 Put_message(temp_buf);
912             }
913             else {
914                 sprintf(temp_buf, "cluster %s sucesfully deleted.", 
915                         info[C_NAME]);
916                 Put_message(temp_buf);
917             }
918         }
919     }
920 }
921
922 /*      Function Name: DeleteCluster
923  *      Description: This function removes a cluster from the database.
924  *      Arguments: argc, argv - the name of the cluster is stored in argv[1].
925  *      Returns: DM_NORMAL.
926  */
927
928 /* ARGSUSED */
929 int
930 DeleteCluster(argc, argv)
931 int argc;
932 char ** argv;
933 {
934     struct qelem *top;
935
936     top = GetMCInfo( CLUSTER, argv[1], (char *) NULL );
937     QueryLoop(top, PrintClusterInfo, RealDeleteCluster, "Delete the cluster");
938
939     FreeQueue(top);
940     return(DM_NORMAL);
941 }
942     
943 /* ----------- Cluster Data Menu -------------- */
944
945 /*      Function Name: ShowClusterData
946  *      Description: This function shows the services for one cluster.
947  *      Arguments: argc, argv - The name of the cluster is argv[1].
948  *                              The label of the data in argv[2].
949  *      Returns: DM_NORMAL.
950  */
951
952 /* ARGSUSED */
953 int
954 ShowClusterData(argc, argv)
955 int argc; 
956 char ** argv; 
957
958     struct qelem *elem, *top;
959     char **info;
960
961     top = elem = GetMCInfo(DATA, argv[1], argv[2]);
962     while (elem != NULL) {
963         info = (char **) elem->q_data;
964         PrintClusterData(info);
965         elem = elem->q_forw;
966     }
967     FreeQueue(top);
968     return(DM_NORMAL);
969 }
970
971 /*      Function Name: AddClusterData
972  *      Description: This function adds some data to the cluster.
973  *      Arguments: argv, argc:   argv[1] - the name of the cluster.
974  *                               argv[2] - the label of the data.
975  *                               argv[3] - the data.
976  *      Returns: DM_NORMAL.
977  */
978
979 /* ARGSUSED */
980 int
981 AddClusterData(argc, argv)
982 int argc; 
983 char ** argv; 
984
985     int stat;
986
987     if( (stat = do_mr_query("add_cluster_data", 3, argv + 1,
988                              Scream, (char *) NULL)) != 0)
989         com_err(program_name, stat, " in AddClusterData.");
990
991 }
992
993 /*      Function Name: RealRemoveClusterData
994  *      Description: actually removes the cluster data.
995  *      Arguments: info - all info necessary to remove the cluster, in an array
996  *                        of strings.
997  *                 one_item - if true then the queue has only one elem and we
998  *                            should confirm.
999  *      Returns: none.
1000  */
1001
1002 static void
1003 RealRemoveClusterData(info, one_item)
1004 char ** info;
1005 Bool one_item;
1006 {
1007     register int stat;
1008     char * temp_ptr;
1009
1010     Put_message(" ");
1011     temp_ptr = "Are you sure that you want to remove this cluster data (y/n) ?";
1012     PrintClusterData(info);
1013     if (!one_item || Confirm(temp_ptr)) {
1014         if( (stat = do_mr_query("delete_cluster_data", 3, info,
1015                                  Scream, (char *) NULL)) != 0) {
1016             com_err(program_name, stat, " in DeleteClusterData.");
1017             Put_message("Data not removed.");
1018         }
1019         else
1020             Put_message("Removal sucessful.");
1021     }
1022 }
1023
1024 /*      Function Name: RemoveClusterData
1025  *      Description: This function removes data on a given cluster.
1026  *      Arguments: argv, argc:   argv[1] - the name of the cluster.
1027  *                               argv[2] - the label of the data.
1028  *                               argv[3] - the data.
1029  *      Returns: DM_NORMAL.
1030  */
1031
1032 /* ARGSUSED */
1033 int 
1034 RemoveClusterData(argc, argv)
1035 int argc; 
1036 char ** argv; 
1037 {
1038     struct qelem *top;
1039
1040     top = GetMCInfo(DATA, argv[1], argv[2]);
1041     QueryLoop(top, PrintClusterData, RealRemoveClusterData, 
1042               "Remove data from cluster");
1043
1044     FreeQueue(top);
1045     return(DM_NORMAL);
1046 }
1047
1048 /*      Function Name: MachineToClusterMap
1049  *      Description: This Retrieves the mapping between machine and cluster
1050  *      Arguments: argc, argv - argv[1] -> machine name or wildcard.
1051  *                              argv[2] -> cluster name or wildcard.
1052  *      Returns: none.
1053  */
1054
1055 /* ARGSUSED */
1056 int 
1057 MachineToClusterMap(argc,argv)
1058 int argc;
1059 char **argv;
1060 {
1061     struct qelem *elem, *top;
1062     char *tmpname;
1063
1064     tmpname = canonicalize_hostname(strsave(argv[1]));
1065     top = elem = GetMCInfo(MAP, tmpname, argv[2]);
1066   
1067     Put_message("");            /* blank line on screen */
1068     while (elem != NULL) {
1069         char ** info = (char **) elem->q_data;
1070         PrintMCMap(info);
1071         elem = elem->q_forw;
1072     }
1073
1074     FreeQueue(top);
1075     free(tmpname);
1076     return(DM_NORMAL);
1077 }
This page took 0.118796 seconds and 5 git commands to generate.