ref: e78b5e27f582a692b81369be4614d0a7b8eee9cb
dir: /netgraph.c/
#include <u.h> #include <libc.h> #include <bio.h> #include <ndb.h> #include <String.h> #include "dat.h" #include "fns.h" static void usage(void) { fprint(2, "usage: %s [-ip] [-s systuples] [-n ipnettuples]\n", argv0); exits("usage"); } #define MAXSYSTP 24 char *Sipnet = "ipnet"; char *netdir = nil; char *systuples[MAXSYSTP]; int nsystuples = 0; char *ipnettuples[MAXSYSTP]; int nipnettuples = 0; /* A3 format: 842 x 1191 */ int pagewidth = 1191; int pageheight = 842; int showipnet = 0; static void procrequest(char *key, char *val) { if (issysarg(key)) { gensys(key, val); return; } if (isnetarg(key)) { genipnet(key, val); return; } } static void procinput(char *s) { char *c; c = strchr(s, '='); if (!(c && c[0] && c[1])) return; c[0] = 0; c++; procrequest(s, c); } void dumptuples(Tuple *t, void*) { fprint(2, " %s=%s\n", t->key, t->value); } void dumpsys(Sys *s, void*) { fprint(2, "sys: %d %d\n", s->p.x, s->p.y); fortuple(s, dumptuples, nil); } void dumpipnet(Ipnet *n, void*) { fprint(2, "ipnet\n"); fortuple(n, dumptuples, nil); } static Color hue2color(float h) { Color c; int i = h; float f = h * 6. - i; float p = 0.; float q = 1. - f; float t = 1. - (1. - f); switch (i % 6) { case 0: c.r = 1; c.g = t; c.b = p; break; case 1: c.r = q; c.g = 1; c.b = p; break; case 2: c.r = p; c.g = 1; c.b = t; break; case 3: c.r = p; c.g = q; c.b = 1; break; case 4: c.r = t; c.g = p; c.b = 1; break; case 5: c.r = 1; c.g = p; c.b = q; break; } c.r = c.r < 0 ? 0 : c.r; c.g = c.g < 0 ? 0 : c.g; c.b = c.b < 0 ? 0 : c.b; return c; } typedef struct Calcipnetparams Calcipnetparams; struct Calcipnetparams { int i; int x; }; static void calcnetlayout(Ipnet *n, void *aux) { Calcipnetparams *p = aux; int num = numipnets(); int i = p->i; float step = 2*PI / num; float hue = (step * i) / PI; n->color = hue2color(hue); setblocksize(n); n->p.x = p->x + 5; n->p.y = 5; p->i++; p->x += n->width + 10; } static void calcsyslayout(Sys *s, void *aux) { int n = numsystems(); int *ip = aux; int i = *ip; float step = 2*PI / n; setblocksize(s); float pagex = pagewidth/2.; float pagey = pageheight/2.; float spread = 0.6; s->p.x = cos(step * i) * pagex * spread + pagex - s->width/2; s->p.y = sin(step * i) * pagey * spread + pagey - s->height/2; (*ip)++; } static void calcconn(Tuple *t, void *aux) { Sys *from = aux; Sys *to = findsys(t->key, t->value); if (!to) return; if (to == from) return; addconn(from, to, t->key); } void calcconns(Sys *s, void*) { fortuple(s, calcconn, s); } static void drawconns(Conn *c, void*) { dconn(c->from, c->to, s_to_c(c->types)); } static void drawsystems(Sys *s, void*) { dblock(s); } static void drawipnets(Ipnet *n, void*) { dblock(n); } static void injectpdfout(void) { char *size; int p[2]; pipe(p); switch (fork()) { case -1: sysfatal("fork: %r"); case 0: break; default: /* parent */ dup(p[0], 1); close(p[1]); return; } /* child */ dup(p[1], 0); close(p[0]); size = smprint("-g%dx%d", pagewidth, pageheight); execl("/bin/ps2pdf", "ps2pdf", size, "-r72", nil); sysfatal("execl: %r"); } void main(int argc, char **argv) { Biobuf *bin; Calcipnetparams netparams; char *stp = "sys,ether,ip,ipgw,ipnet,dom,auth,authdom"; char *ntp = "ipnet,ip,ipmask,ipgw,authdom,auth,fs,dns"; char *s; int i; int pdf = 0; ARGBEGIN{ case 'h': usage(); case 's': stp = EARGF(usage()); break; case 'n': ntp = EARGF(usage()); break; case 'x': netdir = EARGF(usage()); break; case 'i': showipnet++; break; case 'p': pdf++; break; }ARGEND; if (pdf) injectpdfout(); nsystuples = getfields(stp, systuples, MAXSYSTP, 1, ","); nipnettuples = getfields(ntp, ipnettuples, MAXSYSTP, 1, ","); bin = Bfdopen(0, OREAD); if (!bin) sysfatal("%r"); while (s = Brdstr(bin, '\n', 1)) { procinput(s); free(s); } Bterm(bin); /* calculation stage */ i = 0; forsys(calcsyslayout, &i); netparams.i = 0; netparams.x = 0; fornet(calcnetlayout, &netparams); forsys(calcconns, nil); /* drawing stage */ dheader(); forconn(drawconns, nil); forsys(drawsystems, nil); fornet(drawipnets, nil); dfooter(); } static int tryaddsys(char *s, void *aux) { char *sys = aux; return gensys(s, sys); } void fillblockvalue(Block *b, char *key, char *ids, char *idv) { char *val; Ndbtuple *t; val = csgetvalue(netdir, ids, idv, key, nil); if (val) { addtuple(b, key, val, 0); return; } t = csipinfo(netdir, ids, idv, &key, 1); if (t) { if (t->val) val = strdup(t->val); ndbfree(t); } if (!val) return; addtuple(b, key, val, 1); if (!isconnsrv(key)) return; forsysarg(tryaddsys, val); }