Beispiel #1
0
static char *
wraptls(void)
{
	TLSconn *c;
	Thumbprint *goodcerts;
	char *h, *err;
	int fd;
	uchar hash[SHA1dlen];

	goodcerts = nil;
	err = Giveup;
	c = mallocz(sizeof(*c), 1);
	if (c == nil)
		return err;

	fd = tlsClient(Bfildes(&bout), c);
	if (fd < 0) {
		syslog(0, "smtp", "tlsClient to %q: %r", ddomain);
		goto Out;
	}
	Bterm(&bout);
	Binit(&bout, fd, OWRITE);
	fd = dup(fd, Bfildes(&bin));
	Bterm(&bin);
	Binit(&bin, fd, OREAD);

	goodcerts = initThumbprints(smtpthumbs, smtpexclthumbs);
	if (goodcerts == nil) {
		syslog(0, "smtp", "bad thumbprints in %s", smtpthumbs);
		goto Out;
	}
	/* compute sha1 hash of remote's certificate, see if we know it */
	sha1(c->cert, c->certlen, hash, nil);
	if (!okThumbprint(hash, goodcerts)) {
		/* TODO? if not excluded, add hash to thumb list */
		h = malloc(2*sizeof hash + 1);
		if (h == nil)
			goto Out;
		enc16(h, 2*sizeof hash + 1, hash, sizeof hash);
		syslog(0, "smtp", "remote cert. has bad thumbprint: x509 sha1=%s server=%q",
			h, ddomain);
		free(h);
		goto Out;
	}
	syslog(0, "smtp", "started TLS to %q", ddomain);
	err = nil;
Out:
	if(goodcerts != nil)
		freeThumbprints(goodcerts);
	free(c->cert);
	free(c->sessionID);
	free(c);
	return err;
}
Beispiel #2
0
/*
 *  read a remote file
 */
int
readfile1(Node *node)
{
	Biobuf *bp;
	char buf[4*1024];
	long off;
	int n;
	int tries;

	if(changedir(node->parent) < 0)
		return -1;

	for(tries = 0; tries < 4; tries++){
		switch(data(OREAD, &bp, "RETR", s_to_c(node->remname))){
		case Extra:
			break;
		case TempFail:
			continue;
		default:
			return seterr(nosuchfile);
		}
		off = 0;
		while((n = read(Bfildes(bp), buf, sizeof buf)) > 0){
			if(filewrite(node, buf, off, n) != n){
				off = -1;
				break;
			}
			off += n;
		}
		if(off < 0)
			return -1;

		/* make sure a file gets created even for a zero length file */
		if(off == 0)
			filewrite(node, buf, 0, 0);

		close(Bfildes(bp));
		switch(getreply(&ctlin, msg, sizeof(msg), 0)){
		case Success:
			return off;
		case TempFail:
			continue;
		default:
			return seterr(nosuchfile);
		}
	}
	return seterr(nosuchfile);
}
Beispiel #3
0
/*
 *  send an x display location to the other side
 */
int
xlocsub(Biobuf *bp, uchar *sub, int n)
{
	char buf[64];
	char *term;
	char *p = buf;

	if(n < 1)
		return 0;
	if(sub[0] == 1){
		*p++ = Iac;
		*p++ = Sb;
		*p++ = opt[Xloc].code;
		*p++ = 0;
		term = getenv("XDISP");
		if(term == 0 || *term == 0)
			term = "unknown";
		strncpy(p, term, p - buf - 2);
		p += strlen(term);
		*p++ = Iac;
		*p++ = Se;
		return iwrite(Bfildes(bp), buf, p-buf);
	}
	return 0;
}
Beispiel #4
0
/*
 *  send terminal type to the other side
 */
int
termsub(Biobuf *bp, uchar *sub, int n)
{
	char buf[64];
	char *term;
	char *p = buf;

	if(n < 1)
		return 0;
	if(sub[0] == 1){
		*p++ = Iac;
		*p++ = Sb;
		*p++ = opt[Term].code;
		*p++ = 0;
		term = getenv("TERM");
		if(term == 0 || *term == 0)
			term = "p9win";
		strncpy(p, term, sizeof(buf) - (p - buf) - 2);
		buf[sizeof(buf)-2] = 0;
		p += strlen(p);
		*p++ = Iac;
		*p++ = Se;
		return iwrite(Bfildes(bp), buf, p-buf);
	}
	return 0;
}
Beispiel #5
0
int
menu(Biobuf *bp, int net)
{
	char *cp;
	int done;

	comm->stopped = 1;

	rawoff();
	fprint(2, ">>> ");
	for(done = 0; !done; ){
		cp = Brdline(bp, '\n');
		if(cp == 0){
			comm->stopped = 0;
			return -1;
		}
		cp[Blinelen(bp)-1] = 0;
		switch(*cp){
		case '!':
			system(Bfildes(bp), cp+1);
			done = 1;
			break;
		case '.':
			done = 1;
			break;
		case 'q':
			comm->stopped = 0;
			return -1;
		case 'o':
			switch(*(cp+1)){
			case 'd':
				send3(net, Iac, Do, atoi(cp+2));
				break;
			case 'w':
				send3(net, Iac, Will, atoi(cp+2));
				break;
			}
			break;
		case 'r':
			comm->returns = !comm->returns;
			done = 1;
			break;
		case 'i':
			send2(net, Iac, Interrupt);
			break;
		case 'b':
			send2(net, Iac, Break);
			break;
		default:
			fprint(2, STDHELP);
			break;
		}
		if(!done)
			fprint(2, ">>> ");
	}

	rawon();
	comm->stopped = 0;
	return 0;
}
Beispiel #6
0
void
contentinit(void)
{
	static Biobuf *b = nil;
	static Qid qid;
	char *file, *s;
	Suffix *this;

	file = "/sys/lib/mimetype";
	if(b == nil){ /* first time */
		b = Bopen(file, OREAD);
		if(b == nil)
			sysfatal("can't read from %s", file);
	}
	if(updateQid(Bfildes(b), &qid) == 0)
		return;
	Bseek(b, 0, 0);
	while(suffixes!=nil){
		this = suffixes;
		suffixes = suffixes->next;
		free(this->suffix);
		free(this->generic);
		free(this->specific);
		free(this->encoding);
		free(this);
	}

	while((s = Brdline(b, '\n')) != nil){
		s[Blinelen(b) - 1] = 0;
		suffixes = parsesuffix(s, suffixes);
	}
}
Beispiel #7
0
/*
 *	Copy the file referenced by fd to the temp file
 */
