]> andersk Git - moira.git/blob - clients/moira/cluster.c
catch ^C's, clean up error messages, warn about hostname canonicalization
[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             if (stat == MR_NO_MATCH) {
192                 char buf[128];
193                 sprintf(buf, "Machine '%s' is not in the database.", name1);
194                 Put_message(buf);
195             } else
196               com_err(program_name, stat, " in get_machine.");
197             return(NULL);
198         }
199         break;
200     case CLUSTER:
201         if ( (stat = do_mr_query("get_cluster",  1, &name1,
202                                   StoreInfo, (char *)&elem)) != 0) {
203             com_err(program_name, stat, " in get_cluster.");
204             return(NULL);
205         }
206         break;
207     case MAP:
208         args[MAP_MACHINE] = name1;
209         args[MAP_CLUSTER] = name2;
210         if ( (stat = do_mr_query("get_machine_to_cluster_map", 2, args,
211                                   StoreInfo, (char *)&elem)) != 0) {
212             com_err(program_name, stat, " in get_machine_to_cluster_map.");
213             return(NULL);
214         }
215         break;
216     case DATA:
217         args[CD_NAME] = name1;
218         args[CD_LABEL] = name2;
219         if ( (stat = do_mr_query("get_cluster_data", 2, args,
220                                   StoreInfo, (char *)&elem)) != 0) {
221             com_err(program_name, stat, " in get_cluster_data.");
222             return(NULL);
223         }
224     }
225     return(QueueTop(elem));
226 }
227
228 /*      Function Name: AskMCDInfo.
229  *      Description: This function askes the user for information about a 
230  *                   machine and saves it into a structure.
231  *      Arguments: info - a pointer the information to ask about
232  *                 type - type of information - MACHINE
233  *                                              CLUSTER
234  *                                              DATA
235  *                 name - T/F : change the name of this type.
236  *      Returns: none.
237  */
238
239 char **
240 AskMCDInfo(info, type, name)
241 char ** info;
242 int type;
243 Bool name;
244 {
245     char temp_buf[BUFSIZ], *newname, *oldnewname;
246
247     switch (type) {
248     case MACHINE:
249         sprintf(temp_buf, "Setting the information for the Machine %s.",
250                 info[M_NAME]);
251         break;
252     case CLUSTER:
253         sprintf(temp_buf, "Setting the information for the Cluster %s.",
254                 info[C_NAME]);
255         break;
256     case DATA:
257         sprintf(temp_buf, "Setting the Data for the Cluster %s.",
258                 info[CD_NAME]);
259         break;
260     }
261     Put_message(temp_buf);
262
263     if (name) {
264         switch (type) {
265         case MACHINE:
266             newname = Strsave(info[M_NAME]);
267             if (GetValueFromUser("The new name for this machine? ", &newname) ==
268                 SUB_ERROR)
269               return(NULL);
270             oldnewname = Strsave(newname);
271             newname = canonicalize_hostname(newname);
272             if (strcasecmp(newname, oldnewname)) {
273                 sprintf(temp_buf, "Warning: '%s' canonicalized to '%s'\n",
274                         oldnewname, newname);
275                 Put_message(temp_buf);
276             }
277             free(oldnewname);
278             break;
279         case CLUSTER:
280             newname = Strsave(info[C_NAME]);
281             if (GetValueFromUser("The new name for this cluster? ",
282                                  &newname) == SUB_ERROR)
283               return(NULL);
284             break;
285         default:
286             Put_message("Unknown type in AskMCDInfo, programmer botch");
287             return(NULL);
288         }
289     }
290
291     switch(type) {
292     case MACHINE:
293         if (GetTypeFromUser("Machine's Type", "mac_type", &info[M_TYPE]) ==
294             SUB_ERROR)
295           return(NULL);
296         FreeAndClear(&info[M_MODTIME], TRUE);
297         FreeAndClear(&info[M_MODBY], TRUE);
298         FreeAndClear(&info[M_MODWITH], TRUE);
299         break;
300     case CLUSTER:
301         if (GetValueFromUser("Cluster's Description:", &info[C_DESCRIPT]) ==
302             SUB_ERROR)
303           return(NULL);
304         if (GetValueFromUser("Cluster's Location:", &info[C_LOCATION]) ==
305             SUB_ERROR)
306           return(NULL);
307         FreeAndClear(&info[C_MODTIME], TRUE);
308         FreeAndClear(&info[C_MODBY], TRUE);
309         FreeAndClear(&info[C_MODWITH], TRUE);
310         break;
311     case DATA:
312         if (GetValueFromUser("Label defining this data?", &info[CD_LABEL]) ==
313             SUB_ERROR)
314           return(NULL);
315         if (GetValueFromUser("The data itself ? ", &info[CD_DATA]) == SUB_ERROR)
316           return(NULL);
317         break;
318     }
319
320 /* 
321  * Slide the newname into the #2 slot, this screws up all future references 
322  * to this list.
323  */
324     if (name)                   
325         SlipInNewName(info, newname);
326
327     return(info);
328 }
329
330 /* -----------  Machine Menu ----------- */
331
332 /*      Function Name: ShowMachineInfo
333  *      Description: This function shows the information about a machine.
334  *      Arguments: argc, argv - the name of the machine in argv[1].
335  *      Returns: DM_NORMAL.
336  */
337
338 /* ARGSUSED */
339 int
340 ShowMachineInfo(argc, argv)
341 int argc;
342 char **argv;
343 {
344     struct qelem *top;
345     char *tmpname;
346
347     tmpname = canonicalize_hostname(strsave(argv[1]));
348     top = GetMCInfo(MACHINE, tmpname, (char *) NULL);
349     Loop(top, ( (void *) PrintMachInfo) );
350     FreeQueue(top);
351     return(DM_NORMAL);
352 }
353
354 /*      Function Name: AddMachine
355  *      Description: This function adds a new machine to the database.
356  *      Arguments: argc, argv - the name of the machine in argv[1].
357  *      Returns: DM_NORMAL.
358  */
359
360 /* ARGSUSED */
361 int
362 AddMachine(argc, argv)
363 int argc;
364 char **argv;
365 {
366     char **args, *info[MAX_ARGS_SIZE], *name, buf[256];
367     int stat;
368
369     if (!ValidName(argv[1]))    /* Checks for wildcards. */
370         return(DM_NORMAL);
371 /* 
372  * Check to see if this machine already exists. 
373  */
374     name =  canonicalize_hostname(strsave(argv[1]));
375
376     if ( (stat = do_mr_query("get_machine", 1, &name, NullFunc, NULL)) == 0) {
377         sprintf(buf, "The machine '%s' already exists.", name);
378         Put_message(buf);
379         free(name);
380         return(DM_NORMAL);
381     }
382     else if (stat != MR_NO_MATCH) {
383         com_err(program_name, stat,
384                 " while checking machine '%s' in AddMachine.", name);
385         free(name);
386         return(DM_NORMAL);
387     }
388
389     if ((args = AskMCDInfo(SetMachineDefaults(info, name), MACHINE, FALSE)) ==
390         NULL) {
391         Put_message("Aborted.");
392         return(DM_NORMAL);
393     }
394
395 /*
396  * Actually create the new Machine.
397  */
398     
399     if ( (stat = do_mr_query("add_machine", CountArgs(args), 
400                               args, Scream, NULL)) != 0)
401         com_err(program_name, stat, " in AddMachine.");
402
403     FreeInfo(info);
404     free(name);
405     return(DM_NORMAL);
406 }
407
408 /*      Function Name: RealUpdateMachine
409  *      Description: Performs the actual update of the machine data.
410  *      Arguments: info - the information on the machine to update.
411  *                 junk - an UNUSED Boolean.
412  *      Returns: none.
413  */
414
415 /* ARGSUSED */
416 static void
417 RealUpdateMachine(info, junk)
418 char ** info;
419 Bool junk;
420 {
421     register int stat;
422     char ** args = AskMCDInfo(info, MACHINE, TRUE);
423     if (args == NULL) {
424         Put_message("Aborted.");
425         return;
426     }
427     if ( (stat = do_mr_query("update_machine", CountArgs(args), 
428                               args, Scream, NULL)) != 0)
429         com_err(program_name, stat, " in UpdateMachine.");
430     else
431         Put_message("Machine sucessfully updated.");
432 }
433
434 /*      Function Name: UpdateMachine
435  *      Description: This function adds a new machine to the database.
436  *      Arguments: argc, argv - the name of the machine in argv[1].
437  *      Returns: DM_NORMAL.
438  */
439
440 /* ARGSUSED */
441 int
442 UpdateMachine(argc, argv)
443 int argc;
444 char **argv;
445 {
446     struct qelem *top;
447     char *tmpname;
448
449     tmpname = canonicalize_hostname(strsave(argv[1]));
450     top = GetMCInfo( MACHINE,  tmpname, (char *) NULL);
451     QueryLoop(top, NullPrint, RealUpdateMachine, "Update the machine");
452
453     FreeQueue(top);
454     free(tmpname);
455     return(DM_NORMAL);
456 }
457
458 /*      Function Name: CheckAndRemoveFromCluster
459  *      Description: This func tests to see if a machine is in a cluster.
460  *                   and if so then removes it
461  *      Arguments: name - name of the machine (already Canonocalized).
462  *                 ask_user- query the user before removing if from clusters?
463  *      Returns: MR_ERROR if machine left in a cluster, or mr_error.
464  */
465
466 int 
467 CheckAndRemoveFromCluster(name, ask_user)
468 char * name;
469 Bool ask_user;
470 {
471     register int stat, ret_value;
472     Bool delete_it;
473     char *args[10], temp_buf[BUFSIZ], *ptr;
474     struct qelem *top, *elem = NULL;
475     
476     ret_value = SUB_NORMAL;     /* initialize ret_value. */
477     args[0] = name;
478     args[1] = "*";
479     stat = do_mr_query("get_machine_to_cluster_map", 2, args, 
480                         StoreInfo, (char *)&elem);
481     if (stat && stat != MR_NO_MATCH) {
482         com_err(program_name, stat, " in get_machine_to_cluster_map.");
483         return(DM_NORMAL);
484     }
485     if (stat == MR_SUCCESS) {
486         elem = top = QueueTop(elem);
487         if (ask_user) {
488             sprintf(temp_buf, "%s is assigned to the following clusters.",
489                     name);
490             Put_message(temp_buf);
491             Loop(top, (void *) PrintMCMap);
492             ptr = "Remove this machine from ** ALL ** these clusters?";
493             if (YesNoQuestion(ptr, FALSE) == TRUE) /* may return -1. */
494                 delete_it = TRUE;
495             else {
496                 Put_message("Aborting...");
497                 FreeQueue(top);
498                 return(SUB_ERROR);
499             }
500         }
501         else
502             delete_it = TRUE;
503
504         if (delete_it) {
505             while (elem != NULL) {
506                 char **info = (char **) elem->q_data;
507                 if ( (stat = do_mr_query( "delete_machine_from_cluster",
508                                           2, info, Scream, NULL)) != 0) {
509                     ret_value = SUB_ERROR;
510                     com_err(program_name, stat, 
511                             " in delete_machine_from_cluster.");
512                     sprintf(temp_buf, 
513                             "Machine %s ** NOT ** removed from cluster %s.",
514                             info[MAP_MACHINE], info[MAP_CLUSTER]);
515                     Put_message(temp_buf);
516                 }
517                 elem = elem->q_forw;
518             }
519         }
520     }
521     return(ret_value);
522 }
523
524 /*      Function Name: RealDeleteMachine
525  *      Description: Actually Deletes the Machine.
526  *      Arguments: info - nescessary information stored as an array of char *'s
527  *                 one_machine - a boolean, true if there is only one item in
528  *                               the query.
529  *      Returns: none.
530  */
531
532 static void
533 RealDeleteMachine(info, one_machine)
534 char ** info;
535 Bool one_machine;
536 {
537     register int stat;
538     char temp_buf[BUFSIZ];
539
540     sprintf(temp_buf, "Are you sure you want to delete the machine %s (y/n)? ",
541             info[M_NAME]);
542     if(!one_machine || Confirm(temp_buf)) {
543         if (CheckAndRemoveFromCluster(info[M_NAME], TRUE) != SUB_ERROR) {
544             if ( (stat = do_mr_query("delete_machine", 1,
545                                       &info[M_NAME], Scream, NULL)) != 0) {
546                 com_err(program_name, stat, " in DeleteMachine.");
547                 sprintf(temp_buf, "%s ** NOT ** deleted.", 
548                         info[M_NAME]);
549                 Put_message(temp_buf);
550             }
551             else {
552                 sprintf(temp_buf, "%s successfully Deleted.", info[M_NAME]);
553                 Put_message(temp_buf);
554             }
555         }
556     }
557 }
558
559 /*      Function Name: DeleteMachine
560  *      Description: This function removes a machine from the data base.
561  *      Arguments: argc, argv - the machines name int argv[1].
562  *      Returns: DM_NORMAL.
563  */
564
565 /* Perhaps we should remove the cluster if it has no machine now. */
566
567 /* ARGSUSED */
568 int
569 DeleteMachine(argc, argv)
570 int argc;
571 char **argv;
572 {
573     struct qelem *top;
574     char *tmpname;
575
576     tmpname = canonicalize_hostname(strsave(argv[1]));
577     top = GetMCInfo(MACHINE, tmpname, (char *) NULL);
578     QueryLoop(top, PrintMachInfo, RealDeleteMachine, "Delete the machine");
579     FreeQueue(top);
580     free(tmpname);
581     return(DM_NORMAL);
582 }
583
584 /*      Function Name: AddMachineToCluster
585  *      Description: This function adds a machine to a cluster
586  *      Arguments: argc, argv - The machine name is argv[1].
587  *                              The cluster name in argv[2].
588  *      Returns: DM_NORMAL.
589  */
590
591 /* ARGSUSED */
592 int 
593 AddMachineToCluster(argc, argv)
594 int argc;
595 char ** argv;
596 {
597     int stat;
598     char *machine, *cluster, temp_buf[BUFSIZ], *args[10];
599     Bool add_it, one_machine, one_cluster;
600     struct qelem * melem, *mtop, *celem, *ctop;
601
602     machine = canonicalize_hostname(strsave(argv[1]));
603     if (strcasecmp(machine, argv[1])) {
604         sprintf(temp_buf, "Warning: '%s' canonicalized to '%s'.",
605                 argv[1], machine);
606         Put_message(temp_buf);
607     }
608     cluster = argv[2];
609
610     celem = ctop = GetMCInfo(CLUSTER,  cluster, (char *) NULL);
611     melem = mtop = GetMCInfo(MACHINE,  machine, (char *) NULL);
612     free(machine);
613
614     one_machine = (QueueCount(mtop) == 1);
615     one_cluster = (QueueCount(ctop) == 1);
616
617     /* No good way to use QueryLoop() here, sigh */
618
619     while (melem != NULL) {
620         char ** minfo = (char **) melem->q_data;
621         while (celem != NULL) {
622             char ** cinfo = (char **) celem->q_data;
623             if (one_machine && one_cluster) 
624                 add_it = TRUE;
625             else {
626                 sprintf(temp_buf,"Add machine %s to cluster %s (y/n/q) ?",
627                         minfo[M_NAME], cinfo[C_NAME]);
628                 switch (YesNoQuitQuestion(temp_buf, FALSE)) {
629                 case TRUE:
630                     add_it = TRUE;
631                     break;
632                 case FALSE:
633                     add_it = FALSE;
634                     break;
635                 default:
636                     Put_message("Aborting...");
637                     FreeQueue(ctop);
638                     FreeQueue(mtop);
639                     return(DM_NORMAL);
640                 }
641             }
642             if (add_it) {
643                 args[0] = minfo[M_NAME];
644                 args[1] = cinfo[C_NAME];
645                 stat = do_mr_query("add_machine_to_cluster", 2, args,
646                                     Scream, NULL);
647                 switch (stat) {
648                 case MR_SUCCESS:
649                     break;
650                 case MR_EXISTS:
651                     sprintf(temp_buf, "%s is already in cluster %s",
652                             minfo[M_NAME], cinfo[C_NAME]);
653                     Put_message(temp_buf);
654                     break;
655                 default:
656                     com_err(program_name, stat, " in AddMachineToCluster.");
657                     break;
658                 }
659             }
660             celem = celem->q_forw;
661         }
662         celem = ctop;           /* reset cluster element. */
663         melem = melem->q_forw;
664     }
665     FreeQueue(ctop);
666     FreeQueue(mtop);                
667     return(DM_NORMAL);
668 }
669
670 /*      Function Name: RealRemoveMachineFromCluster
671  *      Description: This function actually removes the machine from its 
672  *                   cluster.
673  *      Arguments: info - all information nescessary to perform the removal.
674  *                 one_map - True if there is only one case, and we should
675  *                           confirm.
676  *      Returns: none.
677  */
678
679 static void
680 RealRemoveMachineFromCluster(info, one_map)
681 char ** info;
682 Bool one_map;
683 {
684     char temp_buf[BUFSIZ];
685     register int stat;
686
687     sprintf(temp_buf, "Remove %s from the cluster %s", 
688             info[MAP_MACHINE], info[MAP_CLUSTER]);
689     if (!one_map || Confirm(temp_buf)) {
690         if ( (stat = do_mr_query("delete_machine_from_cluster", 2, 
691                                   info, Scream, NULL)) != 0 )
692             com_err(program_name, stat, " in delete_machine_from_cluster");
693         else {
694             sprintf(temp_buf, "%s has been removed from the cluster %s.",
695                     info[MAP_MACHINE], info[MAP_CLUSTER]);
696             Put_message(temp_buf);
697         }
698     }
699     else
700         Put_message("Machine not removed.");
701 }
702
703 /*      Function Name: RemoveMachineFromCluster
704  *      Description: Removes this machine form a specific cluster.
705  *      Arguments: argc, argv - Name of machine in argv[1].
706  *                              Name of cluster in argv[2].
707  *      Returns: none.
708  */
709
710 /* ARGSUSED */
711 int
712 RemoveMachineFromCluster(argc, argv)
713 int argc;
714 char ** argv;
715 {
716     struct qelem *elem = NULL;
717     char buf[BUFSIZ], * args[10];
718     register int stat;
719
720     args[MAP_MACHINE] = canonicalize_hostname(strsave(argv[1]));
721     if (strcasecmp(args[MAP_MACHINE], argv[1])) {
722         sprintf(temp_buf, "Warning: '%s' canonicalized to '%s'.",
723                 argv[1], args[MAP_MACHINE]);
724         Put_message(temp_buf);
725     }
726     args[MAP_CLUSTER] = argv[2];
727     args[MAP_END] = NULL;
728
729     stat = do_mr_query("get_machine_to_cluster_map", CountArgs(args), args,
730                         StoreInfo, (char *)&elem);
731     if (stat == MR_NO_MATCH) {
732         sprintf(buf, "The machine %s is not is the cluster %s.",
733                 args[MAP_MACHINE], args[MAP_CLUSTER]);
734         Put_message(buf);
735         free(args[MAP_MACHINE]);
736         return(DM_NORMAL);
737     }
738     if (stat != MR_SUCCESS)
739         com_err(program_name, stat, " in delete_machine_from_cluster");
740
741     elem = QueueTop(elem);
742     QueryLoop(elem, PrintMCMap, RealRemoveMachineFromCluster,
743               "Remove this machine from this cluster");
744
745     FreeQueue(elem);
746     free(args[MAP_MACHINE]);
747     return(DM_NORMAL);
748 }
749
750 /* ---------- Cluster Menu -------- */
751
752 /*      Function Name: ShowClusterInfo
753  *      Description: Gets information about a cluser given its name.
754  *      Arguments: argc, argc - the name of the cluster in in argv[1].
755  *      Returns: DM_NORMAL.
756  */
757
758 /* ARGSUSED */
759 int
760 ShowClusterInfo(argc, argv)
761 int argc;
762 char ** argv;
763 {
764     struct qelem *top;
765
766     top = GetMCInfo(CLUSTER, argv[1], (char *) NULL);
767     Loop(top, (void *) PrintClusterInfo);
768     FreeQueue(top);
769     return(DM_NORMAL);
770 }
771
772 /*      Function Name: AddCluster
773  *      Description: Creates a new cluster.
774  *      Arguments: argc, argv - the name of the new cluster is argv[1].
775  *      Returns: DM_NORMAL.
776  */
777
778 /* ARGSUSED */
779 int
780 AddCluster(argc, argv)
781 int argc;
782 char ** argv;
783 {
784     char **args, *info[MAX_ARGS_SIZE], *name = argv[1];
785     int stat;
786 /* 
787  * Check to see if this cluster already exists. 
788  */
789     if (!ValidName(name))
790         return(DM_NORMAL);
791
792     if ( (stat = do_mr_query("get_cluster", 1, &name, 
793                               NullFunc, NULL)) == MR_SUCCESS) {
794         Put_message("This cluster already exists.");
795         return(DM_NORMAL);
796     }
797     else if (stat != MR_NO_MATCH) {
798         com_err(program_name, stat, " in AddCluster.");
799         return(DM_NORMAL);
800     }
801     if ((args = AskMCDInfo(SetClusterDefaults(info, name), CLUSTER, FALSE)) ==
802         NULL) {
803         Put_message("Aborted.");
804         FreeInfo(info);
805         return(DM_NORMAL);
806     }
807
808 /*
809  * Actually create the new Cluster.
810  */
811     if ( (stat = do_mr_query("add_cluster", CountArgs(args), 
812                               args, Scream, NULL)) != 0)
813         com_err(program_name, stat, " in AddCluster.");
814
815     FreeInfo(info);
816     return(DM_NORMAL);
817 }
818
819 /*      Function Name: RealUpdateCluster
820  *      Description: This function actually performs the cluster update.
821  *      Arguments: info - all information nesc. for updating the cluster.
822  *                 junk - an UNUSED boolean.
823  *      Returns: none.
824  */
825
826 /* ARGSUSED */
827 static void
828 RealUpdateCluster(info, junk)
829 char ** info;
830 Bool junk;
831 {
832     register int stat;
833     char ** args = AskMCDInfo(info, CLUSTER, TRUE);
834     if (args == NULL) {
835         Put_message("Aborted.");
836         return;
837     }
838     if ( (stat = do_mr_query("update_cluster", CountArgs(args), 
839                               args, Scream, NULL)) != 0)
840         com_err(program_name, stat, " in UpdateCluster.");
841     else
842         Put_message("Cluster successfully updated.");
843 }
844
845 /*      Function Name: UpdateCluster
846  *      Description: This Function Updates a cluster
847  *      Arguments: name of the cluster in argv[1].
848  *      Returns: DM_NORMAL.
849  */
850
851 /* ARGSUSED */
852 int 
853 UpdateCluster(argc, argv)
854 int argc;
855 char ** argv;
856 {
857     struct qelem *top;    
858     top = GetMCInfo( CLUSTER, argv[1], (char *) NULL );
859     QueryLoop(top, NullPrint, RealUpdateCluster, "Update the cluster");
860
861     FreeQueue(top);
862     return(DM_NORMAL);
863 }
864
865 /*      Function Name: CheckAndRemoveMachine
866  *      Description: This function checks and removes all machines from a
867  *                   cluster.
868  *      Arguments: name - name of the cluster.
869  *                 ask_first - if TRUE, then we will query the user, before
870  *                             deletion.
871  *      Returns: SUB_ERROR if all machines not removed.
872  */
873
874 int
875 CheckAndRemoveMachines(name, ask_first)
876 char * name;
877 Bool ask_first;
878 {
879     register int stat, ret_value;
880     Bool delete_it;
881     char *args[10], temp_buf[BUFSIZ], *ptr;
882     struct qelem *top, *elem = NULL;
883     
884     ret_value = SUB_NORMAL;
885     args[MAP_MACHINE] = "*";
886     args[MAP_CLUSTER] = name;
887     stat = do_mr_query("get_machine_to_cluster_map", 2, args, 
888                         StoreInfo, (char *)&elem);
889     if (stat && stat != MR_NO_MATCH) {
890         com_err(program_name, stat, " in get_machine_to_cluster_map.");
891         return(DM_NORMAL);
892     }
893     if (stat == 0) {
894         elem = top = QueueTop(elem);
895         if (ask_first) {
896             sprintf(temp_buf,
897                     "The cluster %s has the following machines in it:",
898                     name);
899             Put_message(temp_buf);
900             while (elem != NULL) {
901                 char **info = (char **) elem->q_data;
902                 Print(1, &info[MAP_MACHINE], (char *) NULL);
903                 elem = elem->q_forw;
904             }
905             ptr = "Remove ** ALL ** these machines from this cluster?";
906
907             if (YesNoQuestion(ptr, FALSE) == TRUE) /* may return -1. */
908                 delete_it = TRUE;
909             else {
910                 Put_message("Aborting...");
911                 FreeQueue(top);
912                 return(SUB_ERROR);
913             }
914         }
915         else
916             delete_it = TRUE;
917
918         if (delete_it) {
919             elem = top;
920             while (elem != 0) {
921                 char **info = (char **) elem->q_data;
922                 if ( (stat = do_mr_query("delete_machine_from_cluster",
923                                           2, info, Scream, NULL)) != 0) {
924                     ret_value = SUB_ERROR;
925                     com_err(program_name, stat, 
926                             " in delete_machine_from_cluster.");
927                     sprintf(temp_buf, 
928                             "Machine %s ** NOT ** removed from cluster %s.",
929                             info[MAP_MACHINE], info[MAP_CLUSTER]);
930                     Put_message(temp_buf);
931                 }
932                 elem = elem->q_forw;
933             }
934         }
935     }
936     return(ret_value);
937 }
938
939 /*      Function Name: RealDeleteCluster
940  *      Description: Actually performs the cluster deletion.
941  *      Arguments: info - all information about this cluster.
942  *                 one_cluster - If true then there was only one cluster in
943  *                               the queue, and we should confirm.
944  *      Returns: none.
945  */
946
947 static void
948 RealDeleteCluster(info, one_cluster)
949 char ** info;
950 Bool one_cluster;
951 {
952     register int stat;
953     char temp_buf[BUFSIZ];
954     
955     sprintf(temp_buf, 
956             "Are you sure the you want to delete the cluster %s (y/n) ?", 
957             info[C_NAME]);
958     if (!one_cluster || Confirm(temp_buf)) {
959         if (CheckAndRemoveMachines(info[C_NAME], TRUE) != SUB_ERROR) {
960             if ( (stat = do_mr_query("delete_cluster", 1,
961                                       &info[C_NAME], Scream, NULL)) != 0) {
962                 com_err(program_name, stat, " in delete_cluster.");
963                 sprintf(temp_buf, "Cluster %s ** NOT ** deleted.", 
964                         info[C_NAME]);
965                 Put_message(temp_buf);
966             }
967             else {
968                 sprintf(temp_buf, "cluster %s sucesfully deleted.", 
969                         info[C_NAME]);
970                 Put_message(temp_buf);
971             }
972         }
973     }
974 }
975
976 /*      Function Name: DeleteCluster
977  *      Description: This function removes a cluster from the database.
978  *      Arguments: argc, argv - the name of the cluster is stored in argv[1].
979  *      Returns: DM_NORMAL.
980  */
981
982 /* ARGSUSED */
983 int
984 DeleteCluster(argc, argv)
985 int argc;
986 char ** argv;
987 {
988     struct qelem *top;
989
990     top = GetMCInfo( CLUSTER, argv[1], (char *) NULL );
991     QueryLoop(top, PrintClusterInfo, RealDeleteCluster, "Delete the cluster");
992
993     FreeQueue(top);
994     return(DM_NORMAL);
995 }
996     
997 /* ----------- Cluster Data Menu -------------- */
998
999 /*      Function Name: ShowClusterData
1000  *      Description: This function shows the services for one cluster.
1001  *      Arguments: argc, argv - The name of the cluster is argv[1].
1002  *                              The label of the data in argv[2].
1003  *      Returns: DM_NORMAL.
1004  */
1005
1006 /* ARGSUSED */
1007 int
1008 ShowClusterData(argc, argv)
1009 int argc; 
1010 char ** argv; 
1011
1012     struct qelem *elem, *top;
1013     char **info;
1014
1015     top = elem = GetMCInfo(DATA, argv[1], argv[2]);
1016     while (elem != NULL) {
1017         info = (char **) elem->q_data;
1018         PrintClusterData(info);
1019         elem = elem->q_forw;
1020     }
1021     FreeQueue(top);
1022     return(DM_NORMAL);
1023 }
1024
1025 /*      Function Name: AddClusterData
1026  *      Description: This function adds some data to the cluster.
1027  *      Arguments: argv, argc:   argv[1] - the name of the cluster.
1028  *                               argv[2] - the label of the data.
1029  *                               argv[3] - the data.
1030  *      Returns: DM_NORMAL.
1031  */
1032
1033 /* ARGSUSED */
1034 int
1035 AddClusterData(argc, argv)
1036 int argc; 
1037 char ** argv; 
1038
1039     int stat;
1040
1041     if( (stat = do_mr_query("add_cluster_data", 3, argv + 1,
1042                              Scream, (char *) NULL)) != 0)
1043         com_err(program_name, stat, " in AddClusterData.");
1044     return(DM_NORMAL);
1045 }
1046
1047 /*      Function Name: RealRemoveClusterData
1048  *      Description: actually removes the cluster data.
1049  *      Arguments: info - all info necessary to remove the cluster, in an array
1050  *                        of strings.
1051  *                 one_item - if true then the queue has only one elem and we
1052  *                            should confirm.
1053  *      Returns: none.
1054  */
1055
1056 static void
1057 RealRemoveClusterData(info, one_item)
1058 char ** info;
1059 Bool one_item;
1060 {
1061     register int stat;
1062     char * temp_ptr;
1063
1064     Put_message(" ");
1065     temp_ptr = "Are you sure that you want to remove this cluster data (y/n) ?";
1066     PrintClusterData(info);
1067     if (!one_item || Confirm(temp_ptr)) {
1068         if( (stat = do_mr_query("delete_cluster_data", 3, info,
1069                                  Scream, (char *) NULL)) != 0) {
1070             com_err(program_name, stat, " in DeleteClusterData.");
1071             Put_message("Data not removed.");
1072         }
1073         else
1074             Put_message("Removal sucessful.");
1075     }
1076 }
1077
1078 /*      Function Name: RemoveClusterData
1079  *      Description: This function removes data on a given cluster.
1080  *      Arguments: argv, argc:   argv[1] - the name of the cluster.
1081  *                               argv[2] - the label of the data.
1082  *                               argv[3] - the data.
1083  *      Returns: DM_NORMAL.
1084  */
1085
1086 /* ARGSUSED */
1087 int 
1088 RemoveClusterData(argc, argv)
1089 int argc; 
1090 char ** argv; 
1091 {
1092     struct qelem *top;
1093
1094     top = GetMCInfo(DATA, argv[1], argv[2]);
1095     QueryLoop(top, PrintClusterData, RealRemoveClusterData, 
1096               "Remove data from cluster");
1097
1098     FreeQueue(top);
1099     return(DM_NORMAL);
1100 }
1101
1102 /*      Function Name: MachineToClusterMap
1103  *      Description: This Retrieves the mapping between machine and cluster
1104  *      Arguments: argc, argv - argv[1] -> machine name or wildcard.
1105  *                              argv[2] -> cluster name or wildcard.
1106  *      Returns: none.
1107  */
1108
1109 /* ARGSUSED */
1110 int 
1111 MachineToClusterMap(argc,argv)
1112 int argc;
1113 char **argv;
1114 {
1115     struct qelem *elem, *top;
1116     char *tmpname;
1117
1118     tmpname = canonicalize_hostname(strsave(argv[1]));
1119     if (strcasecmp(tmpname, argv[1])) {
1120         sprintf(temp_buf, "Warning: '%s' canonicalized to '%s'.",
1121                 argv[1], tmpname);
1122         Put_message(temp_buf);
1123     }
1124     top = elem = GetMCInfo(MAP, tmpname, argv[2]);
1125   
1126     Put_message("");            /* blank line on screen */
1127     while (elem != NULL) {
1128         char ** info = (char **) elem->q_data;
1129         PrintMCMap(info);
1130         elem = elem->q_forw;
1131     }
1132
1133     FreeQueue(top);
1134     free(tmpname);
1135     return(DM_NORMAL);
1136 }
This page took 0.156976 seconds and 5 git commands to generate.