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