void
armove(Biobuf *b, Arfile *ap, Armember *bp)
{
    char *cp;
    Dir *d;

    if ((d = dirfstat(Bfildes(b))) == nil) {
        fprint(2, "ar: cannot stat %s: %r\n", file);
        return;
    }
    trim(file, bp->hdr.name, sizeof(bp->hdr.name));
    for (cp = strchr(bp->hdr.name, 0);		/* blank pad on right */
            cp < bp->hdr.name+sizeof(bp->hdr.name); cp++)
        *cp = ' ';
    sprint(bp->hdr.date, "%-12ld", d->mtime);
    sprint(bp->hdr.uid, "%-6d", 0);
    sprint(bp->hdr.gid, "%-6d", 0);
    sprint(bp->hdr.mode, "%-8lo", d->mode);
    sprint(bp->hdr.size, "%-10lld", (vlong)d->length);
    strncpy(bp->hdr.fmag, ARFMAG, 2);
    bp->size = d->length;
    bp->date = d->mtime;
    arread(b, bp, bp->size);
    if (d->length&0x01)
        d->length++;
    if (ap) {
        arinsert(ap, bp);
        ap->size += d->length+SAR_HDR;
    }
    free(d);
}
Beispiel #8
0
/*
 *  return true if any part of the database has changed
 */
int
ndbchanged(struct ndb *db)
{
	/* TODO: implement me (no one calls this yet) */
	assert(0);
	return 0;
#if 0
	struct ndb *ndb;
	struct dir *d;

/* FIX ME */
	for(ndb = db; ndb != NULL; ndb = ndb->next){
		d = dirfstat(Bfildes(&ndb->b));
		if(d == NULL)
			continue;
		if(ndb->qid.path != d->qid.path
		|| ndb->qid.vers != d->qid.vers){
			free(d);
			return 1;
		}
		free(d);
	}
	return 0;
#endif
}
Beispiel #9
0
void
redirectinit(void)
{
	static Biobuf *b = nil;
	static Qid qid;
	char *file, *line, *s, *host, *field[3];
	static char pfx[] = "http://";

	file = "/sys/lib/httpd.rewrite";
	if(b != nil){
		if(updateQid(Bfildes(b), &qid) == 0)
			return;
		Bterm(b);
	}
	b = Bopen(file, OREAD);
	if(b == nil)
		sysfatal("can't read from %s", file);
	updateQid(Bfildes(b), &qid);

	cleartab(redirtab);
	cleartab(vhosttab);

	while((line = Brdline(b, '\n')) != nil){
		line[Blinelen(b)-1] = 0;
		s = strchr(line, '#');
		if(s != nil && (s == line || s[-1] == ' ' || s[-1] == '\t'))
			*s = '\0'; 	/* chop comment iff after whitespace */
		if(tokenize(line, field, nelem(field)) == 2){
			if(strncmp(field[0], pfx, STRLEN(pfx)) == 0 &&
			   strncmp(undecorated(field[1]), pfx, STRLEN(pfx)) != 0){
				/* url -> filename */
				host = field[0] + STRLEN(pfx);
				s = strrchr(host, '/');
				if(s)
					*s = 0;  /* chop trailing slash */

				insert(vhosttab, estrdup(host), estrdup(field[1]));
			}else{
				insert(redirtab, estrdup(field[0]), estrdup(field[1]));
			}
		}
	}
	syslog(0, HTTPLOG, "redirectinit pid=%d", getpid());
}
Beispiel #10
0
extern void
stream_free(stream *sp)
{
	int fd;

	close(sp->fd);
	fd = Bfildes(sp->fp);
	Bterm(sp->fp);
	close(fd);
	free((char *)sp);
}
Beispiel #11
0
void
starttls(void)
{
	int certlen, fd;
	uchar *cert;
	TLSconn *conn;

	if (tlscert == nil) {
		reply("500 5.5.1 illegal command or bad syntax\r\n");
		return;
	}
	conn = mallocz(sizeof *conn, 1);
	cert = readcert(tlscert, &certlen);
	if (conn == nil || cert == nil) {
		if (conn != nil)
			free(conn);
		reply("454 4.7.5 TLS not available\r\n");
		return;
	}
	reply("220 2.0.0 Go ahead make my day\r\n");
	conn->cert = cert;
	conn->certlen = certlen;
	fd = tlsServer(Bfildes(&bin), conn);
	if (fd < 0) {
		free(cert);
		free(conn);
		syslog(0, "smtpd", "TLS start-up failed with %s", him);

		/* force the client to hang up */
		close(Bfildes(&bin));		/* probably fd 0 */
		close(1);
		exits("tls failed");
	}
	Bterm(&bin);
	Binit(&bin, fd, OREAD);
	if (dup(fd, 1) < 0)
		fprint(2, "dup of %d failed: %r\n", fd);
	passwordinclear = 1;
	syslog(0, "smtpd", "started TLS with %s", him);
}
Beispiel #12
0
/*
 *  close the database files
 */
