Пример #1
0
void
initfontpaths(void)
{
    Biobufhdr *bp;
    char buf[128];
    char *s;
    int i;

    /* we don't care if getenv(2) fails */
    s = getenv("home");
    snprint(buf, sizeof(buf)-1, "%s/lib/abaco.fonts", s);
    free(s);
    if((bp=Bopen(buf, OREAD)) == nil)
        goto Default;

    for(i=0; i<NumFnt; i++)
        if((fontpaths[i]=Brdstr(bp, '\n', 1)) == nil)
            goto Error;

    Bterm(bp);
    return;
Error:
    fprint(2, "abaco: not enough fontpaths in '%s'\n", buf);
    Bterm(bp);
    for(i--; i>=0; i--)
        free(fontpaths[i]);
Default:
    for(i=0; i<NumFnt; i++)
        fontpaths[i] = deffontpaths[i];
}
Пример #2
0
static void
loadThumbprints(char *file, Thumbprint *table, Thumbprint *crltab)
{
	Thumbprint *entry;
	Biobuf *bin;
	char *line, *field[50];
	uchar sum[SHA1dlen];
	int i;

	bin = Bopen(file, OREAD);
	if(bin == nil)
		return;
	for(; (line = Brdstr(bin, '\n', 1)) != 0; free(line)){
		if(tokenize(line, field, nelem(field)) < 2)
			continue;
		if(strcmp(field[0], "#include") == 0){
			loadThumbprints(field[1], table, crltab);
			continue;
		}
		if(strcmp(field[0], "x509") != 0 || strncmp(field[1], "sha1=", strlen("sha1=")) != 0)
			continue;
		field[1] += strlen("sha1=");
		dec16(sum, sizeof(sum), field[1], strlen(field[1]));
		if(crltab && okThumbprint(sum, crltab))
			continue;
		entry = (Thumbprint*)emalloc(sizeof(*entry));
		memcpy(entry->sha1, sum, SHA1dlen);
		i = ((sum[0]<<8) + sum[1]) & (ThumbTab-1);
		entry->next = table[i].next;
		table[i].next = entry;
	}
	Bterm(bin);
}
Пример #3
0
static char*
pop3resp(Pop *pop)
{
	char *s;
	char *p;

	alarm(60*1000);
	if((s = Brdstr(&pop->bin, '\n', 0)) == nil){
		close(pop->fd);
		pop->fd = -1;
		alarm(0);
		return "unexpected eof";
	}
	alarm(0);

	p = s+strlen(s)-1;
	while(p >= s && (*p == '\r' || *p == '\n'))
		*p-- = '\0';

	if(pop->debug)
		fprint(2, "-> %s\n", s);
	free(pop->lastline);
	pop->lastline = s;
	return s;
}
Пример #4
0
static int
looksize(char *file, int64_t size, int *pixels, int *lines, int *chunk)
{
	Biobuf *bp;
	uint64_t l, p, c;
	char *s, *a[12];

	/*
	 * This may not always work, there could be an alias between file
	 * sizes of different standards stored in 8bits and 10 bits.
	 */
	if((bp = Bopen(file, OREAD)) == nil)
		return -1;
	while((s = Brdstr(bp, '\n', 1)) != nil){
		if(tokenize(s, a, nelem(a)) < 3)
			continue;
		if(a[0][0] == '#')
			continue;
		p = atoll(a[3]);
		l = atoll(a[5]);
		l += atoll(a[7]);
		c = 128 * ceil(p/48);
		if(l*c == size){
			*pixels = p;
			*lines = l;
			*chunk = c;
			break;
		}
	}
	Bterm(bp);
	if(s == nil)
		return -1;
	return 0;
}
Пример #5
0
Файл: pop3.c Проект: npe9/harvey
static int
retrcmd(char *arg)
{
	int n;
	Biobuf *b;
	char buf[40], *p;

	if(*arg == 0)
		return senderr("RETR requires a message number");
	n = atoi(arg)-1;
	if(n < 0 || n >= nmsg || msg[n].deleted)
		return senderr("no such message");
	snprint(buf, sizeof buf, "%d/raw", msg[n].upasnum);
	if((b = Bopen(buf, OREAD)) == nil)
		return senderr("message disappeared");
	sendok("");
	while((p = Brdstr(b, '\n', 1)) != nil){
		if(p[0]=='.')
			Bwrite(&out, ".", 1);
		Bwrite(&out, p, strlen(p));
		Bwrite(&out, "\r\n", 2);
		free(p);
	}
	Bterm(b);
	sendcrnl(".");
	return 0;
}
Пример #6
0
int
tline(Biobuf *bp, char **str, char **args, int max)
{
	char *s, *p;
	int q, dq, rc;

	do{
		s = Brdstr(bp, '\n', 10);
		if(s == nil)
			return -1;
		q = dq = 0;
		for(p = s; *p != 0; p++)
			if(*p == '\'')
				dq = !dq;
			else{
				if(dq){
					q = !q;
					dq = 0;
				}
				if(*p == '#' && !q){
					*p = 0;
					break;
				}
			}
		rc = tokenize(s, args, max);
	}while(rc == 0 && (free(s), 1));
	*str = s;
	return rc;
}
Пример #7
0
int
smtpread(Biobuf *b, int code)
{
	char *p, *q;
	int n;
	
	while((p = Brdstr(b, '\n', 1)) != nil) {
		n = strtol(p, &q, 10);
		if(n == 0 || q != p+3) {
		error:
			vtlogprint(errlog, "sending mail: %s\n", p);
			free(p);
			return -1;
		}
		if(*q == ' ') {
			if(n == code) {
				free(p);
				return 0;
			}
			goto error;
		}
		if(*q != '-') {
			goto error;
		}
	}
	return -1;
}
Пример #8
0
RSApub*
readpublickey(Biobuf *b, char **sp)
{
	char *s;
	RSApub *key;

	key = rsapuballoc();
	if(key == nil)
		return nil;

	for(;;){
		if((s = Brdstr(b, '\n', 1)) == nil){
			rsapubfree(key);
			return nil;
		}
		if(s[0]=='#'){
			free(s);
			continue;
		}
		if(parsepubkey(s, key, sp, 10)==0
		|| parsepubkey(s, key, sp, 16)==0)
			return key;
		fprint(2, "warning: skipping line '%s'; cannot parse\n", s);
		free(s);
	}
}
Пример #9
0
Файл: pop3.c Проект: npe9/harvey
static int
topcmd(char *arg)
{
	int done, i, lines, n;
	char buf[40], *p;
	Biobuf *b;

	if(*arg == 0)
		return senderr("TOP requires a message number");
	n = atoi(arg)-1;
	if(n < 0 || n >= nmsg || msg[n].deleted)
		return senderr("no such message");
	arg = nextarg(arg);
	if(*arg == 0)
		return senderr("TOP requires a line count");
	lines = atoi(arg);
	if(lines < 0)
		return senderr("bad args to TOP");
	snprint(buf, sizeof buf, "%d/raw", msg[n].upasnum);
	if((b = Bopen(buf, OREAD)) == nil)
		return senderr("message disappeared");
	sendok("");
	while(p = Brdstr(b, '\n', 1)){
		if(p[0]=='.')
			Bputc(&out, '.');
		Bwrite(&out, p, strlen(p));
		Bwrite(&out, "\r\n", 2);
		done = p[0]=='\0';
		free(p);
		if(done)
			break;
	}
	for(i=0; i<lines; i++){
		p = Brdstr(b, '\n', 1);
		if(p == nil)
			break;
		if(p[0]=='.')
			Bwrite(&out, ".", 1);
		Bwrite(&out, p, strlen(p));
		Bwrite(&out, "\r\n", 2);
		free(p);
	}
	sendcrnl(".");
	Bterm(b);
	return 0;
}
Пример #10
0
void
xwrite(int argc, char **argv)
{
	char buf[4096];
	int n, did;
	CFid *fid;
	Biobuf *b;
	char *p;
	int byline;

	byline = 0;
	ARGBEGIN{
	case 'l':
		byline = 1;
		break;
	default:
		usage();
	}ARGEND

	if(argc != 1)
		usage();

	did = 0;
	fid = xopen(argv[0], OWRITE|OTRUNC);
	if(byline){
		n = 0;
		b = malloc(sizeof *b);
		if(b == nil)
			sysfatal("out of memory");
		Binit(b, 0, OREAD);
		while((p = Brdstr(b, '\n', 0)) != nil){
			n = strlen(p);
			did = 1;
			if(fswrite(fid, p, n) != n)
				fprint(2, "write: %r\n");
		}
		free(b);
	}else{
		while((n = read(0, buf, sizeof buf)) > 0){
			did = 1;
			if(fswrite(fid, buf, n) != n)
				sysfatal("write error: %r");
		}
	}
	if(n == 0 && !did){
		if(fswrite(fid, buf, 0) != 0)
			sysfatal("write error: %r");
	}
	if(n < 0)
		sysfatal("read error: %r");
	fsclose(fid);
	threadexitsall(0);	
}
Пример #11
0
/*
 * 18. Insertions from the standard input
 */
