/* * test main for lut module, usage: a.out [lhs[=rhs]...] */ int main(int argc, char *argv[]) { struct lut *r = NULL; struct lut *dupr = NULL; char *equals; err_init(argv[0]); setbuf(stdout, NULL); for (argv++; *argv; argv++) if ((equals = strchr(*argv, '=')) != NULL) { *equals++ = '\0'; r = lut_add(r, *argv, equals); } else r = lut_add(r, *argv, "NULL"); printf("lut contains:\n"); lut_walk(r, printer, r); dupr = lut_dup(r); lut_free(r, NULL); printf("dup lut contains:\n"); lut_walk(dupr, printer, dupr); lut_free(dupr, NULL); err_done(0); /* NOTREACHED */ return (0); }
struct ipath * ipath_for_usednames(struct node *np) { struct ipath *ret, *ipp; int i = 0; struct node *np2; for (np2 = np; np2 != NULL; np2 = np2->u.name.next) i++; ret = MALLOC(sizeof (*ret) * (i + 1)); for (i = 0, np2 = np; np2 != NULL; np2 = np2->u.name.next) { ret[i].s = np2->u.name.s; ret[i++].i = 0; } ret[i].s = NULL; if ((ipp = lut_lookup(Ipaths, (void *)ret, (lut_cmp)ipath_cmp)) != NULL) { FREE(ret); return (ipp); } Ipaths = lut_add(Ipaths, (void *)ret, (void *)ret, (lut_cmp)ipath_cmp); stats_counter_bump(Nipath); stats_counter_add(Nbytes, (i + 1) * sizeof (struct ipath)); return (ret); }
struct ipath * ipath_dummy(struct node *np, struct ipath *ipp) { struct ipath *ret; ret = ipp; while (ipp[1].s != NULL) ipp++; if (strcmp(ipp[0].s, np->u.name.last->u.name.s) == 0) return (ret); ret = MALLOC(sizeof (*ret) * 2); ret[0].s = np->u.name.last->u.name.s; ret[0].i = 0; ret[1].s = NULL; if ((ipp = lut_lookup(Ipaths, (void *)ret, (lut_cmp)ipath_cmp)) != NULL) { FREE(ret); return (ipp); } Ipaths = lut_add(Ipaths, (void *)ret, (void *)ret, (lut_cmp)ipath_cmp); stats_counter_bump(Nipath); stats_counter_add(Nbytes, 2 * sizeof (struct ipath)); return (ret); }
/* helper function for lut_dup() */ static void dooper(const char *lhs, void *rhs, void *arg) { struct lut **rootp = (struct lut **)arg; *rootp = lut_add(*rootp, lhs, rhs); }
/* * dodictionary -- handle "#pragma dictionary" directives */ static void dodictionary() { int c; char *ptr = Tok; char *eptr = &Tok[MAXTOK]; /* skip white space and quotes */ while ((c = getc(Fp)) != EOF && (c == ' ' || c == '\t' || c == '"')) ; if (c == EOF || c == '\n') outfl(O_DIE, File, Line, "bad dictionary"); /* pull in next token */ ptr = Tok; *ptr++ = c; while ((c = getc(Fp)) != EOF && c != '"' && c != '\n') if (ptr < eptr - 1) *ptr++ = c; *ptr++ = '\0'; if (c != '\n') { /* skip to end of line (including close quote, if any) */ while ((c = getc(Fp)) != EOF && c != '\n') ; } (void) ungetc(c, Fp); Dicts = lut_add(Dicts, (void *)stable(Tok), (void *)0, NULL); outfl(O_VERB, File, Line, "pragma set: dictionary \"%s\"", Tok); }
void ipath_dummy_lut(struct arrow *arrowp) { const struct ipath *ipp; ipp = arrowp->head->myevent->ipp_un; while (ipp->s != NULL) { Usednames = lut_add(Usednames, (void *)ipp->s, (void *)ipp->s, NULL); ipp++; } ipp = arrowp->tail->myevent->ipp_un; while (ipp->s != NULL) { Usednames = lut_add(Usednames, (void *)ipp->s, (void *)ipp->s, NULL); ipp++; } }
/* * ipath -- find instanced path in cache, or add it if necessary */ const struct ipath * ipath(struct node *np) { struct ipath *ret; int count; struct node *namep; int i; if ((ret = lut_lookup(Ipaths, (void *)np, (lut_cmp)ipath_epnamecmp)) != NULL) return (ret); /* already in cache */ /* * not in cache, make new cache entry. * start by counting the length of the name. */ count = 0; namep = np; while (namep != NULL) { ASSERTinfo(namep->t == T_NAME, ptree_nodetype2str(namep->t)); count++; namep = namep->u.name.next; } ASSERT(count > 0); /* allocate array for name and last NULL entry */ ret = MALLOC(sizeof (*ret) * (count + 1)); ret[count].s = NULL; /* fill in ipath entry */ namep = np; i = 0; while (namep != NULL) { ASSERT(i < count); ret[i].s = namep->u.name.s; if (namep->u.name.child != NULL && namep->u.name.child->t == T_NUM) ret[i].i = (int)namep->u.name.child->u.ull; else config_getcompname(namep->u.name.cp, NULL, &ret[i].i); i++; namep = namep->u.name.next; } /* add it to the cache */ Ipaths = lut_add(Ipaths, (void *)ret, (void *)ret, (lut_cmp)ipath_cmp); stats_counter_bump(Nipath); stats_counter_add(Nbytes, (count + 1) * sizeof (struct ipath)); return (ret); }
/* * lut_add -- add an entry to the table * * use it like this: * struct lut *root = NULL; * root = lut_add(root, "key", value); * * the key string gets strdup'd by lut_add(), but the memory holding * the *value should not be freed until the lut is freed by lut_free(). */ struct lut * lut_add(struct lut *root, const char *lhs, void *rhs) { int diff = 0; if (root == NULL) { /* not in tree, create new node */ root = MALLOC(sizeof (*root)); root->lut_lhs = STRDUP(lhs); root->lut_rhs = rhs; root->lut_left = root->lut_right = NULL; } else if (lhs != NULL && (diff = strcmp(root->lut_lhs, lhs)) == 0) { /* already in tree, replace node */ root->lut_rhs = rhs; } else if (diff > 0) root->lut_left = lut_add(root->lut_left, lhs, rhs); else root->lut_right = lut_add(root->lut_right, lhs, rhs); return (root); }
void ipathlastcomp(const struct ipath *ipp) { int i; for (i = 0; ipp[i].s != NULL; i++) ; out(O_ALTFP, "newfme: add %s to Usednames", ipp[i - 1].s); Usednames = lut_add(Usednames, (void *)ipp[i - 1].s, (void *)ipp[i - 1].s, NULL); }
/* allocate & fill in another entry in our list */ static void fillconflist(int lineno, const char *entry, struct opts *opts, const char *com, int flags) { struct confinfo *cp = MALLOC(sizeof (*cp)); cp->cf_next = NULL; cp->cf_lineno = lineno; cp->cf_entry = entry; cp->cf_opts = opts; cp->cf_com = com; cp->cf_flags = flags; if (entry != NULL) { Conflut = lut_add(Conflut, entry, cp); fn_list_adds(Confentries, entry); } if (Confinfo == NULL) Confinfo = Confinfolast = cp; else { Confinfolast->cf_next = cp; Confinfolast = cp; } }
/* * kw_init -- initialize keywords based on given filename */ void kw_init(struct fn *fnp, struct fn *nfnp) { static char *fullpath; static char *nfullpath; static char *splitpath; static char secs[MAXDIGITS]; static struct utsname un; static char platform[SYS_NMLN]; static char isa[SYS_NMLN]; static char domain[256]; static char *home; static char *user; static char *logname; static char zonename[ZONENAME_MAX]; static zoneid_t zoneid; static int initialized; char *ptr; /* make a copy of the string for $file */ if (fullpath) FREE(fullpath); fullpath = STRDUP(fn_s(fnp)); Keywords = lut_add(Keywords, "file", fullpath); /* make a copy of the string for $nfile */ if (nfullpath) FREE(nfullpath); if (nfnp == NULL) { nfullpath = NULL; Keywords = lut_add(Keywords, "nfile", ""); } else { nfullpath = STRDUP(fn_s(nfnp)); Keywords = lut_add(Keywords, "nfile", nfullpath); } /* make a copy of the string for $dirname/$basename */ if (splitpath) FREE(splitpath); splitpath = STRDUP(fn_s(fnp)); if ((ptr = strrchr(splitpath, '/')) == NULL) { Keywords = lut_add(Keywords, "basename", splitpath); Keywords = lut_add(Keywords, "dirname", "."); } else { *ptr++ = '\0'; Keywords = lut_add(Keywords, "basename", ptr); Keywords = lut_add(Keywords, "dirname", splitpath); } if (initialized) return; /* rest of the keywords don't change */ (void) snprintf(secs, MAXDIGITS, "%d", (int)Now); Keywords = lut_add(Keywords, "secs", secs); if (uname(&un) < 0) err(EF_SYS, "uname"); Keywords = lut_add(Keywords, "nodename", un.nodename); Keywords = lut_add(Keywords, "release", un.release); Keywords = lut_add(Keywords, "machine", un.machine); if (sysinfo(SI_ARCHITECTURE, isa, sizeof (isa)) == -1) err(EF_WARN|EF_SYS, "sysinfo(SI_ARCHITECTURE) failed."); else Keywords = lut_add(Keywords, "isa", isa); if (sysinfo(SI_PLATFORM, platform, sizeof (platform)) == -1) err(EF_WARN|EF_SYS, "sysinfo(SI_PLATFORM) failed."); else Keywords = lut_add(Keywords, "platform", platform); if (sysinfo(SI_SRPC_DOMAIN, domain, sizeof (domain)) == -1) err(EF_WARN|EF_SYS, "sysinfo(SI_SRPC_DOMAIN) failed."); else Keywords = lut_add(Keywords, "domain", domain); if ((home = getenv("HOME")) != NULL) Keywords = lut_add(Keywords, "home", STRDUP(home)); if ((user = getenv("USER")) != NULL) Keywords = lut_add(Keywords, "user", STRDUP(user)); if ((logname = getenv("LOGNAME")) != NULL) Keywords = lut_add(Keywords, "logname", STRDUP(logname)); zoneid = getzoneid(); if ((getzonenamebyid(zoneid, zonename, sizeof (zonename))) == -1) err(EF_WARN|EF_SYS, "getzonenamebyid() failed."); else Keywords = lut_add(Keywords, "zonename", STRDUP(zonename)); initialized = 1; }
static struct lut * lex_s2ullp_lut_add(struct lut *root, const char *s, const unsigned long long *ullp) { return (lut_add(root, (void *)s, (void *)ullp, NULL)); }
static struct lut * lex_s2i_lut_add(struct lut *root, const char *s, intptr_t i) { return (lut_add(root, (void *)s, (void *)i, NULL)); }
FILE * eftread_fopen(const char *fname, char *idbuf, size_t idbufsz) { FILE *fp; FILE *tfp; struct eftheader hdr; #define BUFLEN 8192 char buf[BUFLEN]; int cc; uint32_t csum = 0; char *ptr; if ((ptr = strrchr(fname, '.')) == NULL || strcmp(ptr, ".eft") != 0) { out(O_ERR, "%s: not a valid EFT (bad extension)", fname); return (NULL); } if ((fp = fopen(fname, "r")) == NULL) { out(O_ERR|O_SYS, "%s", fname); return (NULL); } if (fread(&hdr, 1, sizeof (hdr), fp) < sizeof (hdr)) { (void) fclose(fp); out(O_ERR, "%s: not a valid EFT (too short)", fname); return (NULL); } hdr.magic = ntohl(hdr.magic); hdr.major = ntohs(hdr.major); hdr.minor = ntohs(hdr.minor); hdr.cmajor = ntohs(hdr.cmajor); hdr.cminor = ntohs(hdr.cminor); hdr.identlen = ntohl(hdr.identlen); hdr.dictlen = ntohl(hdr.dictlen); hdr.csum = ntohl(hdr.csum); if (Showheader) out(O_VERB, "%s: magic %x EFT version %d.%d esc version %d.%d", fname, hdr.magic, hdr.major, hdr.minor, hdr.cmajor, hdr.cminor); if (hdr.magic != EFT_HDR_MAGIC) { (void) fclose(fp); out(O_ERR, "%s: not a valid EFT (bad magic)", fname); return (NULL); } if (hdr.major != EFT_HDR_MAJOR || hdr.minor > EFT_HDR_MINOR) { (void) fclose(fp); out(O_ERR, "%s is version %d.%d, " "this program supports up to %d.%d", fname, hdr.major, hdr.minor, EFT_HDR_MAJOR, EFT_HDR_MINOR); return (NULL); } bzero(idbuf, idbufsz); if (hdr.identlen != 0) { long npos = ftell(fp) + (long)hdr.identlen; /* after ident */ size_t rsz = MIN(hdr.identlen, idbufsz - 1); if (fread(idbuf, 1, rsz, fp) != rsz) out(O_DIE|O_SYS, "%s: fread", fname); if (fseek(fp, npos, SEEK_SET) == -1) out(O_DIE|O_SYS, "%s: fseek", fname); } if (hdr.dictlen && (hdr.dictlen < 2 || hdr.dictlen > 1000)) { (void) fclose(fp); out(O_ERR, "%s: bad dictlen: %d", fname, hdr.dictlen); return (NULL); } /* read in dict strings */ if (hdr.dictlen) { char *dbuf = alloca(hdr.dictlen); char *dptr; if ((cc = fread(dbuf, 1, hdr.dictlen, fp)) != hdr.dictlen) out(O_DIE|O_SYS, "short fread on %s (dictlen %d)", fname, hdr.dictlen); /* work from end of string array backwards, finding names */ for (dptr = &dbuf[hdr.dictlen - 2]; dptr > dbuf; dptr--) if (*dptr == '\0') { /* found separator, record string */ Dicts = lut_add(Dicts, (void *)stable(dptr + 1), (void *)0, NULL); } /* record the first string */ Dicts = lut_add(Dicts, (void *)stable(dptr), (void *)0, NULL); } if ((tfp = tmpfile()) == NULL) out(O_DIE|O_SYS, "cannot create temporary file"); while ((cc = fread(buf, 1, BUFLEN, fp)) > 0) { char *ptr; for (ptr = buf; ptr < &buf[cc]; ptr++) { *ptr = ~((unsigned char)*ptr); csum += (uint32_t)*ptr; } if (cc != fwrite(buf, 1, cc, tfp) || ferror(tfp)) out(O_DIE|O_SYS, "fwrite on tmpfile"); } if (ferror(fp)) out(O_DIE|O_SYS, "fread on %s", fname); (void) fclose(fp); if (hdr.csum != csum) { out(O_ERR, "%s: bad checksum (%x != %x)", fname, hdr.csum, csum); (void) fclose(tfp); return (NULL); } if (Showheader) { int len = strlen(hdr.comment); if (len > 0 && hdr.comment[len - 1] == '\n') hdr.comment[len - 1] = '\0'; out(O_OK, "%s:\n\t%s", fname, hdr.comment); } rewind(tfp); return (tfp); }