void
ndbclose(Ndb *db)
{
	Ndb *nextdb;

	for(; db; db = nextdb){
		nextdb = db->next;
		_ndbcacheflush(db);
		hffree(db);
		close(Bfildes(&db->b));
		Bterm(&db->b);
		free(db);
	}
}
Beispiel #13
0
int
eof(void)
{
	if(Bfildes(&(infile->Biobufhdr)) != 0)
		Bterm(&(infile->Biobufhdr));
	if(filesp > files)
		infile = *--filesp;
	else
	if(*argv)
		infile = opn(*argv++);
	else
		exits(0);
	return(C);
}
Beispiel #14
0
int
Bage(Biobuf *b)
{
	Dir *dir;
	int32_t mtime;

	dir = dirfstat(Bfildes(b));
	if(dir != nil)
		mtime = dir->mtime;
	else
		mtime = 0;
	free(dir);
	return time(nil) - mtime;
}
Beispiel #15
0
/* start a new process */
extern process *
noshell_proc_start(char **av, stream *inp, stream *outp, stream *errp, int newpg, char *who)
{
	process *pp;
	int i, n;

	if ((pp = (process *)malloc(sizeof(process))) == 0) {
		if (inp != 0)
			stream_free(inp);
		if (outp != 0)
			stream_free(outp);
		if (errp != 0)
			stream_free(errp);
		return 0;
	}
	pp->std[0] = inp;
	pp->std[1] = outp;
	pp->std[2] = errp;
	switch (pp->pid = fork()) {
	case -1:
		proc_free(pp);
		return 0;
	case 0:
		if(newpg)
			sysdetach();
		for (i=0; i<3; i++)
			if (pp->std[i] != 0){
				close(Bfildes(pp->std[i]->fp));
				while(pp->std[i]->fd < 3)
					pp->std[i]->fd = dup(pp->std[i]->fd, -1);
			}
		for (i=0; i<3; i++)
			if (pp->std[i] != 0)
				dup(pp->std[i]->fd, i);
		for (n = sysfiles(); i < n; i++)
			close(i);
		if(who)
			become(av, who);
		exec(av[0], av);
		perror("proc_start");
		exits("proc_start");
	default:
		for (i=0; i<3; i++)
			if (pp->std[i] != 0) {
				close(pp->std[i]->fd);
				pp->std[i]->fd = -1;
			}
		return pp;
	}
}
Beispiel #16
0
/*
 * process symbols in a file
 */
void
dofile(Biobuf *bp)
{
	int obj;

	obj = objtype(bp, 0);
	if (obj < 0)
		execsyms(Bfildes(bp));
	else
	if (readobj(bp, obj)) {
		nsym = 0;
		objtraverse(psym, 0);
		printsyms(symptr, nsym);
	}
}
Beispiel #17
0
/*
 *  write back a file
 */
int
createfile1(Node *node)
{
	Biobuf *bp;
	char buf[4*1024];
	long off;
	int n;

	if(changedir(node->parent) < 0)
		return -1;

	if(data(OWRITE, &bp, "STOR", s_to_c(node->remname)) != Extra)
		return -1;
	for(off = 0; ; off += n){
		n = fileread(node, buf, off, sizeof(buf));
		if(n <= 0)
			break;
		write(Bfildes(bp), buf, n);
	}
	close(Bfildes(bp));
	if(getreply(&ctlin, msg, sizeof(msg), 0) != Success)
		return -1;
	return off;
}
Beispiel #18
0
static String*
Brdstring(Biobuf *b)
{
	int32_t len;
	String *s;
	Dir *d;

	d = dirfstat(Bfildes(b));
	if (d == nil)	/* shouldn't happen, we just opened it */
		len = 0;
	else
		len = d->length;
	free(d);
	s = s_newalloc(len);
	s_read(b, s, len);
	return s;
}
Beispiel #19
0
/*
 *  return true if any part of the database has changed
 */
int
ndbchanged(Ndb *db)
{
	Ndb *ndb;
	Dir *d;

	for(ndb = db; ndb != nil; ndb = ndb->next){
		d = dirfstat(Bfildes(&ndb->b));
		if(d == nil)
			continue;
		if(ndb->qid.path != d->qid.path
		|| ndb->qid.vers != d->qid.vers){
			free(d);
			return 1;
		}
		free(d);
	}
	return 0;
}
Beispiel #20
0
/*
 *  exchange names with remote host, attempt to
 *  enable encryption and optionally authenticate.
 *  not fatal if we can't.
 */
