dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / cmd-inet / usr.sbin / ilbadm / ilbadm_sg.c
blob8a0d92bbd75a837766890bff9c2533f235098d34
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 * Copyright 2012 Milan Jurik. All rights reserved.
28 #include <stdio.h>
29 #include <unistd.h>
30 #include <stdlib.h>
31 #include <strings.h>
32 #include <stddef.h>
33 #include <assert.h>
34 #include <errno.h>
35 #include <sys/types.h>
36 #include <sys/socket.h>
37 #include <netinet/in.h>
38 #include <arpa/inet.h>
39 #include <sys/list.h>
40 #include <ofmt.h>
41 #include <libilb.h>
42 #include "ilbadm.h"
44 static ilbadm_key_name_t servrange_keys[] = {
45 {ILB_KEY_SERVER, "server", "servers"},
46 {ILB_KEY_SERVRANGE, "server", "servers"},
47 {ILB_KEY_BAD, "", ""}
50 static ilbadm_key_name_t serverID_keys[] = {
51 {ILB_KEY_SERVERID, "server", ""},
52 {ILB_KEY_BAD, "", ""}
55 typedef struct sg_export_arg {
56 FILE *fp;
57 ilbadm_sgroup_t *sg;
58 } sg_export_arg_t;
60 typedef struct arg_struct {
61 int flags;
62 char *o_str;
63 ofmt_field_t *o_fields;
64 ofmt_handle_t oh;
65 } list_arg_t;
67 typedef struct sg_srv_o_struct {
68 char *sgname;
69 ilb_server_data_t *sd;
70 } sg_srv_o_arg_t;
72 static ofmt_cb_t of_sgname;
73 static ofmt_cb_t of_srvID;
74 static ofmt_cb_t of_port;
75 static ofmt_cb_t of_ip;
77 static ofmt_field_t sgfields_v4[] = {
78 {"SGNAME", ILB_SGNAME_SZ, 0, of_sgname},
79 {"SERVERID", ILB_NAMESZ, 0, of_srvID},
80 {"MINPORT", 8, 0, of_port},
81 {"MAXPORT", 8, 1, of_port},
82 {"IP_ADDRESS", 15, 0, of_ip},
83 {NULL, 0, 0, NULL}
85 static ofmt_field_t sgfields_v6[] = {
86 {"SGNAME", ILB_SGNAME_SZ, 0, of_sgname},
87 {"SERVERID", ILB_NAMESZ, 0, of_srvID},
88 {"MINPORT", 8, 0, of_port},
89 {"MAXPORT", 8, 1, of_port},
90 {"IP_ADDRESS", 39, 0, of_ip},
91 {NULL, 0, 0, NULL}
94 #define MAXCOLS 80 /* make flexible? */
96 extern int optind, optopt, opterr;
97 extern char *optarg;
99 static boolean_t
100 of_sgname(ofmt_arg_t *of_arg, char *buf, uint_t bufsize)
102 sg_srv_o_arg_t *l = (sg_srv_o_arg_t *)of_arg->ofmt_cbarg;
104 (void) strlcpy(buf, l->sgname, bufsize);
105 return (B_TRUE);
108 static boolean_t
109 of_srvID(ofmt_arg_t *of_arg, char *buf, uint_t bufsize)
111 sg_srv_o_arg_t *l = (sg_srv_o_arg_t *)of_arg->ofmt_cbarg;
113 (void) strlcpy(buf, l->sd->sd_srvID, bufsize);
114 return (B_TRUE);
117 static boolean_t
118 of_port(ofmt_arg_t *of_arg, char *buf, uint_t bufsize)
120 sg_srv_o_arg_t *l = (sg_srv_o_arg_t *)of_arg->ofmt_cbarg;
121 int port;
123 if (of_arg->ofmt_id == 0) {
124 port = ntohs(l->sd->sd_minport);
125 if (port == 0)
126 *buf = '\0';
127 else
128 (void) snprintf(buf, bufsize, "%d", port);
129 } else {
130 port = ntohs(l->sd->sd_maxport);
131 if (port == 0)
132 *buf = '\0';
133 else
134 (void) snprintf(buf, bufsize, "%d", port);
136 return (B_TRUE);
139 static boolean_t
140 of_ip(ofmt_arg_t *of_arg, char *buf, uint_t bufsize)
142 sg_srv_o_arg_t *l = (sg_srv_o_arg_t *)of_arg->ofmt_cbarg;
144 ip2str(&l->sd->sd_addr, buf, bufsize, V6_ADDRONLY);
145 return (B_TRUE);
148 ilbadm_status_t
149 i_list_sg_srv_ofmt(char *sgname, ilb_server_data_t *sd, void *arg)
151 list_arg_t *larg = (list_arg_t *)arg;
152 sg_srv_o_arg_t line_arg;
154 line_arg.sgname = sgname;
155 line_arg.sd = sd;
156 ofmt_print(larg->oh, &line_arg);
157 return (ILBADM_OK);
161 * This function is always called via ilb_walk_servergroups()
162 * and so must return libilb errors.
163 * That's why we need to retain currently unused "h" argument
165 /* ARGSUSED */
166 static ilb_status_t
167 ilbadm_list_sg_srv(ilb_handle_t h, ilb_server_data_t *sd, const char *sgname,
168 void *arg)
170 char ip_str[2*INET6_ADDRSTRLEN + 3] = "";
171 char port_str[INET6_ADDRSTRLEN];
172 list_arg_t *larg = (list_arg_t *)arg;
173 ofmt_status_t oerr;
174 int oflags = 0;
175 int ocols = MAXCOLS;
176 int h_minport, h_maxport;
177 static ofmt_handle_t oh = (ofmt_handle_t)NULL;
178 ofmt_field_t *ofp;
180 if (larg->o_str != NULL) {
181 if (oh == NULL) {
182 if (sd->sd_addr.ia_af == AF_INET)
183 ofp = sgfields_v6;
184 else
185 ofp = sgfields_v4;
187 if (larg->flags & ILBADM_LIST_PARSE)
188 oflags |= OFMT_PARSABLE;
190 oerr = ofmt_open(larg->o_str, ofp, oflags, ocols, &oh);
191 if (oerr != OFMT_SUCCESS) {
192 char e[80];
194 ilbadm_err(gettext("ofmt_open failed: %s"),
195 ofmt_strerror(oh, oerr, e, sizeof (e)));
196 return (ILB_STATUS_GENERIC);
198 larg->oh = oh;
202 (void) i_list_sg_srv_ofmt((char *)sgname, sd, arg);
203 return (ILB_STATUS_OK);
206 ip2str(&sd->sd_addr, ip_str, sizeof (ip_str), 0);
208 h_minport = ntohs(sd->sd_minport);
209 h_maxport = ntohs(sd->sd_maxport);
210 if (h_minport == 0)
211 *port_str = '\0';
212 else if (h_maxport > h_minport)
213 (void) sprintf(port_str, ":%d-%d", h_minport, h_maxport);
214 else
215 (void) sprintf(port_str, ":%d", h_minport);
217 (void) printf("%s: id:%s %s%s\n", sgname,
218 sd->sd_srvID?sd->sd_srvID:"(null)", ip_str, port_str);
219 return (ILB_STATUS_OK);
222 ilb_status_t
223 ilbadm_list_sg(ilb_handle_t h, ilb_sg_data_t *sg, void *arg)
225 if (sg->sgd_srvcount == 0) {
226 ilb_server_data_t tmp_srv;
228 bzero(&tmp_srv, sizeof (tmp_srv));
229 return (ilbadm_list_sg_srv(h, &tmp_srv, sg->sgd_name, arg));
232 return (ilb_walk_servers(h, ilbadm_list_sg_srv, sg->sgd_name, arg));
235 static char *def_fields = "SGNAME,SERVERID,MINPORT,MAXPORT,IP_ADDRESS";
237 /* ARGSUSED */
238 ilbadm_status_t
239 ilbadm_show_servergroups(int argc, char *argv[])
241 ilb_handle_t h = ILB_INVALID_HANDLE;
242 ilb_status_t rclib = ILB_STATUS_OK;
243 ilbadm_status_t rc = ILBADM_OK;
244 int c;
245 char optstr[] = ":po:";
247 boolean_t o_opt = B_FALSE, p_opt = B_FALSE;
248 list_arg_t larg = {0, def_fields, NULL, NULL};
250 while ((c = getopt(argc, argv, optstr)) != -1) {
251 switch ((char)c) {
252 case 'p': p_opt = B_TRUE;
253 larg.flags |= ILBADM_LIST_PARSE;
254 break;
255 case 'o': larg.o_str = optarg;
256 o_opt = B_TRUE;
257 break;
258 case ':': ilbadm_err(gettext("missing option argument"
259 " for %c"), (char)optopt);
260 rc = ILBADM_LIBERR;
261 goto out;
262 default: unknown_opt(argv, optind-1);
263 /* not reached */
264 break;
268 if (p_opt && !o_opt) {
269 ilbadm_err(gettext("option -p requires -o"));
270 exit(1);
273 if (p_opt && larg.o_str != NULL &&
274 (strcasecmp(larg.o_str, "all") == 0)) {
275 ilbadm_err(gettext("option -p requires explicit field"
276 " names for -o"));
277 exit(1);
280 rclib = ilb_open(&h);
281 if (rclib != ILB_STATUS_OK)
282 goto out;
284 if (optind >= argc) {
285 rclib = ilb_walk_servergroups(h, ilbadm_list_sg, NULL,
286 (void*)&larg);
287 if (rclib != ILB_STATUS_OK)
288 rc = ILBADM_LIBERR;
289 } else {
290 while (optind < argc) {
291 rclib = ilb_walk_servergroups(h, ilbadm_list_sg,
292 argv[optind++], (void*)&larg);
293 if (rclib != ILB_STATUS_OK) {
294 rc = ILBADM_LIBERR;
295 break;
300 if (larg.oh != NULL)
301 ofmt_close(larg.oh);
302 out:
303 if (h != ILB_INVALID_HANDLE)
304 (void) ilb_close(h);
306 if (rclib != ILB_STATUS_OK) {
308 * The show function returns ILB_STATUS_GENERIC after printing
309 * out an error message. So we don't need to print it again.
311 if (rclib != ILB_STATUS_GENERIC)
312 ilbadm_err(ilb_errstr(rclib));
313 rc = ILBADM_LIBERR;
316 return (rc);
319 ilbadm_servnode_t *
320 i_new_sg_elem(ilbadm_sgroup_t *sgp)
322 ilbadm_servnode_t *s;
324 s = (ilbadm_servnode_t *)calloc(sizeof (*s), 1);
325 if (s != NULL) {
326 list_insert_tail(&sgp->sg_serv_list, s);
327 sgp->sg_count++;
329 return (s);
332 static ilbadm_status_t
333 i_parse_servrange_list(char *arg, ilbadm_sgroup_t *sgp)
335 ilbadm_status_t rc;
336 int count;
338 rc = i_parse_optstring(arg, (void *) sgp, servrange_keys,
339 OPT_VALUE_LIST|OPT_IP_RANGE|OPT_PORTS, &count);
340 return (rc);
343 static ilbadm_status_t
344 i_parse_serverIDs(char *arg, ilbadm_sgroup_t *sgp)
346 ilbadm_status_t rc;
347 int count;
349 rc = i_parse_optstring(arg, (void *) sgp, serverID_keys,
350 OPT_VALUE_LIST|OPT_PORTS, &count);
351 return (rc);
354 static ilbadm_status_t
355 i_mod_sg(ilb_handle_t h, ilbadm_sgroup_t *sgp, ilbadm_cmd_t cmd,
356 int flags)
358 ilbadm_servnode_t *sn;
359 ilb_server_data_t *srv;
360 ilb_status_t rclib = ILB_STATUS_OK;
361 ilbadm_status_t rc = ILBADM_OK;
363 if (h == ILB_INVALID_HANDLE && cmd != cmd_enable_server &&
364 cmd != cmd_disable_server)
365 return (ILBADM_LIBERR);
367 sn = list_head(&sgp->sg_serv_list);
368 while (sn != NULL) {
369 srv = &sn->s_spec;
371 srv->sd_flags |= flags;
372 if (cmd == cmd_create_sg || cmd == cmd_add_srv) {
373 rclib = ilb_add_server_to_group(h, sgp->sg_name,
374 srv);
375 if (rclib != ILB_STATUS_OK) {
376 char buf[INET6_ADDRSTRLEN + 1];
378 rc = ILBADM_LIBERR;
379 ip2str(&srv->sd_addr, buf, sizeof (buf),
380 V6_ADDRONLY);
381 ilbadm_err(gettext("cannot add %s to %s: %s"),
382 buf, sgp->sg_name, ilb_errstr(rclib));
383 /* if we created the SG, we bail out */
384 if (cmd == cmd_create_sg)
385 return (rc);
387 } else {
388 assert(cmd == cmd_rem_srv);
389 rclib = ilb_rem_server_from_group(h, sgp->sg_name,
390 srv);
391 /* if we fail, we tell user and continue */
392 if (rclib != ILB_STATUS_OK) {
393 rc = ILBADM_LIBERR;
394 ilbadm_err(
395 gettext("cannot remove %s from %s: %s"),
396 srv->sd_srvID, sgp->sg_name,
397 ilb_errstr(rclib));
402 * list_next returns NULL instead of cycling back to head
403 * so we don't have to check for list_head explicitly.
405 sn = list_next(&sgp->sg_serv_list, sn);
408 return (rc);
411 static void
412 i_ilbadm_alloc_sgroup(ilbadm_sgroup_t **sgp)
414 ilbadm_sgroup_t *sg;
416 *sgp = sg = (ilbadm_sgroup_t *)calloc(sizeof (*sg), 1);
417 if (sg == NULL)
418 return;
419 list_create(&sg->sg_serv_list, sizeof (ilbadm_servnode_t),
420 offsetof(ilbadm_servnode_t, s_link));
423 static void
424 i_ilbadm_free_sgroup(ilbadm_sgroup_t *sg)
426 ilbadm_servnode_t *s;
428 while ((s = list_remove_head(&sg->sg_serv_list)) != NULL)
429 free(s);
431 list_destroy(&sg->sg_serv_list);
434 ilbadm_status_t
435 ilbadm_create_servergroup(int argc, char *argv[])
437 ilb_handle_t h = ILB_INVALID_HANDLE;
438 ilb_status_t rclib = ILB_STATUS_OK;
439 ilbadm_status_t rc = ILBADM_OK;
440 ilbadm_sgroup_t *sg;
441 int c;
442 int flags = 0;
444 i_ilbadm_alloc_sgroup(&sg);
446 while ((c = getopt(argc, argv, ":s:")) != -1) {
447 switch ((char)c) {
448 case 's':
449 rc = i_parse_servrange_list(optarg, sg);
450 break;
451 case ':':
452 ilbadm_err(gettext("missing option-argument for"
453 " %c"), (char)optopt);
454 rc = ILBADM_LIBERR;
455 break;
456 case '?':
457 default:
458 unknown_opt(argv, optind-1);
459 /* not reached */
460 break;
463 if (rc != ILBADM_OK)
464 goto out;
467 if (optind >= argc) {
468 ilbadm_err(gettext("missing mandatory arguments - please refer"
469 " to 'create-servergroup' subcommand"
470 " description in ilbadm(1M)"));
471 rc = ILBADM_LIBERR;
472 goto out;
475 if (strlen(argv[optind]) > ILB_SGNAME_SZ - 1) {
476 ilbadm_err(gettext("servergroup name %s is too long -"
477 " must not exceed %d chars"), argv[optind],
478 ILB_SGNAME_SZ - 1);
479 rc = ILBADM_LIBERR;
480 goto out;
483 sg->sg_name = argv[optind];
485 rclib = ilb_open(&h);
486 if (rclib != ILB_STATUS_OK)
487 goto out;
489 rclib = ilb_create_servergroup(h, sg->sg_name);
490 if (rclib != ILB_STATUS_OK)
491 goto out;
493 /* we create a servergroup with all servers enabled */
494 ILB_SET_ENABLED(flags);
495 rc = i_mod_sg(h, sg, cmd_create_sg, flags);
497 if (rc != ILBADM_OK)
498 (void) ilb_destroy_servergroup(h, sg->sg_name);
500 out:
501 i_ilbadm_free_sgroup(sg);
502 if (h != ILB_INVALID_HANDLE)
503 (void) ilb_close(h);
505 if (rclib != ILB_STATUS_OK) {
506 ilbadm_err(ilb_errstr(rclib));
507 rc = ILBADM_LIBERR;
509 if ((rc != ILBADM_OK) && (rc != ILBADM_LIBERR))
510 ilbadm_err(ilbadm_errstr(rc));
512 return (rc);
515 ilbadm_status_t
516 ilbadm_add_server_to_group(int argc, char **argv)
518 ilb_handle_t h = ILB_INVALID_HANDLE;
519 ilb_status_t rclib = ILB_STATUS_OK;
520 ilbadm_status_t rc = ILBADM_OK;
521 ilbadm_sgroup_t *sg;
522 int c;
523 int flags = 0;
525 i_ilbadm_alloc_sgroup(&sg);
527 while ((c = getopt(argc, argv, ":s:")) != -1) {
528 switch ((char)c) {
529 case 's':
530 rc = i_parse_servrange_list(optarg, sg);
531 break;
532 case ':':
533 ilbadm_err(gettext("missing option-argument for"
534 " %c"), (char)optopt);
535 rc = ILBADM_LIBERR;
536 break;
537 case '?':
538 default: unknown_opt(argv, optind-1);
539 /* not reached */
540 break;
543 if (rc != ILBADM_OK)
544 goto out;
547 if (optind >= argc) {
548 ilbadm_err(gettext("missing mandatory arguments - please refer"
549 " to 'add-server' subcommand description in ilbadm(1M)"));
550 rc = ILBADM_LIBERR;
551 goto out;
554 sg->sg_name = argv[optind];
556 rclib = ilb_open(&h);
557 if (rclib != ILB_STATUS_OK)
558 goto out;
560 /* A server is added enabled */
561 ILB_SET_ENABLED(flags);
562 rc = i_mod_sg(h, sg, cmd_add_srv, flags);
563 out:
564 i_ilbadm_free_sgroup(sg);
565 if (h != ILB_INVALID_HANDLE)
566 (void) ilb_close(h);
568 if ((rc != ILBADM_OK) && (rc != ILBADM_LIBERR))
569 ilbadm_err(ilbadm_errstr(rc));
570 return (rc);
573 /* ARGSUSED */
574 static ilbadm_status_t
575 ilbadm_Xable_server(int argc, char *argv[], ilbadm_cmd_t cmd)
577 ilb_handle_t h = ILB_INVALID_HANDLE;
578 ilbadm_status_t rc = ILBADM_OK;
579 ilb_status_t rclib = ILB_STATUS_OK;
580 int i;
582 if (argc < 2) {
583 ilbadm_err(gettext("missing required argument"
584 " (server specification)"));
585 rc = ILBADM_LIBERR;
586 goto out;
589 rclib = ilb_open(&h);
590 if (rclib != ILB_STATUS_OK)
591 goto out;
593 /* enable-server and disable-server only accepts serverids */
594 for (i = 1; i < argc && rclib == ILB_STATUS_OK; i++) {
595 ilb_server_data_t srv;
597 if (argv[i][0] != ILB_SRVID_PREFIX) {
598 rc = ILBADM_INVAL_SRVID;
599 goto out;
602 bzero(&srv, sizeof (srv));
603 /* to do: check length */
604 (void) strlcpy(srv.sd_srvID, argv[i], sizeof (srv.sd_srvID));
605 switch (cmd) {
606 case cmd_enable_server:
607 rclib = ilb_enable_server(h, &srv, NULL);
608 break;
609 case cmd_disable_server:
610 rclib = ilb_disable_server(h, &srv, NULL);
611 break;
614 /* if we can't find a given server ID, just plough on */
615 if (rclib == ILB_STATUS_ENOENT) {
616 const char *msg = ilb_errstr(rclib);
618 rc = ILBADM_LIBERR;
619 ilbadm_err("%s: %s", msg, argv[i]);
620 rclib = ILB_STATUS_OK;
621 continue;
623 if (rclib != ILB_STATUS_OK)
624 break;
626 out:
627 if (h != ILB_INVALID_HANDLE)
628 (void) ilb_close(h);
630 if (rclib != ILB_STATUS_OK) {
631 ilbadm_err(ilb_errstr(rclib));
632 rc = ILBADM_LIBERR;
635 if ((rc != ILBADM_OK) && (rc != ILBADM_LIBERR))
636 ilbadm_err(ilbadm_errstr(rc));
637 return (rc);
640 ilbadm_status_t
641 ilbadm_disable_server(int argc, char *argv[])
643 return (ilbadm_Xable_server(argc, argv, cmd_disable_server));
646 ilbadm_status_t
647 ilbadm_enable_server(int argc, char *argv[])
649 return (ilbadm_Xable_server(argc, argv, cmd_enable_server));
652 /* ARGSUSED */
653 ilbadm_status_t
654 ilbadm_rem_server_from_group(int argc, char *argv[])
656 ilb_handle_t h = ILB_INVALID_HANDLE;
657 ilb_status_t rclib = ILB_STATUS_OK;
658 ilbadm_status_t rc = ILBADM_OK;
659 ilbadm_sgroup_t *sg;
660 int c;
662 i_ilbadm_alloc_sgroup(&sg);
664 while ((c = getopt(argc, argv, ":s:")) != -1) {
665 switch ((char)c) {
666 case 's':
667 rc = i_parse_serverIDs(optarg, sg);
668 break;
669 case ':':
670 ilbadm_err(gettext("missing option-argument for"
671 " %c"), (char)optopt);
672 rc = ILBADM_LIBERR;
673 break;
674 case '?':
675 default: unknown_opt(argv, optind-1);
676 /* not reached */
677 break;
679 if (rc != ILBADM_OK)
680 goto out;
683 /* we need servergroup name and at least one serverID to remove */
684 if (optind >= argc || sg->sg_count == 0) {
685 rc = ILBADM_ENOOPTION;
686 goto out;
689 sg->sg_name = argv[optind];
691 rclib = ilb_open(&h);
692 if (rclib != ILB_STATUS_OK)
693 goto out;
695 rc = i_mod_sg(h, sg, cmd_rem_srv, 0);
696 out:
697 i_ilbadm_free_sgroup(sg);
699 if (h != ILB_INVALID_HANDLE)
700 (void) ilb_close(h);
701 if ((rc != ILBADM_OK) && (rc != ILBADM_LIBERR))
702 ilbadm_err(ilbadm_errstr(rc));
703 return (rc);
706 ilbadm_status_t
707 ilbadm_destroy_servergroup(int argc, char *argv[])
709 ilb_handle_t h = ILB_INVALID_HANDLE;
710 ilb_status_t rclib = ILB_STATUS_OK;
711 ilbadm_status_t rc = ILBADM_OK;
712 char *sgname;
714 if (argc != 2) {
715 ilbadm_err(gettext("usage:ilbadm"
716 " delete-servergroup groupname"));
717 rc = ILBADM_LIBERR;
718 goto out;
721 sgname = argv[1];
723 rclib = ilb_open(&h);
724 if (rclib != ILB_STATUS_OK)
725 goto out;
727 rclib = ilb_destroy_servergroup(h, sgname);
728 out:
729 if (h != ILB_INVALID_HANDLE)
730 (void) ilb_close(h);
732 if (rclib != ILB_STATUS_OK) {
733 ilbadm_err(ilb_errstr(rclib));
734 rc = ILBADM_LIBERR;
737 return (rc);
740 #define BUFSZ 1024
742 static int
743 export_srv_spec(ilb_server_data_t *srv, char *buf, const int bufsize)
745 int len = 0, bufsz = (int)bufsize;
747 ip2str(&srv->sd_addr, buf, bufsz, 0);
749 len += strlen(buf);
750 bufsz -= len;
752 if (srv->sd_minport != 0) {
753 in_port_t h_min, h_max;
754 int inc;
756 h_min = ntohs(srv->sd_minport);
757 h_max = ntohs(srv->sd_maxport);
759 /* to do: if service name was given, print that, not number */
760 if (h_max <= h_min)
761 inc = snprintf(buf+len, bufsz, ":%d", h_min);
762 else
763 inc = snprintf(buf+len, bufsz, ":%d-%d", h_min, h_max);
765 if (inc > bufsz) /* too little space */
766 return (-1);
767 len += inc;
770 return (len);
775 * this is called by ilb_walk_servers(), therefore we return ilb_status_t
776 * not ilbadm_status, and retain an unused function argument
778 /* ARGSUSED */
779 ilb_status_t
780 ilbadm_export_a_srv(ilb_handle_t h, ilb_server_data_t *srv, const char *sgname,
781 void *arg)
783 sg_export_arg_t *larg = (sg_export_arg_t *)arg;
784 FILE *fp = larg->fp;
785 char linebuf[BUFSZ]; /* XXXms make that dynamic */
786 int sz = BUFSZ;
788 if (export_srv_spec(srv, linebuf, sz) == -1)
789 return (ILB_STATUS_OK);
791 (void) fprintf(fp, "add-server -s server=");
793 (void) fprintf(fp, "%s %s\n", linebuf, sgname);
794 return (ILB_STATUS_OK);
797 ilb_status_t
798 ilbadm_export_sg(ilb_handle_t h, ilb_sg_data_t *sg, void *arg)
800 ilb_status_t rc = ILB_STATUS_OK;
801 sg_export_arg_t *larg = (sg_export_arg_t *)arg;
802 FILE *fp = larg->fp;
804 (void) fprintf(fp, "create-servergroup %s\n", sg->sgd_name);
805 if (sg->sgd_srvcount == 0)
806 return (ILB_STATUS_OK);
808 rc = ilb_walk_servers(h, ilbadm_export_a_srv, sg->sgd_name, arg);
809 if (rc != ILB_STATUS_OK)
810 goto out;
812 if (fflush(fp) == EOF)
813 rc = ILB_STATUS_WRITE;
815 out:
816 return (rc);
819 ilbadm_status_t
820 ilbadm_export_servergroups(ilb_handle_t h, FILE *fp)
822 ilb_status_t rclib = ILB_STATUS_OK;
823 ilbadm_status_t rc = ILBADM_OK;
824 sg_export_arg_t arg;
826 arg.fp = fp;
827 arg.sg = NULL;
829 rclib = ilb_walk_servergroups(h, ilbadm_export_sg, NULL, (void *)&arg);
830 if (rclib != ILB_STATUS_OK) {
831 ilbadm_err(ilb_errstr(rclib));
832 rc = ILBADM_LIBERR;
835 return (rc);