/* $Id: common.c,v 1.6 2001/08/16 19:08:17 garbled Exp $ */ /* * Copyright (c) 1998, 1999, 2000 * Tim Rightnour. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Tim Rightnour. * 4. The name of Tim Rightnour may not be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY TIM RIGHTNOUR ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL TIM RIGHTNOUR BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * these are routines that are used in all the dsh programs, and therefore * rather than having to fix them in n places, they are kept here. */ #include "common.h" #if !defined(lint) && defined(__NetBSD__) __COPYRIGHT( "@(#) Copyright (c) 1998, 1999, 2000\n\ Tim Rightnour. All rights reserved\n"); __RCSID("$Id: common.c,v 1.6 2001/08/16 19:08:17 garbled Exp $"); #endif #ifdef CLUSTERS /* * This routine just rips open the various arrays and prints out information * about what the command would have done, and the topology of your cluster. * Invoked via the -q switch. */ void do_showcluster(fanout) int fanout; { node_t *nodeptr; int i, j, l, n; char *group; i = l = 0; for (nodeptr = nodelink; nodeptr->next != NULL; nodeptr = nodeptr->next) i++; /* just count the nodes */ ; j = i / fanout; /* how many times do I have to run in order to reach them all */ if (i % fanout) j++; if (rungroup[0] != NULL) { (void)printf("Rungroup:"); for (i=0; rungroup[i] != NULL; i++) { if (!(i % 4) && i > 0) (void)printf("\n"); (void)printf("\t%s", rungroup[i]); } if (i % 4) (void)printf("\n"); } nodeptr = nodelink; if (getenv("CLUSTER")) (void)printf("Cluster file: %s\n", getenv("CLUSTER")); (void)printf("Fanout size: %d\n", fanout); for (n=0; n <= j; n++) { for (i=0; (i < fanout && nodeptr != NULL); i++) { l++; group = NULL; if (nodeptr->group >= 0 && grouplist[nodeptr->group].name) group = strdup(grouplist[nodeptr->group].name); if (group == NULL) (void)printf("Node: %3d Fangroup: %3d Rungroup: None" " Host: %-15s\n", l, n + 1, nodeptr->name); else (void)printf("Node: %3d Fangroup: %3d Rungroup: %-15s" " Host: %-15s\n", l, n + 1, group, nodeptr->name); nodeptr = nodeptr->next; } } } /* * A routine to parse the command arguments, and prepare a nodelist for use * returns the number of groups in the list. */ int parse_cluster(exclude) char **exclude; { FILE *fd; char *clusterfile, *p, *nodename; int i, j, g, fail, gfail, lumping, n, ging; char buf[MAXBUF]; extern int errno; group_t *grouptemp; node_t *nodeptr; char **lumptemp; g = -1; lumping = ging = 0; n = 0; gfail = 1; grouplist = (group_t *)malloc(GROUP_MALLOC * sizeof(group_t)); if (grouplist == NULL) bailout(__LINE__); lumplist = (char **)malloc(GROUP_MALLOC * sizeof(char *)); if (lumplist == NULL) bailout(__LINE__); /* if -w wasn't specified, we need to parse the cluster file */ clusterfile = getenv("CLUSTER"); if (clusterfile == NULL) { (void)fprintf(stderr, "%s: must use -w flag without CLUSTER environment setting.\n", progname); exit(EXIT_FAILURE); } fd = fopen(clusterfile, "r"); if (NULL == fd) { (void)fprintf(stderr, "%s: open of clusterfile failed:%s\n", progname, strerror(errno)); exit(EXIT_FAILURE); } /* this is horrid. rewrite me in lex/yacc */ /* First, find all the groups, and build a grouplist */ while ((nodename = fgets(buf, sizeof(buf), fd))) { p = (char *)strsep(&nodename, "\n"); if ((strcmp(p, "") != 0) && (strncmp(p, "#", 1) != 0)) { if (strstr(p, "GROUP") != NULL) { ging = 1; strsep(&p, ":"); if (((g+1) % GROUP_MALLOC) != 0 && n > 0) { grouplist[++g].name = strdup(p); grouplist[g].lump = 0; } else { grouptemp = realloc(grouplist, (g+1)*sizeof(group_t) + GROUP_MALLOC * sizeof(group_t)); if (grouptemp != NULL) grouplist = grouptemp; else bailout(__LINE__); grouplist[++g].name = strdup(p); grouplist[g].lump = 0; } } else if (ging && ((strstr(p, "GROUP") != NULL) || (strstr(p, "LUMP") != NULL))) ging = 0; } } rewind(fd); /* now build the lump list */ lumplist[0] = strdup("NO_GROUP_HERE"); if (lumplist[0] == NULL) bailout(__LINE__); while ((nodename = fgets(buf, sizeof(buf), fd))) { p = (char *)strsep(&nodename, "\n"); /* check for a null line, or a comment */ if ((strcmp(p, "") != 0) && (strncmp(p, "#", 1) != 0)) { if (strstr(p, "LUMP") != NULL) { lumping = 1; strsep(&p, ":"); if (((n+1) % GROUP_MALLOC) != 0 && n > 0) { lumplist[++n] = strdup(p); } else { lumptemp = realloc(lumplist, (n+1)*sizeof(char *) + GROUP_MALLOC * sizeof(char *)); if (lumptemp != NULL) lumplist = lumptemp; else bailout(__LINE__); lumplist[++n] = strdup(p); } } else if (lumping){ if ((strstr(p, "GROUP") != NULL) || (strstr(p, "LUMP") != NULL)) lumping = 0; else { for (j = 0; j <= g; j++) if (strcmp(p, grouplist[j].name) == 0) grouplist[j].lump = n; } } } } rewind(fd); /* Now.. parse the file for real, and build the nodelist */ g = -1; i = 0; while ((nodename = fgets(buf, sizeof(buf), fd))) { p = (char *)strsep(&nodename, "\n"); if ((strcmp(p, "") != 0) && (strncmp(p, "#", 1) != 0)) { /*printf("g = %d p = %s\n", g, p);*/ if (strstr(p, "LUMP") != NULL) lumping = 1; if (lumping && (strstr(p, "GROUP") != NULL)) lumping = 0; if (exclusion || grouping) { /* this handles the -x,g option */ fail = 0; for (j = 0; exclude[j] != NULL; j++) if (strcmp(p, exclude[j]) == 0) fail = 1; if (g >= 0) { gfail = 1; for (j = 0; (rungroup[j] != NULL && gfail == 1); j++) if ((strcmp(grouplist[g].name, rungroup[j]) == 0) || (strcmp(lumplist[grouplist[g].lump], rungroup[j]) == 0)) gfail = 0; } if (!fail) { if (strstr(p, "GROUP") != NULL) { g++; } else if (!gfail && !lumping) { nodeptr = nodealloc(strdup(p)); if (g >= 0) nodeptr->group = g; } } } else { if (strstr(p, "GROUP") != NULL) { g++; } else if (!lumping){ nodeptr = nodealloc(strdup(p)); if (g >= 0) nodeptr->group = g; } } /* exlusion */ } /* strcmp */ } /* while nodename */ fclose(fd); return(g); } /* allocates a new/first node, and returns a pointer to the user */ struct node_data * nodealloc(nodename) char * nodename; { struct node_data *nodeptr, *nodex; if (nodelink == NULL) { nodelink = malloc((size_t)sizeof(node_t)); nodelink->name = strdup(nodename); nodelink->group = 0; nodelink->err.fds[0] = NULL; nodelink->err.fds[1] = NULL; nodelink->out.fds[0] = NULL; nodelink->out.fds[1] = NULL; nodelink->index = 1.0; nodelink->free = 1; nodelink->childpid = NULL; nodelink->next = NULL; #ifdef USE_X11 nodelink->win_id = 0; #endif return(nodelink); } nodex = malloc(sizeof(node_t)); if (NULL == nodex) bailout(__LINE__); for (nodeptr = nodelink; nodeptr->next != NULL; nodeptr = nodeptr->next) ; nodeptr->next = nodex; nodex->name = strdup(nodename); nodex->group = 0; nodex->err.fds[0] = NULL; nodex->err.fds[1] = NULL; nodex->out.fds[0] = NULL; nodex->out.fds[1] = NULL; nodex->childpid = NULL; nodex->next = NULL; nodex->free = 1; nodex->index = 1.0; #ifdef USE_X11 nodex->win_id = 0; #endif return(nodex); } #endif /* CLUSTERS */ /* * Simple error handling routine, needs severe work. * Its almost totally useless. */ /*ARGSUSED*/ void bailout(line) int line; { extern int errno; if (debug) (void)fprintf(stderr, "%s: Failed on line %d: %s %d\n", progname, line, strerror(errno), errno); else (void)fprintf(stderr, "%s: Internal error, aborting: %s\n", progname, strerror(errno)); _exit(EXIT_FAILURE); }