static char *
dotls(char *me)
{
	TLSconn *c;
	char *err;
	int fd;

	c = mallocz(sizeof(*c), 1);	/* Note: not freed on success */
	if (c == nil)
		return Giveup;

	dBprint("STARTTLS\r\n");
	if (getreply() != 2)
		return Giveup;

	fd = tlsClient(Bfildes(&bout), c);
	if (fd < 0) {
		syslog(0, "smtp", "tlsClient to %q: %r", ddomain);
		return Giveup;
	}

	err = ckthumbs(c);
	if (err && !okunksecure) {
		free(c);
		close(fd);
		return err;		/* how to recover? TLS is started */
	}

	Bterm(&bin);
	Bterm(&bout);

	/*
	 * set up bin & bout to use the TLS fd, i/o upon which generates
	 * i/o on the original, underlying fd.
	 */
	Binit(&bin, fd, OREAD);
	fd = dup(fd, -1);
	Binit(&bout, fd, OWRITE);

	syslog(0, "smtp", "started TLS to %q", ddomain);
	return(hello(me, 1));
}
Beispiel #21
0
/*
 *  return true if any part of the database has changed
 */
int
ndbchanged(struct ndb *db)
{
	return 1;
#if 0
	struct ndb *ndb;
	struct dir *d;

/* FIX ME */
	for(ndb = db; ndb != NULL; ndb = ndb->next){
		d = dirfstat(Bfildes(&ndb->b));
		if(d == NULL)
			continue;
		if(ndb->qid.path != d->qid.path
		|| ndb->qid.vers != d->qid.vers){
			free(d);
			return 1;
		}
		free(d);
	}
	return 0;
#endif
}
Beispiel #22
0
/*
 *	extract the symbol references from an object file
 */
void
scanobj(Biobuf *b, Arfile *ap, int size)
{
    int obj;
    long offset;
    Dir *d;
    static int lastobj = -1;

    if (!allobj)			/* non-object file encountered */
        return;
    offset = Boffset(b);
    obj = objtype(b, 0);
    if (obj < 0) {			/* not an object file */
        allobj = 0;
        d = dirfstat(Bfildes(b));
        if (d != nil && d->length == 0)
            fprint(2, "ar: zero length file %s\n", file);
        free(d);
        Bseek(b, offset, 0);
        return;
    }
    if (lastobj >= 0 && obj != lastobj) {
        fprint(2, "ar: inconsistent object file %s\n", file);
        allobj = 0;
        Bseek(b, offset, 0);
        return;
    }
    lastobj = obj;
    if (!readar(b, obj, offset+size, 0)) {
        fprint(2, "ar: invalid symbol reference in file %s\n", file);
        allobj = 0;
        Bseek(b, offset, 0);
        return;
    }
    Bseek(b, offset, 0);
    objtraverse(objsym, ap);
}
Beispiel #23
0
/*
 *  dump any cached information, forget the hash tables, and reopen a single file
 */
int
ndbreopen(Ndb *db)
{
	int fd;
	Dir *d;

	/* forget what we know about the open files */
	if(db->mtime){
		_ndbcacheflush(db);
		hffree(db);
		close(Bfildes(&db->b));
		Bterm(&db->b);
		db->mtime = 0;
	}

	/* try the open again */
	fd = open(db->file, OREAD);
	if(fd < 0)
		return -1;
	d = dirfstat(fd);
	if(d == nil){
		close(fd);
		return -1;
	}

	/* no hashfile for /net/ndb (avoids deadlock in cs) */
	if(d->type == 'I')
		db->nohash = 1;

	db->qid = d->qid;
	db->mtime = d->mtime;
	db->length = d->length;
	Binits(&db->b, fd, OREAD, db->buf, sizeof(db->buf));
	free(d);
	return 0;
}
Beispiel #24
0
/*
 *  try a message
 */