void
r_rd(int argc, Rune **argv)
{
	char buf[100];
	char *s;
	Rune *p;
	Fmt fmt;
	static int didstdin;
	static Biobuf bstdin;
	
	/*
	 * print prompt, then read until double newline,
	 * then run the text just read as though it were
	 * a macro body, using the remaining arguments.
	 */
	if(fd2path(0, buf, sizeof buf) >= 0 && strstr(buf, "/dev/cons")){
		if(argc > 1)
			fprint(2, "%S", argv[1]);
		else
			fprint(2, "%c", 7/*BEL*/);
	}
	
	if(!didstdin){
		Binit(&bstdin, 0, OREAD);
		didstdin = 1;
	}
	runefmtstrinit(&fmt);
	while((s = Brdstr(&bstdin, '\n', 0)) != nil){
		if(s[0] == '\n'){
			free(s);
			break;
		}
		fmtprint(&fmt, "%s", s);
		free(s);
	}
	p = runefmtstrflush(&fmt);
	if(p == nil)
		warn("out of memory in %Crd", dot);
	ds(L(".rd"), p);
	argc--;
	argv++;
	argv[0] = L(".rd");
	runmacro('.', argc, argv);
	ds(L(".rd"), nil);
}
Пример #12
0
static void
_backtrace(int pid, char *btarg) {
	char *proc, *spid, *gdbcmd;
	int fd[3], p[2];
	int status, cmdfd;

	gdbcmd = estrdup("/tmp/gdbcmd.XXXXXX");
	if(pipe(p) < 0)
		goto done;
	closeexec(p[0]);

	cmdfd = mkstemp(gdbcmd);
	if(cmdfd < 0)
		goto done;

	fprint(cmdfd, "bt %s\n", btarg);
	fprint(cmdfd, "detach\n");
	close(cmdfd);

	fd[0] = open("/dev/null", O_RDONLY);
	fd[1] = p[1];
	fd[2] = dup(2);

	proc = sxprint("/proc/%d/" PROGTXT, pid);
	spid = sxprint("%d", pid);
	if(spawn3l(fd, "gdb", "gdb", "-batch", "-x", gdbcmd, proc, spid, nil) < 0) {
		unlink(gdbcmd);
		goto done;
	}

	Biobuf bp;
	char *s;

	Binit(&bp, p[0], OREAD);
	while((s = Brdstr(&bp, '\n', 1))) {
		Dprint(DStack, "%s\n", s);
		free(s);
	}
	unlink(gdbcmd);

done:
	free(gdbcmd);
	kill(pid, SIGKILL);
	waitpid(pid, &status, 0);
}
Пример #13
0
Файл: db.c Проект: 99years/plan9
Db*
opendb(char *file)
{
	char *f[10], *s, *t;
	int i, fd, nf;
	Biobuf b;
	Db *db;
	Entry e;

	if(file == nil)
		fd = -1;
	else if((fd = open(file, ORDWR)) < 0)
		sysfatal("opendb %s: %r", file);
	db = emalloc(sizeof(Db));
	db->avl = mkavltree(entrycmp);
	db->fd = fd;
	if(fd < 0)
		return db;
	Binit(&b, fd, OREAD);
	i = 0;
	for(; s=Brdstr(&b, '\n', 1); free(s)){
		t = estrdup(s);
		nf = tokenize(s, f, nelem(f));
		if(nf != 7)
			sysfatal("bad database entry '%s'", t);
		free(t);
		if(strcmp(f[2], "REMOVED") == 0)
			_removedb(db, f[0]);
		else{
			memset(&e, 0, sizeof e);
			e.name = atom(f[0]);
			e.d.name = atom(f[1]);
			if(strcmp(e.d.name, "-")==0)
				e.d.name = e.name;
			e.d.mode = strtoul(f[2], 0, 8);
			e.d.uid = atom(f[3]);
			e.d.gid = atom(f[4]);
			e.d.mtime = strtoul(f[5], 0, 10);
			e.d.length = strtoll(f[6], 0, 10);
			_insertdb(db, &e);
			i++;
		}
	}
	return db;
}
Пример #14
0
void
fmt(void)
{
	char *s;
	int i, nw;
	Word **w;

	nw = 0;
	w = nil;
	while((s = Brdstr(&bin, '\n', 1)) != nil){
		w = parseline(s, w, &nw);
		free(s);
	}
	printwords(w, nw);
	for(i=0; i<nw; i++)
		free(w[i]);
	free(w);
}
Пример #15
0
char*
readhttphdr(Biobuf *netbio, vlong *size)
{
	char *s, *stat;

	stat = nil;
	while((s = Brdstr(netbio, '\n', 1)) != nil && s[0] != '\r'
			&& s[0] != '\0'){
		if(stat == nil)
			stat = estrdup9p(s);
		if(strncmp(s, "Content-Length: ", 16) == 0 && size != nil)
			*size = atoll(s + 16);
		free(s);
	}
	if(stat)
		nocr(stat);

	return stat;
}
Пример #16
0
void
main(int argc, char* argv[])
{
    if(argc > 2)
    {
        fprint(2, "usage: %s [file]\n", argv[0]);
        exits("usage");
    }

	// Run script from file given as parameter instead of stdin if necesary
	if(argc == 2)
		redirect_stdin(argv[1]);

	// Allocate buffer for standard input
	Biobuf bin;
	if(Binit(&bin, 0, OREAD))
		sysfatal("%s: standard input: %r", argv0);

	tHeredoc heredoc;
	heredoc.mode = 0;

	// Main loop
	char* line;
	while((line = Brdstr(&bin, '\n', 0)))
	{
		// Process heredoc
		line = heredoc_process(&heredoc, line);
		if(line)
		{
		    // Process script
		    script_process(line);

		    // Free procesed line
		    free(line);
		}
	}

	// Free stdin buffer
	Bterm(&bin);

	// Exit sucesfully
	exits(nil);
}
Пример #17
0
void
loadexcludefile(char *file)
{
	Biobuf *b;
	char *p, *q;
	int n, inc;
	Reprog *re;

	if((b = Bopen(file, OREAD)) == nil)
		sysfatal("open %s: %r", file);
	for(n=1; (p=Brdstr(b, '\n', 1)) != nil; free(p), n++){
		q = p+strlen(p);
		while(q > p && isspace((uint8_t)*(q-1)))
			*--q = 0;
		switch(p[0]){
		case '\0':
		case '#':
			continue;
		}

		inc = 0;
		if(strncmp(p, "include ", 8) == 0){
			inc = 1;
		}else if(strncmp(p, "exclude ", 8) == 0){
			inc = 0;
		}else
			sysfatal("%s:%d: line does not begin with include or exclude", file, n);

		if(strchr(p+8, ' '))
			fprint(2, "%s:%d: warning: space in pattern\n", file, n);

		if((re = glob2regexp(p+8)) == nil)
			sysfatal("%s:%d: bad glob pattern", file, n);

		pattern = vtrealloc(pattern, (npattern+1)*sizeof pattern[0]);
		pattern[npattern].re = re;
		pattern[npattern].include = inc;
		npattern++;
	}
	Bterm(b);
}
Пример #18
0
RSApub*
readpublickey(Biobuf *b, char **sp)
{
	char *s;
	RSApub *key;

	key = emalloc9p(sizeof(RSApub));
	if(key == nil)
		return nil;

	for (; (s = Brdstr(b, '\n', 1)) != nil; free(s))
		if(s[0] != '#'){
			if(parsepubkey(s, key, sp, 10) == 0 ||
			    parsepubkey(s, key, sp, 16) == 0)
				return key;
			fprint(2, "warning: skipping line '%s'; cannot parse\n",
				s);
		}
	free(key);
	return nil;
}
Пример #19
0
/*
 * Are we actually allowed to look in here?
 *
 * Rules:
 *	1) If neither allowed nor denied files exist, access is granted.
 *	2) If allowed exists and denied does not, dir *must* be in allowed
 *	   for access to be granted, otherwise, access is denied.
 *	3) If denied exists and allowed does not, dir *must not* be in
 *	   denied for access to be granted, otherwise, access is enied.
 *	4) If both exist, okay if either (a) file is not in denied, or
 *	   (b) in denied and in allowed.  Otherwise, access is denied.
 */
