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