void
dofile(Dir *dp)
{
	Dir *d;
	int dfd, ac, dtime, efd, pid, i, etime;
	char *buf, *cp, **av;
	Waitmsg *wm;
	Biobuf *b;
	Mlock *l = nil;

	if(debug)
		fprint(2, "dofile %s\n", dp->name);
	/*
	 *  if no data file or empty control or data file, just clean up
	 *  the empty control file must be 15 minutes old, to minimize the
	 *  chance of a race.
	 */
	d = dirstat(file(dp->name, 'D'));
	if(d == nil){
		syslog(0, runqlog, "no data file for %s", dp->name);
		remmatch(dp->name);
		return;
	}
	if(dp->length == 0){
		if(time(0)-dp->mtime > 15*60){
			syslog(0, runqlog, "empty ctl file for %s", dp->name);
			remmatch(dp->name);
		}
		return;
	}
	dtime = d->mtime;
	free(d);

	/*
	 *  retry times depend on the age of the errors file
	 */
	if(!Eflag && (d = dirstat(file(dp->name, 'E'))) != nil){
		etime = d->mtime;
		free(d);
		if(etime - dtime < 15*60){
			/* up to the first 15 minutes, every 30 seconds */
			if(time(0) - etime < 30)
				return;
		} else if(etime - dtime < 60*60){
			/* up to the first hour, try every 15 minutes */
			if(time(0) - etime < 15*60)
				return;
		} else {
			/* after the first hour, try once an hour */
			if(time(0) - etime < 60*60)
				return;
		}

	}

	/*
	 *  open control and data
	 */
	b = sysopen(file(dp->name, 'C'), "rl", 0660);
	if(b == 0) {
		if(debug)
			fprint(2, "can't open %s: %r\n", file(dp->name, 'C'));
		return;
	}
	dfd = open(file(dp->name, 'D'), OREAD);
	if(dfd < 0){
		if(debug)
			fprint(2, "can't open %s: %r\n", file(dp->name, 'D'));
		Bterm(b);
		sysunlockfile(Bfildes(b));
		return;
	}

	/*
	 *  make arg list
	 *	- read args into (malloc'd) buffer
	 *	- malloc a vector and copy pointers to args into it
	 */
	buf = malloc(dp->length+1);
	if(buf == 0){
		warning("buffer allocation", 0);
		Bterm(b);
		sysunlockfile(Bfildes(b));
		close(dfd);
		return;
	}
	if(Bread(b, buf, dp->length) != dp->length){
		warning("reading control file %s\n", dp->name);
		Bterm(b);
		sysunlockfile(Bfildes(b));
		close(dfd);
		free(buf);
		return;
	}
	buf[dp->length] = 0;
	av = malloc(2*sizeof(char*));
	if(av == 0){
		warning("argv allocation", 0);
		close(dfd);
		free(buf);
		Bterm(b);
		sysunlockfile(Bfildes(b));
		return;
	}
	for(ac = 1, cp = buf; *cp; ac++){
		while(isspace(*cp))
			*cp++ = 0;
		if(*cp == 0)
			break;

		av = realloc(av, (ac+2)*sizeof(char*));
		if(av == 0){
			warning("argv allocation", 0);
			close(dfd);
			free(buf);
			Bterm(b);
			sysunlockfile(Bfildes(b));
			return;
		}
		av[ac] = cp;
		while(*cp && !isspace(*cp)){
			if(*cp++ == '"'){
				while(*cp && *cp != '"')
					cp++;
				if(*cp)
					cp++;
			}
		}
	}
	av[0] = cmd;
	av[ac] = 0;

	if(!Eflag &&time(0) - dtime > giveup){
		if(returnmail(av, dp->name, "Giveup") != 0)
			logit("returnmail failed", dp->name, av);
		remmatch(dp->name);
		goto done;
	}

	for(i = 0; i < nbad; i++){
		if(strcmp(av[3], badsys[i]) == 0)
			goto done;
	}

	/*
	 * Ken's fs, for example, gives us 5 minutes of inactivity before
	 * the lock goes stale, so we have to keep reading it.
 	 */
	l = keeplockalive(file(dp->name, 'C'), Bfildes(b));

	/*
	 *  transfer
	 */
	pid = fork();
	switch(pid){
	case -1:
		sysunlock(l);
		sysunlockfile(Bfildes(b));
		syslog(0, runqlog, "out of procs");
		exits(0);
	case 0:
		if(debug) {
			fprint(2, "Starting %s", cmd);
			for(ac = 0; av[ac]; ac++)
				fprint(2, " %s", av[ac]);
			fprint(2, "\n");
		}
		logit("execing", dp->name, av);
		close(0);
		dup(dfd, 0);
		close(dfd);
		close(2);
		efd = open(file(dp->name, 'E'), OWRITE);
		if(efd < 0){
			if(debug) syslog(0, "runq", "open %s as %s: %r", file(dp->name,'E'), getuser());
			efd = create(file(dp->name, 'E'), OWRITE, 0666);
			if(efd < 0){
				if(debug) syslog(0, "runq", "create %s as %s: %r", file(dp->name, 'E'), getuser());
				exits("could not open error file - Retry");
			}
		}
		seek(efd, 0, 2);
		exec(cmd, av);
		error("can't exec %s", cmd);
		break;
	default:
		for(;;){
			wm = wait();
			if(wm == nil)
				error("wait failed: %r", "");
			if(wm->pid == pid)
				break;
			free(wm);
		}
		if(debug)
			fprint(2, "wm->pid %d wm->msg == %s\n", wm->pid, wm->msg);

		if(wm->msg[0]){
			if(debug)
				fprint(2, "[%d] wm->msg == %s\n", getpid(), wm->msg);
			syslog(0, runqlog, "message: %s\n", wm->msg);
			if(strstr(wm->msg, "Ignore") != nil){
				/* fix for fish/chips, leave message alone */
				logit("ignoring", dp->name, av);
			}else if(!Rflag && strstr(wm->msg, "Retry")==0){
				/* return the message and remove it */
				if(returnmail(av, dp->name, wm->msg) != 0)
					logit("returnmail failed", dp->name, av);
				remmatch(dp->name);
			} else {
				/* add sys to bad list and try again later */
				nbad++;
				badsys = realloc(badsys, nbad*sizeof(char*));
				badsys[nbad-1] = strdup(av[3]);
			}
		} else {
			/* it worked remove the message */
			remmatch(dp->name);
		}
		free(wm);

	}
done:
	if (l)
		sysunlock(l);
	Bterm(b);
	sysunlockfile(Bfildes(b));
	free(buf);
	free(av);
	close(dfd);
}
Beispiel #25
0
void
comline(void)
{
	long c1, c2;

	while(C==' ' || c=='\t')
		;
comx:
	if((c1=c) == '\n')
		return;
	c2 = C;
	if(c1=='.' && c2!='.')
		inmacro = NO;
	if(msflag && c1 == '['){
		refer(c2);
		return;
	}
	if(c2 == '\n')
		return;
	if(c1 == '\\' && c2 == '\"')
		SKIP;
	else
	if (filesp==files && c1=='E' && c2=='Q')
			eqn();
	else
	if(filesp==files && c1=='T' && (c2=='S' || c2=='C' || c2=='&')) {
		if(msflag)
			stbl(); 
		else
			tbl();
	}
	else
	if(c1=='T' && c2=='E')
		intable = NO;
	else if (!inmacro &&
			((c1 == 'd' && c2 == 'e') ||
		   	 (c1 == 'i' && c2 == 'g') ||
		   	 (c1 == 'a' && c2 == 'm')))
				macro();
	else
	if(c1=='s' && c2=='o') {
		if(iflag)
			SKIP;
		else {
			getfname();
			if(fname[0]) {
				if(infile = opn(fname))
					*++filesp = infile;
				else infile = *filesp;
			}
		}
	}
	else
	if(c1=='n' && c2=='x')
		if(iflag)
			SKIP;
		else {
			getfname();
			if(fname[0] == '\0')
				exits(0);
			if(Bfildes(&(infile->Biobufhdr)) != 0)
				Bterm(&(infile->Biobufhdr));
			infile = *filesp = opn(fname);
		}
	else
	if(c1 == 't' && c2 == 'm')
		SKIP;
	else
	if(c1=='h' && c2=='w')
		SKIP; 
	else
	if(msflag && c1 == 'T' && c2 == 'L') {
		SKIP_TO_COM;
		goto comx; 
	}
	else
	if(msflag && c1=='N' && c2 == 'R')
		SKIP;
	else
	if(msflag && c1 == 'A' && (c2 == 'U' || c2 == 'I')){
		if(mac==MM)SKIP;
		else {
			SKIP_TO_COM;
			goto comx; 
		}
	} else
	if(msflag && c1=='F' && c2=='S') {
		SKIP_TO_COM;
		goto comx; 
	}
	else
	if(msflag && (c1=='S' || c1=='N') && c2=='H') {
		SKIP_TO_COM;
		goto comx; 
	} else
	if(c1 == 'U' && c2 == 'X') {
		if(wordflag)
			Bprint(&(bout.Biobufhdr), "UNIX\n");
		else
			Bprint(&(bout.Biobufhdr), "UNIX ");
	} else
	if(msflag && c1=='O' && c2=='K') {
		SKIP_TO_COM;
		goto comx; 
	} else
	if(msflag && c1=='N' && c2=='D')
		SKIP;
	else
	if(msflag && mac==MM && c1=='H' && (c2==' '||c2=='U'))
		SKIP;
	else
	if(msflag && mac==MM && c2=='L') {
		if(disp || c1=='R')
			sdis('L', 'E');
		else {
			SKIP;
			Bprint(&(bout.Biobufhdr), " .");
		}
	} else
	if(!msflag && c1=='P' && c2=='S') {
		inpic();
	} else
	if(msflag && (c1=='D' || c1=='N' || c1=='K'|| c1=='P') && c2=='S') { 
		sdis(c1, 'E'); 
	} else
	if(msflag && (c1 == 'K' && c2 == 'F')) { 
		sdis(c1,'E'); 
	} else
	if(msflag && c1=='n' && c2=='f')
		sdis('f','i');
	else
	if(msflag && c1=='c' && c2=='e')
		sce();
	else {
		if(c1=='.' && c2=='.') {
			if(msflag) {
				SKIP;
				return;
			}
			while(C == '.')
				;
		}
		inmacro++;
		if(c1 <= 'Z' && msflag)
			regline(YES,ONE);
		else {
			if(wordflag)
				C;
			regline(YES,TWO);
		}
		inmacro--;
	}
}
Beispiel #26
0
void
main(int argc, char **argv)
{
	Ndbtuple *t, *nt;
	int n;
	Dir *d;	
	uint8_t buf[8];
	char file[128];
	int fd;
	uint32_t off;
	uint8_t *p;

	if(argc != 3){
		fprint(2, "usage: mkhash file attribute\n");
		exits("usage");
	}
	db = ndbopen(argv[1]);
	if(db == 0){
		fprint(2, "mkhash: can't open %s\n", argv[1]);
		exits(syserr());
	}

	/* try a bigger than normal buffer */
	Binits(&db->b, Bfildes(&db->b), OREAD, nbuf, sizeof(nbuf));

	/* count entries to calculate hash size */
	n = 0;

	while(nt = ndbparse(db)){
		for(t = nt; t; t = t->entry){
			if(strcmp(t->attr, argv[2]) == 0)
				n++;
		}
		ndbfree(nt);
	}

	/* allocate an array large enough for worst case */
	hlen = 2*n+1;
	n = hlen*NDBPLEN + hlen*2*NDBPLEN;
	ht = mallocz(n, 1);
	if(ht == 0){
		fprint(2, "mkhash: not enough memory\n");
		exits(syserr());
	}
	for(p = ht; p < &ht[n]; p += NDBPLEN)
		NDBPUTP(NDBNAP, p);
	nextchain = hlen*NDBPLEN;

	/* create the in core hash table */
	Bseek(&db->b, 0, 0);
	off = 0;
	while(nt = ndbparse(db)){
		for(t = nt; t; t = t->entry){
			if(strcmp(t->attr, argv[2]) == 0)
				enter(t->val, off);
		}
		ndbfree(nt);
		off = Boffset(&db->b);
	}

	/* create the hash file */
	snprint(file, sizeof(file), "%s.%s", argv[1], argv[2]);
	fd = create(file, ORDWR, 0664);
	if(fd < 0){
		fprint(2, "mkhash: can't create %s\n", file);
		exits(syserr());
	}
	NDBPUTUL(db->mtime, buf);
	NDBPUTUL(hlen, buf+NDBULLEN);
	if(write(fd, buf, NDBHLEN) != NDBHLEN){
		fprint(2, "mkhash: writing %s\n", file);
		exits(syserr());
	}
	if(write(fd, ht, nextchain) != nextchain){
		fprint(2, "mkhash: writing %s\n", file);
		exits(syserr());
	}
	close(fd);

	/* make sure file didn't change while we were making the hash */
	d = dirstat(argv[1]);
	if(d == nil || d->qid.path != db->qid.path
	   || d->qid.vers != db->qid.vers){
		fprint(2, "mkhash: %s changed underfoot\n", argv[1]);
		remove(file);
		exits("changed");
	}

	exits(0);
}
Beispiel #27
0
/*
 *	perform the 'r' and 'u' commands
 */
