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