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