void
arcmd(char *arname, int count, char **files)
{
    int fd;
    int i;
    Arfile *ap;
    Armember *bp;
    Dir *d;
    Biobuf *bfile;

    fd = openar(arname, ORDWR, 1);
    if (fd >= 0) {
        Binit(&bar, fd, OREAD);
        Bseek(&bar,seek(fd,0,1), 1);
    }
    astart = newtempfile(artemp);
    ap = astart;
    aend = 0;
    for(i = 0; fd >= 0; i++) {
        bp = getdir(&bar);
        if (!bp)
            break;
        if (bamatch(file, poname)) {		/* check for pivot */
            aend = newtempfile(tailtemp);
            ap = aend;
        }
        /* pitch symdef file */
        if (i == 0 && strcmp(file, symdef) == 0) {
            skip(&bar, bp->size);
            continue;
        }
        if (count && !match(count, files)) {
            scanobj(&bar, ap, bp->size);
            arcopy(&bar, ap, bp);
            continue;
        }
        bfile = Bopen(file, OREAD);
        if (!bfile) {
            if (count != 0)
                fprint(2, "ar: cannot open %s\n", file);
            scanobj(&bar, ap, bp->size);
            arcopy(&bar, ap, bp);
            continue;
        }
        d = dirfstat(Bfildes(bfile));
        if (d == nil)
            fprint(2, "ar: cannot stat %s: %r\n", file);
        if (uflag && (d == nil || d->mtime <= bp->date)) {
            scanobj(&bar, ap, bp->size);
            arcopy(&bar, ap, bp);
            Bterm(bfile);
            free(d);
            continue;
        }
        mesg('r', file);
        skip(&bar, bp->size);
        scanobj(bfile, ap, d->length);
        free(d);
        armove(bfile, ap, bp);
        Bterm(bfile);
    }
    if(fd >= 0)
        close(fd);
    /* copy in remaining files named on command line */
    for (i = 0; i < count; i++) {
        file = files[i];
        if(file == 0)
            continue;
        files[i] = 0;
        bfile = Bopen(file, OREAD);
        if (!bfile)
            fprint(2, "ar: %s cannot open\n", file);
        else {
            mesg('a', file);
            d = dirfstat(Bfildes(bfile));
            if (d == nil)
                fprint(2, "ar: can't stat %s: %r\n", file);
            else {
                scanobj(bfile, astart, d->length);
                armove(bfile, astart, newmember());
                free(d);
            }
            Bterm(bfile);
        }
    }
    if(fd < 0 && !cflag)
        install(arname, astart, 0, aend, 1);	/* issue 'creating' msg */
    else
        install(arname, astart, 0, aend, 0);
}
Beispiel #28
0
void
extract(char *name, uint32_t mode, uint32_t mtime, char *uid,
	char *gid,
	uint64_t bytes)
{
	Dir d, *nd;
	Biobuf *b;
	char buf[LEN];
	char *p;
	uint32_t n;
	uint64_t tot;

	if(vflag)
		print("x %q %llu bytes\n", name, bytes);

	b = Bopen(name, OWRITE);
	if(!b){
		warn("can't make file %q: %r", name);
		seekpast(bytes);
		return;
	}
	for(tot = 0; tot < bytes; tot += n){
		n = sizeof buf;
		if(tot + n > bytes)
			n = bytes - tot;
		n = Bread(&bin, buf, n);
		if(n <= 0)
			error("premature eof reading %q", name);
		if(Bwrite(b, buf, n) != n)
			warn("error writing %q: %r", name);
	}

	nulldir(&d);
	p = utfrrune(name, '/');
	if(p)
		p++;
	else
		p = name;
	d.name = p;
	if(uflag){
		d.uid = uid;
		d.gid = gid;
	}
	if(Tflag)
		d.mtime = mtime;
	d.mode = mode;
	Bflush(b);
	if(dirfwstat(Bfildes(b), &d) < 0)
		warn("can't set modes for %q: %r", name);
	if(uflag||Tflag){
		if((nd = dirfstat(Bfildes(b))) == nil)
			warn("can't reread modes for %q: %r", name);
		else{
			if(Tflag && nd->mtime != mtime)
				warn("%q: time mismatch %lu %lu\n",
					name, mtime, nd->mtime);
			if(uflag && strcmp(uid, nd->uid))
				warn("%q: uid mismatch %q %q",
					name, uid, nd->uid);
			if(uflag && strcmp(gid, nd->gid))
				warn("%q: gid mismatch %q %q",
					name, gid, nd->gid);
			free(nd);
		}
	}
	Bterm(b);
}
Beispiel #29
0
void
mesgpost(Article *m)
{
	Biobuf *b;
	char *p, *ep;
	int isfirst, ishdr, havegroup, havefrom;

	p = estrstrdup(dir, "post");
	if((b = Bopen(p, OWRITE)) == nil){
		fprint(2, "cannot open %s: %r\n", p);
		free(p);
		return;
	}
	free(p);

	winopenbody(m->w, OREAD);
	ishdr = 1;
	isfirst = 1;
	havegroup = havefrom = 0;
	while(p = Brdline(m->w->body, '\n')){
		ep = p+Blinelen(m->w->body);
		if(ishdr && p+1==ep){
			if(!havegroup)
				Bprint(b, "Newsgroups: %s\n", group);
			if(!havefrom)
				Bprint(b, "From: %s\n", from);
			ishdr = 0;
		}
		if(ishdr){
			ep[-1] = '\0';
			if(isfirst && strchr(p, ':')==0){	/* group list */
				commas(p, ep);
				Bprint(b, "newsgroups: %s\n", p);
				havegroup = 1;
				isfirst = 0;
				continue;
			}
			if(cistrncmp(p, "newsgroup:", 10)==0){
				commas(skip(p, "newsgroup:"), ep);
				Bprint(b, "newsgroups: %s\n", skip(p, "newsgroup:"));
				havegroup = 1;
				continue;
			}
			if(cistrncmp(p, "newsgroups:", 11)==0){
				commas(skip(p, "newsgroups:"), ep);
				Bprint(b, "newsgroups: %s\n", skip(p, "newsgroups:"));
				havegroup = 1;
				continue;
			}
			if(cistrncmp(p, "from:", 5)==0)
				havefrom = 1;
			ep[-1] = '\n';
		}
		Bwrite(b, p, ep-p);
	}
	winclosebody(m->w);
	Bflush(b);
	if(write(Bfildes(b), "", 0) == 0)
		winclean(m->w);
	else
		fprint(2, "post: %r\n");
	Bterm(b);
}
Beispiel #30
0
/*
 *  read a remote directory
 */
