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