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