int
readdir(Node *node)
{
	Biobuf *bp;
	char *line;
	Node *np;
	Dir *d;
	long n;
	int tries, x, files;
	static int uselist;
	int usenlist;
	String *remname;

	if(changedir(node) < 0)
		return -1;

	usenlist = 0;
	for(tries = 0; tries < 3; tries++){
		if(usenlist || usenlst)
			x = data(OREAD, &bp, "NLST", nil);
		else if(os == Unix && !uselist)
			x = data(OREAD, &bp, "LIST -l", nil);
		else
			x = data(OREAD, &bp, "LIST", nil);
		switch(x){
		case Extra:
			break;
/*		case TempFail:
			continue;
*/
		default:
			if(os == Unix && uselist == 0){
				uselist = 1;
				continue;
			}
			return seterr(nosuchfile);
		}
		files = 0;
		while(line = Brdline(bp, '\n')){
			n = Blinelen(bp);
			if(debug)
				write(2, line, n);
			if(n > 1 && line[n-2] == '\r')
				n--;
			line[n - 1] = 0;

			d = crackdir(line, &remname);
			if(d == nil)
				continue;
			files++;
			np = extendpath(node, remname);
			d->qid.path = np->d->qid.path;
			d->qid.vers = np->d->qid.vers;
			d->type = np->d->type;
			d->dev = 1;			/* mark node as valid */
			if(os == MVS && node == remroot){
				d->qid.type = QTDIR;
				d->mode |= DMDIR;
			}
			free(np->d);
			np->d = d;
		}
		close(Bfildes(bp));

		switch(getreply(&ctlin, msg, sizeof(msg), 0)){
		case Success:
			if(files == 0 && !usenlst && !usenlist){
				usenlist = 1;
				continue;
			}
			if(files && usenlist)
				usenlst = 1;
			if(usenlst)
				node->chdirunknown = 1;
			return 0;
		case TempFail:
			break;
		default:
			return seterr(nosuchfile);
		}
	}
	return seterr(nosuchfile);
}