int main( int argc, /* I */ char **argv) /* I */ { struct batch_status *bstatus = NULL; int con; char *specified_server = NULL; int errflg = 0; int i; extern char *optarg; extern int optind; char **pa; struct batch_status *pbstat; int flag = ALLI; char *note = NULL; enum note_flags note_flag = unused; char **nodeargs = NULL; int lindex; enum NStateEnum ListType = tnsNONE; /* get default server, may be changed by -s option */ progname = strdup(argv[0]); while ((i = getopt(argc, argv, "acdlopqrs:x-:N:n")) != EOF) { switch (i) { case 'a': flag = ALLI; break; case 'c': flag = CLEAR; break; case 'd': flag = DIAG; break; case 'l': flag = LIST; break; case 'o': flag = OFFLINE; break; case 'p': flag = PURGE; break; case 'q': quiet = 1; break; case 'r': flag = RESET; break; case 's': specified_server = optarg; break; case 'x': flag = ALLI; DisplayXML = TRUE; break; case 'N': /* preserve any previous option other than the default, * to allow -N to be combined with -o, -c, etc */ if (flag == ALLI) flag = NOTE; note = strdup(optarg); if (note == NULL) { perror("Error: strdup() returned NULL"); exit(1); } note_flag = set; /* -N n is the same as -N "" -- it clears the note */ if (!strcmp(note, "n")) *note = '\0'; if (strlen(note) > MAX_NOTE) { fprintf(stderr, "Warning: note exceeds length limit (%d) - server may reject it...\n", MAX_NOTE); } if (strchr(note, '\n') != NULL) fprintf(stderr, "Warning: note contains a newline - server may reject it...\n"); break; case 'n': note_flag = list; break; case '-': if ((optarg != NULL) && !strcmp(optarg, "version")) { fprintf(stderr, "Version: %s\nRevision: %s\n", PACKAGE_VERSION, SVN_VERSION); exit(0); } else if ((optarg != NULL) && !strcmp(optarg, "about")) { TShowAbout_exit(); } errflg = 1; break; case '?': default: errflg = 1; break; } /* END switch (i) */ } /* END while (i = getopt()) */ if ((note_flag == list) && (flag != LIST)) { fprintf(stderr, "Error: -n requires -l\n"); errflg = 1; } for (pa = argv + optind;*pa;pa++) { if (strlen(*pa) == 0) { errflg = 1; } } if (errflg != 0) { if (!quiet) { fprintf(stderr, "usage:\t%s [-{c|d|l|o|p|r}] [-s server] [-n] [-N \"note\"] [-q] node ...\n", progname); fprintf(stderr, "\t%s [-{a|x}] [-s server] [-q] [node]\n", progname); } exit(1); } con = cnt2server(specified_server); if (con <= 0) { if (!quiet) { fprintf(stderr, "%s: cannot connect to server %s, error=%d (%s)\n", progname, (specified_server) ? specified_server : pbs_default(), con * -1, pbs_strerror(con * -1)); } exit(1); } /* if flag is ALLI, LIST, get status of all nodes */ if ((flag == ALLI) || (flag == LIST) || (flag == DIAG)) { if ((flag == ALLI) || (flag == LIST) || (flag == DIAG)) { if (flag == LIST) { /* allow state specification */ if (argv[optind] != NULL) { for (lindex = 1;lindex < tnsLAST;lindex++) { if (!strcasecmp(NState[lindex], argv[optind])) { ListType = lindex; optind++; break; } } } } /* allow node specification (if none, then create an empty list) */ if (argv[optind] != NULL) { nodeargs = argv + optind; } else { nodeargs = calloc(2, sizeof(char **)); nodeargs[0] = strdup(""); nodeargs[1] = '\0'; } } } if ((note_flag == set) && (note != NULL)) { /* set the note attrib string on specified nodes */ for (pa = argv + optind;*pa;pa++) { set_note(con, *pa, note); } } switch (flag) { case DIAG: /* NYI */ break; case CLEAR: /* clear OFFLINE from specified nodes */ for (pa = argv + optind;*pa;pa++) { marknode(con, *pa, ND_offline, DECR, NULL, DECR); } break; case RESET: /* clear OFFLINE, add DOWN to specified nodes */ for (pa = argv + optind;*pa;pa++) { marknode(con, *pa, ND_offline, DECR, ND_down, INCR); } break; case OFFLINE: /* set OFFLINE on specified nodes */ for (pa = argv + optind;*pa;pa++) { marknode(con, *pa, ND_offline, INCR, NULL, INCR); } break; case PURGE: /* remove node record */ /* NYI */ break; case ALLI: if (DisplayXML == TRUE) { char *tmpBuf = NULL, *tail = NULL; int bufsize; mxml_t *DE; DE = NULL; MXMLCreateE(&DE, "Data"); for (lindex = 0;nodeargs[lindex] != '\0';lindex++) { bstatus = statnode(con, nodeargs[lindex]); for (pbstat = bstatus;pbstat;pbstat = pbstat->next) { addxmlnode(DE, pbstat); } /* END for (pbstat) */ pbs_statfree(pbstat); } MXMLToXString(DE, &tmpBuf, &bufsize, INT_MAX, &tail, TRUE); MXMLDestroyE(&DE); fprintf(stdout, "%s\n", tmpBuf); } else { for (lindex = 0;nodeargs[lindex] != '\0';lindex++) { bstatus = statnode(con, nodeargs[lindex]); for (pbstat = bstatus;pbstat;pbstat = pbstat->next) { printf("%s\n", pbstat->name); prt_node_attr(pbstat, 0); putchar('\n'); } /* END for (bpstat) */ pbs_statfree(pbstat); } } break; case LIST: /* list any node that is DOWN, OFFLINE, or UNKNOWN */ for (lindex = 0;nodeargs[lindex] != '\0';lindex++) { bstatus = statnode(con, nodeargs[lindex]); for (pbstat = bstatus;pbstat != NULL;pbstat = pbstat->next) { char *S; S = get_nstate(pbstat); if (filterbystate(pbstat, ListType, S)) { char *n; if ((note_flag == list) && (n = get_note(pbstat))) { printf("%-20.20s %-26.26s %s\n", pbstat->name, S, n); } else { printf("%-20.20s %s\n", pbstat->name, S); } } } pbs_statfree(pbstat); } break; } /* END switch (flag) */ pbs_disconnect(con); return(0); } /* END main() */
Node * Canonical(Node *n) { Node *m, *p, *k1, *k2, *prev, *dflt = ZN; int tok; if (!n) return n; tok = n->ntyp; if (tok != AND && tok != OR) return n; can = ZN; addcan(tok, n); #if 0 Debug("\nA0: "); Dump(can); Debug("\nA1: "); Dump(n); Debug("\n"); #endif releasenode(1, n); /* mark redundant nodes */ if (tok == AND) { for (m = can; m; m = (m->ntyp == AND) ? m->rgt : ZN) { k1 = (m->ntyp == AND) ? m->lft : m; if (k1->ntyp == TRUE) { marknode(AND, m); dflt = True; continue; } if (k1->ntyp == FALSE) { releasenode(1, can); can = False; goto out; } } for (m = can; m; m = (m->ntyp == AND) ? m->rgt : ZN) for (p = can; p; p = (p->ntyp == AND) ? p->rgt : ZN) { if (p == m || p->ntyp == -1 || m->ntyp == -1) continue; k1 = (m->ntyp == AND) ? m->lft : m; k2 = (p->ntyp == AND) ? p->lft : p; if (isequal(k1, k2)) { marknode(AND, p); continue; } if (anywhere(OR, k1, k2)) { marknode(AND, p); continue; } } } if (tok == OR) { for (m = can; m; m = (m->ntyp == OR) ? m->rgt : ZN) { k1 = (m->ntyp == OR) ? m->lft : m; if (k1->ntyp == FALSE) { marknode(OR, m); dflt = False; continue; } if (k1->ntyp == TRUE) { releasenode(1, can); can = True; goto out; } } for (m = can; m; m = (m->ntyp == OR) ? m->rgt : ZN) for (p = can; p; p = (p->ntyp == OR) ? p->rgt : ZN) { if (p == m || p->ntyp == -1 || m->ntyp == -1) continue; k1 = (m->ntyp == OR) ? m->lft : m; k2 = (p->ntyp == OR) ? p->lft : p; if (isequal(k1, k2)) { marknode(OR, p); continue; } if (anywhere(AND, k1, k2)) { marknode(OR, p); continue; } } } for (m = can, prev = ZN; m; ) /* remove marked nodes */ { if (m->ntyp == -1) { k2 = m->rgt; releasenode(0, m); if (!prev) { m = can = can->rgt; } else { m = prev->rgt = k2; /* if deleted the last node in a chain */ if (!prev->rgt && prev->lft && (prev->ntyp == AND || prev->ntyp == OR)) { k1 = prev->lft; prev->ntyp = prev->lft->ntyp; prev->sym = prev->lft->sym; prev->rgt = prev->lft->rgt; prev->lft = prev->lft->lft; releasenode(0, k1); } } continue; } prev = m; m = m->rgt; } out: #if 0 Debug("A2: "); Dump(can); Debug("\n"); #endif if (!can) { if (!dflt) fatal("cannot happen, Canonical", (char *) 0); return dflt; } return can; }