static Reprog *
getre(Biobuf *buf)
{
	Reprog	*re;
	char	*p, *t;
	char	*bbuf;
	int	n;

	if (buf == nil)
		return(nil);
	for ( ; ; free(p)) {
		p = Brdstr(buf, '\n', 0);
		if (p == nil)
			return(nil);
		t = strchr(p, '#');
		if (t != nil)
			*t = '\0';
		t = p + strlen(p);
		while (--t > p && isspace(*t))
			*t = '\0';
		n = strlen(p);
		if (n == 0)
			continue;

		/* root the regular expresssion */
		bbuf = malloc(n+2);
		if(bbuf == nil)
			sysfatal("out of memory");
		bbuf[0] = '^';
		strcpy(bbuf+1, p);
		re = regcomp(bbuf);
		free(bbuf);

		if (re == nil)
			continue;
		free(p);
		return(re);
	}
}
Пример #20
0
static int
looksize(char *file, vlong size, int *pixels, int *lines, int *bits)
{
    Biobuf *bp;
    uvlong l, p;
    char *s, *a[12];

    /*
     * This may not always work, there could be an alias between file
     * sizes of different standards stored in 8bits and 10 bits.
     */
    if ((bp = Bopen(file, OREAD)) == nil)
        return -1;
    while((s = Brdstr(bp, '\n', 1)) != nil) {
        if (tokenize(s, a, nelem(a)) < 3)
            continue;
        if (a[0][0] == '#')
            continue;
        p = atoll(a[3]);
        l = atoll(a[5]);
        l += atoll(a[7]);
        if (l*p*2 == size) {
            *pixels = p;
            *lines = l;
            *bits = 8;
            break;
        }
        if ((l*p*20)/8 == size) {
            *pixels = p;
            *lines = l;
            *bits = 10;
            break;
        }
    }
    Bterm(bp);
    if (s == nil)
        return -1;
    return 0;
}
Пример #21
0
RSApriv*
getkey(int argc, char **argv, int needprivate, Attr **pa)
{
    char *file, *s, *p;
    int sz;
    RSApriv *key;
    Biobuf *b;
    int regen;
    Attr *a;

    if(argc == 0)
        file = "#d/0";
    else
        file = argv[0];

    key = mallocz(sizeof(RSApriv), 1);
    if(key == nil)
        return nil;

    if((b = Bopen(file, OREAD)) == nil) {
        werrstr("open %s: %r", file);
        return nil;
    }
    s = Brdstr(b, '\n', 1);
    if(s == nil) {
        werrstr("read %s: %r", file);
        return nil;
    }
    if(strncmp(s, "key ", 4) != 0) {
        werrstr("bad key format");
        return nil;
    }

    regen = 0;
    a = _parseattr(s+4);
    if(a == nil) {
        werrstr("empty key");
        return nil;
    }
    if((p = _strfindattr(a, "proto")) == nil) {
        werrstr("no proto");
        return nil;
    }
    if(strcmp(p, "rsa") != 0) {
        werrstr("proto not rsa");
        return nil;
    }
    if((p = _strfindattr(a, "ek")) == nil) {
        werrstr("no ek");
        return nil;
    }
    if((key->pub.ek = strtomp(p, &p, 16, nil)) == nil || *p != 0) {
        werrstr("bad ek");
        return nil;
    }
    if((p = _strfindattr(a, "n")) == nil) {
        werrstr("no n");
        return nil;
    }
    if((key->pub.n = strtomp(p, &p, 16, nil)) == nil || *p != 0) {
        werrstr("bad n");
        return nil;
    }
    if((p = _strfindattr(a, "size")) == nil)
        fprint(2, "warning: missing size; will add\n");
    else if((sz = strtol(p, &p, 10)) == 0 || *p != 0)
        fprint(2, "warning: bad size; will correct\n");
    else if(sz != mpsignif(key->pub.n))
        fprint(2, "warning: wrong size (got %d, expected %d); will correct\n",
               sz, mpsignif(key->pub.n));
    if(!needprivate)
        goto call;
    if((p = _strfindattr(a, "!dk")) == nil) {
        werrstr("no !dk");
        return nil;
    }
    if((key->dk = strtomp(p, &p, 16, nil)) == nil || *p != 0) {
        werrstr("bad !dk");
        return nil;
    }
    if((p = _strfindattr(a, "!p")) == nil) {
        werrstr("no !p");
        return nil;
    }
    if((key->p = strtomp(p, &p, 16, nil)) == nil || *p != 0) {
        werrstr("bad !p");
        return nil;
    }
    if((p = _strfindattr(a, "!q")) == nil) {
        werrstr("no !q");
        return nil;
    }
    if((key->q = strtomp(p, &p, 16, nil)) == nil || *p != 0) {
        werrstr("bad !q");
        return nil;
    }
    if((p = _strfindattr(a, "!kp")) == nil) {
        fprint(2, "warning: no !kp\n");
        regen = 1;
        goto regen;
    }
    if((key->kp = strtomp(p, &p, 16, nil)) == nil || *p != 0) {
        fprint(2, "warning: bad !kp\n");
        regen = 1;
        goto regen;
    }
    if((p = _strfindattr(a, "!kq")) == nil) {
        fprint(2, "warning: no !kq\n");
        regen = 1;
        goto regen;
    }
    if((key->kq = strtomp(p, &p, 16, nil)) == nil || *p != 0) {
        fprint(2, "warning: bad !kq\n");
        regen = 1;
        goto regen;
    }
    if((p = _strfindattr(a, "!c2")) == nil) {
        fprint(2, "warning: no !c2\n");
        regen = 1;
        goto regen;
    }
    if((key->c2 = strtomp(p, &p, 16, nil)) == nil || *p != 0) {
        fprint(2, "warning: bad !c2\n");
        regen = 1;
        goto regen;
    }
regen:
    if(regen) {
        RSApriv *k2;

        k2 = rsafill(key->pub.n, key->pub.ek, key->dk, key->p, key->q);
        if(k2 == nil) {
            werrstr("regenerating chinese-remainder parts failed: %r");
            return nil;
        }
        key = k2;
    }
call:
    a = _delattr(a, "ek");
    a = _delattr(a, "n");
    a = _delattr(a, "size");
    a = _delattr(a, "!dk");
    a = _delattr(a, "!p");
    a = _delattr(a, "!q");
    a = _delattr(a, "!c2");
    a = _delattr(a, "!kp");
    a = _delattr(a, "!kq");
    if(pa)
        *pa = a;
    return key;
}
Пример #22
0
Файл: main.c Проект: 8l/go-learn
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;

	quotefmtinstall();

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

	n = 0;
	av[n++] = "gcc";
	av[n++] = "-c";
	av[n++] = "-fdollars-in-identifiers";
	av[n++] = "-S";	// write assembly
	av[n++] = "-gstabs";	// include stabs info
	av[n++] = "-o-";	// to 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;

	// Run gcc writing assembly and stabs debugging to p[1].
	if(pipe(p) < 0)
		sysfatal("pipe: %r");

	pid = fork();
	if(pid < 0)
		sysfatal("fork: %r");
	if(pid == 0) {
		close(p[0]);
		dup(p[1], 1);
		if(argc == 0) {
			exec(av[0], av);
			fprint(2, "exec gcc: %r\n");
			exit(1);
		}
		// Some versions of gcc do not accept -S with multiple files.
		// Run gcc once for each file.
		close(0);
		open("/dev/null", OREAD);
		for(i=0; i<argc; i++) {
			pid = fork();
			if(pid < 0)
				sysfatal("fork: %r");
			if(pid == 0) {
				av[n-1] = argv[i];
				exec(av[0], av);
				fprint(2, "exec gcc: %r\n");
				exit(1);
			}
			waitpid();
		}
		exit(0);
	}
	close(p[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);
	waitpid();

	// 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++)
			Bprint(bout, lang->constfmt, con[i].name, con[i].value);
		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\n", lang->typdef, name, t);
			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];
				// 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%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);
}
Пример #23
0
DSApriv*
getdsakey(int argc, char **argv, int needprivate, Attr **pa)
{
    char *file, *s, *p;
    DSApriv *key;
    Biobuf *b;
    Attr *a;

    if(argc == 0)
        file = "#d/0";
    else
        file = argv[0];

    key = mallocz(sizeof(RSApriv), 1);
    if(key == nil)
        return nil;

    if((b = Bopen(file, OREAD)) == nil) {
        werrstr("open %s: %r", file);
        return nil;
    }
    s = Brdstr(b, '\n', 1);
    if(s == nil) {
        werrstr("read %s: %r", file);
        return nil;
    }
    if(strncmp(s, "key ", 4) != 0) {
        werrstr("bad key format");
        return nil;
    }

    a = _parseattr(s+4);
    if(a == nil) {
        werrstr("empty key");
        return nil;
    }
    if((p = _strfindattr(a, "proto")) == nil) {
        werrstr("no proto");
        return nil;
    }
    if(strcmp(p, "dsa") != 0) {
        werrstr("proto not dsa");
        return nil;
    }
    if((p = _strfindattr(a, "p")) == nil) {
        werrstr("no p");
        return nil;
    }
    if((key->pub.p = strtomp(p, &p, 16, nil)) == nil || *p != 0) {
        werrstr("bad p");
        return nil;
    }
    if((p = _strfindattr(a, "q")) == nil) {
        werrstr("no q");
        return nil;
    }
    if((key->pub.q = strtomp(p, &p, 16, nil)) == nil || *p != 0) {
        werrstr("bad q");
        return nil;
    }
    if((p = _strfindattr(a, "alpha")) == nil) {
        werrstr("no alpha");
        return nil;
    }
    if((key->pub.alpha = strtomp(p, &p, 16, nil)) == nil || *p != 0) {
        werrstr("bad alpha");
        return nil;
    }
    if((p = _strfindattr(a, "key")) == nil) {
        werrstr("no key=");
        return nil;
    }
    if((key->pub.key = strtomp(p, &p, 16, nil)) == nil || *p != 0) {
        werrstr("bad key=");
        return nil;
    }
    if(!needprivate)
        goto call;
    if((p = _strfindattr(a, "!secret")) == nil) {
        werrstr("no !secret");
        return nil;
    }
    if((key->secret = strtomp(p, &p, 16, nil)) == nil || *p != 0) {
        werrstr("bad !secret");
        return nil;
    }
call:
    a = _delattr(a, "p");
    a = _delattr(a, "q");
    a = _delattr(a, "alpha");
    a = _delattr(a, "key");
    a = _delattr(a, "!secret");
    if(pa)
        *pa = a;
    return key;
}
Пример #24
0
void
main(int argc, char **argv)
{ 
	char *f[10], *local, *name, *remote, *s, *t, verb;
	int fd, havedb, havelocal, i, k, n, nf, resolve1, skip;
	int checkedmatch1, checkedmatch2, 
		checkedmatch3, checkedmatch4;
	ulong now;
	Biobuf bin;
	Dir dbd, ld, nd, rd;
	Avlwalk *w;
	Entry *e;

	membogus(argv);
	quotefmtinstall();
	ARGBEGIN{
	case 's':
	case 'c':
		i = ARGC();
		addresolve(i, EARGF(usage()));
		break;
	case 'n':
		donothing = 1;
		verbose = 1;
		break;
	case 'S':
		safeinstall = 0;
		break;
	case 'T':
		timefile = EARGF(usage());
		break;
	case 't':
		tempspool = 0;
		break;
	case 'u':
		douid = 1;
		break;
	case 'v':
		verbose++;
		break;
	default:
		usage();
	}ARGEND

	if(argc < 3)
		usage();

	if(timefile)
		readtimefile();

	lroot = argv[1];
	if(!isdir(lroot))
		sysfatal("bad local root directory");
	rroot = argv[2];
	if(!isdir(rroot))
		sysfatal("bad remote root directory");

	match = argv+3;
	nmatch = argc-3;
	for(i=0; i<nmatch; i++)
		if(match[i][0] == '/')
			match[i]++;

	if((clientdb = opendb(argv[0])) == nil)
		sysfatal("opendb %q: %r", argv[2]);
	
	copyerr = opendb(nil);

	skip = 0;
	Binit(&bin, 0, OREAD);
	for(; s=Brdstr(&bin, '\n', 1); free(s)){
		t = estrdup(s);
		nf = tokenize(s, f, nelem(f));
		if(nf != 10 || strlen(f[2]) != 1){
			skip = 1;
			fprint(2, "warning: skipping bad log entry <%s>\n", t);
			free(t);
			continue;
		}
		free(t);
		now = strtoul(f[0], 0, 0);
		n = atoi(f[1]);
		verb = f[2][0];
		name = f[3];
		if(now < maxnow || (now==maxnow && n <= maxn))
			continue;
		local = mkname(localbuf, sizeof localbuf, lroot, name);
		if(strcmp(f[4], "-") == 0)
			f[4] = f[3];
		remote = mkname(remotebuf, sizeof remotebuf, rroot, f[4]);
		rd.name = f[4];
		rd.mode = strtoul(f[5], 0, 8);
		rd.uid = f[6];
		rd.gid = f[7];
		rd.mtime = strtoul(f[8], 0, 10);
		rd.length = strtoll(f[9], 0, 10);
		havedb = finddb(clientdb, name, &dbd)>=0;
		havelocal = localdirstat(local, &ld)>=0;

		resolve1 = resolve(name);

		/*
		 * if(!ismatch(name)){
		 *	skip = 1;
		 *	continue;
		 * }
		 * 
		 * This check used to be right here, but we want
		 * the time to be able to move forward past entries
		 * that don't match and have already been applied.
		 * So now every path below must checked !ismatch(name)
		 * before making any changes to the local file
		 * system.  The fake variable checkedmatch
		 * tracks whether !ismatch(name) has been checked.
		 * If the compiler doesn't produce any used/set
		 * warnings, then all the paths should be okay.
		 * Even so, we have the asserts to fall back on.
		 */
		switch(verb){
		case 'd':	/* delete file */
			delce(local);
			if(!havelocal)	/* doesn't exist; who cares? */
				break;
			if(access(remote, AEXIST) >= 0)	/* got recreated! */
				break;
			if(!ismatch(name)){
				skip = prstopped(skip, name);
				continue;
			}
			SET(checkedmatch1);
			if(!havedb){
				if(resolve1 == 's')
					goto DoRemove;
				else if(resolve1 == 'c')
					goto DoRemoveDb;
				conflict(name, "locally created; will not remove");
				skip = 1;
				continue;
			}
			assert(havelocal && havedb);
			if(dbd.mtime > rd.mtime)		/* we have a newer file than what was deleted */
				break;
			if(samecontents(local, remote) > 0){	/* going to get recreated */
				chat("= %q %luo %q %q %lud\n", name, rd.mode, rd.uid, rd.gid, rd.mtime);
				break;
			}
			if(!(dbd.mode&DMDIR) && (dbd.mtime != ld.mtime || dbd.length != ld.length)){	/* locally modified since we downloaded it */
				if(resolve1 == 's')
					goto DoRemove;
				else if(resolve1 == 'c')
					break;
				conflict(name, "locally modified; will not remove");
				skip = 1;
				continue;
			}
		    DoRemove:
			USED(checkedmatch1);
			assert(ismatch(name));
			chat("d %q %luo %q %q %lud\n", name, rd.mode, rd.uid, rd.gid, rd.mtime);
			if(donothing)
				break;
			if(remove(local) < 0){
				error("removing %q: %r", name);
				skip = 1;
				continue;
			}
		    DoRemoveDb:
			USED(checkedmatch1);
			assert(ismatch(name));
			removedb(clientdb, name);
			break;

		case 'a':	/* add file */
			if(!havedb){
				if(!ismatch(name)){
					skip = prstopped(skip, name);
					continue;
				}
				SET(checkedmatch2);
				if(!havelocal)
					goto DoCreate;
				if((ld.mode&DMDIR) && (rd.mode&DMDIR))
					break;
				if(samecontents(local, remote) > 0){
					chat("= %q %luo %q %q %lud\n", name, rd.mode, rd.uid, rd.gid, rd.mtime);
					goto DoCreateDb;
				}
				if(resolve1 == 's')
					goto DoCreate;
				else if(resolve1 == 'c')
					goto DoCreateDb;
				conflict(name, "locally created; will not overwrite");
				skip = 1;
				continue;
			}
			assert(havedb);
			if(dbd.mtime >= rd.mtime)	/* already created this file; ignore */
				break;
			if(havelocal){
				if((ld.mode&DMDIR) && (rd.mode&DMDIR))
					break;
				if(!ismatch(name)){
					skip = prstopped(skip, name);
					continue;
				}
				SET(checkedmatch2);
				if(samecontents(local, remote) > 0){
					chat("= %q %luo %q %q %lud\n", name, rd.mode, rd.uid, rd.gid, rd.mtime);
					goto DoCreateDb;
				}
				if(dbd.mtime==ld.mtime && dbd.length==ld.length)
					goto DoCreate;
				if(resolve1=='s')
					goto DoCreate;
				else if(resolve1 == 'c')
					goto DoCreateDb;
				conflict(name, "locally modified; will not overwrite");
				skip = 1;
				continue;
			}
			if(!ismatch(name)){
				skip = prstopped(skip, name);
				continue;
			}
			SET(checkedmatch2);
		    DoCreate:
			USED(checkedmatch2);
			assert(ismatch(name));
			if(notexists(remote)){
				addce(local);
				/* no skip=1 */
				break;;
			}
			chat("a %q %luo %q %q %lud\n", name, rd.mode, rd.uid, rd.gid, rd.mtime);
			if(donothing)
				break;
			if(rd.mode&DMDIR){
				fd = create(local, OREAD, DMDIR);
				if(fd < 0 && isdir(local))
					fd = open(local, OREAD);
				if(fd  < 0){
					error("mkdir %q: %r", name);
					skip = 1;
					continue;
				}
				nulldir(&nd);
				nd.mode = rd.mode;
				if(dirfwstat(fd, &nd) < 0)
					fprint(2, "warning: cannot set mode on %q\n", local);
				nulldir(&nd);
				nd.gid = rd.gid;
				if(dirfwstat(fd, &nd) < 0)
					fprint(2, "warning: cannot set gid on %q\n", local);
				if(douid){
					nulldir(&nd);
					nd.uid = rd.uid;
					if(dirfwstat(fd, &nd) < 0)
						fprint(2, "warning: cannot set uid on %q\n", local);
				}
				close(fd);
				rd.mtime = now;
			}else{
				if(copyfile(local, remote, name, &rd, 1, &k) < 0){
					if(k)
						addce(local);
					skip = 1;
					continue;
				}
			}
		    DoCreateDb:
			USED(checkedmatch2);
			assert(ismatch(name));
			insertdb(clientdb, name, &rd);
			break;
			
		case 'c':	/* change contents */
			if(!havedb){
				if(notexists(remote)){
					addce(local);
					/* no skip=1 */
					break;
				}
				if(!ismatch(name)){
					skip = prstopped(skip, name);
					continue;
				}
				SET(checkedmatch3);
				if(resolve1 == 's')
					goto DoCopy;
				else if(resolve1=='c')
					goto DoCopyDb;
				if(samecontents(local, remote) > 0){
					chat("= %q %luo %q %q %lud\n", name, rd.mode, rd.uid, rd.gid, rd.mtime);
					goto DoCopyDb;
				}
				if(havelocal)
					conflict(name, "locally created; will not update");
				else
					conflict(name, "not replicated; will not update");
				skip = 1;
				continue;
			}
			if(dbd.mtime >= rd.mtime)		/* already have/had this version; ignore */
				break;
			if(!ismatch(name)){
				skip = prstopped(skip, name);
				continue;
			}
			SET(checkedmatch3);
			if(!havelocal){
				if(notexists(remote)){
					addce(local);
					/* no skip=1 */
					break;
				}
				if(resolve1 == 's')
					goto DoCopy;
				else if(resolve1 == 'c')
					break;
				conflict(name, "locally removed; will not update");
				skip = 1;
				continue;
			}
			assert(havedb && havelocal);
			if(dbd.mtime != ld.mtime || dbd.length != ld.length){
				if(notexists(remote)){
					addce(local);
					/* no skip=1 */
					break;
				}
				if(samecontents(local, remote) > 0){
					chat("= %q %luo %q %q %lud\n", name, rd.mode, rd.uid, rd.gid, rd.mtime);
					goto DoCopyDb;
				}
				if(resolve1 == 's')
					goto DoCopy;
				else if(resolve1 == 'c')
					goto DoCopyDb;
				conflict(name, "locally modified; will not update [%llud %lud -> %llud %lud]", dbd.length, dbd.mtime, ld.length, ld.mtime);
				skip = 1;
				continue;
			}
		    DoCopy:
			USED(checkedmatch3);
			assert(ismatch(name));
			if(notexists(remote)){
				addce(local);
				/* no skip=1 */
				break;
			}
			chat("c %q\n", name);
			if(donothing)
				break;
			if(copyfile(local, remote, name, &rd, 0, &k) < 0){
				if(k)
					addce(local);
				skip = 1;
				continue;
			}
		    DoCopyDb:
			USED(checkedmatch3);
			assert(ismatch(name));
			if(!havedb){
				if(havelocal)
					dbd = ld;
				else
					dbd = rd;
			}
			dbd.mtime = rd.mtime;
			dbd.length = rd.length;
			insertdb(clientdb, name, &dbd);
			break;			

		case 'm':	/* change metadata */
			if(!havedb){
				if(notexists(remote)){
					addce(local);
					/* no skip=1 */
					break;
				}
				if(!ismatch(name)){
					skip = prstopped(skip, name);
					continue;
				}
				SET(checkedmatch4);
				if(resolve1 == 's'){
					USED(checkedmatch4);
					SET(checkedmatch2);
					goto DoCreate;
				}
				else if(resolve1 == 'c')
					goto DoMetaDb;
				if(havelocal)
					conflict(name, "locally created; will not update metadata");
				else
					conflict(name, "not replicated; will not update metadata");
				skip = 1;
				continue;
			}
			if(!(dbd.mode&DMDIR) && dbd.mtime > rd.mtime)		/* have newer version; ignore */
				break;
			if((dbd.mode&DMDIR) && dbd.mtime > now)
				break;
			if(havelocal && (!douid || strcmp(ld.uid, rd.uid)==0) && strcmp(ld.gid, rd.gid)==0 && ld.mode==rd.mode)
				break;
			if(!havelocal){
				if(notexists(remote)){
					addce(local);
					/* no skip=1 */
					break;
				}
				if(!ismatch(name)){
					skip = prstopped(skip, name);
					continue;
				}
				SET(checkedmatch4);
				if(resolve1 == 's'){
					USED(checkedmatch4);
					SET(checkedmatch2);
					goto DoCreate;
				}
				else if(resolve1 == 'c')
					break;
				conflict(name, "locally removed; will not update metadata");
				skip = 1;
				continue;
			}
			if(!(dbd.mode&DMDIR) && (dbd.mtime != ld.mtime || dbd.length != ld.length)){	/* this check might be overkill */
				if(notexists(remote)){
					addce(local);
					/* no skip=1 */
					break;
				}
				if(!ismatch(name)){
					skip = prstopped(skip, name);
					continue;
				}
				SET(checkedmatch4);
				if(resolve1 == 's' || samecontents(local, remote) > 0)
					goto DoMeta;
				else if(resolve1 == 'c')
					break;
				conflict(name, "contents locally modified (%s); will not update metadata to %s %s %luo",
					dbd.mtime != ld.mtime ? "mtime" :
					dbd.length != ld.length ? "length" : 
					"unknown",
					rd.uid, rd.gid, rd.mode);
				skip = 1;
				continue;
			}
			if((douid && strcmp(ld.uid, dbd.uid)!=0) || strcmp(ld.gid, dbd.gid)!=0 || ld.mode!=dbd.mode){
				if(notexists(remote)){
					addce(local);
					/* no skip=1 */
					break;
				}
				if(!ismatch(name)){
					skip = prstopped(skip, name);
					continue;
				}
				SET(checkedmatch4);
				if(resolve1 == 's')
					goto DoMeta;
				else if(resolve1 == 'c')
					break;
				conflict(name, "metadata locally changed; will not update metadata to %s %s %luo", rd.uid, rd.gid, rd.mode);
				skip = 1;
				continue;
			}
			if(!ismatch(name)){
				skip = prstopped(skip, name);
				continue;
			}
			SET(checkedmatch4);
		    DoMeta:
			USED(checkedmatch4);
			assert(ismatch(name));
			if(notexists(remote)){
				addce(local);
				/* no skip=1 */
				break;
			}
			chat("m %q %luo %q %q %lud\n", name, rd.mode, rd.uid, rd.gid, rd.mtime);
			if(donothing)
				break;
			nulldir(&nd);
			nd.gid = rd.gid;
			nd.mode = rd.mode;
			if(douid)
				nd.uid = rd.uid;
			if(dirwstat(local, &nd) < 0){
				error("dirwstat %q: %r", name);
				skip = 1;
				continue;
			}
		    DoMetaDb:
			USED(checkedmatch4);
			assert(ismatch(name));
			if(!havedb){
				if(havelocal)
					dbd = ld;
				else
					dbd = rd;
			}
			if(dbd.mode&DMDIR)
				dbd.mtime = now;
			dbd.gid = rd.gid;
			dbd.mode = rd.mode;
			if(douid)
				dbd.uid = rd.uid;
			insertdb(clientdb, name, &dbd);
			break;
		}
		if(!skip && !donothing){
			maxnow = now;
			maxn = n;
		}
	}

	w = avlwalk(copyerr->avl);
	while(e = (Entry*)avlnext(w))
		error("copying %q: %s\n", e->name, e->d.name);

	if(timefile)
		writetimefile();
	if(nconf)
		exits("conflicts");

	if(errors)
		exits("errors");
	exits(nil);
}