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