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