Beispiel #1
0
void
threadmain(int argc, char *argv[])
{
	int serveudp, servetcp;
	char *service;

	serveudp = 0;
	servetcp = 0;
	service = "dns";
	ARGBEGIN{
	case 'd':
		debug = 1;
		traceactivity = 1;
		break;
	case 'f':
		dbfile = EARGF(usage());
		break;
	case 'x':
		service = EARGF(usage());
		break;
	case 'r':
		resolver = 1;
		break;
	case 's':
		serveudp = 1;
		cachedb = 1;
		break;
	case 't':
		servetcp = 1;
		cachedb = 1;
		break;
	case 'a':
		maxage = atoi(EARGF(usage()));
		break;
	case 'z':
		zonerefreshprogram = EARGF(usage());
		break;
	case 'n':
		sendnotifies = 1;
		break;
	case 'U':
		udpaddr = estrdup(netmkaddr(EARGF(usage()), "udp", "domain"));
		break;
	case 'T':
		tcpaddr = estrdup(netmkaddr(EARGF(usage()), "tcp", "domain"));
		break;
	default:
		usage();
	}ARGEND
	
	if(argc)
		usage();
	if(serveudp && servetcp)
		checkaddress();

	rfork(RFNOTEG);

	/* start syslog before we fork */
	fmtinstall('F', fcallfmt);
	dninit();
	if(myipaddr(ipaddr, mntpt) < 0)
		sysfatal("can't read my ip address");

	syslog(0, logfile, "starting dns on %I", ipaddr);

	opendatabase();

	mountinit(service);

	now = time(0);
	srand(now*getpid());
	db2cache(1);

	if(serveudp)
		proccreate(dnudpserver, nil, STACK);
	if(servetcp)
		proccreate(dntcpserver, nil, STACK);
	if(sendnotifies)
		proccreate(notifyproc, nil, STACK);

	io();
}
Beispiel #2
0
void
main(int argc, char **argv)
{
	int p[2], pid, i, j, n, off, npad, prefix;
	char **av, *q, *r, *tofree, *name;
	char nambuf[100];
	Biobuf *bin, *bout;
	Type *t;
	Field *f;
	int orig_output_fd;

	quotefmtinstall();

	oargc = argc;
	oargv = argv;
	av = emalloc((30+argc)*sizeof av[0]);
	atexit(waitforgcc);

	n = 0;
	av[n++] = "gcc";
	av[n++] = "-fdollars-in-identifiers";
	av[n++] = "-S";	// write assembly
	av[n++] = "-gstabs+";	// include stabs info
	av[n++] = "-o";	// to ...
	av[n++] = "-";	// ... stdout
	av[n++] = "-xc";	// read C

	ARGBEGIN{
	case 'g':
		lang = &go;
		pkg = EARGF(usage());
		break;
	case 'c':
		av[0] = EARGF(usage());
		break;
	case 'f':
		av[n++] = EARGF(usage());
		break;
	default:
		usage();
	}ARGEND

	if(argc == 0)
		av[n++] = "-";
	else
		av[n++] = argv[0];
	av[n] = nil;

	orig_output_fd = dup(1, -1);
	for(i=0; i==0 || i < argc; i++) {
		// Some versions of gcc do not accept -S with multiple files.
		// Run gcc once for each file.
		// Write assembly and stabs debugging to p[1].
		if(pipe(p) < 0)
			sysfatal("pipe: %r");
		dup(p[1], 1);
		close(p[1]);
		if (argc)
			av[n-1] = argv[i];
		pid = spawn(av[0], av);
		dup(orig_output_fd, 1);

		// Read assembly, pulling out .stabs lines.
		bin = Bfdopen(p[0], OREAD);
		while((q = Brdstr(bin, '\n', 1)) != nil) {
			//	.stabs	"float:t(0,12)=r(0,1);4;0;",128,0,0,0
			tofree = q;
			while(*q == ' ' || *q == '\t')
				q++;
			if(strncmp(q, ".stabs", 6) != 0)
				goto Continue;
			q += 6;
			while(*q == ' ' || *q == '\t')
				q++;
			if(*q++ != '\"') {
Bad:
				sysfatal("cannot parse .stabs line:\n%s", tofree);
			}

			r = strchr(q, '\"');
			if(r == nil)
				goto Bad;
			*r++ = '\0';
			if(*r++ != ',')
				goto Bad;
			if(*r < '0' || *r > '9')
				goto Bad;
			if(atoi(r) != 128)	// stabs kind = local symbol
				goto Continue;

			parsestabtype(q);

Continue:
			free(tofree);
		}
		Bterm(bin);
		waitfor(pid);
	}
	close(orig_output_fd);

	// Write defs to standard output.
	bout = Bfdopen(1, OWRITE);
	fmtinstall('T', lang->typefmt);

	// Echo original command line in header.
	Bprint(bout, "//");
	for(i=0; i<oargc; i++)
		Bprint(bout, " %q", oargv[i]);
	Bprint(bout, "\n");
	Bprint(bout, "\n");
	Bprint(bout, "// MACHINE GENERATED - DO NOT EDIT.\n");
	Bprint(bout, "\n");

	if(pkg)
		Bprint(bout, "package %s\n\n", pkg);

	// Constants.
	Bprint(bout, "// Constants\n");
	if(ncon > 0) {
		Bprint(bout, lang->constbegin);
		for(i=0; i<ncon; i++) {
			// Go can handle negative constants,
			// but C enums may not be able to.
			if(lang == &go)
				Bprint(bout, lang->constfmt, con[i].name, con[i].value);
			else
				Bprint(bout, lang->constfmt, con[i].name, con[i].value & 0xFFFFFFFF);
		}
		Bprint(bout, lang->constend);
	}
	Bprint(bout, "\n");

	// Types

	// push our names down
	for(i=0; i<ntyp; i++) {
		t = typ[i];
		name = t->name;
		while(t && t->kind == Typedef)
			t = t->type;
		if(t)
			t->name = name;
	}

	Bprint(bout, "// Types\n");

	// Have to turn off structure padding in Plan 9 compiler,
	// mainly because it is more aggressive than gcc tends to be.
	if(lang == &c)
		Bprint(bout, "#pragma pack on\n");

	for(i=0; i<ntyp; i++) {
		Bprint(bout, "\n");
		t = typ[i];
		name = t->name;
		while(t && t->kind == Typedef) {
			if(name == nil && t->name != nil) {
				name = t->name;
				if(t->printed)
					break;
			}
			t = t->type;
		}
		if(name == nil && t->name != nil) {
			name = t->name;
			if(t->printed)
				continue;
			t->printed = 1;
		}
		if(name == nil) {
			fprint(2, "unknown name for %T", typ[i]);
			continue;
		}
		if(name[0] == '$')
			name++;
		npad = 0;
		off = 0;
		switch(t->kind) {
		case 0:
			fprint(2, "unknown type definition for %s\n", name);
			break;
		default:	// numeric, array, or pointer
		case Array:
		case Ptr:
			Bprint(bout, "%s %lT%s", lang->typdef, name, t, lang->typdefend);
			break;
		case Union:
			// In Go, print union as struct with only first element,
			// padded the rest of the way.
			Bprint(bout, lang->unionbegin, name, name, name);
			goto StructBody;
		case Struct:
			Bprint(bout, lang->structbegin, name, name, name);
		StructBody:
			prefix = 0;
			if(lang == &go)
				prefix = prefixlen(t);
			for(j=0; j<t->nf; j++) {
				f = &t->f[j];
				if(f->type->kind == 0)
					continue;
				// padding
				if(t->kind == Struct || lang == &go) {
					if(f->offset%8 != 0 || f->size%8 != 0) {
						fprint(2, "ignoring bitfield %s.%s\n", t->name, f->name);
						continue;
					}
					if(f->offset < off)
						sysfatal("%s: struct fields went backward", t->name);
					if(off < f->offset) {
						Bprint(bout, lang->structpadfmt, npad++, (f->offset - off) / 8);
						off = f->offset;
					}
					off += f->size;
				}
				name = f->name;
				if(cutprefix(name))
					name += prefix;
				if(strcmp(name, "") == 0) {
					snprint(nambuf, sizeof nambuf, "Pad_godefs_%d", npad++);
					name = nambuf;
				}
				Bprint(bout, "\t%#lT;\n", name, f->type);
				if(t->kind == Union && lang == &go)
					break;
			}
			// final padding
			if(t->kind == Struct || lang == &go) {
				if(off/8 < t->size)
					Bprint(bout, lang->structpadfmt, npad++, t->size - off/8);
			}
			Bprint(bout, lang->structend);
		}
	}
	if(lang == &c)
		Bprint(bout, "#pragma pack off\n");
	Bterm(bout);
	exit(0);
}
Beispiel #3
0
void
threadmain(int argc, char *argv[])
{
	int i, printstats;
	char *host;
	VacFile *f;

	fmtinstall('H', encodefmt);
	fmtinstall('V', vtscorefmt);
	fmtinstall('F', vtfcallfmt);
	fmtinstall('t', mtimefmt);
	fmtinstall('M', dirmodefmt);
	
	host = nil;
	printstats = 0;

	ARGBEGIN{
	case 'T':
		settimes = 1;
		break;
	case 'V':
		chattyventi = 1;
		break;
	case 'c':
		tostdout++;
		break;
	case 'd':
		diff++;
		break;
	case 'h':
		host = EARGF(usage());
		break;
	case 's':
		printstats++;
		break;
	case 't':
		table++;
		break;
	case 'v':
		chatty++;
		break;
	default:
		usage();
	}ARGEND

	if(argc < 1)
		usage();

	if(tostdout && diff){
		fprint(2, "cannot use -c with -d\n");
		usage();
	}

	conn = vtdial(host);
	if(conn == nil)
		sysfatal("could not connect to server: %r");

	if(vtconnect(conn) < 0)
		sysfatal("vtconnect: %r");

	fs = vacfsopen(conn, argv[0], VtOREAD, 128);
	if(fs == nil)
		sysfatal("vacfsopen: %r");

	nwant = argc-1;
	want = argv+1;
	found = vtmallocz(nwant*sizeof found[0]);

	if((f = vacfsgetroot(fs)) == nil)
		sysfatal("vacfsgetroot: %r");
	
	unvac(f, nil, nil);
	for(i=0; i<nwant; i++){
		if(want[i] && !found[i]){
			fprint(2, "warning: didn't find %s\n", want[i]);
			errors++;
		}
	}
	if(errors)
		threadexitsall("errors");
	if(printstats)
		fprint(2, "%lld bytes read, %lld bytes skipped\n",
			stats.data, stats.skipdata);
	threadexitsall(0);
}
Beispiel #4
0
void
threadmain(int argc, char *argv[])
{
	char *mtpt, *s;
	char *secstorepw;
	char err[ERRMAX];
	Dir d;

	rfork(RFNOTEG);

	mtpt = "/mnt";
	extrafactotumdir = 1;
	secstorepw = nil;
	quotefmtinstall();
	fmtinstall('A', attrfmt);
	fmtinstall('H', encodefmt);
	fmtinstall('N', attrnamefmt);

	if(argc == 3 && strcmp(argv[1], "-g") == 0){
		gflag(argv[2]);
		threadexitsall(nil);
	}

	ARGBEGIN{
	default:
		usage();
	case 'D':
		chatty9p++;
		break;
	case 'S':		/* server: read nvram, no prompting for keys */
		askforkeys = 0;
		trysecstore = 0;
		sflag = 1;
		break;
	case 'a':
		authaddr = EARGF(usage());
		break;
	case 'd':
		debug = 1;
		doprivate = 0;
		break;
	case 'g':
		usage();
	case 'k':		/* reinitialize nvram */
		kflag = 1;
		break;
	case 'm':
		mtpt = EARGF(usage());
		break;
	case 'n':
		trysecstore = 0;
		break;
	case 'p':
		doprivate = 0;
		break;
	case 's':
		service = EARGF(usage());
		break;
	case 'u':		/* user: set hostowner */
		uflag = 1;
		break;
	case 'x':
		extrafactotumdir = 0;
		break;
	}ARGEND

	if(argc != 0)
		usage();
	if(doprivate)
		private();

	initcap();

	if(sflag){
		s = getnvramkey(kflag ? NVwrite : NVwriteonerr, &secstorepw);
		if(s == nil)
			fprint(2, "factotum warning: cannot read nvram: %r\n");
		else if(ctlwrite(s) < 0)
			fprint(2, "factotum warning: cannot add nvram key: %r\n");
		if(secstorepw != nil)
			trysecstore = 1;
		if (s != nil) {
			memset(s, 0, strlen(s));
			free(s);
		}
	} else if(uflag)
		promptforhostowner();
	owner = getuser();

	if(trysecstore && havesecstore()){
		while(secstorefetch(secstorepw) < 0){
			rerrstr(err, sizeof err);
			if(strcmp(err, "cancel") == 0)
				break;
			fprint(2, "secstorefetch: %r\n");
			fprint(2, "Enter an empty password to quit.\n");
			free(secstorepw);
			secstorepw = nil; /* just try nvram pw once */
		}
	}
	
	fsinit0();
	threadpostmountsrv(&fs, service, mtpt, MBEFORE);
	if(service){
		nulldir(&d);
		d.mode = 0666;
		s = emalloc(10+strlen(service));
		strcpy(s, "/srv/");
		strcat(s, service);
		if(dirwstat(s, &d) < 0)
			fprint(2, "factotum warning: cannot chmod 666 %s: %r\n", s);
		free(s);
	}
	threadexits(nil);
}
Beispiel #5
0
void
handlefullmsg(Conn *c, Achan *a)
{
	int i;
	uint32_t chan, len, n, rt;
	uint8_t type;
	Msg *m, mm;
	Msg *r;
	Key *k;
	int nk;
	mpint *mod, *ek, *chal;
	uint8_t sessid[16];
	uint8_t chalbuf[32];
	uint8_t digest[16];
	DigestState *s;
	static int first;

	assert(a->len == a->ndata);

	chan = a->chan;
	mm.rp = a->data;
	mm.ep = a->data+a->ndata;
	mm.c = c;
	m = &mm;

	type = getbyte(m);

	if(first == 0){
		first++;
		fmtinstall('H', encodefmt);
	}

	switch(type){
	default:
		debug(DBG_AUTH, "unknown msg type\n");
	Failure:
		debug(DBG_AUTH, "agent sending failure\n");
		r = allocmsg(m->c, SSH_MSG_CHANNEL_DATA, 13);
		putlong(r, chan);
		putlong(r, 5);
		putlong(r, 1);
		putbyte(r, SSH_AGENT_FAILURE);
		sendmsg(r);
		return;

	case SSH_AGENTC_REQUEST_RSA_IDENTITIES:
		debug(DBG_AUTH, "agent request identities\n");
		nk = listkeys(&k);
		if(nk < 0)
			goto Failure;
		len = 1+4;	/* type, nk */
		for(i=0; i<nk; i++){
			len += 4;
			len += 2+(mpsignif(k[i].ek)+7)/8;
			len += 2+(mpsignif(k[i].mod)+7)/8;
			len += 4+strlen(k[i].comment);
		}
		r = allocmsg(m->c, SSH_MSG_CHANNEL_DATA, 12+len);
		putlong(r, chan);
		putlong(r, len+4);
		putlong(r, len);
		putbyte(r, SSH_AGENT_RSA_IDENTITIES_ANSWER);
		putlong(r, nk);
		for(i=0; i<nk; i++){
			debug(DBG_AUTH, "\t%B %B %s\n", k[i].ek, k[i].mod, k[i].comment);
			putlong(r, mpsignif(k[i].mod));
			putmpint(r, k[i].ek);
			putmpint(r, k[i].mod);
			putstring(r, k[i].comment);
			mpfree(k[i].ek);
			mpfree(k[i].mod);
			free(k[i].comment);
		}
		free(k);
		sendmsg(r);
		break;

	case SSH_AGENTC_RSA_CHALLENGE:
		n = getlong(m);
		USED(n);	/* number of bits in key; who cares? */
		ek = getmpint(m);
		mod = getmpint(m);
		chal = getmpint(m);
		memmove(sessid, getbytes(m, 16), 16);
		rt = getlong(m);
		debug(DBG_AUTH, "agent challenge %B %B %B %ud (%p %p)\n",
			ek, mod, chal, rt, m->rp, m->ep);
		if(rt != 1 || dorsa(mod, ek, chal, chalbuf) < 0){
			mpfree(ek);
			mpfree(mod);
			mpfree(chal);
			goto Failure;
		}
		s = md5(chalbuf, 32, nil, nil);
		md5(sessid, 16, digest, s);
		r = allocmsg(m->c, SSH_MSG_CHANNEL_DATA, 12+1+16);
		putlong(r, chan);
		putlong(r, 4+16+1);
		putlong(r, 16+1);
		putbyte(r, SSH_AGENT_RSA_RESPONSE);
		putbytes(r, digest, 16);
		debug(DBG_AUTH, "digest %.16H\n", digest);
		sendmsg(r);
		mpfree(ek);
		mpfree(mod);
		mpfree(chal);
		return;

	case SSH_AGENTC_ADD_RSA_IDENTITY:
		goto Failure;
/*
		n = getlong(m);
		pubmod = getmpint(m);
		pubexp = getmpint(m);
		privexp = getmpint(m);
		pinversemodq = getmpint(m);
		p = getmpint(m);
		q = getmpint(m);
		comment = getstring(m);
		add to factotum;
		send SSH_AGENT_SUCCESS or SSH_AGENT_FAILURE;
*/

	case SSH_AGENTC_REMOVE_RSA_IDENTITY:
		goto Failure;
/*
		n = getlong(m);
		pubmod = getmpint(m);
		pubexp = getmpint(m);
		tell factotum to del key
		send SSH_AGENT_SUCCESS or SSH_AGENT_FAILURE;
*/
	}
}
Beispiel #6
0
void
threadmain(int argc, char *argv[])
{
    int i;
    char *p, *loadfile;
    Column *c;
    int ncol;
    Display *d;

    rfork(RFENVG|RFNAMEG);

    ncol = -1;

    loadfile = nil;
    ARGBEGIN{
    case 'D':
        {   extern int _threaddebuglevel;
            _threaddebuglevel = ~0;
        }
        break;
    case 'a':
        globalautoindent = TRUE;
        break;
    case 'b':
        bartflag = TRUE;
        break;
    case 'c':
        p = ARGF();
        if(p == nil)
            goto Usage;
        ncol = atoi(p);
        if(ncol <= 0)
            goto Usage;
        break;
    case 'f':
        fontnames[0] = ARGF();
        if(fontnames[0] == nil)
            goto Usage;
        break;
    case 'F':
        fontnames[1] = ARGF();
        if(fontnames[1] == nil)
            goto Usage;
        break;
    case 'l':
        loadfile = ARGF();
        if(loadfile == nil)
            goto Usage;
        break;
    case 'm':
        mtpt = ARGF();
        if(mtpt == nil)
            goto Usage;
        break;
    case 'r':
        swapscrollbuttons = TRUE;
        break;
    case 'W':
        winsize = ARGF();
        if(winsize == nil)
            goto Usage;
        break;
    default:
Usage:
        fprint(2, "usage: acme -a -c ncol -f fontname -F fixedwidthfontname -l loadfile -W winsize\n");
        threadexitsall("usage");
    } ARGEND

    fontnames[0] = estrdup(fontnames[0]);
    fontnames[1] = estrdup(fontnames[1]);

    quotefmtinstall();
    fmtinstall('t', timefmt);

    cputype = getenv("cputype");
    objtype = getenv("objtype");
    home = getenv("HOME");
    acmeshell = getenv("acmeshell");
    if(acmeshell && *acmeshell == '\0')
        acmeshell = nil;
    p = getenv("tabstop");
    if(p != nil) {
        maxtab = strtoul(p, nil, 0);
        free(p);
    }
    if(maxtab == 0)
        maxtab = 4;
    if(loadfile)
        rowloadfonts(loadfile);
    putenv("font", fontnames[0]);
    snarffd = open("/dev/snarf", OREAD|OCEXEC);
    /*
    	if(cputype){
    		sprint(buf, "/acme/bin/%s", cputype);
    		bind(buf, "/bin", MBEFORE);
    	}
    	bind("/acme/bin", "/bin", MBEFORE);
    */
    getwd(wdir, sizeof wdir);

    /*
    	if(geninitdraw(nil, derror, fontnames[0], "acme", nil, Refnone) < 0){
    		fprint(2, "acme: can't open display: %r\n");
    		threadexitsall("geninitdraw");
    	}
    */
    if(initdraw(derror, fontnames[0], "acme") < 0) {
        fprint(2, "acme: can't open display: %r\n");
        threadexitsall("initdraw");
    }

    d = display;
    font = d->defaultfont;
    /*assert(font); */

    reffont.f = font;
    reffonts[0] = &reffont;
    incref(&reffont.ref);	/* one to hold up 'font' variable */
    incref(&reffont.ref);	/* one to hold up reffonts[0] */
    fontcache = emalloc(sizeof(Reffont*));
    nfontcache = 1;
    fontcache[0] = &reffont;

    iconinit();
    timerinit();
    rxinit();

    cwait = threadwaitchan();
    ccommand = chancreate(sizeof(Command**), 0);
    ckill = chancreate(sizeof(Rune*), 0);
    cxfidalloc = chancreate(sizeof(Xfid*), 0);
    cxfidfree = chancreate(sizeof(Xfid*), 0);
    cnewwindow = chancreate(sizeof(Channel*), 0);
    cerr = chancreate(sizeof(char*), 0);
    cedit = chancreate(sizeof(int), 0);
    cexit = chancreate(sizeof(int), 0);
    cwarn = chancreate(sizeof(void*), 1);
    if(cwait==nil || ccommand==nil || ckill==nil || cxfidalloc==nil || cxfidfree==nil || cerr==nil || cexit==nil || cwarn==nil) {
        fprint(2, "acme: can't create initial channels: %r\n");
        threadexitsall("channels");
    }
    chansetname(ccommand, "ccommand");
    chansetname(ckill, "ckill");
    chansetname(cxfidalloc, "cxfidalloc");
    chansetname(cxfidfree, "cxfidfree");
    chansetname(cnewwindow, "cnewwindow");
    chansetname(cerr, "cerr");
    chansetname(cedit, "cedit");
    chansetname(cexit, "cexit");
    chansetname(cwarn, "cwarn");

    mousectl = initmouse(nil, screen);
    if(mousectl == nil) {
        fprint(2, "acme: can't initialize mouse: %r\n");
        threadexitsall("mouse");
    }
    mouse = &mousectl->m;
    keyboardctl = initkeyboard(nil);
    if(keyboardctl == nil) {
        fprint(2, "acme: can't initialize keyboard: %r\n");
        threadexitsall("keyboard");
    }
    mainpid = getpid();
    startplumbing();
    /*
    	plumbeditfd = plumbopen("edit", OREAD|OCEXEC);
    	if(plumbeditfd < 0)
    		fprint(2, "acme: can't initialize plumber: %r\n");
    	else{
    		cplumb = chancreate(sizeof(Plumbmsg*), 0);
    		threadcreate(plumbproc, nil, STACK);
    	}
    	plumbsendfd = plumbopen("send", OWRITE|OCEXEC);
    */

    fsysinit();

#define	WPERCOL	8
    disk = diskinit();
    if(!loadfile || !rowload(&row, loadfile, TRUE)) {
        rowinit(&row, screen->clipr);
        if(ncol < 0) {
            if(argc == 0)
                ncol = 2;
            else {
                ncol = (argc+(WPERCOL-1))/WPERCOL;
                if(ncol < 2)
                    ncol = 2;
            }
        }
        if(ncol == 0)
            ncol = 2;
        for(i=0; i<ncol; i++) {
            c = rowadd(&row, nil, -1);
            if(c==nil && i==0)
                error("initializing columns");
        }
        c = row.col[row.ncol-1];
        if(argc == 0)
            readfile(c, wdir);
        else
            for(i=0; i<argc; i++) {
                p = utfrrune(argv[i], '/');
                if((p!=nil && strcmp(p, "/guide")==0) || i/WPERCOL>=row.ncol)
                    readfile(c, argv[i]);
                else
                    readfile(row.col[i/WPERCOL], argv[i]);
            }
    }
    flushimage(display, 1);

    acmeerrorinit();
    threadcreate(keyboardthread, nil, STACK);
    threadcreate(mousethread, nil, STACK);
    threadcreate(waitthread, nil, STACK);
    threadcreate(xfidallocthread, nil, STACK);
    threadcreate(newwindowthread, nil, STACK);
    /*	threadcreate(shutdownthread, nil, STACK); */
    threadnotify(shutdown, 1);
    recvul(cexit);
    killprocs();
    threadexitsall(nil);
}
Beispiel #7
0
void
threadmain(int argc, char **argv)
{
	char *addr;
	SunSrv *srv;
	Channel *nfs3chan;
	Channel *mountchan;
	Nfs3Handle h;

	fmtinstall('B', sunrpcfmt);
	fmtinstall('C', suncallfmt);
	fmtinstall('H', encodefmt);
	fmtinstall('I', eipfmt);
	sunfmtinstall(&nfs3prog);
	sunfmtinstall(&nfsmount3prog);

	srv = sunsrv();
	addr = "*";

	ARGBEGIN{
	default:
		usage();
	case 'L':
		if(srv->localonly == 0)
			srv->localonly = 1;
		else
			srv->localparanoia = 1;
		break;
	case 'R':
		srv->chatty++;
		break;
	case 'T':
		_threaddebuglevel = 0xFFFFFFFF;
		break;
	case 'r':
		srv->alwaysreject++;
		break;
	}ARGEND

	if(argc != 1 && argc != 2)
		usage();

	if((disk = diskopenfile(argv[0])) == nil)
		sysfatal("diskopen: %r");
	if((disk = diskcache(disk, 16384, 256)) == nil)
		sysfatal("diskcache: %r");

	if((fsys = fsysopen(disk)) == nil)
		sysfatal("fsysopen: %r");

	nfs3chan = chancreate(sizeof(SunMsg*), 0);
	mountchan = chancreate(sizeof(SunMsg*), 0);

	if(argc > 1)
		addr = argv[1];
	addr = netmkaddr(addr, "udp", "2049");

	if(sunsrvudp(srv, addr) < 0)
		sysfatal("starting server: %r");

	sunsrvthreadcreate(srv, nfs3proc, nfs3chan);
	sunsrvthreadcreate(srv, mount3proc, mountchan);

	sunsrvprog(srv, &nfs3prog, nfs3chan);
	sunsrvprog(srv, &nfsmount3prog, mountchan);
	fsgetroot(&h);

	print("vmount0 -h %.*H %s /mnt\n", h.len, h.h, addr);

	threadexits(nil);
}
Beispiel #8
0
void
main(int argc, char **argv)
{
	char *mtpt, *srvname;

	mtpt = nil;
	srvname = "font";

	ARGBEGIN{
	case 'D':
		chatty9p++;
		break;
	case 'F':
		chattyfuse++;
		break;
	case 'm':
		mtpt = EARGF(usage());
		break;
	case 's':
		srvname = EARGF(usage());
		break;
	case 'p':
		pflag++;
		break;
	default:
		usage();
	}ARGEND
	
	xsrv.attach = xattach;
	xsrv.open = xopen;
	xsrv.read = xread;
	xsrv.stat = xstat;
	xsrv.walk1 = xwalk1;
	xsrv.destroyfid = xdestroyfid;

	fmtinstall('R', Rfmt);
	fmtinstall('P', Pfmt);
	memimageinit();
	defont = getmemdefont();
	loadfonts();
	qsort(xfont, nxfont, sizeof xfont[0], fontcmp);
	
	if(pflag) {
		if(argc != 1 || chatty9p || chattyfuse)
			usage();
		dump(argv[0]);
		exits(0);
	}

	if(pflag || argc != 0)
		usage();

	/*
	 * Check twice -- if there is an exited instance
	 * mounted there, the first access will fail but unmount it.
	 */
	if(mtpt && access(mtpt, AEXIST) < 0 && access(mtpt, AEXIST) < 0)
		sysfatal("mountpoint %s does not exist", mtpt);

	xsrv.foreground = 1;
	threadpostmountsrv(&xsrv, srvname, mtpt, 0);
}
Beispiel #9
0
void
main(int argc, char **argv)
{
	int i, trysecstore;
	char err[ERRMAX], *s;
	Dir d;
	Proto *p;
	char *secstorepw;

	trysecstore = 1;
	secstorepw = nil;

	ARGBEGIN{
	case 'D':
		chatty9p++;
		break;
	case 'S':		/* server: read nvram, no prompting for keys */
		askforkeys = 0;
		trysecstore = 0;
		sflag = 1;
		break;
	case 'a':
		authaddr = EARGF(usage());
		break;
	case 'd':
		debug = 1;
		doprivate = 0;
		break;
	case 'g':		/* get: prompt for key for name and domain */
		gflag = 1;
		break;
	case 'k':		/* reinitialize nvram */
		kflag = 1;
		break;
	case 'm':		/* set default mount point */
		mtpt = EARGF(usage());
		break;
	case 'n':
		trysecstore = 0;
		break;
	case 'p':
		doprivate = 0;
		break;
	case 's':		/* set service name */
		service = EARGF(usage());
		break;
	case 'u':		/* user: set hostowner */
		uflag = 1;
		break;
	default:
		usage();
	}ARGEND

	if(argc != 0 && !gflag)
		usage();
	if(doprivate)
		private();

	initcap();

	quotefmtinstall();
	fmtinstall('A', _attrfmt);
	fmtinstall('N', attrnamefmt);
	fmtinstall('H', encodefmt);

	ring = emalloc(sizeof(*ring));
	notify(notifyf);

	if(gflag){
		if(argc != 1)
			usage();
		askuser(argv[0]);
		exits(nil);
	}

	for(i=0; prototab[i]; i++){
		p = prototab[i];
		if(p->name == nil)
			sysfatal("protocol %d has no name", i);
		if(p->init == nil)
			sysfatal("protocol %s has no init", p->name);
		if(p->write == nil)
			sysfatal("protocol %s has no write", p->name);
		if(p->read == nil)
			sysfatal("protocol %s has no read", p->name);
		if(p->close == nil)
			sysfatal("protocol %s has no close", p->name);
		if(p->keyprompt == nil)
			p->keyprompt = "";
	}

	if(sflag){
		s = getnvramkey(kflag ? NVwrite : NVwriteonerr, &secstorepw);
		if(s == nil)
			fprint(2, "factotum warning: cannot read nvram: %r\n");
		else if(ctlwrite(s, 0) < 0)
			fprint(2, "factotum warning: cannot add nvram key: %r\n");
		if(secstorepw != nil)
			trysecstore = 1;
		if (s != nil) {
			memset(s, 0, strlen(s));
			free(s);
		}
	} else if(uflag)
		promptforhostowner();
	owner = getuser();

	if(trysecstore){
		if(havesecstore() == 1){
			while(secstorefetch(secstorepw) < 0){
				rerrstr(err, sizeof err);
				if(strcmp(err, "cancel") == 0)
					break;
				fprint(2, "factotum: secstorefetch: %r\n");
				fprint(2, "Enter an empty password to quit.\n");
				free(secstorepw);
				secstorepw = nil; /* just try nvram pw once */
			}
		}else{
/*
			rerrstr(err, sizeof err);
			if(*err)
				fprint(2, "factotum: havesecstore: %r\n");
*/
		}
	}

	postmountsrv(&fs, service, mtpt, MBEFORE);
	if(service){
		nulldir(&d);
		d.mode = 0666;
		s = emalloc(10+strlen(service));
		strcpy(s, "/srv/");
		strcat(s, service);
		if(dirwstat(s, &d) < 0)
			fprint(2, "factotum warning: cannot chmod 666 %s: %r\n", s);
		free(s);
	}
	exits(nil);
}
Beispiel #10
0
void
main(void)
{
	Proc *savup;
	static ulong vfy = Datamagic;
	static char novga[] = "\nno vga; serial console only\n";

	savup = up;
	up = nil;
	/* m has been set by l32v.s */

	/*
	 * disable address wraps at 1MB boundaries.
	 * if we're 9boot, ldecomp.s already did this.
	 */
	a20init();

	mach0init();
//	options();		/* we don't get options passed to us */
	ioinit();
	/* we later call i8250console after plan9.ini has been read */
	i8250config("0");	/* configure serial port 0 with defaults */
	quotefmtinstall();
 	fmtinstall('i', eipfmt);
 	fmtinstall('I', eipfmt);
 	fmtinstall('E', eipfmt);
 	fmtinstall('V', eipfmt);
 	fmtinstall('M', eipfmt);
	screeninit();			/* cga setup */
	cgapost(0xc);

	trapinit0();
	mmuinit0();

	kbdinit();
	i8253init();
	cpuidentify();
	readlsconf();
	meminit();
	confinit();
	archinit();
	xinit();
	if(i8237alloc != nil)
		i8237alloc();		/* dma (for floppy) init */
	trapinit();
	printinit();
	sanity();
	cgapost(1);

	/*
	 * soekris servers have no built-in video but each has a serial port.
	 * they must see serial output, if any, before cga output because
	 * otherwise the soekris bios will translate cga output to serial
	 * output, which will garble serial console output.
	 */
	pcimatch(nil, 0, 0);		/* force scan of pci table */
	if (!pcivga) {
		screenputs = nil;
		uartputs(novga, sizeof novga - 1);
	}
	print(" %s\n\n", hellomsg);

	if (vfy != Datamagic)
		panic("data segment incorrectly aligned or loaded");
	if (savup)
		print("up was non-nil (%#p) upon entry to main; bss wasn't zeroed!\n",
			savup);

//	xsummary();
	cpuidprint();
	mmuinit();
	if(arch->intrinit)	/* launches other processors on an mp */
		arch->intrinit();
	timersinit();
	mathinit();
	kbdenable();
	/*
	 * 9loadusb runs much faster if we don't use the clock.
	 * perhaps we're competing with the bios for the use of it?
	 */
	if(!noclock && arch->clockenable)
		arch->clockenable();
	procinit0();
	initseg();
	if(delaylink){
		bootlinks();
		pcimatch(0, 0, 0);
	}else
		links();
	conf.monitor = 1;
	cgapost(0xcd);
	chandevreset();
	cgapost(2);
	pageinit();	/* must follow xinit, and conf.mem must be populated */
	i8253link();
	userinit();

	active.thunderbirdsarego = 1;
	cgapost(0xb0);
	schedinit();
}
Beispiel #11
0
Display*
initdisplay(char *dev, char *win, void(*error)(Display*, char*))
{
	char buf[128], info[NINFO+1], *t, isnew;
	int n, datafd, ctlfd, reffd;
	Display *disp;
	Dir *dir;
	Image *image;

	fmtinstall('P', Pfmt);
	fmtinstall('R', Rfmt);
	if(dev == 0)
		dev = "/dev";
	if(win == 0)
		win = "/dev";
	if(strlen(dev)>sizeof buf-25 || strlen(win)>sizeof buf-25){
		werrstr("initdisplay: directory name too long");
		return nil;
	}
	t = strdup(win);
	if(t == nil)
		return nil;

	sprint(buf, "%s/draw/new", dev);
	ctlfd = open(buf, ORDWR|OCEXEC);
	if(ctlfd < 0){
		if(bind("#i", dev, MAFTER) < 0){
    Error1:
			free(t);
			werrstr("initdisplay: %s: %r", buf);
			return 0;
		}
		ctlfd = open(buf, ORDWR|OCEXEC);
	}
	if(ctlfd < 0)
		goto Error1;
	if((n=read(ctlfd, info, sizeof info)) < 12){
    Error2:
		close(ctlfd);
		goto Error1;
	}
	if(n==NINFO+1)
		n = NINFO;
	info[n] = '\0';
	isnew = 0;
	if(n < NINFO)	/* this will do for now, we need something better here */
		isnew = 1;
	sprint(buf, "%s/draw/%d/data", dev, atoi(info+0*12));
	datafd = open(buf, ORDWR|OCEXEC);
	if(datafd < 0)
		goto Error2;
	sprint(buf, "%s/draw/%d/refresh", dev, atoi(info+0*12));
	reffd = open(buf, OREAD|OCEXEC);
	if(reffd < 0){
    Error3:
		close(datafd);
		goto Error2;
	}
	disp = mallocz(sizeof(Display), 1);
	if(disp == 0){
    Error4:
		close(reffd);
		goto Error3;
	}
	image = nil;
	if(0){
    Error5:
		free(image);
		free(disp);
		goto Error4;
	}
	if(n >= NINFO){
		image = mallocz(sizeof(Image), 1);
		if(image == nil)
			goto Error5;
		image->display = disp;
		image->id = 0;
		image->chan = strtochan(info+2*12);
		image->depth = chantodepth(image->chan);
		image->repl = atoi(info+3*12);
		image->r.min.x = atoi(info+4*12);
		image->r.min.y = atoi(info+5*12);
		image->r.max.x = atoi(info+6*12);
		image->r.max.y = atoi(info+7*12);
		image->clipr.min.x = atoi(info+8*12);
		image->clipr.min.y = atoi(info+9*12);
		image->clipr.max.x = atoi(info+10*12);
		image->clipr.max.y = atoi(info+11*12);
	}

	disp->_isnewdisplay = isnew;
	disp->bufsize = iounit(datafd);
	if(disp->bufsize <= 0)
		disp->bufsize = 8000;
	if(disp->bufsize < 512){
		werrstr("iounit %d too small", disp->bufsize);
		goto Error5;
	}
	disp->buf = malloc(disp->bufsize+5);	/* +5 for flush message */
	if(disp->buf == nil)
		goto Error5;

	disp->image = image;
	disp->dirno = atoi(info+0*12);
	disp->fd = datafd;
	disp->ctlfd = ctlfd;
	disp->reffd = reffd;
	disp->bufp = disp->buf;
	disp->error = error;
	disp->windir = t;
	disp->devdir = strdup(dev);
	qlock(&disp->qlock);
	disp->white = allocimage(disp, Rect(0, 0, 1, 1), GREY1, 1, DWhite);
	disp->black = allocimage(disp, Rect(0, 0, 1, 1), GREY1, 1, DBlack);
	if(disp->white == nil || disp->black == nil){
		free(disp->devdir);
		free(disp->white);
		free(disp->black);
		goto Error5;
	}
	disp->opaque = disp->white;
	disp->transparent = disp->black;
	dir = dirfstat(ctlfd);
	if(dir!=nil && dir->type=='i'){
		disp->local = 1;
		disp->dataqid = dir->qid.path;
	}
	if(dir!=nil && dir->qid.vers==1)	/* other way to tell */
		disp->_isnewdisplay = 1;
	free(dir);

	return disp;
}
Beispiel #12
0
void
main(int argc, char *argv[])
{
	Dir *db;
	Lsym *l;
	Node *n;
	char buf[128], *s;
	int pid, i;
	char *p;
	char afile[512];

	argv0 = argv[0];
	pid = 0;
	aout = "v.out";
	quiet = 1;
	/* turn off all debugging */
	protodebug = 0;

	mtype = 0;
	ARGBEGIN{
	case 'm':
		mtype = ARGF();
		break;
	case 'w':
		wtflag = 1;
		break;
	case 'l':
		s = ARGF();
		if(s == 0)
			usage();
		lm[nlm++] = s;
		break;
	case 'd':
		p = ARGF();
		if (p == 0)
			usage();
		while (*p) {
			setdbg_opt(*p, 0); /* don't print set message */
			p++;
		}
		break;
	case 'k':
		kernel++;
		break;
	case 'q':
		quiet = 0;
		break;
	case 'r':
		pid = 1;
		remote++;
		kernel++;
		break;
	case 'R':
		pid = 1;
		rdebug++;
		s = ARGF();
		if(s == 0)
			usage();
		remfd = opentty(s, 0);
		if(remfd < 0){
			fprint(2, "acid: can't open %s: %r\n", s);
			exits("open");
		}
		break;
	default:
		usage();
	}ARGEND

	if(argc > 0) {
		if(remote || rdebug)
			aout = argv[0];
		else
		if(isnumeric(argv[0])) {
			pid = atoi(argv[0]);
			sprint(prog, "/proc/%d/text", pid);
			aout = prog;
			if(argc > 1)
				aout = argv[1];
			else if(kernel)
				aout = mysystem();
		}
		else {
			if(kernel) {
				print("-k requires a pid");
				kernel = 0;
			}
			aout = argv[0];
		}
	} else if(rdebug)
		aout = "/386/bpc";
	else if(remote)
		aout = "/mips/bcarrera";

	fmtinstall('x', xfmt);
	fmtinstall('L', Lfmt);
	fmtinstall('f', gfltconv);
	fmtinstall('F', gfltconv);
	fmtinstall('g', gfltconv);
	fmtinstall('G', gfltconv);
	fmtinstall('e', gfltconv);
	fmtinstall('E', gfltconv);
	Binit(&bioout, 1, OWRITE);
	bout = &bioout;

	kinit();
	initialising = 1;
	pushfile(0);
	loadvars();
	installbuiltin();

	if(mtype && machbyname(mtype) == 0)
		print("unknown machine %s", mtype);

	if (attachfiles(aout, pid) < 0)
		varreg();		/* use default register set on error */

	acidlib = getenv("ACIDLIB");
	if(acidlib == nil){
		p = getenv("ROOT");
		if(p == nil)
			p = "/usr/inferno";
		snprint(afile, sizeof(afile)-1, "%s/lib/acid", p);
		acidlib = strdup(afile);
	}

	snprint(afile, sizeof(afile)-1, "%s/port", acidlib);
	loadmodule(afile);
	for(i = 0; i < nlm; i++) {
		if((db = dirstat(lm[i])) != nil) {
			free(db);
			loadmodule(lm[i]);
		} else {
			sprint(buf, "%s/%s", acidlib, lm[i]);
			loadmodule(buf);
		}
	}

	userinit();
	varsym();

	l = look("acidmap");
	if(l && l->proc) {
		n = an(ONAME, ZN, ZN);
		n->sym = l;
		n = an(OCALL, n, ZN);
		execute(n);
	}

	interactive = 1;
	initialising = 0;
	line = 1;

	setup_os_notify();

	for(;;) {
		if(setjmp(err)) {
			Binit(&bioout, 1, OWRITE);
			unwind();
		}
		stacked = 0;

		Bprint(bout, "acid: ");

		if(yyparse() != 1)
			die();
		restartio();

		unwind();
	}
	/* not reached */
}
Beispiel #13
0
/*
 *  fill in all the requested attributes for a system.
 *  if the system's entry doesn't have all required,
 *  walk through successively more inclusive networks
 *  for inherited attributes.
 */
