]>
Commit | Line | Data |
---|---|---|
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 | 43 | void PrintAliases(char **info); |
bc8eefd1 | 44 | static void PrintMachine(char **info); |
600b459e | 45 | struct mqelem *GetMCInfo(int type, char *name1, char *name2); |
7399b4b2 | 46 | struct mqelem *GetMachineByOwner(char *type, char *name); |
7ac48069 | 47 | char **AskMCDInfo(char **info, int type, Bool name); |
48 | int CheckAndRemoveFromCluster(char *name, Bool ask_user); | |
49 | int 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 | 69 | static char *states[] = { |
70 | "Reserved (0)", | |
71 | "Active (1)", | |
72 | "None (2)", | |
73 | "Deleted (3)" | |
74 | }; | |
75 | ||
76 | static 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 | 99 | static 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 | 126 | static 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 | 142 | static 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 | 165 | static char aliasbuf[256]; |
166 | ||
7ac48069 | 167 | void 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 | 186 | static 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 | ||
246 | static 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 | 260 | static 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 | 276 | static 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 | 298 | static 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 | 315 | static 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 | 331 | static 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 | 373 | struct 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 | 460 | char **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 | 690 | int 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 | 714 | int 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 | 764 | int 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 | 844 | static 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 | 865 | int 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 | 887 | int 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 | 955 | static 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 | 991 | int 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 | 1011 | int 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 | 1026 | int 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 | 1052 | int 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 | 1073 | int 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 | 1164 | static 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 | 1194 | int 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 | 1240 | int 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 | 1256 | int 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 | 1301 | static 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 | 1322 | int 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 | 1340 | static 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 | 1371 | int 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 | 1390 | int 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 | 1406 | int 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 | 1451 | static 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 | 1474 | int 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 | 1493 | int 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 | 1569 | static 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 | 1604 | int 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 | 1624 | int 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 | 1648 | int 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 | 1666 | static 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 | 1694 | int 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 | 1713 | int 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 | ||
1747 | int 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 | ||
1789 | struct 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 | } |