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