Ndbtuple*
ndbipinfo(Ndb *db, char *attr, char *val, char **alist, int n)
{
	Ndbtuple *t, *nt, *f;
	Ndbs s;
	char *ipstr;
	uint8_t net[IPaddrlen], ip[IPaddrlen];
	int prefix, smallestprefix, force;
	int64_t r;

	/* just in case */
	fmtinstall('I', eipfmt);
	fmtinstall('M', eipfmt);

	/* get needed attributes */
	f = mkfilter(n, alist);

	/*
	 *  first look for a matching entry with an ip address
	 */
	t = nil;
	ipstr = ndbgetvalue(db, &s, attr, val, "ip", &nt);
	if(ipstr == nil){
		/* none found, make one up */
		if(strcmp(attr, "ip") != 0) {
			ndbfree(f);
			return nil;	
		}
		t = ndbnew("ip", val);
		t->line = t;
		t->entry = nil;
		r = parseip(net, val);
		if(r == -1)
			ndbfree(t);
	} else {
		/* found one */
		while(nt != nil){
			nt = ndbreorder(nt, s.t);
			t = ndbconcatenate(t, nt);
			nt = ndbsnext(&s, attr, val);
		}
		r = parseip(net, ipstr);
		free(ipstr);
	}
	if(r < 0){
		ndbfree(f);
		return nil;
	}
	ipmove(ip, net);
	t = filter(db, t, f);

	/*
	 *  now go through subnets to fill in any missing attributes
	 */
	if(isv4(net)){
		prefix = 127;
		smallestprefix = 100;
		force = 0;
	} else {
		/* in v6, the last 8 bytes have no structure (we hope) */
		prefix = 64;
		smallestprefix = 2;
		memset(net+8, 0, 8);
		force = 1;
	}

	/*
	 *  to find a containing network, keep turning off
	 *  the lower bit and look for a network with
	 *  that address and a shorter mask.  tedius but
	 *  complete, we may need to find a trick to speed this up.
	 */
	for(; prefix >= smallestprefix; prefix--){
		if(filtercomplete(f))
			break;
		if(!force && (net[prefix/8] & (1<<(7-(prefix%8)))) == 0)
			continue;
		force = 0;
		net[prefix/8] &= ~(1<<(7-(prefix%8)));
		t = ndbconcatenate(t, subnet(db, net, f, prefix));
	}

	/*
	 *  if there's an unfulfilled ipmask, make one up
	 */
	nt = ndbfindattr(f, f, "ipmask");
	if(nt && !(nt->ptr & Fignore)){
		char x[64];

		snprint(x, sizeof(x), "%M", defmask(ip));
		t = ndbconcatenate(t, ndbnew("ipmask", x));
	}

	ndbfree(f);
	ndbsetmalloctag(t, getcallerpc());
	return t;
}
Beispiel #14
0
void
main(int argc, char *argv[])
{
	char *p;
	int c;

	thechar = '8';
	thestring = "386";

	ctxt = linknew(&link386);
	ctxt->diag = yyerror;
	ctxt->bso = &bstdout;
	Binit(&bstdout, 1, OWRITE);
	listinit8();
	fmtinstall('L', Lconv);

	// Allow GOARCH=thestring or GOARCH=thestringsuffix,
	// but not other values.	
	p = getgoarch();
	if(strncmp(p, thestring, strlen(thestring)) != 0)
		sysfatal("cannot use %cc with GOARCH=%s", thechar, p);

	ensuresymb(NSYMB);
	memset(debug, 0, sizeof(debug));
	cinit();
	outfile = 0;
	setinclude(".");
	ARGBEGIN {
	default:
		c = ARGC();
		if(c >= 0 && c < sizeof(debug))
			debug[c] = 1;
		break;

	case 'o':
		outfile = ARGF();
		break;

	case 'D':
		p = ARGF();
		if(p) {
			if (nDlist%8 == 0)
				Dlist = allocn(Dlist, nDlist*sizeof(char *), 
					8*sizeof(char *));
			Dlist[nDlist++] = p;
		}
		break;

	case 'I':
		p = ARGF();
		setinclude(p);
		break;

	case 'S':
		ctxt->debugasm++;
		break;
	} ARGEND
	if(*argv == 0) {
		print("usage: %ca [-options] file.s\n", thechar);
		errorexit();
	}
	if(argc > 1){
		print("can't assemble multiple files\n");
		errorexit();
	}
	if(assemble(argv[0]))
		errorexit();
	Bflush(&bstdout);
	exits(0);
}
Beispiel #15
0
void
threadmain(int argc, char *argv[])
{
	int i;
	char *file;
	Arena *arena;
	u64int offset, aoffset;
	Part *part;
	uchar buf[8192];
	ArenaHead head;
	ZClump zerocl;

	ventifmtinstall();
	qlock(&godot);
	aoffset = 0;
	ARGBEGIN{
	case 'f':
		fast = 1;
		ventidoublechecksha1 = 0;
		break;
	case 'h':
		host = EARGF(usage());
		break;
	case 'o':
		haveaoffset = 1;
		aoffset = strtoull(EARGF(usage()), 0, 0);
		break;
	case 'M':
		maxwrites = atoi(EARGF(usage()));
		break;
	case 'v':
		verbose = 1;
		break;
	default:
		usage();
		break;
	}ARGEND

	offset = ~(u64int)0;
	switch(argc) {
	default:
		usage();
	case 2:
		offset = strtoull(argv[1], 0, 0);
		/* fall through */
	case 1:
		file = argv[0];
	}

	fmtinstall('V', vtscorefmt);

	statsinit();

	part = initpart(file, OREAD);
	if(part == nil)
		sysfatal("can't open file %s: %r", file);
	if(readpart(part, aoffset, buf, sizeof buf) < 0)
		sysfatal("can't read file %s: %r", file);

	if(unpackarenahead(&head, buf) < 0)
		sysfatal("corrupted arena header: %r");

	if(aoffset+head.size > part->size)
		sysfatal("arena is truncated: want %llud bytes have %llud",
			head.size, part->size);

	partblocksize(part, head.blocksize);
	initdcache(8 * MaxDiskBlock);

	arena = initarena(part, aoffset, head.size, head.blocksize);
	if(arena == nil)
		sysfatal("initarena: %r");

	z = nil;
	if(host==nil || strcmp(host, "/dev/null") != 0){
		z = vtdial(host);
		if(z == nil)
			sysfatal("could not connect to server: %r");
		if(vtconnect(z) < 0)
			sysfatal("vtconnect: %r");
	}
	
	c = chancreate(sizeof(ZClump), 0);
	for(i=0; i<12; i++)
		vtproc(vtsendthread, nil);

	rdarena(arena, offset);
	if(vtsync(z) < 0)
		sysfatal("executing sync: %r");

	memset(&zerocl, 0, sizeof zerocl);
	for(i=0; i<12; i++)
		send(c, &zerocl);
	if(z){
		vthangup(z);
	}
	threadexitsall(0);
}
Beispiel #16
0
void
main(int argc, char** argv)
{
	char *bios, buf[256], sizeb[256], *p, *vsize, *psize;
	char *type, *vtype;
	int virtual, len;
	Ctlr *ctlr;
	Vga *vga;

	fmtinstall('H', encodefmt);
	Binit(&stdout, 1, OWRITE);

	bios = getenv("vgactlr");
	if((type = getenv("monitor")) == 0)
		type = "vga";
	psize = vsize = "640x480x8";

	ARGBEGIN{
	default:
		usage();
		break;
	case 'b':
		bios = EARGF(usage());
		break;
	case 'B':
		dumpbios(0x10000);
		exits(0);
	case 'c':
		cflag = 1;
		break;
	case 'd':
		dflag = 1;
		break;
	case 'i':
		iflag = 1;
		break;
	case 'l':
		lflag = 1;
		break;
	case 'm':
		type = EARGF(usage());
		break;
	case 'p':
		pflag = 1;
		break;
	case 'r':
		/*
		 * rflag > 1 means "leave me alone, I know what I'm doing."
		 */
		rflag++;
		break;
	case 'v':
		vflag = 1;
		break;
	case 'V':
		vflag = 1;
		Vflag = 1;
		break;
	case 'x':
		dbname = EARGF(usage());
		break;
	}ARGEND

	virtual = 0;
	switch(argc){
	default:
		usage();
		break;
	case 1:
		vsize = psize = argv[0];
		break;
	case 2:
		psize = argv[0];
		vsize = argv[1];
		virtual = 1;
		break;
	case 0:
		break;
	}

	if(lflag && strcmp(vsize, "text") == 0){
		vesatextmode();
		vgactlw("textmode", "");
		exits(0);
	}

	vga = alloc(sizeof(Vga));
	if(bios){
		if((vga->offset = strtol(bios, &p, 0)) == 0 || *p++ != '=')
			error("main: bad BIOS string format - %s\n", bios);
		len = strlen(p);
		vga->bios = alloc(len+1);
		strncpy(vga->bios, p, len);
		trace("main->BIOS %s\n", bios);
	}

	/*
	 * Try to identify the VGA card and grab
	 * registers.  Print them out if requested.
	 * If monitor=vesa or our vga controller can't be found
	 * in vgadb, try vesa modes; failing that, try vga.
	 */
	if(strcmp(type, "vesa") == 0 || dbctlr(dbname, vga) == 0 ||
	    vga->ctlr == 0)
		if(dbvesa(vga) == 0 || vga->ctlr == 0){
			Bprint(&stdout, "%s: controller not in %s, not vesa\n",
				argv0, dbname);
			dumpbios(256);
			type = "vga";
			vsize = psize = "640x480x1";
			virtual = 0;
			vga->ctlr = &generic;
			vga->link = &generic;
		}
Beispiel #17
0
NbSession *
nbssconnect(NbName to, NbName from)
{
	Session *s;
	uchar ipaddr[IPaddrlen];
	char dialaddress[100];
	char dir[NETPATHLEN];
	uchar msg[576];
	int fd;
	long o;
	uchar flags;
	long length;

	if (!nbnameresolve(to, ipaddr))
		return nil;
	fmtinstall('I', eipfmt);
	snprint(dialaddress, sizeof(dialaddress), "tcp!%I!netbios", ipaddr);
	fd = dial(dialaddress, nil, dir, nil);
	if (fd < 0)
		return nil;
	msg[0] = 0x81;
	msg[1] = 0;
	o = 4;
	o += nbnameencode(msg + o, msg + sizeof(msg) - o, to);
	o += nbnameencode(msg + o, msg + sizeof(msg) - o, from);
	hnputs(msg + 2, o - 4);
	if (write(fd, msg, o) != o) {
		close(fd);
		return nil;
	}
	if (readn(fd, msg, 4) != 4) {
		close(fd);
		return nil;
	}
	flags = msg[1];
	length = nhgets(msg + 2) | ((flags & 1) << 16);
	switch (msg[0]) {
	default:
		close(fd);
		werrstr("unexpected session message code 0x%.2ux", msg[0]);
		return nil;
	case 0x82:
		if (length != 0) {
			close(fd);
			werrstr("length not 0 in positive session response");
			return nil;
		}
		break;
	case 0x83:
		if (length != 1) {
			close(fd);
			werrstr("length not 1 in negative session response");
			return nil;
		}
		if (readn(fd, msg + 4, 1) != 1) {
			close(fd);
			return nil;
		}
		close(fd);
		werrstr("negative session response 0x%.2ux", msg[4]);
		return nil;
	}
	s = nbemalloc(sizeof(Session));
	s->fd = fd;
	s->state = Connected;
	qlock(&sessions);
	s->next = sessions.head;
	sessions.head = s;
	qunlock(&sessions);
	return s;
}
Beispiel #18
0
void
notefs(int fd)
{
	uchar buf[IOHDRSZ+Maxfdata];
	int i, n, ncpunote;
	Fcall f;
	Qid wqid[MAXWELEM];
	Fid *fid, *nfid;
	int doreply;

	rfork(RFNOTEG);
	fmtinstall('F', fcallfmt);

	for(n = 0; n < Nfid; n++){
		fids[n].file = -1;
		fids[n].omode = -1;
	}

	ncpunote = 0;
	for(;;){
		n = read9pmsg(fd, buf, sizeof(buf));
		if(n <= 0){
			if(dbg)
				fprint(2, "read9pmsg(%d) returns %d: %r\n", fd, n);
			break;
		}
		if(convM2S(buf, n, &f) <= BIT16SZ)
			break;
		if(dbg)
			fprint(2, "notefs: ->%F\n", &f);
		doreply = 1;
		fid = getfid(f.fid);
		if(fid == nil){
nofids:
			f.type = Rerror;
			f.ename = Enofile;
			fsreply(fd, &f);
			continue;
		}
		switch(f.type++){
		default:
			f.type = Rerror;
			f.ename = "unknown type";
			break;
		case Tflush:
			flushreq(f.oldtag);
			break;
		case Tversion:
			if(f.msize > IOHDRSZ+Maxfdata)
				f.msize = IOHDRSZ+Maxfdata;
			break;
		case Tauth:
			f.type = Rerror;
			f.ename = "authentication not required";
			break;
		case Tattach:
			f.qid = fstab[Qdir].qid;
			fid->file = Qdir;
			break;
		case Twalk:
			nfid = nil;
			if(f.newfid != f.fid){
				nfid = getfid(f.newfid);
				if(nfid == nil)
					goto nofids;
				nfid->file = fid->file;
				fid = nfid;
			}
			for(i=0; i<f.nwname && i<MAXWELEM; i++){
				if(fid->file != Qdir){
					f.type = Rerror;
					f.ename = Enotdir;
					break;
				}
				if(strcmp(f.wname[i], "..") == 0){
					wqid[i] = fstab[Qdir].qid;
					continue;
				}
				if(strcmp(f.wname[i], "cpunote") != 0){
					if(i == 0){
						f.type = Rerror;
						f.ename = "file does not exist";
					}
					break;
				}
				fid->file = Qcpunote;
				wqid[i] = fstab[Qcpunote].qid;
			}
			if(nfid != nil && (f.type == Rerror || i < f.nwname))
				nfid ->file = -1;
			if(f.type != Rerror){
				f.nwqid = i;
				for(i=0; i<f.nwqid; i++)
					f.wqid[i] = wqid[i];
			}
			break;
		case Topen:
			if(f.mode != OREAD){
				f.type = Rerror;
				f.ename = Eperm;
				break;
			}
			fid->omode = f.mode;
			if(fid->file == Qcpunote)
				ncpunote++;
			f.qid = fstab[fid->file].qid;
			f.iounit = 0;
			break;
		case Tread:
			if(fsread(fd, fid, &f) < 0)
				goto err;
			doreply = 0;
			break;
		case Tclunk:
			if(fid->omode != -1 && fid->file == Qcpunote){
				ncpunote--;
				if(ncpunote == 0)	/* remote side is done */
					goto err;
			}
			fid->file = -1;
			fid->omode = -1;
			break;
		case Tstat:
			if(fsstat(fd, fid, &f) < 0)
				goto err;
			doreply = 0;
			break;
		case Tcreate:
		case Twrite:
		case Tremove:
		case Twstat:
			f.type = Rerror;
			f.ename = Eperm;
			break;
		}
		if(doreply)
			if(fsreply(fd, &f) < 0)
				break;
	}
err:
	if(dbg)
		fprint(2, "notefs exiting: %r\n");
	werrstr("success");
	postnote(PNGROUP, exportpid, "kill");
	if(dbg)
		fprint(2, "postnote PNGROUP %d: %r\n", exportpid);
	close(fd);
}
Beispiel #19
0
void
main(int argc, char *argv[])
{
	int dobroadcast, i, n;
	long diff;
	char *p;
	char buf[2*1024];
	uint8_t raddr[Pasize];
	Bnet *bn, **l;
	Udphdr *up;
	Rip *r;
	Ripmsg *m;
	Route route;
	static long btime;

	setnetmtpt(netdir, sizeof(netdir), nil);
	dobroadcast = 0;
	ARGBEGIN{
	case 'b':
		dobroadcast++;
		break;
	case 'd':
		debug++;
		break;
	case 'n':
		readonly++;
		break;
	case 'x':
		p = ARGF();
		if(p == nil)
			usage();
		setnetmtpt(netdir, sizeof(netdir), p);
		break;
	default:
		usage();
	}ARGEND

	/* specific broadcast nets */
	l = &bnets;
	while(argc > 0){
		bn = (Bnet*)malloc(sizeof(Bnet));
		if(bn == 0)
			fatal(1, "out of mem");
		v4parseip(bn->addr, *argv);
		*l = bn;
		l = &bn->next;
		argc--;
		argv++;
		dobroadcast++;
	}

	/* command returns */
	if(!debug)
		switch(rfork(RFNOTEG|RFPROC|RFFDG|RFNOWAIT)) {
		case -1:
			fatal(1, "fork");
		case 0:
			break;
		default:
			exits(0);
		}


	fmtinstall('E', eipfmt);
	fmtinstall('V', eipfmt);

	snprint(routefile, sizeof(routefile), "%s/iproute", netdir);
	snprint(buf, sizeof(buf), "%s/iproute", netdir);

	now = time(0);
	readifcs();
	readroutes();

	notify(ding);

	ripfd = openport();
	for(;;) {
		diff = btime - time(0);
		if(diff <= 0){
			if(dobroadcast)
				broadcast();
			timeoutroutes();

			btime = time(0) + 2*60;
			diff = 2*60;
		}
		alarm(diff*1000);
		n = read(ripfd, buf, sizeof(buf));
		alarm(0);
		if(n <= 0)
			continue;

		n = (n - Udphdrsize - 4) / sizeof(Rip);
		if(n <= 0)
			continue;

		up = (Udphdr*)buf;
		m = (Ripmsg*)(buf+Udphdrsize);
		if(m->type != Response || m->vers != Version)
			continue;
		v6tov4(raddr, up->raddr);

		/* ignore our own messages */
		for(i = 0; i < ialloc.nifc; i++)
			if(equivip(ialloc.ifc[i].addr, raddr))
				continue;

		now = time(0);
		for(r = m->rip; r < &m->rip[n]; r++){
			memmove(route.gate, raddr, Pasize);
			memmove(route.mask, getmask(r->addr), Pasize);
			v4maskip(r->addr, route.mask, route.dest);
			route.metric = nhgetl(r->metric) + 1;
			if(route.metric < 1)
				continue;
			considerroute(&route);
		}
	}
	/* not reached */
}
Beispiel #20
0
void
main(int argc, char **argv)
{
	int i, dowinchange, fd, usepty;
	char *host, *cmd, *user, *p;
	char *f[16];
	Conn c;
	Msg *m;

	fmtinstall('B', mpfmt);
	fmtinstall('H', encodefmt);
	atexit(atexitkiller);
	atexitkill(getpid());

	dowinchange = 0;
	if(getenv("LINES"))
		dowinchange = 1;
	usepty = -1;
	user = nil;
	ARGBEGIN{
	case 'B':	/* undocumented, debugging */
		doabort = 1;
		break;
	case 'D':	/* undocumented, debugging */
		debuglevel = strtol(EARGF(usage()), nil, 0);
		break;
	case 'l':	/* deprecated */
	case 'u':
		user = EARGF(usage());
		break;
	case 'a':	/* used by Unix scp implementations; we must ignore them. */
	case 'x':
		break;

	case 'A':
		authlist = EARGF(usage());
		break;
	case 'C':
		cooked = 1;
		break;
	case 'c':
		cipherlist = EARGF(usage());
		break;
	case 'f':
		forwardagent = 1;
		break;
	case 'I':
		interactive = 0;
		break;
	case 'i':
		interactive = 1;
		break;
	case 'm':
		usemenu = 0;
		break;
	case 'P':
		usepty = 0;
		break;
	case 'p':
		usepty = 1;
		break;
	case 'R':
		rawhack = 1;
		break;
	case 'r':
		crstrip = 1;
		break;
	default:
		usage();
	}ARGEND

	if(argc < 1)
		usage();

	host = argv[0];

	cmd = nil;
	if(argc > 1)
		cmd = buildcmd(argc-1, argv+1);

	if((p = strchr(host, '@')) != nil){
		*p++ = '\0';
		user = host;
		host = p;
	}
	if(user == nil)
		user = getenv("user");
	if(user == nil)
		sysfatal("cannot find user name");

	privatefactotum();
	if(interactive==-1)
		interactive = isatty(0);

	if((fd = dial(netmkaddr(host, "tcp", "ssh"), nil, nil, nil)) < 0)
		sysfatal("dialing %s: %r", host);

	memset(&c, 0, sizeof c);
	c.interactive = interactive;
	c.fd[0] = c.fd[1] = fd;
	c.user = user;
	c.host = host;
	setaliases(&c, host);

	c.nokcipher = getfields(cipherlist, f, nelem(f), 1, ", ");
	c.okcipher = emalloc(sizeof(Cipher*)*c.nokcipher);
	for(i=0; i<c.nokcipher; i++)
		c.okcipher[i] = findcipher(f[i], allcipher, nelem(allcipher));

	c.nokauth = getfields(authlist, f, nelem(f), 1, ", ");
	c.okauth = emalloc(sizeof(Auth*)*c.nokauth);
	for(i=0; i<c.nokauth; i++)
		c.okauth[i] = findauth(f[i], allauth, nelem(allauth));

	sshclienthandshake(&c);

	if(forwardagent){
		if(startagent(&c) < 0)
			forwardagent = 0;
	}
	if(usepty == -1)
		usepty = cmd==nil;
	if(usepty)
		requestpty(&c);
	if(cmd){
		m = allocmsg(&c, SSH_CMSG_EXEC_CMD, 4+strlen(cmd));
		putstring(m, cmd);
	}else
		m = allocmsg(&c, SSH_CMSG_EXEC_SHELL, 0);
	sendmsg(m);

	fromstdin(&c);
	rfork(RFNOTEG);	/* only fromstdin gets notes */
	if(dowinchange)
		winchanges(&c);
	fromnet(&c);
	exits(0);
}
Beispiel #21
0
void
main(int argc, char **argv)
{
	char *netdir;
	char buf[1024];

	netdir = nil;
	quotefmtinstall();
	fmtinstall('I', eipfmt);
	starttime = time(0);
	ARGBEGIN{
	case 'a':
		authenticate = 1;
		break;
	case 'c':
		tlscert = EARGF(usage());
		break;
	case 'D':
		Dflag++;
		break;
	case 'd':
		debug++;
		break;
	case 'f':				/* disallow relaying */
		fflag = 1;
		break;
	case 'g':
		gflag = 1;
		break;
	case 'h':				/* default domain name */
		dom = EARGF(usage());
		break;
	case 'k':				/* prohibited ip address */
		addbadguy(EARGF(usage()));
		break;
	case 'm':				/* set mail command */
		mailer = mailerpath(EARGF(usage()));
		break;
	case 'n':				/* log peer ip address */
		netdir = EARGF(usage());
		break;
	case 'p':
		passwordinclear = 1;
		break;
	case 'r':
		rflag = 1;			/* verify sender's domain */
		break;
	case 's':				/* save blocked messages */
		sflag = 1;
		break;
	case 't':
		fprint(2, "%s: the -t option is no longer supported, see -c\n",
			argv0);
		tlscert = "/sys/lib/ssl/smtpd-cert.pem";
		break;
	default:
		usage();
	}ARGEND;

	nci = getnetconninfo(netdir, 0);
	if(nci == nil)
		sysfatal("can't get remote system's address: %r");
	parseip(rsysip, nci->rsys);

	if(mailer == nil)
		mailer = mailerpath("send");

	if(debug){
		snprint(buf, sizeof buf, "%s/smtpdb/%ld", UPASLOG, time(0));
		close(2);
		if (create(buf, OWRITE | OEXCL, 0662) >= 0) {
			seek(2, 0, 2);
			fprint(2, "%d smtpd %s\n", getpid(), thedate());
		} else
			debug = 0;
	}
	getconf();
	if (isbadguy())
		exits("banned");
	Binit(&bin, 0, OREAD);

	if (chdir(UPASLOG) < 0)
		syslog(0, "smtpd", "no %s: %r", UPASLOG);
	me = sysname_read();
	if(dom == 0 || dom[0] == 0)
		dom = domainname_read();
	if(dom == 0 || dom[0] == 0)
		dom = me;
	sayhi();
	parseinit();

	/* allow 45 minutes to parse the header */
	atnotify(catchalarm, 1);
	alarm(45*60*1000);
	zzparse();
	exits(0);
}
Beispiel #22
0
void
main(int argc, char *argv[])
{
	int kid, pid;
	char servefile[Maxpath], ext[Maxpath];
	Dir *dir;

	setnetmtpt(mntpt, sizeof mntpt, nil);
	ext[0] = 0;
	ARGBEGIN{
	case 'a':
		maxage = atol(EARGF(usage()));
		if (maxage <= 0)
			maxage = Defmaxage;
		break;
	case 'd':
		debug = 1;
		traceactivity = 1;
		break;
	case 'f':
		dbfile = EARGF(usage());
		break;
	case 'F':
		cfg.justforw = cfg.resolver = 1;
		break;
	case 'n':
		sendnotifies = 1;
		break;
	case 'N':
		target = atol(EARGF(usage()));
		if (target < 1000)
			target = 1000;
		break;
	case 'o':
		cfg.straddle = 1;	/* straddle inside & outside networks */
		break;
	case 'r':
		cfg.resolver = 1;
		break;
	case 'R':
		norecursion = 1;
		break;
	case 's':
		cfg.serve = 1;		/* serve network */
		cfg.cachedb = 1;
		break;
	case 't':
		testing = 1;
		break;
	case 'T':
		addforwtarg(EARGF(usage()));
		break;
	case 'x':
		setnetmtpt(mntpt, sizeof mntpt, EARGF(usage()));
		setext(ext, sizeof ext, mntpt);
		break;
	case 'z':
		zonerefreshprogram = EARGF(usage());
		break;
	default:
		usage();
		break;
	}ARGEND
	if(argc != 0)
		usage();

	if(testing)
		mainmem->flags |= POOL_NOREUSE | POOL_ANTAGONISM;
	mainmem->flags |= POOL_ANTAGONISM;
	rfork(RFREND|RFNOTEG);

	cfg.inside = (*mntpt == '\0' || strcmp(mntpt, "/net") == 0);

	/* start syslog before we fork */
	fmtinstall('F', fcallfmt);
	dninit();
	/* this really shouldn't be fatal */
	if(myipaddr(ipaddr, mntpt) < 0)
		sysfatal("can't read my ip address");
	dnslog("starting %s%sdns %s%s%son %I's %s",
		(cfg.straddle? "straddling ": ""),
		(cfg.cachedb? "caching ": ""),
		(cfg.serve?   "udp server ": ""),
		(cfg.justforw? "forwarding-only ": ""),
		(cfg.resolver? "resolver ": ""), ipaddr, mntpt);

	opendatabase();
	now = time(nil);		/* open time files before we fork */
	nowns = nsec();

	snprint(servefile, sizeof servefile, "#s/dns%s", ext);
	dir = dirstat(servefile);
	if (dir)
		sysfatal("%s exists; another dns instance is running",
			servefile);
	free(dir);

	/* don't unmount here; could deadlock */
//	while (unmount(servefile, mntpt) >= 0)
//		;
	mountinit(servefile, mntpt);	/* forks, parent exits */

	srand(now*getpid());
	db2cache(1);
//	dnageallnever();

	if (cfg.straddle && !seerootns())
		dnslog("straddle server misconfigured; can't resolve root name servers");
	/*
	 * fork without sharing heap.
	 * parent waits around for child to die, then forks & restarts.
	 * child may spawn udp server, notify procs, etc.; when it gets too
	 * big or too old, it kills itself and any children.
	 *
	 * /srv/dns remains open and valid, but /net/dns was only mounted in
	 * a child's separate namespace from 9p service, to avoid a deadlock
	 * from serving our own namespace, so we must remount it upon restart,
	 * in a separate process and namespace.
	 */
	for (;;) {
		start = time(nil);
		/* don't unmount here; could deadlock */
//		unmount(servefile, mntpt);
		kid = rfork(RFPROC|RFFDG|RFNOTEG|RFNAMEG);
		switch (kid) {
		case -1:
			sysfatal("fork failed: %r");
		case 0:
			if(cfg.serve)
				dnudpserver(mntpt);
			if(sendnotifies)
				notifyproc();
			io();		/* serve 9p; return implies restart */
			_exits("restart");
		}
		sleep(1000);	/* wait for 9p service to start */
		justremount(servefile, mntpt);
		while ((pid = waitpid()) != kid && pid != -1)
			continue;
		dnslog("restarting");
	}
}
Beispiel #23
0
void
regopt(Prog *firstp)
{
	Reg *r, *r1;
	Prog *p;
	int i, z, nr;
	uint32 vreg;
	Bits bit;

	if(first) {
		fmtinstall('Q', Qconv);
		exregoffset = D_DI;	// no externals
		first = 0;
	}

	// count instructions
	nr = 0;
	for(p=firstp; p!=P; p=p->link)
		nr++;
	// if too big dont bother
	if(nr >= 10000) {
//		print("********** %S is too big (%d)\n", curfn->nname->sym, nr);
		return;
	}

	r1 = R;
	firstr = R;
	lastr = R;
	
	/*
	 * control flow is more complicated in generated go code
	 * than in generated c code.  define pseudo-variables for
	 * registers, so we have complete register usage information.
	 */
	nvar = NREGVAR;
	memset(var, 0, NREGVAR*sizeof var[0]);
	for(i=0; i<NREGVAR; i++)
		var[i].sym = lookup(regname[i]);

	regbits = RtoB(D_SP);
	for(z=0; z<BITS; z++) {
		externs.b[z] = 0;
		params.b[z] = 0;
		consts.b[z] = 0;
		addrs.b[z] = 0;
		ovar.b[z] = 0;
	}

	// build list of return variables
	setoutvar();

	/*
	 * pass 1
	 * build aux data structure
	 * allocate pcs
	 * find use and set of variables
	 */
	nr = 0;
	for(p=firstp; p!=P; p=p->link) {
		switch(p->as) {
		case ADATA:
		case AGLOBL:
		case ANAME:
		case ASIGNAME:
			continue;
		}
		r = rega();
		nr++;
		if(firstr == R) {
			firstr = r;
			lastr = r;
		} else {
			lastr->link = r;
			r->p1 = lastr;
			lastr->s1 = r;
			lastr = r;
		}
		r->prog = p;
		p->reg = r;

		r1 = r->p1;
		if(r1 != R) {
			switch(r1->prog->as) {
			case ARET:
			case AJMP:
			case AIRETL:
				r->p1 = R;
				r1->s1 = R;
			}
		}

		bit = mkvar(r, &p->from);
		if(bany(&bit))
		switch(p->as) {
		/*
		 * funny
		 */
		case ALEAL:
			setaddrs(bit);
			break;

		/*
		 * left side read
		 */
		default:
			for(z=0; z<BITS; z++)
				r->use1.b[z] |= bit.b[z];
			break;

		/*
		 * left side read+write
		 */
		case AXCHGB:
		case AXCHGW:
		case AXCHGL:
			for(z=0; z<BITS; z++) {
				r->use1.b[z] |= bit.b[z];
				r->set.b[z] |= bit.b[z];
			}
			break;
		}

		bit = mkvar(r, &p->to);
		if(bany(&bit))
		switch(p->as) {
		default:
			yyerror("reg: unknown op: %A", p->as);
			break;

		/*
		 * right side read
		 */
		case ACMPB:
		case ACMPL:
		case ACMPW:
		case ATESTB:
		case ATESTL:
		case ATESTW:
			for(z=0; z<BITS; z++)
				r->use2.b[z] |= bit.b[z];
			break;

		/*
		 * right side write
		 */
		case AFSTSW:
		case ALEAL:
		case ANOP:
		case AMOVL:
		case AMOVB:
		case AMOVW:
		case AMOVBLSX:
		case AMOVBLZX:
		case AMOVBWSX:
		case AMOVBWZX:
		case AMOVWLSX:
		case AMOVWLZX:
		case APOPL:
			for(z=0; z<BITS; z++)
				r->set.b[z] |= bit.b[z];
			break;

		/*
		 * right side read+write
		 */
		case AINCB:
		case AINCL:
		case AINCW:
		case ADECB:
		case ADECL:
		case ADECW:

		case AADDB:
		case AADDL:
		case AADDW:
		case AANDB:
		case AANDL:
		case AANDW:
		case ASUBB:
		case ASUBL:
		case ASUBW:
		case AORB:
		case AORL:
		case AORW:
		case AXORB:
		case AXORL:
		case AXORW:
		case ASALB:
		case ASALL:
		case ASALW:
		case ASARB:
		case ASARL:
		case ASARW:
		case ARCLB:
		case ARCLL:
		case ARCLW:
		case ARCRB:
		case ARCRL:
		case ARCRW:
		case AROLB:
		case AROLL:
		case AROLW:
		case ARORB:
		case ARORL:
		case ARORW:
		case ASHLB:
		case ASHLL:
		case ASHLW:
		case ASHRB:
		case ASHRL:
		case ASHRW:
		case AIMULL:
		case AIMULW:
		case ANEGB:
		case ANEGL:
		case ANEGW:
		case ANOTB:
		case ANOTL:
		case ANOTW:
		case AADCL:
		case ASBBL:

		case ASETCC:
		case ASETCS:
		case ASETEQ:
		case ASETGE:
		case ASETGT:
		case ASETHI:
		case ASETLE:
		case ASETLS:
		case ASETLT:
		case ASETMI:
		case ASETNE:
		case ASETOC:
		case ASETOS:
		case ASETPC:
		case ASETPL:
		case ASETPS:

		case AXCHGB:
		case AXCHGW:
		case AXCHGL:
			for(z=0; z<BITS; z++) {
				r->set.b[z] |= bit.b[z];
				r->use2.b[z] |= bit.b[z];
			}
			break;

		/*
		 * funny
		 */
		case AFMOVDP:
		case AFMOVFP:
		case AFMOVLP:
		case AFMOVVP:
		case AFMOVWP:
		case ACALL:
			setaddrs(bit);
			break;
		}

		switch(p->as) {
		case AIMULL:
		case AIMULW:
			if(p->to.type != D_NONE)
				break;

		case AIDIVL:
		case AIDIVW:
		case ADIVL:
		case ADIVW:
		case AMULL:
		case AMULW:
			r->set.b[0] |= RtoB(D_AX) | RtoB(D_DX);
			r->use1.b[0] |= RtoB(D_AX) | RtoB(D_DX);
			break;

		case AIDIVB:
		case AIMULB:
		case ADIVB:
		case AMULB:
			r->set.b[0] |= RtoB(D_AX);
			r->use1.b[0] |= RtoB(D_AX);
			break;

		case ACWD:
			r->set.b[0] |= RtoB(D_AX) | RtoB(D_DX);
			r->use1.b[0] |= RtoB(D_AX);
			break;

		case ACDQ:
			r->set.b[0] |= RtoB(D_DX);
			r->use1.b[0] |= RtoB(D_AX);
			break;

		case AREP:
		case AREPN:
		case ALOOP:
		case ALOOPEQ:
		case ALOOPNE:
			r->set.b[0] |= RtoB(D_CX);
			r->use1.b[0] |= RtoB(D_CX);
			break;

		case AMOVSB:
		case AMOVSL:
		case AMOVSW:
		case ACMPSB:
		case ACMPSL:
		case ACMPSW:
			r->set.b[0] |= RtoB(D_SI) | RtoB(D_DI);
			r->use1.b[0] |= RtoB(D_SI) | RtoB(D_DI);
			break;

		case ASTOSB:
		case ASTOSL:
		case ASTOSW:
		case ASCASB:
		case ASCASL:
		case ASCASW:
			r->set.b[0] |= RtoB(D_DI);
			r->use1.b[0] |= RtoB(D_AX) | RtoB(D_DI);
			break;

		case AINSB:
		case AINSL:
		case AINSW:
			r->set.b[0] |= RtoB(D_DX) | RtoB(D_DI);
			r->use1.b[0] |= RtoB(D_DI);
			break;

		case AOUTSB:
		case AOUTSL:
		case AOUTSW:
			r->set.b[0] |= RtoB(D_DI);
			r->use1.b[0] |= RtoB(D_DX) | RtoB(D_DI);
			break;
		}
	}
	if(firstr == R)
		return;

	for(i=0; i<nvar; i++) {
		Var *v = var+i;
		if(v->addr) {
			bit = blsh(i);
			for(z=0; z<BITS; z++)
				addrs.b[z] |= bit.b[z];
		}

//		print("bit=%2d addr=%d et=%-6E w=%-2d s=%S + %lld\n",
//			i, v->addr, v->etype, v->width, v->sym, v->offset);
	}

	if(debug['R'] && debug['v'])
		dumpit("pass1", firstr);

	/*
	 * pass 2
	 * turn branch references to pointers
	 * build back pointers
	 */
	for(r=firstr; r!=R; r=r->link) {
		p = r->prog;
		if(p->to.type == D_BRANCH) {
			if(p->to.branch == P)
				fatal("pnil %P", p);
			r1 = p->to.branch->reg;
			if(r1 == R)
				fatal("rnil %P", p);
			if(r1 == r) {
				//fatal("ref to self %P", p);
				continue;
			}
			r->s2 = r1;
			r->p2link = r1->p2;
			r1->p2 = r;
		}
	}

	if(debug['R'] && debug['v'])
		dumpit("pass2", firstr);

	/*
	 * pass 2.5
	 * find looping structure
	 */
	for(r = firstr; r != R; r = r->link)
		r->active = 0;
	change = 0;
	loopit(firstr, nr);

	if(debug['R'] && debug['v'])
		dumpit("pass2.5", firstr);

	/*
	 * pass 3
	 * iterate propagating usage
	 * 	back until flow graph is complete
	 */
loop1:
	change = 0;
	for(r = firstr; r != R; r = r->link)
		r->active = 0;
	for(r = firstr; r != R; r = r->link)
		if(r->prog->as == ARET)
			prop(r, zbits, zbits);
loop11:
	/* pick up unreachable code */
	i = 0;
	for(r = firstr; r != R; r = r1) {
		r1 = r->link;
		if(r1 && r1->active && !r->active) {
			prop(r, zbits, zbits);
			i = 1;
		}
	}
	if(i)
		goto loop11;
	if(change)
		goto loop1;

	if(debug['R'] && debug['v'])
		dumpit("pass3", firstr);

	/*
	 * pass 4
	 * iterate propagating register/variable synchrony
	 * 	forward until graph is complete
	 */
loop2:
	change = 0;
	for(r = firstr; r != R; r = r->link)
		r->active = 0;
	synch(firstr, zbits);
	if(change)
		goto loop2;

	if(debug['R'] && debug['v'])
		dumpit("pass4", firstr);

	/*
	 * pass 4.5
	 * move register pseudo-variables into regu.
	 */
	for(r = firstr; r != R; r = r->link) {
		r->regu = (r->refbehind.b[0] | r->set.b[0]) & REGBITS;

		r->set.b[0] &= ~REGBITS;
		r->use1.b[0] &= ~REGBITS;
		r->use2.b[0] &= ~REGBITS;
		r->refbehind.b[0] &= ~REGBITS;
		r->refahead.b[0] &= ~REGBITS;
		r->calbehind.b[0] &= ~REGBITS;
		r->calahead.b[0] &= ~REGBITS;
		r->regdiff.b[0] &= ~REGBITS;
		r->act.b[0] &= ~REGBITS;
	}

	/*
	 * pass 5
	 * isolate regions
	 * calculate costs (paint1)
	 */
	r = firstr;
	if(r) {
		for(z=0; z<BITS; z++)
			bit.b[z] = (r->refahead.b[z] | r->calahead.b[z]) &
			  ~(externs.b[z] | params.b[z] | addrs.b[z] | consts.b[z]);
		if(bany(&bit) && !r->refset) {
			// should never happen - all variables are preset
			if(debug['w'])
				print("%L: used and not set: %Q\n", r->prog->lineno, bit);
			r->refset = 1;
		}
	}
	for(r = firstr; r != R; r = r->link)
		r->act = zbits;
	rgp = region;
	nregion = 0;
	for(r = firstr; r != R; r = r->link) {
		for(z=0; z<BITS; z++)
			bit.b[z] = r->set.b[z] &
			  ~(r->refahead.b[z] | r->calahead.b[z] | addrs.b[z]);
		if(bany(&bit) && !r->refset) {
			if(debug['w'])
				print("%L: set and not used: %Q\n", r->prog->lineno, bit);
			r->refset = 1;
			excise(r);
		}
		for(z=0; z<BITS; z++)
			bit.b[z] = LOAD(r) & ~(r->act.b[z] | addrs.b[z]);
		while(bany(&bit)) {
			i = bnum(bit);
			rgp->enter = r;
			rgp->varno = i;
			change = 0;
			paint1(r, i);
			bit.b[i/32] &= ~(1L<<(i%32));
			if(change <= 0)
				continue;
			rgp->cost = change;
			nregion++;
			if(nregion >= NRGN) {
				if(debug['R'] && debug['v'])
					print("too many regions\n");
				goto brk;
			}
			rgp++;
		}
	}
brk:
	qsort(region, nregion, sizeof(region[0]), rcmp);

	/*
	 * pass 6
	 * determine used registers (paint2)
	 * replace code (paint3)
	 */
	rgp = region;
	for(i=0; i<nregion; i++) {
		bit = blsh(rgp->varno);
		vreg = paint2(rgp->enter, rgp->varno);
		vreg = allreg(vreg, rgp);
		if(rgp->regno != 0)
			paint3(rgp->enter, rgp->varno, vreg, rgp->regno);
		rgp++;
	}

	if(debug['R'] && debug['v'])
		dumpit("pass6", firstr);

	/*
	 * pass 7
	 * peep-hole on basic block
	 */
	if(!debug['R'] || debug['P']) {
		peep();
	}

	/*
	 * eliminate nops
	 * free aux structures
	 */
	for(p=firstp; p!=P; p=p->link) {
		while(p->link != P && p->link->as == ANOP)
			p->link = p->link->link;
		if(p->to.type == D_BRANCH)
			while(p->to.branch != P && p->to.branch->as == ANOP)
				p->to.branch = p->to.branch->link;
	}

	if(r1 != R) {
		r1->link = freer;
		freer = firstr;
	}

	if(debug['R']) {
		if(ostats.ncvtreg ||
		   ostats.nspill ||
		   ostats.nreload ||
		   ostats.ndelmov ||
		   ostats.nvar ||
		   ostats.naddr ||
		   0)
			print("\nstats\n");

		if(ostats.ncvtreg)
			print("	%4d cvtreg\n", ostats.ncvtreg);
		if(ostats.nspill)
			print("	%4d spill\n", ostats.nspill);
		if(ostats.nreload)
			print("	%4d reload\n", ostats.nreload);
		if(ostats.ndelmov)
			print("	%4d delmov\n", ostats.ndelmov);
		if(ostats.nvar)
			print("	%4d delmov\n", ostats.nvar);
		if(ostats.naddr)
			print("	%4d delmov\n", ostats.naddr);

		memset(&ostats, 0, sizeof(ostats));
	}
}
Beispiel #24
0
void
main(int argc, char **argv)
{
	vlong secsize;

	secsize = 0;
	ARGBEGIN{
	case 'a':
		doauto++;
		break;
	case 'b':
		blank++;
		break;
	case 'f':
		file++;
		break;
	case 'p':
		printflag++;
		break;
	case 'r':
		rdonly++;
		break;
	case 's':
		secsize = atoi(ARGF());
		break;
	case 'v':
		printchs++;
		break;
	case 'w':
		dowrite++;
		break;
	}ARGEND;

	fmtinstall('D', Dfmt);

	if(argc != 1)
		usage();

	edit.disk = opendisk(argv[0], rdonly, file);
	if(edit.disk == nil) {
		fprint(2, "cannot open disk: %r\n");
		exits("opendisk");
	}

	if(secsize != 0) {
		edit.disk->secsize = secsize;
		edit.disk->secs = edit.disk->size / secsize;
	}

	sec2cyl = edit.disk->h * edit.disk->s;
	edit.end = edit.disk->secs / sec2cyl;

	findmbr(&edit);

	if(blank)
		blankpart(&edit);
	else
		rdpart(&edit, 0, 0);

	if(doauto)
		autopart(&edit);

	if(dowrite)
		runcmd(&edit, "w");

	if(printflag)
		runcmd(&edit, "P");

	if(dowrite || printflag)
		exits(0);

	fprint(2, "cylinder = %lld bytes\n", sec2cyl*edit.disk->secsize);
	runcmd(&edit, "p");
	for(;;) {
		fprint(2, ">>> ");
		runcmd(&edit, getline(&edit));
	}
}
Beispiel #25
0
void
io(int srvfd)
{
	int n, pid;
	Fcall xreq, xrep;

	req = &xreq;
	rep = &xrep;
	pid = getpid();
	fmtinstall('F', fcallfmt);

	for(;;){
		/*
		 * reading from a pipe or a network device
		 * will give an error after a few eof reads.
		 * however, we cannot tell the difference
		 * between a zero-length read and an interrupt
		 * on the processes writing to us,
		 * so we wait for the error.
		 */
		n = read9pmsg(srvfd, mdata, sizeof mdata);
		if(n < 0)
			break;
		if(n == 0)
			continue;
		if(convM2S(mdata, n, req) == 0)
			continue;

		if(chatty)
			fprint(2, "9660srv %d:<-%F\n", pid, req);

		errno = 0;
		if(!waserror()){
			err_msg[0] = 0;
			if(req->type >= nelem(fcalls) || !fcalls[req->type])
				error("bad fcall type");
			(*fcalls[req->type])();
			poperror();
		}

		if(err_msg[0]){
			rep->type = Rerror;
			rep->ename = err_msg;
		}else{
			rep->type = req->type + 1;
			rep->fid = req->fid;
		}
		rep->tag = req->tag;

		if(chatty)
			fprint(2, "9660srv %d:->%F\n", pid, rep);
		n = convS2M(rep, mdata, sizeof mdata);
		if(n == 0)
			panic(1, "convS2M error on write");
		if(write(srvfd, mdata, n) != n)
			panic(1, "mount write");
		if(nerr_lab != 0)
			panic(0, "err stack %d: %lx %lx %lx %lx %lx %lx", nerr_lab,
			err_lab[0][JMPBUFPC], err_lab[1][JMPBUFPC],
			err_lab[2][JMPBUFPC], err_lab[3][JMPBUFPC],
			err_lab[4][JMPBUFPC], err_lab[5][JMPBUFPC]);
	}
	chat("server shut down");
}
Beispiel #26
0
void
threadmain(int argc, char **argv)
{
	char *pref, *mountname, *mountplace;
	uchar score[VtScoreSize], prev[VtScoreSize];
	int i, fd, csize;
	vlong bsize;
	Tm tm;
	VtEntry e;
	VtBlock *b;
	VtCache *c;
	VtRoot root;
	char *tmp, *tmpnam;

	fmtinstall('F', vtfcallfmt);
	fmtinstall('H', encodefmt);
	fmtinstall('T', timefmt);
	fmtinstall('V', vtscorefmt);

	mountname = sysname();
	mountplace = nil;
	ARGBEGIN{
	default:
		usage();
		break;
	case 'D':
		debug++;
		break;
	case 'V':
		chattyventi = 1;
		break;
	case 'f':
		fastwrites = 1;
		break;
	case 'i':
		incremental = 1;
		break;
	case 'm':
		mountname = EARGF(usage());
		break;
	case 'M':
		mountplace = EARGF(usage());
		i = strlen(mountplace);
		if(i > 0 && mountplace[i-1] == '/')
			mountplace[i-1] = 0;
		break;
	case 'n':
		nop = 1;
		break;
	case 's':
		statustime = atoi(EARGF(usage()));
		break;
	case 'v':
		verbose = 1;
		break;
	case 'w':
		nwritethread = atoi(EARGF(usage()));
		break;
	}ARGEND

	if(argc != 1 && argc != 2)
		usage();

	if(statustime)
		print("# %T vbackup %s %s\n", argv[0], argc>=2 ? argv[1] : "");

	/*
	 * open fs
	 */
	if((disk = diskopenfile(argv[0])) == nil)
		sysfatal("diskopen: %r");
	if((disk = diskcache(disk, 32768, 2*MAXQ+16)) == nil)
		sysfatal("diskcache: %r");
	if((fsys = fsysopen(disk)) == nil)
		sysfatal("fsysopen: %r");

	/*
	 * connect to venti
	 */
	if((z = vtdial(nil)) == nil)
		sysfatal("vtdial: %r");
	if(vtconnect(z) < 0)
		sysfatal("vtconnect: %r");

	/*
	 * set up venti block cache
	 */
	zero = vtmallocz(fsys->blocksize);
	bsize = fsys->blocksize;
	csize = 50;	/* plenty; could probably do with 5 */

	if(verbose)
		fprint(2, "cache %d blocks\n", csize);
	c = vtcachealloc(z, bsize*csize);
	zcache = c;

	/*
	 * parse starting score
	 */
	memset(prev, 0, sizeof prev);
	if(argc == 1){
		vfile = vtfilecreateroot(c, (fsys->blocksize/VtScoreSize)*VtScoreSize,
			fsys->blocksize, VtDataType);
		if(vfile == nil)
			sysfatal("vtfilecreateroot: %r");
		vtfilelock(vfile, VtORDWR);
		if(vtfilewrite(vfile, zero, 1, bsize*fsys->nblock-1) != 1)
			sysfatal("vtfilewrite: %r");
		if(vtfileflush(vfile) < 0)
			sysfatal("vtfileflush: %r");
	}else{
		if(vtparsescore(argv[1], &pref, score) < 0)
			sysfatal("bad score: %r");
		if(pref!=nil && strcmp(pref, fsys->type) != 0)
			sysfatal("score is %s but fsys is %s", pref, fsys->type);
		b = vtcacheglobal(c, score, VtRootType, VtRootSize);
		if(b){
			if(vtrootunpack(&root, b->data) < 0)
				sysfatal("bad root: %r");
			if(strcmp(root.type, fsys->type) != 0)
				sysfatal("root is %s but fsys is %s", root.type, fsys->type);
			memmove(prev, score, VtScoreSize);
			memmove(score, root.score, VtScoreSize);
			vtblockput(b);
		}
		b = vtcacheglobal(c, score, VtDirType, VtEntrySize);
		if(b == nil)
			sysfatal("vtcacheglobal %V: %r", score);
		if(vtentryunpack(&e, b->data, 0) < 0)
			sysfatal("%V: vtentryunpack failed", score);
		if(verbose)
			fprint(2, "entry: size %llud psize %d dsize %d\n",
				e.size, e.psize, e.dsize);
		vtblockput(b);
		if((vfile = vtfileopenroot(c, &e)) == nil)
			sysfatal("vtfileopenroot: %r");
		vtfilelock(vfile, VtORDWR);
		if(e.dsize != bsize)
			sysfatal("file system block sizes don't match %d %lld", e.dsize, bsize);
		if(e.size != fsys->nblock*bsize)
			sysfatal("file system block counts don't match %lld %lld", e.size, fsys->nblock*bsize);
	}

	tmpnam = nil;
	if(incremental){
		if(vtfilegetentry(vfile, &e) < 0)
			sysfatal("vtfilegetentry: %r");
		if((vscores = vtfileopenroot(c, &e)) == nil)
			sysfatal("vtfileopenroot: %r");
		vtfileunlock(vfile);
	}else{
		/*
		 * write scores of blocks into temporary file
		 */
		if((tmp = getenv("TMP")) != nil){
			/* okay, good */
		}else if(access("/var/tmp", 0) >= 0)
			tmp = "/var/tmp";
		else
			tmp = "/tmp";
		tmpnam = smprint("%s/vbackup.XXXXXX", tmp);
		if(tmpnam == nil)
			sysfatal("smprint: %r");
	
		if((fd = opentemp(tmpnam, ORDWR|ORCLOSE)) < 0)
			sysfatal("opentemp %s: %r", tmpnam);
		if(statustime)
			print("# %T reading scores into %s\n", tmpnam);
		if(verbose)
			fprint(2, "read scores into %s...\n", tmpnam);
	
		Binit(&bscores, fd, OWRITE);
		for(i=0; i<fsys->nblock; i++){
			if(vtfileblockscore(vfile, i, score) < 0)
				sysfatal("vtfileblockhash %d: %r", i);
			if(Bwrite(&bscores, score, VtScoreSize) != VtScoreSize)
				sysfatal("Bwrite: %r");
		}
		Bterm(&bscores);
		vtfileunlock(vfile);
	
		/*
		 * prep scores for rereading
		 */
		seek(fd, 0, 0);
		Binit(&bscores, fd, OREAD);
	}

	/*
	 * start the main processes 
	 */
	if(statustime)
		print("# %T starting procs\n");
	qcmp = qalloc();
	qventi = qalloc();

	rlock(&endlk);
	proccreate(fsysproc, nil, STACK);
	rlock(&endlk);
	proccreate(ventiproc, nil, STACK);
	rlock(&endlk);
	proccreate(cmpproc, nil, STACK);
	if(statustime){
		rlock(&endlk);
		proccreate(statusproc, nil, STACK);
	}

	/*
	 * wait for processes to finish
	 */
	wlock(&endlk);
	
	qfree(qcmp);
	qfree(qventi);

	if(statustime)
		print("# %T procs exited: %d of %d %d-byte blocks changed, "
			"%d read, %d written, %d skipped, %d copied\n",
			nchange, fsys->nblock, fsys->blocksize,
			vtcachenread, vtcachenwrite, nskip, vtcachencopy);

	/*
	 * prepare root block
	 */
	if(incremental)
		vtfileclose(vscores);
	vtfilelock(vfile, -1);
	if(vtfileflush(vfile) < 0)
		sysfatal("vtfileflush: %r");
	if(vtfilegetentry(vfile, &e) < 0)
		sysfatal("vtfilegetentry: %r");
	vtfileunlock(vfile);
	vtfileclose(vfile);

	b = vtcacheallocblock(c, VtDirType, VtEntrySize);
	if(b == nil)
		sysfatal("vtcacheallocblock: %r");
	vtentrypack(&e, b->data, 0);
	if(vtblockwrite(b) < 0)
		sysfatal("vtblockwrite: %r");

	memset(&root, 0, sizeof root);
	strecpy(root.name, root.name+sizeof root.name, argv[0]);
	strecpy(root.type, root.type+sizeof root.type, fsys->type);
	memmove(root.score, b->score, VtScoreSize);
	root.blocksize = fsys->blocksize;
	memmove(root.prev, prev, VtScoreSize);
	vtblockput(b);

	b = vtcacheallocblock(c, VtRootType, VtRootSize);
	if(b == nil)
		sysfatal("vtcacheallocblock: %r");
	vtrootpack(&root, b->data);
	if(vtblockwrite(b) < 0)
		sysfatal("vtblockwrite: %r");

	tm = *localtime(time(0));
	tm.year += 1900;
	tm.mon++;
	if(mountplace == nil)
		mountplace = guessmountplace(argv[0]);
	print("mount /%s/%d/%02d%02d%s %s:%V %d/%02d%02d/%02d%02d\n",
		mountname, tm.year, tm.mon, tm.mday, 
		mountplace,
		root.type, b->score,
		tm.year, tm.mon, tm.mday, tm.hour, tm.min);
	print("# %T %s %s:%V\n", argv[0], root.type, b->score);
	if(statustime)
		print("# %T venti sync\n");
	vtblockput(b);
	if(vtsync(z) < 0)
		sysfatal("vtsync: %r");
	if(statustime)
		print("# %T synced\n");
	
	fsysclose(fsys);
	diskclose(disk);
	vtcachefree(zcache);

	// Vtgoodbye hangs on Linux - not sure why.
	// Probably vtfcallrpc doesn't quite get the
	// remote hangup right.  Also probably related
	// to the vtrecvproc problem below.
	// vtgoodbye(z);

	// Leak here, because I can't seem to make
	// the vtrecvproc exit.
	// vtfreeconn(z);

	free(tmpnam);
	z = nil;
	zcache = nil;
	fsys = nil;
	disk = nil;
	threadexitsall(nil);
}
Beispiel #27
0
void
main(int argc, char *argv[])
{
	uchar buf[8*1024], *p;
	char addr[128], dir[40], ldir[40], *s;
	int cmd, fd, cfd, n;
	NetConnInfo *nc;

	fmtinstall('I', eipfmt);

	setnetmtpt(inside, sizeof(inside), 0);
	setnetmtpt(outside, sizeof(outside), 0);
	ARGBEGIN {
	case 'x':
		setnetmtpt(inside, sizeof(inside), ARGF());
		break;
	case 'o':
		setnetmtpt(outside, sizeof(outside), ARGF());
		break;
	} ARGEND;

	/* ver+cmd or ver+nmethod */
	if(readn(0, buf, 2) != 2)
		return;
	socksver = buf[0];
	if(socksver < 4)
		return;
	if(socksver > 5)
		socksver = 5;

	if(socksver == 4){
		/* port+ip4 */
		if(readn(0, buf+2, 2+4) != 2+4)
			return;
		/* +user\0 */
		for(p = buf+2+2+4;; p++){
			if(p >= buf+sizeof(buf))
				return;
			if(read(0, p, 1) != 1)
				return;
			if(*p == 0)
				break;
		}
		/* socks 4a dom hack */
		if((buf[4] | buf[5] | buf[6]) == 0 && buf[7]){
			/* +dom\0 */
			for(++p;; p++){
				if(p >= buf+sizeof(buf))
					return;
				if(read(0, p, 1) != 1)
					return;
				if(*p == 0)
					break;
			}
		}
	} else {
		/* nmethod */
		if((n = buf[1]) > 0)
			if(readn(0, buf+2, n) != n)
				return;

		/* ver+method */
		buf[0] = socksver;
		buf[1] = 0x00;	/* no authentication required */
		if(write(1, buf, 2) != 2)
			return;

		/* ver+cmd+res+atyp */
		if(readn(0, buf, 4) != 4)
			return;
		switch(buf[3]){
		default:
			return;
		case 0x01:	/* +ipv4 */
			if(readn(0, buf+4, 4+2) != 4+2)
				return;
			break;
		case 0x03:	/* +len+dom[len] */
			if(readn(0, buf+4, 1) != 1)
				return;
			if((n = buf[4]) == 0)
				return;
			if(readn(0, buf+5, n+2) != n+2)
				return;
			break;
		case 0x04:	/* +ipv6 */
			if(readn(0, buf+4, 16+2) != 16+2)
				return;
			break;
		}
	}

	dir[0] = 0;
	fd = cfd = -1;
	cmd = buf[1];
	switch(cmd){
	case 0x01:	/* CONNECT */
		snprint(addr, sizeof(addr), "%s/tcp", outside);
		if((s = addr2str(addr, buf)) == nil)
			break;
		alarm(30000);
		fd = dial(s, 0, dir, &cfd);
		alarm(0);
		break;
	case 0x02:	/* BIND */
		if(myipaddr(buf, outside) < 0)
			break;
		snprint(addr, sizeof(addr), "%s/tcp!%I!0", outside, buf);
		fd = announce(addr, dir);
		break;
	case 0x03:	/* UDP */
		if(myipaddr(buf, inside) < 0)
			break;
		snprint(addr, sizeof(addr), "%s/udp!%I!0", inside, buf);
		fd = announce(addr, dir);
		break;
	}

Reply:
	/* reply */
	buf[1] = sockerr(fd < 0);			/* status */
	if(socksver == 4){
		buf[0] = 0x00;				/* vc */
		if(fd < 0){
			memset(buf+2, 0, 2+4);
			write(1, buf, 2+2+4);
			return;
		}
	} else {
		buf[0] = socksver;			/* ver */
		buf[2] = 0x00;				/* res */
		if(fd < 0){
			buf[3] = 0x01;			/* atyp */
			memset(buf+4, 0, 4+2);
			write(1, buf, 4+4+2);
			return;
		}
	}
	if((nc = getnetconninfo(dir, cfd)) == nil)
		return;
	if((n = str2addr((cmd & 0x100) ? nc->raddr : nc->laddr, buf)) <= 0)
		return;
	if(write(1, buf, n) != n)
		return;

	switch(cmd){
	default:
		return;
	case 0x01:	/* CONNECT */
		break;
	case 0x02:	/* BIND */
		cfd = listen(dir, ldir);
		close(fd);
		fd = -1;
		if(cfd >= 0){
			strcpy(dir, ldir);
			fd = accept(cfd, dir);
		}
		cmd |= 0x100;
		goto Reply;
	case 0x102:
		break;		
	case 0x03:	/* UDP */
		if(udprelay(fd, dir) == 0)
			while(read(0, buf, sizeof(buf)) > 0)
				;
		goto Hangup;
	}
	
	/* relay data */
	switch(rfork(RFMEM|RFPROC|RFFDG|RFNOWAIT)){
	case -1:
		return;
	case 0:
		dup(fd, 0);
		break;
	default:
		dup(fd, 1);
	}
	while((n = read(0, buf, sizeof(buf))) > 0)
		if(write(1, buf, n) != n)
			break;
Hangup:
	if(cfd >= 0)
		hangup(cfd);
	postnote(PNGROUP, getpid(), "kill");
}
Beispiel #28
0
static void
connproc(void *v)
{
	VtSconn *sc;
	VtConn *c;
	Packet *p;
	VtReq *r;
	int fd;
static int first=1;

if(first && chattyventi){
	first=0;
	fmtinstall('F', vtfcallfmt);
}
	r = nil;
	sc = v;
	sc->c = nil;
	if(0) fprint(2, "new call %s on %d\n", sc->dir, sc->ctl);
	fd = accept(sc->ctl, sc->dir);
	close(sc->ctl);
	if(fd < 0){
		fprint(2, "accept %s: %r\n", sc->dir);
		goto out;
	}

	c = vtconn(fd, fd);
	sc->c = c;
	if(vtversion(c) < 0){
		fprint(2, "vtversion %s: %r\n", sc->dir);
		goto out;
	}
	if(vtsrvhello(c) < 0){
		fprint(2, "vtsrvhello %s: %r\n", sc->dir);
		goto out;
	}

	if(0) fprint(2, "new proc %s\n", sc->dir);
	proccreate(vtsendproc, c, STACK);
	qlock(&c->lk);
	while(!c->writeq)
		rsleep(&c->rpcfork);
	qunlock(&c->lk);

	while((p = vtrecv(c)) != nil){
		r = vtmallocz(sizeof(VtReq));
		if(vtfcallunpack(&r->tx, p) < 0){
			vtlog(VtServerLog, "<font size=-1>%T %s:</font> recv bad packet %p: %r<br>\n", c->addr, p);
			fprint(2, "bad packet on %s: %r\n", sc->dir);
			packetfree(p);
			continue;
		}
		vtlog(VtServerLog, "<font size=-1>%T %s:</font> recv packet %p (%F)<br>\n", c->addr, p, &r->tx);
		if(chattyventi)
			fprint(2, "%s <- %F\n", argv0, &r->tx);
		packetfree(p);
		if(r->tx.msgtype == VtTgoodbye)
			break;
		r->rx.tag = r->tx.tag;
		r->sc = sc;
		scincref(sc);
		if(_vtqsend(sc->srv->q, r) < 0){
			scdecref(sc);
			fprint(2, "hungup queue\n");
			break;
		}
		r = nil;
	}

	if(0) fprint(2, "eof on %s\n", sc->dir);

out:
	if(r){
		vtfcallclear(&r->tx);
		vtfree(r);
	}
	if(0) fprint(2, "freed %s\n", sc->dir);
	scdecref(sc);
	return;
}
Beispiel #29
0
void
main(int argc, char *argv[])
{
	Etherpkt e;
	Ippkt *ip;
	long n;
	int fd, cfd;
	int ts, len, t;
	long start;
	int delta;
	uchar target[6];
	char buf[256];
	ulong samples;

	samples = -1;
	ARGBEGIN{
	case 'd':
		debug++;
		break;
	case 's':
		samples = atoi(ARGF());
		break;
	}ARGEND;

	if(argc < 2){
		fprint(2, "usage: %s device ip-addr [minutes-per-sample]\n", argv0);
		exits("usage");
	}
	if(argc > 2)
		delta = atoi(argv[2])*60*1000;
	else
		delta = 5*60*1000;
	parseether(target, argv[1]);

	fmtinstall('E', eipfmt);
	fmtinstall('I', eipfmt);

	snprint(buf, sizeof(buf), "%s!-2", argv[0]);
	fd = dial(buf, 0, 0, &cfd);
	if(fd < 0)
		error("opening ether data");
	if(write(cfd, "promiscuous", sizeof("promiscuous")-1) <= 0)
		error("connecting");

	start = 0;
	fd = -1;

	for(;;){
		if(fd < 0){
			fd = dial(buf, 0, 0, &cfd);
			if(fd < 0)
				error("opening ether data");
			if(write(cfd, "promiscuous", sizeof("promiscuous")-1) <= 0)
				error("connecting");
			close(cfd);
		}
		n = read(fd, &e, sizeof(e));
		if(n <= 0)
			break;
		ts = NetL(&e.d[60]);
		n = NetS(&e.d[58]) - ETHERHDRSIZE;
		if(n < 0)
			continue;
		if(start == 0)
			start = ts;
		t = NetS(e.type);
		if(t == 0x0800 || (t&0xFF00) == 0x1000){
			ip = (Ippkt*)e.data;
			len = NetS(ip->length);
			if(len > n)
				len = n;
			if(debug)
				fprint(2, "%I -> %I %d\n", ip->src, ip->dst, len);
			if(memcmp(e.s, target, 6) == 0){
				protopin[0]++;
				protoin[0] += len;
				if(ip->proto){
					protopin[ip->proto]++;
					protoin[ip->proto] += len;
				}
			}
			if(memcmp(e.d, target, 6) == 0){
				protopout[0]++;
				protoout[0] += len;
				if(ip->proto){
					protopout[ip->proto]++;
					protoout[ip->proto] += len;
				}
			}
		}
		if(ts - start >= delta){
			print("%8.8ld %ld", time(0), ts - start);
			printproto(0);
			printproto(IP_MBONEPROTO);
			printproto(IP_UDPPROTO);
			printproto(IP_TCPPROTO);
			print("\n");
			start = 0;
			memset(protoin, 0, sizeof(protoin));
			memset(protoout, 0, sizeof(protoout));
			memset(protopin, 0, sizeof(protopin));
			memset(protopout, 0, sizeof(protopout));
			close(fd);
			fd = -1;
			if(--samples == 0)
				break;
		}
	}
	exits(0);
}
Beispiel #30
0
void
threadmain(int argc, char *argv[])
{
	char *defsrv, *srvname;
	int p[2], fd;
	int stdio;
	char *host = nil;
	ulong mem;

	mem = 16<<20;
	stdio = 0;
	fmtinstall('H', encodefmt);
	fmtinstall('V', vtscorefmt);
	fmtinstall('F', vtfcallfmt);
	
	defmnt = nil;
	defsrv = nil;
	ARGBEGIN{
	case 'd':
		fmtinstall('F', fcallfmt);
		dflag = 1;
		break;
	case 'i':
		defmnt = nil;
		stdio = 1;
		mfd[0] = 0;
		mfd[1] = 1;
		break;
	case 'h':
		host = EARGF(usage());
		break;
	case 'S':
		defsrv = EARGF(usage());
		break;
	case 's':
		defsrv = "vacfs";
		break;
	case 'M':
		mem = unittoull(EARGF(usage()));
		break;
	case 'm':
		defmnt = EARGF(usage());
		break;
	case 'p':
		noperm = 1;
		break;
	case 'V':
		chattyventi = 1;
		break;
	default:
		usage();
	}ARGEND

	if(argc != 1)
		usage();

#ifdef PLAN9PORT
	if(defsrv == nil && defmnt == nil && !stdio){
		srvname = strchr(argv[0], '/');
		if(srvname)
			srvname++;
		else
			srvname = argv[0];
		defsrv = vtmalloc(6+strlen(srvname)+1);
		strcpy(defsrv, "vacfs.");
		strcat(defsrv, srvname);
		if(strcmp(defsrv+strlen(defsrv)-4, ".vac") == 0)
			defsrv[strlen(defsrv)-4] = 0;
	}
#else
	if(defsrv == nil && defmnt == nil && !stdio)
		defmnt = "/n/vac";
#endif
	if(stdio && defmnt)
		sysfatal("cannot use -m with -i");

	initfcalls();

	notify(notifyf);
	user = getuser();

	conn = vtdial(host);
	if(conn == nil)
		sysfatal("could not connect to server: %r");

	if(vtconnect(conn) < 0)
		sysfatal("vtconnect: %r");

	fs = vacfsopen(conn, argv[0], VtOREAD, mem);
	if(fs == nil)
		sysfatal("vacfsopen: %r");

	if(!stdio){
		if(pipe(p) < 0)
			sysfatal("pipe failed: %r");
		mfd[0] = p[0];
		mfd[1] = p[0];
		srvfd = p[1];
#ifndef PLAN9PORT
		if(defsrv){
			srvname = smprint("/srv/%s", defsrv);
			fd = create(srvname, OWRITE|ORCLOSE, 0666);
			if(fd < 0)
				sysfatal("create %s: %r", srvname);
			if(fprint(fd, "%d", srvfd) < 0)
				sysfatal("write %s: %r", srvname);
			free(srvname);
		}
#endif
	}

#ifdef PLAN9PORT
	USED(fd);
	proccreate(srv, 0, 32 * 1024);
	if(!stdio && post9pservice(p[1], defsrv, defmnt) < 0)
		sysfatal("post9pservice");
#else
	procrfork(srv, 0, 32 * 1024, RFFDG|RFNAMEG|RFNOTEG);

	if(!stdio){
		close(p[0]);
		if(defmnt){
			if(mount(srvfd, -1, defmnt, MREPL|MCREATE, "") < 0)
				sysfatal("mount %s: %r", defmnt);
		}
	}
#endif
	threadexits(0);
}