]> andersk Git - moira.git/blame - clients/moira/cluster.c
added hosttable stuff
[moira.git] / clients / moira / cluster.c
CommitLineData
402461ad 1#if (!defined(lint) && !defined(SABER))
08345b74 2 static char rcsid_module_c[] = "$Header$";
3#endif lint
4
8defc06b 5/* This is the file cluster.c for the MOIRA Client, which allows a nieve
6 * user to quickly and easily maintain most parts of the MOIRA database.
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>
8defc06b 26#include <moira.h>
27#include <moira_site.h>
08345b74 28#include <menu.h>
ad7e0e04 29#include <sys/types.h>
30#include <sys/socket.h>
31#include <netinet/in.h>
32#include <arpa/inet.h>
08345b74 33
461c03b6 34#include "mit-copyright.h"
0a2c64cb 35#include "defs.h"
36#include "f_defs.h"
461c03b6 37#include "globals.h"
08345b74 38
461c03b6 39#define MACHINE 0
40#define CLUSTER 1
41#define DATA 2
42#define MAP 3
ad7e0e04 43#define SUBNET 4
44#define CNAME 5
08345b74 45
85ca828a 46#define M_DEFAULT_TYPE DEFAULT_NONE
47
48#define C_DEFAULT_DESCRIPT DEFAULT_NONE
49#define C_DEFAULT_LOCATION DEFAULT_NONE
50
51#define CD_DEFAULT_LABEL DEFAULT_NONE
52#define CD_DEFAULT_DATA DEFAULT_NONE
53
ad7e0e04 54
55static char *states[] = { "Reserved (0)",
56 "Active (1)",
57 "None (2)",
58 "Deleted (3)" };
59
60static char *MacState(state)
61int state;
62{
63 char buf[BUFSIZ];
64
65 if (state < 0 || state > 3) {
66 sprintf(buf, "Unknown (%d)", state);
67 return(buf);
68 }
69 return(states[state]);
70}
71
72
73
85ca828a 74/* -------------------- Set Defaults -------------------- */
75
76/* Function Name: SetMachineDefaults
77 * Description: sets machine defaults.
78 * Arguments: info - an array to put the defaults into.
79 * name - Canonacalized name of the machine.
80 * Returns: info - the array.
81 */
82
402461ad 83static char **
85ca828a 84SetMachineDefaults(info, name)
85char ** info, *name;
86{
87 info[M_NAME] = Strsave(name);
ad7e0e04 88 info[M_VENDOR] = Strsave(M_DEFAULT_TYPE);
89 info[M_MODEL] = Strsave(M_DEFAULT_TYPE);
90 info[M_OS] = Strsave(M_DEFAULT_TYPE);
91 info[M_LOC] = Strsave(M_DEFAULT_TYPE);
92 info[M_CONTACT] = Strsave(M_DEFAULT_TYPE);
93 info[M_USE] = Strsave("0");
94 info[M_STAT] = Strsave("1");
95 info[8] = Strsave("NONE");
96 info[9] = Strsave("unique");
97 info[10] = Strsave("NONE");
98 info[11] = Strsave("NONE");
99 info[12] = Strsave("");
100 info[13] = Strsave("");
101 info[14] = info[15] = info[16] = NULL;
85ca828a 102 return(info);
103}
104
105/* Function Name: SetClusterDefaults
106 * Description: sets Cluster defaults.
107 * Arguments: info - an array to put the defaults into.
108 * name - name of the Cluster.
109 * Returns: info - the array.
110 */
111
402461ad 112static char **
85ca828a 113SetClusterDefaults(info, name)
114char ** info, *name;
115{
116 info[C_NAME] = Strsave(name);
117 info[C_DESCRIPT] = Strsave(C_DEFAULT_DESCRIPT);
118 info[C_LOCATION] = Strsave(C_DEFAULT_LOCATION);
119 info[C_MODBY] = info[C_MODTIME] = info[C_MODWITH] = info[C_END] = NULL;
120 return(info);
121}
122
ad7e0e04 123/* Function Name: SetSubnetDefaults
124 * Description: sets Subnet defaults.
125 * Arguments: info - an array to put the defaults into.
126 * name - name of the Subnet.
127 * Returns: info - the array.
128 */
129
130static char **
131SetSubnetDefaults(info, name)
132char ** info, *name;
133{
134 char buf[256];
135
136 info[C_NAME] = Strsave(name);
137 info[SN_DESC] = Strsave("");
138 sprintf(buf, "%d", ntohl(inet_addr("18.0.0.0")));
139 info[SN_ADDRESS] = Strsave(buf);
140 sprintf(buf, "%d", ntohl(inet_addr("255.255.0.0")));
141 info[SN_MASK] = Strsave(buf);
142 sprintf(buf, "%d", ntohl(inet_addr("18.0.0.10")));
143 info[SN_LOW] = Strsave(buf);
144 sprintf(buf, "%d", ntohl(inet_addr("18.0.1.252")));
145 info[SN_HIGH] = Strsave(buf);
146 info[SN_ACE_TYPE] = Strsave("LIST");
147 info[SN_ACE_NAME] = Strsave("network_acl");
148 info[SN_MODBY] = info[SN_MODTIME] = info[SN_MODWITH] = info[SN_END] = NULL;
149 return(info);
150}
151
85ca828a 152/* -------------------- General Functions -------------------- */
153
08345b74 154/* Function Name: PrintMachInfo
155 * Description: This function Prints out the Machine info in
156 * a coherent form.
157 * Arguments: info - array of information about a machine.
402461ad 158 * Returns: The name of the Machine
08345b74 159 */
160
402461ad 161static char *
08345b74 162PrintMachInfo(info)
163char ** info;
164{
165 char buf[BUFSIZ];
166
85ca828a 167 Put_message("");
ad7e0e04 168 sprintf(buf, "Machine: %s Vendor: %s, Model: %s, OS: %s",
169 info[M_NAME], info[M_VENDOR], info[M_MODEL], info[M_OS]);
170 Put_message(buf);
171 sprintf(buf, "Location: %s, Contact: %s, Owner: %s %s",
172 info[M_LOC], info[M_CONTACT], info[M_OWNER_TYPE],
173 strcmp(info[M_OWNER_TYPE], "NONE") ? info[M_OWNER_NAME] : "");
174 Put_message(buf);
175 sprintf(buf, "Address: %s, Subnet: %s, Use code: %s",
176 info[M_ADDR], info[M_SUBNET], info[M_USE]);
177 Put_message(buf);
178 sprintf(buf, "Status: %s, Status Changed %s",
179 MacState(atoi(info[M_STAT])), info[M_STAT_CHNG]);
180 Put_message(buf);
181 sprintf(buf, "Created on %s by %s", info[M_CREATED], info[M_CREATOR]);
182 Put_message(buf);
183 sprintf(buf, "Last known use %s", info[M_INUSE]);
184 Put_message(buf);
185 sprintf(buf, "Admin cmt: %s; Op cmt: %s",
186 info[M_ACOMMENT], info[M_OCOMMENT]);
08345b74 187 Put_message(buf);
075fe5bb 188 sprintf(buf, MOD_FORMAT, info[M_MODBY], info[M_MODTIME], info[M_MODWITH]);
08345b74 189 Put_message(buf);
402461ad 190 return(info[M_NAME]);
08345b74 191}
192
ad7e0e04 193/* Function Name: PrintCname
194 * Description: Prints the Data on a host alias
195 * Arguments: info a pointer to the data array.
196 * Returns: The name of the alias.
197 */
198
199static char *
200PrintCname(info)
201char ** info;
202{
203 char buf[BUFSIZ];
204
205 sprintf(buf, "Alias: %-32s Canonical Name: %s", info[0], info[1]);
206 Put_message(buf);
207 return(info[0]);
208}
209
08345b74 210/* Function Name: PrintClusterInfo
211 * Description: This function Prints out the cluster info
212 * in a coherent form.
213 * Arguments: info - array of information about a cluster.
402461ad 214 * Returns: The name of the cluster.
08345b74 215 */
216
402461ad 217static char *
08345b74 218PrintClusterInfo(info)
219char ** info;
220{
221 char buf[BUFSIZ];
222
85ca828a 223 Put_message("");
224 sprintf(buf, "Cluster: %s", info[C_NAME]);
225 Put_message(buf);
226 sprintf(buf, "Description: %s", info[C_DESCRIPT]);
461c03b6 227 Put_message(buf);
85ca828a 228 sprintf(buf, "Location: %s", info[C_LOCATION]);
08345b74 229 Put_message(buf);
075fe5bb 230 sprintf(buf, MOD_FORMAT, info[C_MODBY], info[C_MODTIME], info[C_MODWITH]);
08345b74 231 Put_message(buf);
402461ad 232 return(info[C_NAME]);
08345b74 233}
234
235/* Function Name: PrintClusterData
236 * Description: Prints the Data on a cluster
237 * Arguments: info a pointer to the data array.
402461ad 238 * Returns: The name of the cluster.
08345b74 239 */
240
402461ad 241static char *
08345b74 242PrintClusterData(info)
243char ** info;
244{
245 char buf[BUFSIZ];
85ca828a 246
247 Put_message("");
248 sprintf(buf, "Cluster: %-20s Label: %-15s Data: %s",
08345b74 249 info[CD_NAME], info[CD_LABEL], info[CD_DATA]);
250 Put_message(buf);
402461ad 251 return(info[CD_NAME]);
08345b74 252}
253
461c03b6 254/* Function Name: PrintMCMap
255 * Description: Prints the data about a machine to cluster mapping.
256 * Arguments: info a pointer to the data array.
257 * Returns: none
258 */
259
402461ad 260static char *
461c03b6 261PrintMCMap(info)
262char ** info;
263{
264 char buf[BUFSIZ];
265 sprintf(buf, "Cluster: %-30s Machine: %-20s",
266 info[MAP_CLUSTER], info[MAP_MACHINE]);
267 Put_message(buf);
402461ad 268 return(""); /* Used by QueryLoop(). */
461c03b6 269}
270
ad7e0e04 271/* Function Name: PrintSubnetInfo
272 * Description: This function Prints out the subnet info
273 * in a coherent form.
274 * Arguments: info - array of information about a subnet.
275 * Returns: The name of the subnet.
276 */
277
278static char *
279PrintSubnetInfo(info)
280char ** info;
281{
282 char buf[BUFSIZ];
283 struct in_addr addr, mask, low, high;
284
285 Put_message("");
286 sprintf(buf, "Subnet: %s", info[SN_NAME]);
287 Put_message(buf);
288 sprintf(buf, "Description: %s", info[SN_DESC]);
289 Put_message(buf);
290 addr.s_addr = htonl(atoi(info[SN_ADDRESS]));
291 mask.s_addr = htonl(atoi(info[SN_MASK]));
292 low.s_addr = htonl(atoi(info[SN_LOW]));
293 high.s_addr = htonl(atoi(info[SN_HIGH]));
294 /* screwy sequence is here because inet_ntoa returns a pointer to
295 a static buf. If it were all one sprintf, the last value would
296 appear 4 times. */
297 sprintf(buf, "Address %s, Mask ", inet_ntoa(addr));
298 strcat(buf, inet_ntoa(mask));
299 strcat(buf, ", High ");
300 strcat(buf, inet_ntoa(high));
301 strcat(buf, ", Low ");
302 strcat(buf, inet_ntoa(low));
303 Put_message(buf);
304 sprintf(buf, "Owner: %s %s", info[SN_ACE_TYPE],
305 strcmp(info[SN_ACE_TYPE],"NONE") ? info[SN_ACE_NAME] : "");
306 Put_message(buf);
307 sprintf(buf,MOD_FORMAT,info[SN_MODBY],info[SN_MODTIME],info[SN_MODWITH]);
308 Put_message(buf);
309 return(info[SN_NAME]);
310}
311
08345b74 312/* Function Name: GetMCInfo.
313 * Description: This function stores info about a machine.
314 * type - type of data we are trying to retrieve.
315 * name1 - the name of argv[0] for the call.
316 * name2 - the name of argv[1] for the call.
317 * Returns: the top element of a queue containing the data or NULL.
318 */
319
320struct qelem *
461c03b6 321GetMCInfo(type, name1, name2)
08345b74 322int type;
323char * name1, *name2;
324{
325
326 int stat;
327 struct qelem * elem = NULL;
ad7e0e04 328 char * args[5];
08345b74 329
330 switch (type) {
461c03b6 331 case MACHINE:
ad7e0e04 332 args[0] = name1;
333 args[1] = args[2] = args[3] = "*";
334 if ( (stat = do_mr_query("get_host", 4, args,
14f99d7d 335 StoreInfo, (char *)&elem)) != 0) {
576ba5e7 336 if (stat == MR_NO_MATCH) {
337 char buf[128];
338 sprintf(buf, "Machine '%s' is not in the database.", name1);
339 Put_message(buf);
340 } else
341 com_err(program_name, stat, " in get_machine.");
08345b74 342 return(NULL);
343 }
344 break;
ad7e0e04 345 case CNAME:
346 args[0] = name1;
347 args[1] = name2;
348 if ( (stat = do_mr_query("get_hostalias", 2, args,
349 StoreInfo, (char *)&elem)) != 0) {
350 com_err(program_name, stat, " in get_hostalias.");
351 return(NULL);
352 }
353 break;
354 case SUBNET:
355 if ( (stat = do_mr_query("get_subnet", 1, &name1,
356 StoreInfo, (char *)&elem)) != 0) {
357 if (stat == MR_NO_MATCH) {
358 char buf[128];
359 sprintf(buf, "Subnet '%s' is not in the database.", name1);
360 Put_message(buf);
361 } else
362 com_err(program_name, stat, " in get_subnet.");
363 return(NULL);
364 }
365 break;
461c03b6 366 case CLUSTER:
8defc06b 367 if ( (stat = do_mr_query("get_cluster", 1, &name1,
14f99d7d 368 StoreInfo, (char *)&elem)) != 0) {
461c03b6 369 com_err(program_name, stat, " in get_cluster.");
08345b74 370 return(NULL);
371 }
372 break;
461c03b6 373 case MAP:
374 args[MAP_MACHINE] = name1;
375 args[MAP_CLUSTER] = name2;
8defc06b 376 if ( (stat = do_mr_query("get_machine_to_cluster_map", 2, args,
14f99d7d 377 StoreInfo, (char *)&elem)) != 0) {
461c03b6 378 com_err(program_name, stat, " in get_machine_to_cluster_map.");
08345b74 379 return(NULL);
380 }
381 break;
461c03b6 382 case DATA:
383 args[CD_NAME] = name1;
384 args[CD_LABEL] = name2;
8defc06b 385 if ( (stat = do_mr_query("get_cluster_data", 2, args,
14f99d7d 386 StoreInfo, (char *)&elem)) != 0) {
461c03b6 387 com_err(program_name, stat, " in get_cluster_data.");
08345b74 388 return(NULL);
389 }
390 }
391 return(QueueTop(elem));
392}
393
461c03b6 394/* Function Name: AskMCDInfo.
08345b74 395 * Description: This function askes the user for information about a
396 * machine and saves it into a structure.
397 * Arguments: info - a pointer the information to ask about
461c03b6 398 * type - type of information - MACHINE
399 * CLUSTER
400 * DATA
08345b74 401 * name - T/F : change the name of this type.
402 * Returns: none.
403 */
404
461c03b6 405char **
406AskMCDInfo(info, type, name)
407char ** info;
08345b74 408int type;
409Bool name;
410{
576ba5e7 411 char temp_buf[BUFSIZ], *newname, *oldnewname;
08345b74 412
413 switch (type) {
461c03b6 414 case MACHINE:
85ca828a 415 sprintf(temp_buf, "Setting the information for the Machine %s.",
416 info[M_NAME]);
08345b74 417 break;
ad7e0e04 418 case SUBNET:
419 sprintf(temp_buf, "Setting the information for the Subnet %s.",
420 info[SN_NAME]);
421 break;
461c03b6 422 case CLUSTER:
85ca828a 423 sprintf(temp_buf, "Setting the information for the Cluster %s.",
424 info[C_NAME]);
08345b74 425 break;
461c03b6 426 case DATA:
85ca828a 427 sprintf(temp_buf, "Setting the Data for the Cluster %s.",
428 info[CD_NAME]);
08345b74 429 break;
430 }
431 Put_message(temp_buf);
432
433 if (name) {
08345b74 434 switch (type) {
461c03b6 435 case MACHINE:
436 newname = Strsave(info[M_NAME]);
576ba5e7 437 if (GetValueFromUser("The new name for this machine? ", &newname) ==
438 SUB_ERROR)
439 return(NULL);
440 oldnewname = Strsave(newname);
1c3831ea 441 newname = canonicalize_hostname(newname);
fbebf6df 442 if (strcasecmp(newname, oldnewname) && *oldnewname != '"') {
576ba5e7 443 sprintf(temp_buf, "Warning: '%s' canonicalized to '%s'\n",
444 oldnewname, newname);
445 Put_message(temp_buf);
446 }
447 free(oldnewname);
08345b74 448 break;
ad7e0e04 449 case SUBNET:
450 newname = Strsave(info[SN_NAME]);
451 if (GetValueFromUser("The new name for this subnet? ",
452 &newname) == SUB_ERROR)
453 return(NULL);
454 break;
461c03b6 455 case CLUSTER:
456 newname = Strsave(info[C_NAME]);
576ba5e7 457 if (GetValueFromUser("The new name for this cluster? ",
458 &newname) == SUB_ERROR)
459 return(NULL);
08345b74 460 break;
461 default:
461c03b6 462 Put_message("Unknown type in AskMCDInfo, programmer botch");
463 return(NULL);
08345b74 464 }
465 }
466
467 switch(type) {
461c03b6 468 case MACHINE:
ad7e0e04 469 if (GetValueFromUser("Machine's Vendor", &info[M_VENDOR]) == SUB_ERROR)
470 return(NULL);
471 if (GetValueFromUser("Machine's Model", &info[M_MODEL]) == SUB_ERROR)
472 return(NULL);
473 if (GetValueFromUser("Machine's Operating System", &info[M_OS]) ==
474 SUB_ERROR)
475 return(NULL);
476 if (GetValueFromUser("Location of Machine", &info[M_LOC]) == SUB_ERROR)
477 return(NULL);
478 if (GetValueFromUser("Contact for Machine", &info[M_CONTACT]) ==
479 SUB_ERROR)
480 return(NULL);
481 if (GetValueFromUser("Machine's Use Code", &info[M_USE]) == SUB_ERROR)
482 return(NULL);
483 while (1) {
484 int i;
485 if (GetValueFromUser("Machine's Status (? for help)",
486 &info[M_STAT]) == SUB_ERROR)
487 return(NULL);
488 if (isdigit(info[M_STAT][0])) break;
489 Put_message("Valid status numbers:");
490 for (i = 0; i < 4; i++) Put_message(states[i]);
491 }
492 if (name) {
493 free(info[8]);
494 info[8] = info[M_SUBNET];
495 info[9] = info[M_ADDR];
496 info[10] = info[M_OWNER_TYPE];
497 info[11] = info[M_OWNER_NAME];
498 info[12] = info[M_ACOMMENT];
499 info[13] = info[M_OCOMMENT];
500 }
501 if (GetValueFromUser("Machine's subnet (or 'none')", &info[8])
502 == SUB_ERROR)
503 return(NULL);
504 if (GetValueFromUser("Machine's address (or 'unassigned' or 'unique')",
505 &info[9]) == SUB_ERROR)
506 return(NULL);
507 if (GetTypeFromUser("Machine's Owner Type", "ace_type", &info[10]) ==
576ba5e7 508 SUB_ERROR)
509 return(NULL);
ad7e0e04 510 if (strcmp(info[10], "NONE") &&
511 GetValueFromUser("Owner's Name", &info[11]) == SUB_ERROR)
512 return(NULL);
513 if (GetValueFromUser("Administrative Comment", &info[12]) == SUB_ERROR)
514 return(NULL);
515 if (GetValueFromUser("Operational Comment", &info[13]) == SUB_ERROR)
516 return(NULL);
517 info[14] = NULL;
518 FreeAndClear(&info[15], TRUE);
519 FreeAndClear(&info[16], TRUE);
520 break;
521 case SUBNET:
522 if (GetValueFromUser("Subnet Description", &info[SN_DESC]) == SUB_ERROR)
523 return(NULL);
524 if (GetAddressFromUser("Subnet Address", &info[SN_ADDRESS]) == SUB_ERROR)
525 return(NULL);
526 if (GetAddressFromUser("Subnet Mask", &info[SN_MASK]) == SUB_ERROR)
527 return(NULL);
528 if (GetAddressFromUser("Lowest assignable address", &info[SN_LOW]) == SUB_ERROR)
529 return(NULL);
530 if (GetAddressFromUser("Highest assignable address", &info[SN_HIGH]) == SUB_ERROR)
531 return(NULL);
532 if (GetTypeFromUser("Owner Type", "ace_type", &info[SN_ACE_TYPE]) == SUB_ERROR)
533 return(NULL);
534 if (strcmp(info[SN_ACE_TYPE], "NONE") &&
535 GetValueFromUser("Owner Name", &info[SN_ACE_NAME]) == SUB_ERROR)
536 return(NULL);
537 FreeAndClear(&info[SN_MODTIME], TRUE);
538 FreeAndClear(&info[SN_MODBY], TRUE);
539 FreeAndClear(&info[SN_MODWITH], TRUE);
08345b74 540 break;
461c03b6 541 case CLUSTER:
576ba5e7 542 if (GetValueFromUser("Cluster's Description:", &info[C_DESCRIPT]) ==
543 SUB_ERROR)
544 return(NULL);
545 if (GetValueFromUser("Cluster's Location:", &info[C_LOCATION]) ==
546 SUB_ERROR)
547 return(NULL);
08345b74 548 FreeAndClear(&info[C_MODTIME], TRUE);
549 FreeAndClear(&info[C_MODBY], TRUE);
550 FreeAndClear(&info[C_MODWITH], TRUE);
551 break;
461c03b6 552 case DATA:
576ba5e7 553 if (GetValueFromUser("Label defining this data?", &info[CD_LABEL]) ==
554 SUB_ERROR)
555 return(NULL);
556 if (GetValueFromUser("The data itself ? ", &info[CD_DATA]) == SUB_ERROR)
557 return(NULL);
08345b74 558 break;
559 }
560
561/*
562 * Slide the newname into the #2 slot, this screws up all future references
563 * to this list.
564 */
565 if (name)
566 SlipInNewName(info, newname);
567
568 return(info);
569}
570
571/* ----------- Machine Menu ----------- */
572
573/* Function Name: ShowMachineInfo
574 * Description: This function shows the information about a machine.
575 * Arguments: argc, argv - the name of the machine in argv[1].
576 * Returns: DM_NORMAL.
577 */
578
579/* ARGSUSED */
580int
581ShowMachineInfo(argc, argv)
582int argc;
583char **argv;
584{
402461ad 585 struct qelem *top;
1c3831ea 586 char *tmpname;
08345b74 587
1c3831ea 588 tmpname = canonicalize_hostname(strsave(argv[1]));
589 top = GetMCInfo(MACHINE, tmpname, (char *) NULL);
402461ad 590 Loop(top, ( (void *) PrintMachInfo) );
08345b74 591 FreeQueue(top);
592 return(DM_NORMAL);
593}
594
ad7e0e04 595/* Function Name: ShowMachineQuery
596 * Description: This function shows the information about a machine.
597 * or group of machines, which may be selected through a
598 * number of criteria.
599 * Arguments: argc, argv - the name of the machine in argv[1],
600 * the address of the machine in argv[2],
601 * the location of the machine in argv[3],
602 * and the contact name in argv[4].
603 * any of these may be wildcards.
604 * Returns: DM_NORMAL.
605 */
606
607/* ARGSUSED */
608int
609ShowMachineQuery(argc, argv)
610int argc;
611char **argv;
612{
613 int stat;
614 struct qelem *top, *elem = NULL;
615 char *args[5];
616
617 if (!strcmp(argv[1], "") && !strcmp(argv[2], "") &&
618 !strcmp(argv[3], "") && !strcmp(argv[4], "")) {
619 Put_message("You must specify at least one parameter of the query.");
620 return(DM_NORMAL);
621 }
622
623 if (*argv[1])
624 args[0] = canonicalize_hostname(strsave(argv[1]));
625 else
626 args[0] = "*";
627 if (*argv[2])
628 args[1] = argv[2];
629 else
630 args[1] = "*";
631 if (*argv[3])
632 args[2] = argv[3];
633 else
634 args[2] = "*";
635 if (*argv[4])
636 args[3] = argv[4];
637 else
638 args[3] = "*";
639
640 if ((stat = do_mr_query("get_host", 4, args, StoreInfo,
641 (char *)&elem)) != 0) {
642 if (stat == MR_NO_MATCH)
643 Put_message("No machine(s) found matching query in the database.");
644 else
645 com_err(program_name, stat, " in get_machine.");
646 return(DM_NORMAL);
647 }
648 top = QueueTop(elem);
649 Loop(top, ( (void *) PrintMachInfo) );
650 FreeQueue(top);
651 return(DM_NORMAL);
652}
653
08345b74 654/* Function Name: AddMachine
655 * Description: This function adds a new machine to the database.
656 * Arguments: argc, argv - the name of the machine in argv[1].
657 * Returns: DM_NORMAL.
658 */
659
660/* ARGSUSED */
661int
662AddMachine(argc, argv)
663int argc;
664char **argv;
665{
ad7e0e04 666 char **args, *info[MAX_ARGS_SIZE], *name, buf[256], *xargs[5];
08345b74 667 int stat;
402461ad 668
669 if (!ValidName(argv[1])) /* Checks for wildcards. */
670 return(DM_NORMAL);
08345b74 671/*
672 * Check to see if this machine already exists.
673 */
1c3831ea 674 name = canonicalize_hostname(strsave(argv[1]));
08345b74 675
ad7e0e04 676 xargs[0] = name;
677 xargs[1] = xargs[2] = xargs[3] = "*";
678 if ( (stat = do_mr_query("get_host", 4, xargs, NullFunc, NULL)) == 0) {
576ba5e7 679 sprintf(buf, "The machine '%s' already exists.", name);
680 Put_message(buf);
1c3831ea 681 free(name);
08345b74 682 return(DM_NORMAL);
683 }
8defc06b 684 else if (stat != MR_NO_MATCH) {
576ba5e7 685 com_err(program_name, stat,
686 " while checking machine '%s' in AddMachine.", name);
1c3831ea 687 free(name);
08345b74 688 return(DM_NORMAL);
689 }
690
576ba5e7 691 if ((args = AskMCDInfo(SetMachineDefaults(info, name), MACHINE, FALSE)) ==
692 NULL) {
693 Put_message("Aborted.");
694 return(DM_NORMAL);
695 }
08345b74 696
697/*
698 * Actually create the new Machine.
699 */
700
ad7e0e04 701 if ( (stat = do_mr_query("add_host", CountArgs(args),
14f99d7d 702 args, Scream, NULL)) != 0)
461c03b6 703 com_err(program_name, stat, " in AddMachine.");
08345b74 704
705 FreeInfo(info);
1c3831ea 706 free(name);
08345b74 707 return(DM_NORMAL);
708}
709
402461ad 710/* Function Name: RealUpdateMachine
711 * Description: Performs the actual update of the machine data.
712 * Arguments: info - the information on the machine to update.
713 * junk - an UNUSED Boolean.
714 * Returns: none.
715 */
716
717/* ARGSUSED */
718static void
719RealUpdateMachine(info, junk)
720char ** info;
721Bool junk;
722{
723 register int stat;
724 char ** args = AskMCDInfo(info, MACHINE, TRUE);
576ba5e7 725 if (args == NULL) {
726 Put_message("Aborted.");
727 return;
728 }
ad7e0e04 729 if ( (stat = do_mr_query("update_host", CountArgs(args),
14f99d7d 730 args, Scream, NULL)) != 0)
402461ad 731 com_err(program_name, stat, " in UpdateMachine.");
732 else
733 Put_message("Machine sucessfully updated.");
734}
735
08345b74 736/* Function Name: UpdateMachine
737 * Description: This function adds a new machine to the database.
738 * Arguments: argc, argv - the name of the machine in argv[1].
739 * Returns: DM_NORMAL.
740 */
741
742/* ARGSUSED */
743int
744UpdateMachine(argc, argv)
745int argc;
746char **argv;
747{
1c3831ea 748 struct qelem *top;
749 char *tmpname;
750
751 tmpname = canonicalize_hostname(strsave(argv[1]));
752 top = GetMCInfo( MACHINE, tmpname, (char *) NULL);
402461ad 753 QueryLoop(top, NullPrint, RealUpdateMachine, "Update the machine");
08345b74 754
08345b74 755 FreeQueue(top);
1c3831ea 756 free(tmpname);
08345b74 757 return(DM_NORMAL);
758}
759
85ca828a 760/* Function Name: CheckAndRemoveFromCluster
761 * Description: This func tests to see if a machine is in a cluster.
762 * and if so then removes it
763 * Arguments: name - name of the machine (already Canonocalized).
764 * ask_user- query the user before removing if from clusters?
8defc06b 765 * Returns: MR_ERROR if machine left in a cluster, or mr_error.
85ca828a 766 */
767
768int
769CheckAndRemoveFromCluster(name, ask_user)
770char * name;
771Bool ask_user;
772{
773 register int stat, ret_value;
774 Bool delete_it;
775 char *args[10], temp_buf[BUFSIZ], *ptr;
776 struct qelem *top, *elem = NULL;
777
402461ad 778 ret_value = SUB_NORMAL; /* initialize ret_value. */
85ca828a 779 args[0] = name;
780 args[1] = "*";
8defc06b 781 stat = do_mr_query("get_machine_to_cluster_map", 2, args,
14f99d7d 782 StoreInfo, (char *)&elem);
8defc06b 783 if (stat && stat != MR_NO_MATCH) {
85ca828a 784 com_err(program_name, stat, " in get_machine_to_cluster_map.");
785 return(DM_NORMAL);
786 }
8defc06b 787 if (stat == MR_SUCCESS) {
85ca828a 788 elem = top = QueueTop(elem);
789 if (ask_user) {
790 sprintf(temp_buf, "%s is assigned to the following clusters.",
791 name);
792 Put_message(temp_buf);
402461ad 793 Loop(top, (void *) PrintMCMap);
85ca828a 794 ptr = "Remove this machine from ** ALL ** these clusters?";
85ca828a 795 if (YesNoQuestion(ptr, FALSE) == TRUE) /* may return -1. */
796 delete_it = TRUE;
797 else {
798 Put_message("Aborting...");
799 FreeQueue(top);
800 return(SUB_ERROR);
801 }
802 }
803 else
804 delete_it = TRUE;
805
806 if (delete_it) {
402461ad 807 while (elem != NULL) {
85ca828a 808 char **info = (char **) elem->q_data;
8defc06b 809 if ( (stat = do_mr_query( "delete_machine_from_cluster",
14f99d7d 810 2, info, Scream, NULL)) != 0) {
85ca828a 811 ret_value = SUB_ERROR;
812 com_err(program_name, stat,
813 " in delete_machine_from_cluster.");
814 sprintf(temp_buf,
815 "Machine %s ** NOT ** removed from cluster %s.",
816 info[MAP_MACHINE], info[MAP_CLUSTER]);
817 Put_message(temp_buf);
818 }
819 elem = elem->q_forw;
820 }
821 }
822 }
823 return(ret_value);
824}
825
402461ad 826/* Function Name: RealDeleteMachine
827 * Description: Actually Deletes the Machine.
828 * Arguments: info - nescessary information stored as an array of char *'s
829 * one_machine - a boolean, true if there is only one item in
830 * the query.
831 * Returns: none.
832 */
833
834static void
835RealDeleteMachine(info, one_machine)
836char ** info;
837Bool one_machine;
838{
839 register int stat;
840 char temp_buf[BUFSIZ];
841
842 sprintf(temp_buf, "Are you sure you want to delete the machine %s (y/n)? ",
843 info[M_NAME]);
844 if(!one_machine || Confirm(temp_buf)) {
845 if (CheckAndRemoveFromCluster(info[M_NAME], TRUE) != SUB_ERROR) {
ad7e0e04 846 if ( (stat = do_mr_query("delete_host", 1,
14f99d7d 847 &info[M_NAME], Scream, NULL)) != 0) {
402461ad 848 com_err(program_name, stat, " in DeleteMachine.");
849 sprintf(temp_buf, "%s ** NOT ** deleted.",
850 info[M_NAME]);
851 Put_message(temp_buf);
852 }
853 else {
854 sprintf(temp_buf, "%s successfully Deleted.", info[M_NAME]);
855 Put_message(temp_buf);
856 }
857 }
858 }
859}
860
08345b74 861/* Function Name: DeleteMachine
862 * Description: This function removes a machine from the data base.
863 * Arguments: argc, argv - the machines name int argv[1].
864 * Returns: DM_NORMAL.
865 */
866
85ca828a 867/* Perhaps we should remove the cluster if it has no machine now. */
868
08345b74 869/* ARGSUSED */
870int
461c03b6 871DeleteMachine(argc, argv)
08345b74 872int argc;
873char **argv;
874{
402461ad 875 struct qelem *top;
1c3831ea 876 char *tmpname;
08345b74 877
1c3831ea 878 tmpname = canonicalize_hostname(strsave(argv[1]));
879 top = GetMCInfo(MACHINE, tmpname, (char *) NULL);
402461ad 880 QueryLoop(top, PrintMachInfo, RealDeleteMachine, "Delete the machine");
85ca828a 881 FreeQueue(top);
1c3831ea 882 free(tmpname);
08345b74 883 return(DM_NORMAL);
884}
885
ad7e0e04 886/* Function Name: ShowCname
887 * Description: This function shows machine aliases
888 * Arguments: argc, argv - the alias argv[1], the real name in argv[2]
889 * Returns: DM_NORMAL.
890 */
891
892/* ARGSUSED */
893int
894ShowCname(argc, argv)
895int argc;
896char **argv;
897{
898 struct qelem *top;
899 char *tmpalias, *tmpname;
900
901 tmpalias = canonicalize_hostname(strsave(argv[1]));
902 tmpname = canonicalize_hostname(strsave(argv[2]));
903 top = GetMCInfo(CNAME, tmpalias, tmpname);
904 Put_message(""); /* blank line on screen */
905 Loop(top, ( (void *) PrintCname) );
906 FreeQueue(top);
907 return(DM_NORMAL);
908}
909
910
911/* ARGSUSED */
912int
913AddCname(argc, argv)
914int argc;
915char ** argv;
916{
917 int stat;
918 char *machine, *cluster, temp_buf[BUFSIZ], *args[10];
919 Bool add_it, one_machine, one_cluster;
920 struct qelem * melem, *mtop, *celem, *ctop;
921
922 args[0] = canonicalize_hostname(strsave(argv[1]));
923 args[1] = canonicalize_hostname(strsave(argv[2]));
924 stat = do_mr_query("add_hostalias", 2, args, Scream, NULL);
925 switch (stat) {
926 case MR_SUCCESS:
927 break;
928 case MR_EXISTS:
929 Put_message("That alias name is already in use.");
930 break;
931 case MR_PERM:
932 Put_message("Permission denied. (Regular users can only add two aliases to a host.");
933 break;
934 default:
935 com_err(program_name, stat, " in add_hostalias");
936 }
937 return(DM_NORMAL);
938}
939
940
941/* ARGSUSED */
942int
943DeleteCname(argc, argv)
944int argc;
945char ** argv;
946{
947 int stat;
948 char *machine, *cluster, temp_buf[BUFSIZ], *args[10];
949 Bool add_it, one_machine, one_cluster;
950 struct qelem * melem, *mtop, *celem, *ctop;
951
952 args[0] = canonicalize_hostname(strsave(argv[1]));
953 args[1] = canonicalize_hostname(strsave(argv[2]));
954 stat = do_mr_query("delete_hostalias", 2, args, Scream, NULL);
955 if (stat)
956 com_err(program_name, stat, " in delete_hostalias");
957 return(DM_NORMAL);
958}
959
960
08345b74 961/* Function Name: AddMachineToCluster
962 * Description: This function adds a machine to a cluster
963 * Arguments: argc, argv - The machine name is argv[1].
964 * The cluster name in argv[2].
965 * Returns: DM_NORMAL.
966 */
967
968/* ARGSUSED */
969int
970AddMachineToCluster(argc, argv)
971int argc;
972char ** argv;
973{
974 int stat;
85ca828a 975 char *machine, *cluster, temp_buf[BUFSIZ], *args[10];
976 Bool add_it, one_machine, one_cluster;
977 struct qelem * melem, *mtop, *celem, *ctop;
978
1c3831ea 979 machine = canonicalize_hostname(strsave(argv[1]));
fbebf6df 980 if (strcasecmp(machine, argv[1]) && *argv[1] != '"') {
576ba5e7 981 sprintf(temp_buf, "Warning: '%s' canonicalized to '%s'.",
982 argv[1], machine);
983 Put_message(temp_buf);
984 }
85ca828a 985 cluster = argv[2];
986
987 celem = ctop = GetMCInfo(CLUSTER, cluster, (char *) NULL);
988 melem = mtop = GetMCInfo(MACHINE, machine, (char *) NULL);
1c3831ea 989 free(machine);
85ca828a 990
991 one_machine = (QueueCount(mtop) == 1);
992 one_cluster = (QueueCount(ctop) == 1);
993
402461ad 994 /* No good way to use QueryLoop() here, sigh */
995
85ca828a 996 while (melem != NULL) {
997 char ** minfo = (char **) melem->q_data;
998 while (celem != NULL) {
999 char ** cinfo = (char **) celem->q_data;
1000 if (one_machine && one_cluster)
1001 add_it = TRUE;
1002 else {
1003 sprintf(temp_buf,"Add machine %s to cluster %s (y/n/q) ?",
1004 minfo[M_NAME], cinfo[C_NAME]);
1005 switch (YesNoQuitQuestion(temp_buf, FALSE)) {
1006 case TRUE:
1007 add_it = TRUE;
1008 break;
1009 case FALSE:
1010 add_it = FALSE;
1011 break;
1012 default:
1013 Put_message("Aborting...");
1014 FreeQueue(ctop);
1015 FreeQueue(mtop);
1016 return(DM_NORMAL);
1017 }
1018 }
1019 if (add_it) {
1020 args[0] = minfo[M_NAME];
1021 args[1] = cinfo[C_NAME];
8defc06b 1022 stat = do_mr_query("add_machine_to_cluster", 2, args,
14f99d7d 1023 Scream, NULL);
85ca828a 1024 switch (stat) {
8defc06b 1025 case MR_SUCCESS:
85ca828a 1026 break;
8defc06b 1027 case MR_EXISTS:
85ca828a 1028 sprintf(temp_buf, "%s is already in cluster %s",
1029 minfo[M_NAME], cinfo[C_NAME]);
1030 Put_message(temp_buf);
1031 break;
1032 default:
1033 com_err(program_name, stat, " in AddMachineToCluster.");
1034 break;
1035 }
1036 }
1037 celem = celem->q_forw;
1038 }
1039 celem = ctop; /* reset cluster element. */
1040 melem = melem->q_forw;
1041 }
1042 FreeQueue(ctop);
1043 FreeQueue(mtop);
08345b74 1044 return(DM_NORMAL);
1045}
1046
402461ad 1047/* Function Name: RealRemoveMachineFromCluster
1048 * Description: This function actually removes the machine from its
1049 * cluster.
1050 * Arguments: info - all information nescessary to perform the removal.
1051 * one_map - True if there is only one case, and we should
1052 * confirm.
1053 * Returns: none.
1054 */
1055
1056static void
1057RealRemoveMachineFromCluster(info, one_map)
1058char ** info;
1059Bool one_map;
1060{
1061 char temp_buf[BUFSIZ];
1062 register int stat;
1063
1064 sprintf(temp_buf, "Remove %s from the cluster %s",
04597fbb 1065 info[MAP_MACHINE], info[MAP_CLUSTER]);
402461ad 1066 if (!one_map || Confirm(temp_buf)) {
8defc06b 1067 if ( (stat = do_mr_query("delete_machine_from_cluster", 2,
14f99d7d 1068 info, Scream, NULL)) != 0 )
402461ad 1069 com_err(program_name, stat, " in delete_machine_from_cluster");
1070 else {
1071 sprintf(temp_buf, "%s has been removed from the cluster %s.",
1072 info[MAP_MACHINE], info[MAP_CLUSTER]);
1073 Put_message(temp_buf);
1074 }
1075 }
1076 else
1077 Put_message("Machine not removed.");
1078}
1079
08345b74 1080/* Function Name: RemoveMachineFromCluster
1081 * Description: Removes this machine form a specific cluster.
1082 * Arguments: argc, argv - Name of machine in argv[1].
85ca828a 1083 * Name of cluster in argv[2].
08345b74 1084 * Returns: none.
1085 */
1086
1087/* ARGSUSED */
1088int
1089RemoveMachineFromCluster(argc, argv)
1090int argc;
1091char ** argv;
1092{
402461ad 1093 struct qelem *elem = NULL;
85ca828a 1094 char buf[BUFSIZ], * args[10];
402461ad 1095 register int stat;
85ca828a 1096
1c3831ea 1097 args[MAP_MACHINE] = canonicalize_hostname(strsave(argv[1]));
fbebf6df 1098 if (strcasecmp(args[MAP_MACHINE], argv[1]) && *argv[1] != '"') {
dc5b50ac 1099 sprintf(buf, "Warning: '%s' canonicalized to '%s'.",
576ba5e7 1100 argv[1], args[MAP_MACHINE]);
dc5b50ac 1101 Put_message(buf);
576ba5e7 1102 }
85ca828a 1103 args[MAP_CLUSTER] = argv[2];
1104 args[MAP_END] = NULL;
1105
8defc06b 1106 stat = do_mr_query("get_machine_to_cluster_map", CountArgs(args), args,
14f99d7d 1107 StoreInfo, (char *)&elem);
8defc06b 1108 if (stat == MR_NO_MATCH) {
85ca828a 1109 sprintf(buf, "The machine %s is not is the cluster %s.",
1110 args[MAP_MACHINE], args[MAP_CLUSTER]);
1111 Put_message(buf);
1c3831ea 1112 free(args[MAP_MACHINE]);
85ca828a 1113 return(DM_NORMAL);
08345b74 1114 }
8defc06b 1115 if (stat != MR_SUCCESS)
85ca828a 1116 com_err(program_name, stat, " in delete_machine_from_cluster");
1117
402461ad 1118 elem = QueueTop(elem);
1119 QueryLoop(elem, PrintMCMap, RealRemoveMachineFromCluster,
1120 "Remove this machine from this cluster");
1121
1122 FreeQueue(elem);
1c3831ea 1123 free(args[MAP_MACHINE]);
08345b74 1124 return(DM_NORMAL);
1125}
1126
ad7e0e04 1127/* ---------- Subnet Menu -------- */
1128
1129/* Function Name: ShowSubnetInfo
1130 * Description: Gets information about a subnet given its name.
1131 * Arguments: argc, argc - the name of the subnet in in argv[1].
1132 * Returns: DM_NORMAL.
1133 */
1134
1135/* ARGSUSED */
1136int
1137ShowSubnetInfo(argc, argv)
1138int argc;
1139char ** argv;
1140{
1141 struct qelem *top;
1142
1143 top = GetMCInfo(SUBNET, argv[1], (char *) NULL);
1144 Loop(top, (void *) PrintSubnetInfo);
1145 FreeQueue(top);
1146 return(DM_NORMAL);
1147}
1148
1149/* Function Name: AddSubnet
1150 * Description: Creates a new subnet.
1151 * Arguments: argc, argv - the name of the new subnet is argv[1].
1152 * Returns: DM_NORMAL.
1153 */
1154
1155/* ARGSUSED */
1156int
1157AddSubnet(argc, argv)
1158int argc;
1159char ** argv;
1160{
1161 char **args, *info[MAX_ARGS_SIZE], *name = argv[1];
1162 int stat;
1163/*
1164 * Check to see if this subnet already exists.
1165 */
1166 if (!ValidName(name))
1167 return(DM_NORMAL);
1168
1169 if ( (stat = do_mr_query("get_subnet", 1, &name,
1170 NullFunc, NULL)) == MR_SUCCESS) {
1171 Put_message("This subnet already exists.");
1172 return(DM_NORMAL);
1173 }
1174 else if (stat != MR_NO_MATCH) {
1175 com_err(program_name, stat, " in AddSubnet.");
1176 return(DM_NORMAL);
1177 }
1178 if ((args = AskMCDInfo(SetSubnetDefaults(info, name), SUBNET, FALSE)) ==
1179 NULL) {
1180 Put_message("Aborted.");
1181 FreeInfo(info);
1182 return(DM_NORMAL);
1183 }
1184
1185/*
1186 * Actually create the new Subnet.
1187 */
1188 if ( (stat = do_mr_query("add_subnet", CountArgs(args),
1189 args, Scream, NULL)) != 0)
1190 com_err(program_name, stat, " in AddSubnet.");
1191
1192 FreeInfo(info);
1193 return(DM_NORMAL);
1194}
1195
1196/* Function Name: RealUpdateSubnet
1197 * Description: This function actually performs the subnet update.
1198 * Arguments: info - all information nesc. for updating the subnet.
1199 * junk - an UNUSED boolean.
1200 * Returns: none.
1201 */
1202
1203/* ARGSUSED */
1204static void
1205RealUpdateSubnet(info, junk)
1206char ** info;
1207Bool junk;
1208{
1209 register int stat;
1210 char ** args = AskMCDInfo(info, SUBNET, TRUE);
1211 if (args == NULL) {
1212 Put_message("Aborted.");
1213 return;
1214 }
1215 if ( (stat = do_mr_query("update_subnet", CountArgs(args),
1216 args, Scream, NULL)) != 0)
1217 com_err(program_name, stat, " in UpdateSubnet.");
1218 else
1219 Put_message("Subnet successfully updated.");
1220}
1221
1222/* Function Name: UpdateSubnet
1223 * Description: This Function Updates a subnet
1224 * Arguments: name of the subnet in argv[1].
1225 * Returns: DM_NORMAL.
1226 */
1227
1228/* ARGSUSED */
1229int
1230UpdateSubnet(argc, argv)
1231int argc;
1232char ** argv;
1233{
1234 struct qelem *top;
1235 top = GetMCInfo( SUBNET, argv[1], (char *) NULL );
1236 QueryLoop(top, NullPrint, RealUpdateSubnet, "Update the subnet");
1237
1238 FreeQueue(top);
1239 return(DM_NORMAL);
1240}
1241
1242/* Function Name: RealDeleteSubnet
1243 * Description: Actually performs the subnet deletion.
1244 * Arguments: info - all information about this subnet.
1245 * one_subnet - If true then there was only one subnet in
1246 * the queue, and we should confirm.
1247 * Returns: none.
1248 */
1249
1250static void
1251RealDeleteSubnet(info, one_subnet)
1252char ** info;
1253Bool one_subnet;
1254{
1255 register int stat;
1256 char temp_buf[BUFSIZ];
1257
1258 sprintf(temp_buf,
1259 "Are you sure the you want to delete the subnet %s (y/n) ?",
1260 info[C_NAME]);
1261 if (!one_subnet || Confirm(temp_buf)) {
1262 if ( (stat = do_mr_query("delete_subnet", 1,
1263 &info[C_NAME], Scream, NULL)) != 0) {
1264 com_err(program_name, stat, " in delete_subnet.");
1265 sprintf(temp_buf, "Subnet %s ** NOT ** deleted.",
1266 info[C_NAME]);
1267 Put_message(temp_buf);
1268 }
1269 else {
1270 sprintf(temp_buf, "subnet %s sucesfully deleted.",
1271 info[C_NAME]);
1272 Put_message(temp_buf);
1273 }
1274 }
1275}
1276
1277/* Function Name: DeleteSubnet
1278 * Description: This function removes a subnet from the database.
1279 * Arguments: argc, argv - the name of the subnet is stored in argv[1].
1280 * Returns: DM_NORMAL.
1281 */
1282
1283/* ARGSUSED */
1284int
1285DeleteSubnet(argc, argv)
1286int argc;
1287char ** argv;
1288{
1289 struct qelem *top;
1290
1291 top = GetMCInfo( SUBNET, argv[1], (char *) NULL );
1292 QueryLoop(top, PrintSubnetInfo, RealDeleteSubnet, "Delete the subnet");
1293
1294 FreeQueue(top);
1295 return(DM_NORMAL);
1296}
1297
08345b74 1298/* ---------- Cluster Menu -------- */
1299
1300/* Function Name: ShowClusterInfo
1301 * Description: Gets information about a cluser given its name.
1302 * Arguments: argc, argc - the name of the cluster in in argv[1].
1303 * Returns: DM_NORMAL.
1304 */
1305
1306/* ARGSUSED */
1307int
461c03b6 1308ShowClusterInfo(argc, argv)
08345b74 1309int argc;
1310char ** argv;
1311{
402461ad 1312 struct qelem *top;
08345b74 1313
5cd3b188 1314 top = GetMCInfo(CLUSTER, argv[1], (char *) NULL);
402461ad 1315 Loop(top, (void *) PrintClusterInfo);
08345b74 1316 FreeQueue(top);
1317 return(DM_NORMAL);
1318}
1319
1320/* Function Name: AddCluster
1321 * Description: Creates a new cluster.
1322 * Arguments: argc, argv - the name of the new cluster is argv[1].
1323 * Returns: DM_NORMAL.
1324 */
1325
1326/* ARGSUSED */
1327int
1328AddCluster(argc, argv)
1329int argc;
1330char ** argv;
1331{
402461ad 1332 char **args, *info[MAX_ARGS_SIZE], *name = argv[1];
08345b74 1333 int stat;
1334/*
402461ad 1335 * Check to see if this cluster already exists.
08345b74 1336 */
402461ad 1337 if (!ValidName(name))
1338 return(DM_NORMAL);
08345b74 1339
8defc06b 1340 if ( (stat = do_mr_query("get_cluster", 1, &name,
1341 NullFunc, NULL)) == MR_SUCCESS) {
08345b74 1342 Put_message("This cluster already exists.");
1343 return(DM_NORMAL);
1344 }
8defc06b 1345 else if (stat != MR_NO_MATCH) {
461c03b6 1346 com_err(program_name, stat, " in AddCluster.");
08345b74 1347 return(DM_NORMAL);
1348 }
576ba5e7 1349 if ((args = AskMCDInfo(SetClusterDefaults(info, name), CLUSTER, FALSE)) ==
1350 NULL) {
1351 Put_message("Aborted.");
1352 FreeInfo(info);
1353 return(DM_NORMAL);
1354 }
1355
08345b74 1356/*
1357 * Actually create the new Cluster.
1358 */
8defc06b 1359 if ( (stat = do_mr_query("add_cluster", CountArgs(args),
14f99d7d 1360 args, Scream, NULL)) != 0)
461c03b6 1361 com_err(program_name, stat, " in AddCluster.");
08345b74 1362
1363 FreeInfo(info);
1364 return(DM_NORMAL);
1365}
1366
402461ad 1367/* Function Name: RealUpdateCluster
1368 * Description: This function actually performs the cluster update.
1369 * Arguments: info - all information nesc. for updating the cluster.
1370 * junk - an UNUSED boolean.
1371 * Returns: none.
1372 */
1373
1374/* ARGSUSED */
1375static void
1376RealUpdateCluster(info, junk)
1377char ** info;
1378Bool junk;
1379{
1380 register int stat;
1381 char ** args = AskMCDInfo(info, CLUSTER, TRUE);
576ba5e7 1382 if (args == NULL) {
1383 Put_message("Aborted.");
1384 return;
1385 }
8defc06b 1386 if ( (stat = do_mr_query("update_cluster", CountArgs(args),
14f99d7d 1387 args, Scream, NULL)) != 0)
402461ad 1388 com_err(program_name, stat, " in UpdateCluster.");
1389 else
1390 Put_message("Cluster successfully updated.");
1391}
1392
08345b74 1393/* Function Name: UpdateCluster
1394 * Description: This Function Updates a cluster
1395 * Arguments: name of the cluster in argv[1].
1396 * Returns: DM_NORMAL.
1397 */
1398
1399/* ARGSUSED */
1400int
1401UpdateCluster(argc, argv)
1402int argc;
1403char ** argv;
1404{
402461ad 1405 struct qelem *top;
1406 top = GetMCInfo( CLUSTER, argv[1], (char *) NULL );
1407 QueryLoop(top, NullPrint, RealUpdateCluster, "Update the cluster");
08345b74 1408
08345b74 1409 FreeQueue(top);
1410 return(DM_NORMAL);
1411}
1412
85ca828a 1413/* Function Name: CheckAndRemoveMachine
1414 * Description: This function checks and removes all machines from a
1415 * cluster.
1416 * Arguments: name - name of the cluster.
1417 * ask_first - if TRUE, then we will query the user, before
1418 * deletion.
1419 * Returns: SUB_ERROR if all machines not removed.
1420 */
1421
1422int
1423CheckAndRemoveMachines(name, ask_first)
1424char * name;
1425Bool ask_first;
1426{
1427 register int stat, ret_value;
1428 Bool delete_it;
1429 char *args[10], temp_buf[BUFSIZ], *ptr;
1430 struct qelem *top, *elem = NULL;
1431
1432 ret_value = SUB_NORMAL;
1433 args[MAP_MACHINE] = "*";
1434 args[MAP_CLUSTER] = name;
8defc06b 1435 stat = do_mr_query("get_machine_to_cluster_map", 2, args,
14f99d7d 1436 StoreInfo, (char *)&elem);
8defc06b 1437 if (stat && stat != MR_NO_MATCH) {
85ca828a 1438 com_err(program_name, stat, " in get_machine_to_cluster_map.");
1439 return(DM_NORMAL);
1440 }
1441 if (stat == 0) {
1442 elem = top = QueueTop(elem);
1443 if (ask_first) {
1444 sprintf(temp_buf,
1445 "The cluster %s has the following machines in it:",
1446 name);
1447 Put_message(temp_buf);
1448 while (elem != NULL) {
1449 char **info = (char **) elem->q_data;
1450 Print(1, &info[MAP_MACHINE], (char *) NULL);
1451 elem = elem->q_forw;
1452 }
1453 ptr = "Remove ** ALL ** these machines from this cluster?";
1454
1455 if (YesNoQuestion(ptr, FALSE) == TRUE) /* may return -1. */
1456 delete_it = TRUE;
1457 else {
1458 Put_message("Aborting...");
1459 FreeQueue(top);
1460 return(SUB_ERROR);
1461 }
1462 }
1463 else
1464 delete_it = TRUE;
1465
1466 if (delete_it) {
1467 elem = top;
1468 while (elem != 0) {
1469 char **info = (char **) elem->q_data;
8defc06b 1470 if ( (stat = do_mr_query("delete_machine_from_cluster",
14f99d7d 1471 2, info, Scream, NULL)) != 0) {
85ca828a 1472 ret_value = SUB_ERROR;
1473 com_err(program_name, stat,
1474 " in delete_machine_from_cluster.");
1475 sprintf(temp_buf,
1476 "Machine %s ** NOT ** removed from cluster %s.",
1477 info[MAP_MACHINE], info[MAP_CLUSTER]);
1478 Put_message(temp_buf);
1479 }
1480 elem = elem->q_forw;
1481 }
1482 }
1483 }
1484 return(ret_value);
1485}
1486
402461ad 1487/* Function Name: RealDeleteCluster
1488 * Description: Actually performs the cluster deletion.
1489 * Arguments: info - all information about this cluster.
1490 * one_cluster - If true then there was only one cluster in
1491 * the queue, and we should confirm.
1492 * Returns: none.
1493 */
1494
1495static void
1496RealDeleteCluster(info, one_cluster)
1497char ** info;
1498Bool one_cluster;
1499{
1500 register int stat;
1501 char temp_buf[BUFSIZ];
1502
1503 sprintf(temp_buf,
1504 "Are you sure the you want to delete the cluster %s (y/n) ?",
1505 info[C_NAME]);
1506 if (!one_cluster || Confirm(temp_buf)) {
1507 if (CheckAndRemoveMachines(info[C_NAME], TRUE) != SUB_ERROR) {
8defc06b 1508 if ( (stat = do_mr_query("delete_cluster", 1,
14f99d7d 1509 &info[C_NAME], Scream, NULL)) != 0) {
402461ad 1510 com_err(program_name, stat, " in delete_cluster.");
1511 sprintf(temp_buf, "Cluster %s ** NOT ** deleted.",
1512 info[C_NAME]);
1513 Put_message(temp_buf);
1514 }
1515 else {
1516 sprintf(temp_buf, "cluster %s sucesfully deleted.",
1517 info[C_NAME]);
1518 Put_message(temp_buf);
1519 }
1520 }
1521 }
1522}
85ca828a 1523
08345b74 1524/* Function Name: DeleteCluster
1525 * Description: This function removes a cluster from the database.
1526 * Arguments: argc, argv - the name of the cluster is stored in argv[1].
1527 * Returns: DM_NORMAL.
1528 */
1529
1530/* ARGSUSED */
1531int
461c03b6 1532DeleteCluster(argc, argv)
08345b74 1533int argc;
1534char ** argv;
1535{
402461ad 1536 struct qelem *top;
08345b74 1537
402461ad 1538 top = GetMCInfo( CLUSTER, argv[1], (char *) NULL );
1539 QueryLoop(top, PrintClusterInfo, RealDeleteCluster, "Delete the cluster");
08345b74 1540
85ca828a 1541 FreeQueue(top);
08345b74 1542 return(DM_NORMAL);
1543}
402461ad 1544
08345b74 1545/* ----------- Cluster Data Menu -------------- */
1546
1547/* Function Name: ShowClusterData
1548 * Description: This function shows the services for one cluster.
1549 * Arguments: argc, argv - The name of the cluster is argv[1].
461c03b6 1550 * The label of the data in argv[2].
08345b74 1551 * Returns: DM_NORMAL.
1552 */
1553
85ca828a 1554/* ARGSUSED */
08345b74 1555int
1556ShowClusterData(argc, argv)
1557int argc;
1558char ** argv;
1559{
1560 struct qelem *elem, *top;
1561 char **info;
1562
461c03b6 1563 top = elem = GetMCInfo(DATA, argv[1], argv[2]);
08345b74 1564 while (elem != NULL) {
1565 info = (char **) elem->q_data;
1566 PrintClusterData(info);
461c03b6 1567 elem = elem->q_forw;
08345b74 1568 }
1569 FreeQueue(top);
1570 return(DM_NORMAL);
1571}
1572
1573/* Function Name: AddClusterData
1574 * Description: This function adds some data to the cluster.
1575 * Arguments: argv, argc: argv[1] - the name of the cluster.
1576 * argv[2] - the label of the data.
1577 * argv[3] - the data.
1578 * Returns: DM_NORMAL.
1579 */
1580
1581/* ARGSUSED */
1582int
1583AddClusterData(argc, argv)
1584int argc;
1585char ** argv;
1586{
461c03b6 1587 int stat;
1588
8defc06b 1589 if( (stat = do_mr_query("add_cluster_data", 3, argv + 1,
14f99d7d 1590 Scream, (char *) NULL)) != 0)
461c03b6 1591 com_err(program_name, stat, " in AddClusterData.");
7b53f00f 1592 return(DM_NORMAL);
08345b74 1593}
1594
402461ad 1595/* Function Name: RealRemoveClusterData
1596 * Description: actually removes the cluster data.
1597 * Arguments: info - all info necessary to remove the cluster, in an array
1598 * of strings.
1599 * one_item - if true then the queue has only one elem and we
1600 * should confirm.
1601 * Returns: none.
1602 */
1603
1604static void
1605RealRemoveClusterData(info, one_item)
1606char ** info;
1607Bool one_item;
1608{
1609 register int stat;
1610 char * temp_ptr;
1611
1612 Put_message(" ");
bae441d9 1613 temp_ptr = "Are you sure that you want to remove this cluster data (y/n) ?";
1614 PrintClusterData(info);
402461ad 1615 if (!one_item || Confirm(temp_ptr)) {
8defc06b 1616 if( (stat = do_mr_query("delete_cluster_data", 3, info,
14f99d7d 1617 Scream, (char *) NULL)) != 0) {
402461ad 1618 com_err(program_name, stat, " in DeleteClusterData.");
1619 Put_message("Data not removed.");
1620 }
1621 else
1622 Put_message("Removal sucessful.");
1623 }
1624}
1625
461c03b6 1626/* Function Name: RemoveClusterData
1627 * Description: This function removes data on a given cluster.
08345b74 1628 * Arguments: argv, argc: argv[1] - the name of the cluster.
1629 * argv[2] - the label of the data.
1630 * argv[3] - the data.
1631 * Returns: DM_NORMAL.
1632 */
1633
1634/* ARGSUSED */
461c03b6 1635int
1636RemoveClusterData(argc, argv)
08345b74 1637int argc;
1638char ** argv;
1639{
402461ad 1640 struct qelem *top;
08345b74 1641
402461ad 1642 top = GetMCInfo(DATA, argv[1], argv[2]);
1643 QueryLoop(top, PrintClusterData, RealRemoveClusterData,
1f88d281 1644 "Remove data from cluster");
08345b74 1645
85ca828a 1646 FreeQueue(top);
08345b74 1647 return(DM_NORMAL);
1648}
1649
08345b74 1650/* Function Name: MachineToClusterMap
1651 * Description: This Retrieves the mapping between machine and cluster
1652 * Arguments: argc, argv - argv[1] -> machine name or wildcard.
1653 * argv[2] -> cluster name or wildcard.
1654 * Returns: none.
1655 */
1656
1657/* ARGSUSED */
1658int
1659MachineToClusterMap(argc,argv)
1660int argc;
1661char **argv;
1662{
461c03b6 1663 struct qelem *elem, *top;
dc5b50ac 1664 char *tmpname, temp_buf[256];
08345b74 1665
1c3831ea 1666 tmpname = canonicalize_hostname(strsave(argv[1]));
fbebf6df 1667 if (strcasecmp(tmpname, argv[1]) && *argv[1] != '"') {
576ba5e7 1668 sprintf(temp_buf, "Warning: '%s' canonicalized to '%s'.",
1669 argv[1], tmpname);
1670 Put_message(temp_buf);
1671 }
1c3831ea 1672 top = elem = GetMCInfo(MAP, tmpname, argv[2]);
08345b74 1673
85ca828a 1674 Put_message(""); /* blank line on screen */
461c03b6 1675 while (elem != NULL) {
1676 char ** info = (char **) elem->q_data;
1677 PrintMCMap(info);
1678 elem = elem->q_forw;
1679 }
1680
1681 FreeQueue(top);
1c3831ea 1682 free(tmpname);
461c03b6 1683 return(DM_NORMAL);
1684}
This page took 0.54647 seconds and 5 git commands to generate.