]> andersk Git - moira.git/blame - clients/moira/cluster.c
thou shalt not free memory thou did not malloc
[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>
24419c79 25#include <string.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 */
4bae4be1 550
551
552 if(name) {
553 /* info did not come from SetMachineDefaults(), which does not
554 * initialize entry 8 (M_STAT_CHNG), therefore we can
555 * free it.
556 */
557 /* This is an update of an existing machine and the structure
558 * was filled in thru a query to the db which does fill in this
559 * field.
560 */
ad7e0e04 561 free(info[8]);
4bae4be1 562 }
563
564 info[8] = info[M_SUBNET];
565 info[9] = info[M_ADDR];
566 info[10] = info[M_OWNER_TYPE];
567 info[11] = info[M_OWNER_NAME];
568 info[12] = info[M_ACOMMENT];
569 info[13] = info[M_OCOMMENT];
54864ee6 570
571 if(name)
572 if (GetValueFromUser("Machine's network (or 'none')", &info[8])
ad7e0e04 573 == SUB_ERROR)
54864ee6 574 return(NULL);
ad7e0e04 575 if (GetValueFromUser("Machine's address (or 'unassigned' or 'unique')",
576 &info[9]) == SUB_ERROR)
577 return(NULL);
54864ee6 578 if (GetTypeFromUser("Machine's owner type", "ace_type", &info[10]) ==
576ba5e7 579 SUB_ERROR)
580 return(NULL);
ad7e0e04 581 if (strcmp(info[10], "NONE") &&
582 GetValueFromUser("Owner's Name", &info[11]) == SUB_ERROR)
583 return(NULL);
54864ee6 584 if (GetValueFromUser("Administrative comment", &info[12]) == SUB_ERROR)
ad7e0e04 585 return(NULL);
54864ee6 586 if (GetValueFromUser("Operational comment", &info[13]) == SUB_ERROR)
ad7e0e04 587 return(NULL);
588 info[14] = NULL;
589 FreeAndClear(&info[15], TRUE);
590 FreeAndClear(&info[16], TRUE);
591 break;
592 case SUBNET:
54864ee6 593 if (GetValueFromUser("Network description", &info[SN_DESC]) == SUB_ERROR)
ad7e0e04 594 return(NULL);
54864ee6 595 if (GetAddressFromUser("Network address", &info[SN_ADDRESS]) == SUB_ERROR)
ad7e0e04 596 return(NULL);
54864ee6 597 if (GetAddressFromUser("Network mask", &info[SN_MASK]) == SUB_ERROR)
ad7e0e04 598 return(NULL);
5cfca28f 599 if (atoi(info[SN_LOW]) == ntohl(inet_addr(S_DEFAULT_LOW))) {
600 struct in_addr low;
601 unsigned long mask, addr;
602
603 addr = atoi(info[SN_ADDRESS]);
604 mask = atoi(info[SN_MASK]);
605 low.s_addr = atoi(info[SN_LOW]);
606 low.s_addr = (low.s_addr & ~mask) | (addr & mask);
607 free(info[SN_LOW]);
608 sprintf(temp_buf, "%d", low.s_addr);
609 info[SN_LOW] = strsave(temp_buf);
610 }
ad7e0e04 611 if (GetAddressFromUser("Lowest assignable address", &info[SN_LOW]) == SUB_ERROR)
612 return(NULL);
5cfca28f 613 if (atoi(info[SN_HIGH]) == ntohl(inet_addr(S_DEFAULT_HIGH))) {
614 struct in_addr high;
615 unsigned long mask, addr;
616
617 addr = atoi(info[SN_ADDRESS]);
618 mask = atoi(info[SN_MASK]);
619 high.s_addr = atoi(info[SN_HIGH]);
620 high.s_addr = (high.s_addr & ~mask) | (addr & mask);
621 free(info[SN_HIGH]);
622 sprintf(temp_buf, "%d", high.s_addr);
623 info[SN_HIGH] = strsave(temp_buf);
624 }
ad7e0e04 625 if (GetAddressFromUser("Highest assignable address", &info[SN_HIGH]) == SUB_ERROR)
626 return(NULL);
5cfca28f 627 if (GetValueFromUser("Hostname prefix", &info[SN_PREFIX]) == SUB_ERROR)
628 return(NULL);
54864ee6 629 if (GetTypeFromUser("Owner type", "ace_type", &info[SN_ACE_TYPE]) == SUB_ERROR)
ad7e0e04 630 return(NULL);
631 if (strcmp(info[SN_ACE_TYPE], "NONE") &&
54864ee6 632 GetValueFromUser("Owner name", &info[SN_ACE_NAME]) == SUB_ERROR)
ad7e0e04 633 return(NULL);
634 FreeAndClear(&info[SN_MODTIME], TRUE);
635 FreeAndClear(&info[SN_MODBY], TRUE);
636 FreeAndClear(&info[SN_MODWITH], TRUE);
08345b74 637 break;
461c03b6 638 case CLUSTER:
576ba5e7 639 if (GetValueFromUser("Cluster's Description:", &info[C_DESCRIPT]) ==
640 SUB_ERROR)
641 return(NULL);
642 if (GetValueFromUser("Cluster's Location:", &info[C_LOCATION]) ==
643 SUB_ERROR)
644 return(NULL);
08345b74 645 FreeAndClear(&info[C_MODTIME], TRUE);
646 FreeAndClear(&info[C_MODBY], TRUE);
647 FreeAndClear(&info[C_MODWITH], TRUE);
648 break;
461c03b6 649 case DATA:
576ba5e7 650 if (GetValueFromUser("Label defining this data?", &info[CD_LABEL]) ==
651 SUB_ERROR)
652 return(NULL);
653 if (GetValueFromUser("The data itself ? ", &info[CD_DATA]) == SUB_ERROR)
654 return(NULL);
08345b74 655 break;
656 }
657
658/*
659 * Slide the newname into the #2 slot, this screws up all future references
660 * to this list.
661 */
662 if (name)
663 SlipInNewName(info, newname);
664
665 return(info);
666}
667
668/* ----------- Machine Menu ----------- */
669
670/* Function Name: ShowMachineInfo
671 * Description: This function shows the information about a machine.
672 * Arguments: argc, argv - the name of the machine in argv[1].
673 * Returns: DM_NORMAL.
674 */
675
676/* ARGSUSED */
677int
678ShowMachineInfo(argc, argv)
679int argc;
680char **argv;
681{
402461ad 682 struct qelem *top;
1c3831ea 683 char *tmpname;
08345b74 684
1c3831ea 685 tmpname = canonicalize_hostname(strsave(argv[1]));
686 top = GetMCInfo(MACHINE, tmpname, (char *) NULL);
402461ad 687 Loop(top, ( (void *) PrintMachInfo) );
08345b74 688 FreeQueue(top);
689 return(DM_NORMAL);
690}
691
ad7e0e04 692/* Function Name: ShowMachineQuery
693 * Description: This function shows the information about a machine.
694 * or group of machines, which may be selected through a
695 * number of criteria.
696 * Arguments: argc, argv - the name of the machine in argv[1],
697 * the address of the machine in argv[2],
698 * the location of the machine in argv[3],
699 * and the contact name in argv[4].
700 * any of these may be wildcards.
701 * Returns: DM_NORMAL.
702 */
703
704/* ARGSUSED */
705int
706ShowMachineQuery(argc, argv)
707int argc;
708char **argv;
709{
710 int stat;
711 struct qelem *top, *elem = NULL;
712 char *args[5];
713
714 if (!strcmp(argv[1], "") && !strcmp(argv[2], "") &&
715 !strcmp(argv[3], "") && !strcmp(argv[4], "")) {
716 Put_message("You must specify at least one parameter of the query.");
717 return(DM_NORMAL);
718 }
719
720 if (*argv[1])
721 args[0] = canonicalize_hostname(strsave(argv[1]));
722 else
723 args[0] = "*";
724 if (*argv[2])
725 args[1] = argv[2];
726 else
727 args[1] = "*";
728 if (*argv[3])
729 args[2] = argv[3];
730 else
731 args[2] = "*";
732 if (*argv[4])
733 args[3] = argv[4];
734 else
735 args[3] = "*";
736
737 if ((stat = do_mr_query("get_host", 4, args, StoreInfo,
738 (char *)&elem)) != 0) {
739 if (stat == MR_NO_MATCH)
740 Put_message("No machine(s) found matching query in the database.");
741 else
742 com_err(program_name, stat, " in get_machine.");
743 return(DM_NORMAL);
744 }
745 top = QueueTop(elem);
746 Loop(top, ( (void *) PrintMachInfo) );
747 FreeQueue(top);
748 return(DM_NORMAL);
749}
750
08345b74 751/* Function Name: AddMachine
752 * Description: This function adds a new machine to the database.
54864ee6 753 * Arguments: argc, argv - the name of the network in argv[1].
08345b74 754 * Returns: DM_NORMAL.
755 */
756
757/* ARGSUSED */
758int
759AddMachine(argc, argv)
760int argc;
761char **argv;
762{
ad7e0e04 763 char **args, *info[MAX_ARGS_SIZE], *name, buf[256], *xargs[5];
54864ee6 764 char **rinfo;
765 struct qelem * elem = NULL;
08345b74 766 int stat;
402461ad 767
768 if (!ValidName(argv[1])) /* Checks for wildcards. */
769 return(DM_NORMAL);
54864ee6 770
771 /*
772 * get the network record
773 */
774
775 if (strcasecmp(argv[1], "none") &&
776 (stat = do_mr_query("get_subnet", 1, &argv[1],
777 StoreInfo, (char *)&elem)) != 0) {
778 if (stat == MR_NO_MATCH) {
779 char buf[128];
780 sprintf(buf, "Network '%s' is not in the database.", argv[1]);
781 Put_message(buf);
782 } else
783 com_err(program_name, stat, " in get_subnet.");
784 return(DM_NORMAL);
785 }
786
08345b74 787/*
788 * Check to see if this machine already exists.
789 */
54864ee6 790
791 name = strsave(""); /* want to put prefix here */
792 if (GetValueFromUser("Machine name", &name) == SUB_ERROR)
793 return(NULL);
794
795 name = canonicalize_hostname(strsave(name));
08345b74 796
ad7e0e04 797 xargs[0] = name;
798 xargs[1] = xargs[2] = xargs[3] = "*";
799 if ( (stat = do_mr_query("get_host", 4, xargs, NullFunc, NULL)) == 0) {
576ba5e7 800 sprintf(buf, "The machine '%s' already exists.", name);
801 Put_message(buf);
1c3831ea 802 free(name);
08345b74 803 return(DM_NORMAL);
804 }
8defc06b 805 else if (stat != MR_NO_MATCH) {
576ba5e7 806 com_err(program_name, stat,
807 " while checking machine '%s' in AddMachine.", name);
1c3831ea 808 free(name);
08345b74 809 return(DM_NORMAL);
810 }
54864ee6 811 rinfo = SetMachineDefaults(info, name);
812 rinfo[M_SUBNET] = argv[1];
813 if ((args = AskMCDInfo(rinfo, MACHINE, FALSE)) == NULL) {
576ba5e7 814 Put_message("Aborted.");
815 return(DM_NORMAL);
816 }
08345b74 817
818/*
819 * Actually create the new Machine.
820 */
821
ad7e0e04 822 if ( (stat = do_mr_query("add_host", CountArgs(args),
14f99d7d 823 args, Scream, NULL)) != 0)
461c03b6 824 com_err(program_name, stat, " in AddMachine.");
08345b74 825
826 FreeInfo(info);
1c3831ea 827 free(name);
08345b74 828 return(DM_NORMAL);
829}
830
402461ad 831/* Function Name: RealUpdateMachine
832 * Description: Performs the actual update of the machine data.
833 * Arguments: info - the information on the machine to update.
834 * junk - an UNUSED Boolean.
835 * Returns: none.
836 */
837
838/* ARGSUSED */
839static void
840RealUpdateMachine(info, junk)
841char ** info;
842Bool junk;
843{
844 register int stat;
845 char ** args = AskMCDInfo(info, MACHINE, TRUE);
576ba5e7 846 if (args == NULL) {
847 Put_message("Aborted.");
848 return;
849 }
ad7e0e04 850 if ( (stat = do_mr_query("update_host", CountArgs(args),
14f99d7d 851 args, Scream, NULL)) != 0)
402461ad 852 com_err(program_name, stat, " in UpdateMachine.");
853 else
854 Put_message("Machine sucessfully updated.");
855}
856
08345b74 857/* Function Name: UpdateMachine
858 * Description: This function adds a new machine to the database.
859 * Arguments: argc, argv - the name of the machine in argv[1].
860 * Returns: DM_NORMAL.
861 */
862
863/* ARGSUSED */
864int
865UpdateMachine(argc, argv)
866int argc;
867char **argv;
868{
1c3831ea 869 struct qelem *top;
870 char *tmpname;
871
872 tmpname = canonicalize_hostname(strsave(argv[1]));
873 top = GetMCInfo( MACHINE, tmpname, (char *) NULL);
402461ad 874 QueryLoop(top, NullPrint, RealUpdateMachine, "Update the machine");
08345b74 875
08345b74 876 FreeQueue(top);
1c3831ea 877 free(tmpname);
08345b74 878 return(DM_NORMAL);
879}
880
85ca828a 881/* Function Name: CheckAndRemoveFromCluster
882 * Description: This func tests to see if a machine is in a cluster.
883 * and if so then removes it
884 * Arguments: name - name of the machine (already Canonocalized).
885 * ask_user- query the user before removing if from clusters?
8defc06b 886 * Returns: MR_ERROR if machine left in a cluster, or mr_error.
85ca828a 887 */
888
889int
890CheckAndRemoveFromCluster(name, ask_user)
891char * name;
892Bool ask_user;
893{
894 register int stat, ret_value;
895 Bool delete_it;
896 char *args[10], temp_buf[BUFSIZ], *ptr;
897 struct qelem *top, *elem = NULL;
898
402461ad 899 ret_value = SUB_NORMAL; /* initialize ret_value. */
85ca828a 900 args[0] = name;
901 args[1] = "*";
8defc06b 902 stat = do_mr_query("get_machine_to_cluster_map", 2, args,
14f99d7d 903 StoreInfo, (char *)&elem);
8defc06b 904 if (stat && stat != MR_NO_MATCH) {
85ca828a 905 com_err(program_name, stat, " in get_machine_to_cluster_map.");
906 return(DM_NORMAL);
907 }
8defc06b 908 if (stat == MR_SUCCESS) {
85ca828a 909 elem = top = QueueTop(elem);
910 if (ask_user) {
911 sprintf(temp_buf, "%s is assigned to the following clusters.",
912 name);
913 Put_message(temp_buf);
402461ad 914 Loop(top, (void *) PrintMCMap);
85ca828a 915 ptr = "Remove this machine from ** ALL ** these clusters?";
85ca828a 916 if (YesNoQuestion(ptr, FALSE) == TRUE) /* may return -1. */
917 delete_it = TRUE;
918 else {
919 Put_message("Aborting...");
920 FreeQueue(top);
921 return(SUB_ERROR);
922 }
923 }
924 else
925 delete_it = TRUE;
926
927 if (delete_it) {
402461ad 928 while (elem != NULL) {
85ca828a 929 char **info = (char **) elem->q_data;
8defc06b 930 if ( (stat = do_mr_query( "delete_machine_from_cluster",
14f99d7d 931 2, info, Scream, NULL)) != 0) {
85ca828a 932 ret_value = SUB_ERROR;
933 com_err(program_name, stat,
934 " in delete_machine_from_cluster.");
935 sprintf(temp_buf,
936 "Machine %s ** NOT ** removed from cluster %s.",
937 info[MAP_MACHINE], info[MAP_CLUSTER]);
938 Put_message(temp_buf);
939 }
940 elem = elem->q_forw;
941 }
942 }
943 }
944 return(ret_value);
945}
946
402461ad 947/* Function Name: RealDeleteMachine
948 * Description: Actually Deletes the Machine.
949 * Arguments: info - nescessary information stored as an array of char *'s
950 * one_machine - a boolean, true if there is only one item in
951 * the query.
952 * Returns: none.
953 */
954
955static void
956RealDeleteMachine(info, one_machine)
957char ** info;
958Bool one_machine;
959{
960 register int stat;
961 char temp_buf[BUFSIZ];
962
963 sprintf(temp_buf, "Are you sure you want to delete the machine %s (y/n)? ",
964 info[M_NAME]);
965 if(!one_machine || Confirm(temp_buf)) {
966 if (CheckAndRemoveFromCluster(info[M_NAME], TRUE) != SUB_ERROR) {
ad7e0e04 967 if ( (stat = do_mr_query("delete_host", 1,
14f99d7d 968 &info[M_NAME], Scream, NULL)) != 0) {
402461ad 969 com_err(program_name, stat, " in DeleteMachine.");
970 sprintf(temp_buf, "%s ** NOT ** deleted.",
971 info[M_NAME]);
972 Put_message(temp_buf);
973 }
974 else {
975 sprintf(temp_buf, "%s successfully Deleted.", info[M_NAME]);
976 Put_message(temp_buf);
977 }
978 }
979 }
980}
981
08345b74 982/* Function Name: DeleteMachine
983 * Description: This function removes a machine from the data base.
984 * Arguments: argc, argv - the machines name int argv[1].
985 * Returns: DM_NORMAL.
986 */
987
85ca828a 988/* Perhaps we should remove the cluster if it has no machine now. */
989
08345b74 990/* ARGSUSED */
991int
461c03b6 992DeleteMachine(argc, argv)
08345b74 993int argc;
994char **argv;
995{
402461ad 996 struct qelem *top;
1c3831ea 997 char *tmpname;
08345b74 998
1c3831ea 999 tmpname = canonicalize_hostname(strsave(argv[1]));
1000 top = GetMCInfo(MACHINE, tmpname, (char *) NULL);
402461ad 1001 QueryLoop(top, PrintMachInfo, RealDeleteMachine, "Delete the machine");
85ca828a 1002 FreeQueue(top);
1c3831ea 1003 free(tmpname);
08345b74 1004 return(DM_NORMAL);
1005}
1006
5cfca28f 1007
1008char *partial_canonicalize_hostname(s)
1009char *s;
1010{
1011 char buf[256], *cp;
1012 static char *def_domain = NULL;
1013 struct hostent *hp;
1014#ifdef POSIX
1015 struct utsname name;
1016#endif
1017
1018 if (!def_domain) {
1019#ifdef POSIX
1020 (void) uname(&name);
1021 strncpy(buf, name.nodename, sizeof(buf));
1022#else
1023 gethostname(buf, sizeof(buf));
1024#endif
1025 hp = gethostbyname(buf);
54864ee6 1026 cp = (char *) strchr(hp->h_name, '.');
5cfca28f 1027 if (cp)
1028 def_domain = strsave(++cp);
1029 else
1030 def_domain = "";
1031 }
1032
1033 if (strchr(s, '.') || strchr(s, '*'))
1034 return(s);
1035 sprintf(buf, "%s.%s", s, def_domain);
1036 free(s);
1037 return(strsave(buf));
1038}
1039
1040
ad7e0e04 1041/* Function Name: ShowCname
1042 * Description: This function shows machine aliases
1043 * Arguments: argc, argv - the alias argv[1], the real name in argv[2]
1044 * Returns: DM_NORMAL.
1045 */
1046
1047/* ARGSUSED */
1048int
1049ShowCname(argc, argv)
1050int argc;
1051char **argv;
1052{
1053 struct qelem *top;
1054 char *tmpalias, *tmpname;
1055
5cfca28f 1056 tmpalias = partial_canonicalize_hostname(strsave(argv[1]));
ad7e0e04 1057 tmpname = canonicalize_hostname(strsave(argv[2]));
1058 top = GetMCInfo(CNAME, tmpalias, tmpname);
1059 Put_message(""); /* blank line on screen */
1060 Loop(top, ( (void *) PrintCname) );
1061 FreeQueue(top);
1062 return(DM_NORMAL);
1063}
1064
1065
1066/* ARGSUSED */
1067int
1068AddCname(argc, argv)
1069int argc;
1070char ** argv;
1071{
1072 int stat;
1073 char *machine, *cluster, temp_buf[BUFSIZ], *args[10];
1074 Bool add_it, one_machine, one_cluster;
1075 struct qelem * melem, *mtop, *celem, *ctop;
1076
5cfca28f 1077 args[0] = partial_canonicalize_hostname(strsave(argv[1]));
ad7e0e04 1078 args[1] = canonicalize_hostname(strsave(argv[2]));
1079 stat = do_mr_query("add_hostalias", 2, args, Scream, NULL);
1080 switch (stat) {
1081 case MR_SUCCESS:
1082 break;
1083 case MR_EXISTS:
1084 Put_message("That alias name is already in use.");
1085 break;
1086 case MR_PERM:
1087 Put_message("Permission denied. (Regular users can only add two aliases to a host.");
1088 break;
1089 default:
1090 com_err(program_name, stat, " in add_hostalias");
1091 }
1092 return(DM_NORMAL);
1093}
1094
1095
1096/* ARGSUSED */
1097int
1098DeleteCname(argc, argv)
1099int argc;
1100char ** argv;
1101{
1102 int stat;
1103 char *machine, *cluster, temp_buf[BUFSIZ], *args[10];
1104 Bool add_it, one_machine, one_cluster;
1105 struct qelem * melem, *mtop, *celem, *ctop;
1106
5cfca28f 1107 args[0] = partial_canonicalize_hostname(strsave(argv[1]));
ad7e0e04 1108 args[1] = canonicalize_hostname(strsave(argv[2]));
1109 stat = do_mr_query("delete_hostalias", 2, args, Scream, NULL);
1110 if (stat)
1111 com_err(program_name, stat, " in delete_hostalias");
1112 return(DM_NORMAL);
1113}
1114
1115
08345b74 1116/* Function Name: AddMachineToCluster
1117 * Description: This function adds a machine to a cluster
1118 * Arguments: argc, argv - The machine name is argv[1].
1119 * The cluster name in argv[2].
1120 * Returns: DM_NORMAL.
1121 */
1122
1123/* ARGSUSED */
1124int
1125AddMachineToCluster(argc, argv)
1126int argc;
1127char ** argv;
1128{
1129 int stat;
85ca828a 1130 char *machine, *cluster, temp_buf[BUFSIZ], *args[10];
1131 Bool add_it, one_machine, one_cluster;
1132 struct qelem * melem, *mtop, *celem, *ctop;
1133
1c3831ea 1134 machine = canonicalize_hostname(strsave(argv[1]));
fbebf6df 1135 if (strcasecmp(machine, argv[1]) && *argv[1] != '"') {
576ba5e7 1136 sprintf(temp_buf, "Warning: '%s' canonicalized to '%s'.",
1137 argv[1], machine);
1138 Put_message(temp_buf);
1139 }
85ca828a 1140 cluster = argv[2];
1141
1142 celem = ctop = GetMCInfo(CLUSTER, cluster, (char *) NULL);
1143 melem = mtop = GetMCInfo(MACHINE, machine, (char *) NULL);
1c3831ea 1144 free(machine);
85ca828a 1145
1146 one_machine = (QueueCount(mtop) == 1);
1147 one_cluster = (QueueCount(ctop) == 1);
1148
402461ad 1149 /* No good way to use QueryLoop() here, sigh */
1150
85ca828a 1151 while (melem != NULL) {
1152 char ** minfo = (char **) melem->q_data;
1153 while (celem != NULL) {
1154 char ** cinfo = (char **) celem->q_data;
1155 if (one_machine && one_cluster)
1156 add_it = TRUE;
1157 else {
1158 sprintf(temp_buf,"Add machine %s to cluster %s (y/n/q) ?",
1159 minfo[M_NAME], cinfo[C_NAME]);
1160 switch (YesNoQuitQuestion(temp_buf, FALSE)) {
1161 case TRUE:
1162 add_it = TRUE;
1163 break;
1164 case FALSE:
1165 add_it = FALSE;
1166 break;
1167 default:
1168 Put_message("Aborting...");
1169 FreeQueue(ctop);
1170 FreeQueue(mtop);
1171 return(DM_NORMAL);
1172 }
1173 }
1174 if (add_it) {
1175 args[0] = minfo[M_NAME];
1176 args[1] = cinfo[C_NAME];
8defc06b 1177 stat = do_mr_query("add_machine_to_cluster", 2, args,
14f99d7d 1178 Scream, NULL);
85ca828a 1179 switch (stat) {
8defc06b 1180 case MR_SUCCESS:
85ca828a 1181 break;
8defc06b 1182 case MR_EXISTS:
85ca828a 1183 sprintf(temp_buf, "%s is already in cluster %s",
1184 minfo[M_NAME], cinfo[C_NAME]);
1185 Put_message(temp_buf);
1186 break;
1187 default:
1188 com_err(program_name, stat, " in AddMachineToCluster.");
1189 break;
1190 }
1191 }
1192 celem = celem->q_forw;
1193 }
1194 celem = ctop; /* reset cluster element. */
1195 melem = melem->q_forw;
1196 }
1197 FreeQueue(ctop);
1198 FreeQueue(mtop);
08345b74 1199 return(DM_NORMAL);
1200}
1201
402461ad 1202/* Function Name: RealRemoveMachineFromCluster
1203 * Description: This function actually removes the machine from its
1204 * cluster.
1205 * Arguments: info - all information nescessary to perform the removal.
1206 * one_map - True if there is only one case, and we should
1207 * confirm.
1208 * Returns: none.
1209 */
1210
1211static void
1212RealRemoveMachineFromCluster(info, one_map)
1213char ** info;
1214Bool one_map;
1215{
1216 char temp_buf[BUFSIZ];
1217 register int stat;
1218
1219 sprintf(temp_buf, "Remove %s from the cluster %s",
04597fbb 1220 info[MAP_MACHINE], info[MAP_CLUSTER]);
402461ad 1221 if (!one_map || Confirm(temp_buf)) {
8defc06b 1222 if ( (stat = do_mr_query("delete_machine_from_cluster", 2,
14f99d7d 1223 info, Scream, NULL)) != 0 )
402461ad 1224 com_err(program_name, stat, " in delete_machine_from_cluster");
1225 else {
1226 sprintf(temp_buf, "%s has been removed from the cluster %s.",
1227 info[MAP_MACHINE], info[MAP_CLUSTER]);
1228 Put_message(temp_buf);
1229 }
1230 }
1231 else
1232 Put_message("Machine not removed.");
1233}
1234
08345b74 1235/* Function Name: RemoveMachineFromCluster
1236 * Description: Removes this machine form a specific cluster.
1237 * Arguments: argc, argv - Name of machine in argv[1].
85ca828a 1238 * Name of cluster in argv[2].
08345b74 1239 * Returns: none.
1240 */
1241
1242/* ARGSUSED */
1243int
1244RemoveMachineFromCluster(argc, argv)
1245int argc;
1246char ** argv;
1247{
402461ad 1248 struct qelem *elem = NULL;
85ca828a 1249 char buf[BUFSIZ], * args[10];
402461ad 1250 register int stat;
85ca828a 1251
1c3831ea 1252 args[MAP_MACHINE] = canonicalize_hostname(strsave(argv[1]));
fbebf6df 1253 if (strcasecmp(args[MAP_MACHINE], argv[1]) && *argv[1] != '"') {
dc5b50ac 1254 sprintf(buf, "Warning: '%s' canonicalized to '%s'.",
576ba5e7 1255 argv[1], args[MAP_MACHINE]);
dc5b50ac 1256 Put_message(buf);
576ba5e7 1257 }
85ca828a 1258 args[MAP_CLUSTER] = argv[2];
1259 args[MAP_END] = NULL;
1260
8defc06b 1261 stat = do_mr_query("get_machine_to_cluster_map", CountArgs(args), args,
14f99d7d 1262 StoreInfo, (char *)&elem);
8defc06b 1263 if (stat == MR_NO_MATCH) {
85ca828a 1264 sprintf(buf, "The machine %s is not is the cluster %s.",
1265 args[MAP_MACHINE], args[MAP_CLUSTER]);
1266 Put_message(buf);
1c3831ea 1267 free(args[MAP_MACHINE]);
85ca828a 1268 return(DM_NORMAL);
08345b74 1269 }
8defc06b 1270 if (stat != MR_SUCCESS)
85ca828a 1271 com_err(program_name, stat, " in delete_machine_from_cluster");
1272
402461ad 1273 elem = QueueTop(elem);
1274 QueryLoop(elem, PrintMCMap, RealRemoveMachineFromCluster,
1275 "Remove this machine from this cluster");
1276
1277 FreeQueue(elem);
1c3831ea 1278 free(args[MAP_MACHINE]);
08345b74 1279 return(DM_NORMAL);
1280}
1281
ad7e0e04 1282/* ---------- Subnet Menu -------- */
1283
1284/* Function Name: ShowSubnetInfo
1285 * Description: Gets information about a subnet given its name.
1286 * Arguments: argc, argc - the name of the subnet in in argv[1].
1287 * Returns: DM_NORMAL.
1288 */
1289
1290/* ARGSUSED */
1291int
1292ShowSubnetInfo(argc, argv)
1293int argc;
1294char ** argv;
1295{
1296 struct qelem *top;
1297
1298 top = GetMCInfo(SUBNET, argv[1], (char *) NULL);
1299 Loop(top, (void *) PrintSubnetInfo);
1300 FreeQueue(top);
1301 return(DM_NORMAL);
1302}
1303
1304/* Function Name: AddSubnet
1305 * Description: Creates a new subnet.
1306 * Arguments: argc, argv - the name of the new subnet is argv[1].
1307 * Returns: DM_NORMAL.
1308 */
1309
1310/* ARGSUSED */
1311int
1312AddSubnet(argc, argv)
1313int argc;
1314char ** argv;
1315{
1316 char **args, *info[MAX_ARGS_SIZE], *name = argv[1];
1317 int stat;
1318/*
1319 * Check to see if this subnet already exists.
1320 */
1321 if (!ValidName(name))
1322 return(DM_NORMAL);
1323
1324 if ( (stat = do_mr_query("get_subnet", 1, &name,
1325 NullFunc, NULL)) == MR_SUCCESS) {
1326 Put_message("This subnet already exists.");
1327 return(DM_NORMAL);
1328 }
1329 else if (stat != MR_NO_MATCH) {
1330 com_err(program_name, stat, " in AddSubnet.");
1331 return(DM_NORMAL);
1332 }
1333 if ((args = AskMCDInfo(SetSubnetDefaults(info, name), SUBNET, FALSE)) ==
1334 NULL) {
1335 Put_message("Aborted.");
1336 FreeInfo(info);
1337 return(DM_NORMAL);
1338 }
1339
1340/*
1341 * Actually create the new Subnet.
1342 */
1343 if ( (stat = do_mr_query("add_subnet", CountArgs(args),
1344 args, Scream, NULL)) != 0)
1345 com_err(program_name, stat, " in AddSubnet.");
1346
1347 FreeInfo(info);
1348 return(DM_NORMAL);
1349}
1350
1351/* Function Name: RealUpdateSubnet
1352 * Description: This function actually performs the subnet update.
1353 * Arguments: info - all information nesc. for updating the subnet.
1354 * junk - an UNUSED boolean.
1355 * Returns: none.
1356 */
1357
1358/* ARGSUSED */
1359static void
1360RealUpdateSubnet(info, junk)
1361char ** info;
1362Bool junk;
1363{
1364 register int stat;
1365 char ** args = AskMCDInfo(info, SUBNET, TRUE);
1366 if (args == NULL) {
1367 Put_message("Aborted.");
1368 return;
1369 }
1370 if ( (stat = do_mr_query("update_subnet", CountArgs(args),
1371 args, Scream, NULL)) != 0)
1372 com_err(program_name, stat, " in UpdateSubnet.");
1373 else
1374 Put_message("Subnet successfully updated.");
1375}
1376
1377/* Function Name: UpdateSubnet
1378 * Description: This Function Updates a subnet
1379 * Arguments: name of the subnet in argv[1].
1380 * Returns: DM_NORMAL.
1381 */
1382
1383/* ARGSUSED */
1384int
1385UpdateSubnet(argc, argv)
1386int argc;
1387char ** argv;
1388{
1389 struct qelem *top;
1390 top = GetMCInfo( SUBNET, argv[1], (char *) NULL );
1391 QueryLoop(top, NullPrint, RealUpdateSubnet, "Update the subnet");
1392
1393 FreeQueue(top);
1394 return(DM_NORMAL);
1395}
1396
1397/* Function Name: RealDeleteSubnet
1398 * Description: Actually performs the subnet deletion.
1399 * Arguments: info - all information about this subnet.
1400 * one_subnet - If true then there was only one subnet in
1401 * the queue, and we should confirm.
1402 * Returns: none.
1403 */
1404
1405static void
1406RealDeleteSubnet(info, one_subnet)
1407char ** info;
1408Bool one_subnet;
1409{
1410 register int stat;
1411 char temp_buf[BUFSIZ];
1412
1413 sprintf(temp_buf,
1414 "Are you sure the you want to delete the subnet %s (y/n) ?",
1415 info[C_NAME]);
1416 if (!one_subnet || Confirm(temp_buf)) {
1417 if ( (stat = do_mr_query("delete_subnet", 1,
1418 &info[C_NAME], Scream, NULL)) != 0) {
1419 com_err(program_name, stat, " in delete_subnet.");
1420 sprintf(temp_buf, "Subnet %s ** NOT ** deleted.",
1421 info[C_NAME]);
1422 Put_message(temp_buf);
1423 }
1424 else {
1425 sprintf(temp_buf, "subnet %s sucesfully deleted.",
1426 info[C_NAME]);
1427 Put_message(temp_buf);
1428 }
1429 }
1430}
1431
1432/* Function Name: DeleteSubnet
1433 * Description: This function removes a subnet from the database.
1434 * Arguments: argc, argv - the name of the subnet is stored in argv[1].
1435 * Returns: DM_NORMAL.
1436 */
1437
1438/* ARGSUSED */
1439int
1440DeleteSubnet(argc, argv)
1441int argc;
1442char ** argv;
1443{
1444 struct qelem *top;
1445
1446 top = GetMCInfo( SUBNET, argv[1], (char *) NULL );
1447 QueryLoop(top, PrintSubnetInfo, RealDeleteSubnet, "Delete the subnet");
1448
1449 FreeQueue(top);
1450 return(DM_NORMAL);
1451}
1452
08345b74 1453/* ---------- Cluster Menu -------- */
1454
1455/* Function Name: ShowClusterInfo
1456 * Description: Gets information about a cluser given its name.
1457 * Arguments: argc, argc - the name of the cluster in in argv[1].
1458 * Returns: DM_NORMAL.
1459 */
1460
1461/* ARGSUSED */
1462int
461c03b6 1463ShowClusterInfo(argc, argv)
08345b74 1464int argc;
1465char ** argv;
1466{
402461ad 1467 struct qelem *top;
08345b74 1468
5cd3b188 1469 top = GetMCInfo(CLUSTER, argv[1], (char *) NULL);
402461ad 1470 Loop(top, (void *) PrintClusterInfo);
08345b74 1471 FreeQueue(top);
1472 return(DM_NORMAL);
1473}
1474
1475/* Function Name: AddCluster
1476 * Description: Creates a new cluster.
1477 * Arguments: argc, argv - the name of the new cluster is argv[1].
1478 * Returns: DM_NORMAL.
1479 */
1480
1481/* ARGSUSED */
1482int
1483AddCluster(argc, argv)
1484int argc;
1485char ** argv;
1486{
402461ad 1487 char **args, *info[MAX_ARGS_SIZE], *name = argv[1];
08345b74 1488 int stat;
1489/*
402461ad 1490 * Check to see if this cluster already exists.
08345b74 1491 */
402461ad 1492 if (!ValidName(name))
1493 return(DM_NORMAL);
08345b74 1494
8defc06b 1495 if ( (stat = do_mr_query("get_cluster", 1, &name,
1496 NullFunc, NULL)) == MR_SUCCESS) {
08345b74 1497 Put_message("This cluster already exists.");
1498 return(DM_NORMAL);
1499 }
8defc06b 1500 else if (stat != MR_NO_MATCH) {
461c03b6 1501 com_err(program_name, stat, " in AddCluster.");
08345b74 1502 return(DM_NORMAL);
1503 }
576ba5e7 1504 if ((args = AskMCDInfo(SetClusterDefaults(info, name), CLUSTER, FALSE)) ==
1505 NULL) {
1506 Put_message("Aborted.");
1507 FreeInfo(info);
1508 return(DM_NORMAL);
1509 }
1510
08345b74 1511/*
1512 * Actually create the new Cluster.
1513 */
8defc06b 1514 if ( (stat = do_mr_query("add_cluster", CountArgs(args),
14f99d7d 1515 args, Scream, NULL)) != 0)
461c03b6 1516 com_err(program_name, stat, " in AddCluster.");
08345b74 1517
1518 FreeInfo(info);
1519 return(DM_NORMAL);
1520}
1521
402461ad 1522/* Function Name: RealUpdateCluster
1523 * Description: This function actually performs the cluster update.
1524 * Arguments: info - all information nesc. for updating the cluster.
1525 * junk - an UNUSED boolean.
1526 * Returns: none.
1527 */
1528
1529/* ARGSUSED */
1530static void
1531RealUpdateCluster(info, junk)
1532char ** info;
1533Bool junk;
1534{
1535 register int stat;
1536 char ** args = AskMCDInfo(info, CLUSTER, TRUE);
576ba5e7 1537 if (args == NULL) {
1538 Put_message("Aborted.");
1539 return;
1540 }
8defc06b 1541 if ( (stat = do_mr_query("update_cluster", CountArgs(args),
14f99d7d 1542 args, Scream, NULL)) != 0)
402461ad 1543 com_err(program_name, stat, " in UpdateCluster.");
1544 else
1545 Put_message("Cluster successfully updated.");
1546}
1547
08345b74 1548/* Function Name: UpdateCluster
1549 * Description: This Function Updates a cluster
1550 * Arguments: name of the cluster in argv[1].
1551 * Returns: DM_NORMAL.
1552 */
1553
1554/* ARGSUSED */
1555int
1556UpdateCluster(argc, argv)
1557int argc;
1558char ** argv;
1559{
402461ad 1560 struct qelem *top;
1561 top = GetMCInfo( CLUSTER, argv[1], (char *) NULL );
1562 QueryLoop(top, NullPrint, RealUpdateCluster, "Update the cluster");
08345b74 1563
08345b74 1564 FreeQueue(top);
1565 return(DM_NORMAL);
1566}
1567
85ca828a 1568/* Function Name: CheckAndRemoveMachine
1569 * Description: This function checks and removes all machines from a
1570 * cluster.
1571 * Arguments: name - name of the cluster.
1572 * ask_first - if TRUE, then we will query the user, before
1573 * deletion.
1574 * Returns: SUB_ERROR if all machines not removed.
1575 */
1576
1577int
1578CheckAndRemoveMachines(name, ask_first)
1579char * name;
1580Bool ask_first;
1581{
1582 register int stat, ret_value;
1583 Bool delete_it;
1584 char *args[10], temp_buf[BUFSIZ], *ptr;
1585 struct qelem *top, *elem = NULL;
1586
1587 ret_value = SUB_NORMAL;
1588 args[MAP_MACHINE] = "*";
1589 args[MAP_CLUSTER] = name;
8defc06b 1590 stat = do_mr_query("get_machine_to_cluster_map", 2, args,
14f99d7d 1591 StoreInfo, (char *)&elem);
8defc06b 1592 if (stat && stat != MR_NO_MATCH) {
85ca828a 1593 com_err(program_name, stat, " in get_machine_to_cluster_map.");
1594 return(DM_NORMAL);
1595 }
1596 if (stat == 0) {
1597 elem = top = QueueTop(elem);
1598 if (ask_first) {
1599 sprintf(temp_buf,
1600 "The cluster %s has the following machines in it:",
1601 name);
1602 Put_message(temp_buf);
1603 while (elem != NULL) {
1604 char **info = (char **) elem->q_data;
1605 Print(1, &info[MAP_MACHINE], (char *) NULL);
1606 elem = elem->q_forw;
1607 }
1608 ptr = "Remove ** ALL ** these machines from this cluster?";
1609
1610 if (YesNoQuestion(ptr, FALSE) == TRUE) /* may return -1. */
1611 delete_it = TRUE;
1612 else {
1613 Put_message("Aborting...");
1614 FreeQueue(top);
1615 return(SUB_ERROR);
1616 }
1617 }
1618 else
1619 delete_it = TRUE;
1620
1621 if (delete_it) {
1622 elem = top;
1623 while (elem != 0) {
1624 char **info = (char **) elem->q_data;
8defc06b 1625 if ( (stat = do_mr_query("delete_machine_from_cluster",
14f99d7d 1626 2, info, Scream, NULL)) != 0) {
85ca828a 1627 ret_value = SUB_ERROR;
1628 com_err(program_name, stat,
1629 " in delete_machine_from_cluster.");
1630 sprintf(temp_buf,
1631 "Machine %s ** NOT ** removed from cluster %s.",
1632 info[MAP_MACHINE], info[MAP_CLUSTER]);
1633 Put_message(temp_buf);
1634 }
1635 elem = elem->q_forw;
1636 }
1637 }
1638 }
1639 return(ret_value);
1640}
1641
402461ad 1642/* Function Name: RealDeleteCluster
1643 * Description: Actually performs the cluster deletion.
1644 * Arguments: info - all information about this cluster.
1645 * one_cluster - If true then there was only one cluster in
1646 * the queue, and we should confirm.
1647 * Returns: none.
1648 */
1649
1650static void
1651RealDeleteCluster(info, one_cluster)
1652char ** info;
1653Bool one_cluster;
1654{
1655 register int stat;
1656 char temp_buf[BUFSIZ];
1657
1658 sprintf(temp_buf,
1659 "Are you sure the you want to delete the cluster %s (y/n) ?",
1660 info[C_NAME]);
1661 if (!one_cluster || Confirm(temp_buf)) {
1662 if (CheckAndRemoveMachines(info[C_NAME], TRUE) != SUB_ERROR) {
8defc06b 1663 if ( (stat = do_mr_query("delete_cluster", 1,
14f99d7d 1664 &info[C_NAME], Scream, NULL)) != 0) {
402461ad 1665 com_err(program_name, stat, " in delete_cluster.");
1666 sprintf(temp_buf, "Cluster %s ** NOT ** deleted.",
1667 info[C_NAME]);
1668 Put_message(temp_buf);
1669 }
1670 else {
1671 sprintf(temp_buf, "cluster %s sucesfully deleted.",
1672 info[C_NAME]);
1673 Put_message(temp_buf);
1674 }
1675 }
1676 }
1677}
85ca828a 1678
08345b74 1679/* Function Name: DeleteCluster
1680 * Description: This function removes a cluster from the database.
1681 * Arguments: argc, argv - the name of the cluster is stored in argv[1].
1682 * Returns: DM_NORMAL.
1683 */
1684
1685/* ARGSUSED */
1686int
461c03b6 1687DeleteCluster(argc, argv)
08345b74 1688int argc;
1689char ** argv;
1690{
402461ad 1691 struct qelem *top;
08345b74 1692
402461ad 1693 top = GetMCInfo( CLUSTER, argv[1], (char *) NULL );
1694 QueryLoop(top, PrintClusterInfo, RealDeleteCluster, "Delete the cluster");
08345b74 1695
85ca828a 1696 FreeQueue(top);
08345b74 1697 return(DM_NORMAL);
1698}
402461ad 1699
08345b74 1700/* ----------- Cluster Data Menu -------------- */
1701
1702/* Function Name: ShowClusterData
1703 * Description: This function shows the services for one cluster.
1704 * Arguments: argc, argv - The name of the cluster is argv[1].
461c03b6 1705 * The label of the data in argv[2].
08345b74 1706 * Returns: DM_NORMAL.
1707 */
1708
85ca828a 1709/* ARGSUSED */
08345b74 1710int
1711ShowClusterData(argc, argv)
1712int argc;
1713char ** argv;
1714{
1715 struct qelem *elem, *top;
1716 char **info;
1717
461c03b6 1718 top = elem = GetMCInfo(DATA, argv[1], argv[2]);
08345b74 1719 while (elem != NULL) {
1720 info = (char **) elem->q_data;
1721 PrintClusterData(info);
461c03b6 1722 elem = elem->q_forw;
08345b74 1723 }
1724 FreeQueue(top);
1725 return(DM_NORMAL);
1726}
1727
1728/* Function Name: AddClusterData
1729 * Description: This function adds some data to the cluster.
1730 * Arguments: argv, argc: argv[1] - the name of the cluster.
1731 * argv[2] - the label of the data.
1732 * argv[3] - the data.
1733 * Returns: DM_NORMAL.
1734 */
1735
1736/* ARGSUSED */
1737int
1738AddClusterData(argc, argv)
1739int argc;
1740char ** argv;
1741{
461c03b6 1742 int stat;
1743
8defc06b 1744 if( (stat = do_mr_query("add_cluster_data", 3, argv + 1,
14f99d7d 1745 Scream, (char *) NULL)) != 0)
461c03b6 1746 com_err(program_name, stat, " in AddClusterData.");
7b53f00f 1747 return(DM_NORMAL);
08345b74 1748}
1749
402461ad 1750/* Function Name: RealRemoveClusterData
1751 * Description: actually removes the cluster data.
1752 * Arguments: info - all info necessary to remove the cluster, in an array
1753 * of strings.
1754 * one_item - if true then the queue has only one elem and we
1755 * should confirm.
1756 * Returns: none.
1757 */
1758
1759static void
1760RealRemoveClusterData(info, one_item)
1761char ** info;
1762Bool one_item;
1763{
1764 register int stat;
1765 char * temp_ptr;
1766
1767 Put_message(" ");
bae441d9 1768 temp_ptr = "Are you sure that you want to remove this cluster data (y/n) ?";
1769 PrintClusterData(info);
402461ad 1770 if (!one_item || Confirm(temp_ptr)) {
8defc06b 1771 if( (stat = do_mr_query("delete_cluster_data", 3, info,
14f99d7d 1772 Scream, (char *) NULL)) != 0) {
402461ad 1773 com_err(program_name, stat, " in DeleteClusterData.");
1774 Put_message("Data not removed.");
1775 }
1776 else
1777 Put_message("Removal sucessful.");
1778 }
1779}
1780
461c03b6 1781/* Function Name: RemoveClusterData
1782 * Description: This function removes data on a given cluster.
08345b74 1783 * Arguments: argv, argc: argv[1] - the name of the cluster.
1784 * argv[2] - the label of the data.
1785 * argv[3] - the data.
1786 * Returns: DM_NORMAL.
1787 */
1788
1789/* ARGSUSED */
461c03b6 1790int
1791RemoveClusterData(argc, argv)
08345b74 1792int argc;
1793char ** argv;
1794{
402461ad 1795 struct qelem *top;
08345b74 1796
402461ad 1797 top = GetMCInfo(DATA, argv[1], argv[2]);
1798 QueryLoop(top, PrintClusterData, RealRemoveClusterData,
1f88d281 1799 "Remove data from cluster");
08345b74 1800
85ca828a 1801 FreeQueue(top);
08345b74 1802 return(DM_NORMAL);
1803}
1804
08345b74 1805/* Function Name: MachineToClusterMap
1806 * Description: This Retrieves the mapping between machine and cluster
1807 * Arguments: argc, argv - argv[1] -> machine name or wildcard.
1808 * argv[2] -> cluster name or wildcard.
1809 * Returns: none.
1810 */
1811
1812/* ARGSUSED */
1813int
1814MachineToClusterMap(argc,argv)
1815int argc;
1816char **argv;
1817{
461c03b6 1818 struct qelem *elem, *top;
dc5b50ac 1819 char *tmpname, temp_buf[256];
08345b74 1820
1c3831ea 1821 tmpname = canonicalize_hostname(strsave(argv[1]));
fbebf6df 1822 if (strcasecmp(tmpname, argv[1]) && *argv[1] != '"') {
576ba5e7 1823 sprintf(temp_buf, "Warning: '%s' canonicalized to '%s'.",
1824 argv[1], tmpname);
1825 Put_message(temp_buf);
1826 }
1c3831ea 1827 top = elem = GetMCInfo(MAP, tmpname, argv[2]);
08345b74 1828
85ca828a 1829 Put_message(""); /* blank line on screen */
461c03b6 1830 while (elem != NULL) {
1831 char ** info = (char **) elem->q_data;
1832 PrintMCMap(info);
1833 elem = elem->q_forw;
1834 }
1835
1836 FreeQueue(top);
1c3831ea 1837 free(tmpname);
461c03b6 1838 return(DM_NORMAL);
1839}
This page took 0.366987 seconds and 5 git commands to generate.