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