Ejemplo n.º 1
0
int
colclean(Column *c)
{
	int i, clean;

	clean = TRUE;
	for(i=0; i<c->nw; i++)
		clean &= winclean(c->w[i], TRUE);
	return clean;
}
Ejemplo n.º 2
0
void
replywindow(Article *m)
{
	Biobuf *b;
	char *p, *ep, *q, tmp[40];
	int fd, copy;
	Article *reply;

	sprint(tmp, "%d/article", m->n);
	p = estrstrdup(dir, tmp);
	if((fd = open(p, OREAD)) < 0){
		free(p);	
		return;
	}
	free(p);

	reply = newpost();
	winopenbody(reply->w, OWRITE);
	b = emalloc(sizeof(*b));
	Binit(b, fd, OREAD);
	copy = 0;
	while(p = Brdline(b, '\n')){
		if(Blinelen(b)==1)
			break;
		ep = p+Blinelen(b);
		if(!isspace(*p)){
			copy = 0;
			if(cistrncmp(p, "newsgroups:", 11)==0){
				for(q=p+11; *q!='\n'; q++)
					if(*q==',')
						*q = ' ';
				copy = 1;
			}else if(cistrncmp(p, "subject:", 8)==0){
				if(!strstr(p, " Re:") && !strstr(p, " RE:") && !strstr(p, " re:")){
					p = skip(p, "subject:");
					ep[-1] = '\0';
					Bprint(reply->w->body, "Subject: Re: %s\n", p);
				}else
					copy = 1;
			}else if(cistrncmp(p, "message-id:", 11)==0){
				Bprint(reply->w->body, "References: ");
				p += 11;
				copy = 1;
			}
		}
		if(copy)
			Bwrite(reply->w->body, p, ep-p);
	}
	Bterm(b);
	close(fd);
	free(b);
	Bprint(reply->w->body, "\n");
	winclean(reply->w);
	winselect(reply->w, "$", 0);
}
Ejemplo n.º 3
0
void
wikithread(void *v)
{
	char tmp[40];
	Event *e;
	Wiki *w;

	w = v;

	if(w->isnew){
		sprint(tmp, "+new+%d", w->isnew);
		wikiname(w->win, tmp);
		if(w->arg){
			winopenbody(w->win, OWRITE);
			Bprint(w->win->body, "%s\n\n", w->arg);
		}
		winclean(w->win);
	}else if(!w->special){
		wikiget(w);
		wikiname(w->win, w->arg);
		if(w->addr)
			winselect(w->win, w->addr, 1);
	}
	fprint(w->win->ctl, "menu\n");
	wintagwrite(w->win, "Get History Diff New", 4+8+4+4);
	winclean(w->win);
		
	while(!w->dead && (e = recvp(w->win->cevent)))
		acmeevent(w, e);

	windormant(w->win);
	unlink(w);
	free(w->win);
	free(w->arg);
	free(w);
	threadexits(nil);
}
Ejemplo n.º 4
0
/* 
 * Show the first nshow messages in the window.
 * This depends on nntpfs presenting contiguously
 * numbered directories, and on the qid version being
 * the topmost numbered directory.
 */
void
dirwindow(Window *w)
{
	if((hi=gethi()) < 0)
		return;

	if(w->data < 0)
		w->data = winopenfile(w, "data");

	fprint(w->ctl, "dirty\n");
	
	winopenbody(w, OWRITE);
	lo = adddir(w->body, hi, 0, nshow);
	winclean(w);
}
Ejemplo n.º 5
0
void
mesgmenumark(Window *w, char *which, char *mark)
{
	char *buf;

	if(w->data < 0)
		w->data = winopenfile(w, "data");
	buf = name2regexp(deletedrx01, which);
	if(winsetaddr(w, buf, 1) && winsetaddr(w, "+0-#1", 1))	/* go to end of line */
		write(w->data, mark, strlen(mark));
	free(buf);
	close(w->data);
	close(w->addr);
	w->addr = w->data = -1;
	if(!mbox.dirty)
		winclean(w);
}
Ejemplo n.º 6
0
/* one new message has arrived, as mbox->tail */
void
mesgmenunew(Window *w, Message *mbox)
{
	Biobuf *b;

	winselect(w, "0", 0);
	w->data = winopenfile(w, "data");
	b = emalloc(sizeof(Biobuf));
	Binit(b, w->data, OWRITE);
	mesgmenu0(w, mbox, mbox->name, "", 0, b, 1, !shortmenu);
	Bterm(b);
	free(b);
	if(!mbox->dirty)
		winclean(w);
	/* select tag line plus following indented lines, but not final newline (it's distinctive) */
	winselect(w, "0/.*\\n((\t.*\\n)*\t.*)?/", 1);
	close(w->addr);
	close(w->data);
	w->addr = -1;
	w->data = -1;
}
Ejemplo n.º 7
0
void
rewritembox(Window *w, Message *mbox)
{
	Message *m, *next;
	char *deletestr, *t;
	int nopen;

	deletestr = estrstrdup("delete ", fsname);

	nopen = 0;
	for(m=mbox->head; m!=nil; m=next){
		next = m->next;
		if(m->deleted == 0)
			continue;
		if(m->opened){
			nopen++;
			continue;
		}
		if(m->writebackdel){
			/* messages deleted by plumb message are not removed again */
			t = estrdup(m->name);
			if(strlen(t) > 0)
				t[strlen(t)-1] = '\0';
			deletestr = egrow(deletestr, " ", t);
		}
		mesgmenudel(w, mbox, m);
		mesgdel(mbox, m);
	}
	if(write(mbox->ctlfd, deletestr, strlen(deletestr)) < 0)
		fprint(2, "Mail: warning: error removing mail message files: %r\n");
	free(deletestr);
	winselect(w, "0", 0);
	if(nopen == 0)
		winclean(w);
	mbox->dirty = 0;
}
Ejemplo n.º 8
0
void
wikiget(Wiki *w)
{
	char *p;
	int fd, normal;
	Biobuf *bin;

	fprint(w->win->ctl, "dirty\n");

	p = emalloc(strlen(w->arg)+8+1);
	strcpy(p, w->arg);
	normal = 1;
	if(p[strlen(p)-1] == '/'){
		normal = 0;
		strcat(p, "current");
	}else if(strlen(p)>8 && strcmp(p+strlen(p)-8, "/current")==0){
		normal = 0;
		w->arg[strlen(w->arg)-7] = '\0';
	}

	if((fd = open(p, OREAD)) < 0){
		fprint(2, "Wiki: cannot read %s: %r\n", p);
		winclean(w->win);
		return;
	}
	free(p);

	winopenbody(w->win, OWRITE);
	bin = emalloc(sizeof(*bin));
	Binit(bin, fd, OREAD);

	p = nil;
	if(!normal){
		if((p = Brdline(bin, '\n')) == nil){
			fprint(2, "Wiki: cannot read title: %r\n");
			winclean(w->win);
			close(fd);
			free(bin);
			return;
		}
		p[Blinelen(bin)-1] = '\0';
	}
	/* clear window */
	if(w->win->data < 0)
		w->win->data = winopenfile(w->win, "data");
	if(winsetaddr(w->win, ",", 0))
		write(w->win->data, "", 0);

	if(!normal)
		Bprint(w->win->body, "%s\n\n", p);

	while(p = Brdline(bin, '\n')){
		p[Blinelen(bin)-1] = '\0';
		if(normal)
			Bprint(w->win->body, "%s\n", p);
		else{
			if(p[0]=='D')
				w->time = strtoul(p+1, 0, 10);
			else if(p[0]=='#')
				Bprint(w->win->body, "%s\n", p+1);
		}
	}
	winclean(w->win);
	free(bin);
	close(fd);
}
Ejemplo n.º 9
0
void
threadmain(int argc, char *argv[])
{
	char *s, *name;
	char err[ERRMAX], *cmd;
	int i, newdir;
	Fmt fmt;

	doquote = needsrcquote;
	quotefmtinstall();

	/* open these early so we won't miss notification of new mail messages while we read mbox */
	if((plumbsendfd = plumbopenfid("send", OWRITE|OCEXEC)) == nil)
		fprint(2, "warning: open plumb/send: %r\n");
	if((plumbseemailfd = plumbopenfid("seemail", OREAD|OCEXEC)) == nil)
		fprint(2, "warning: open plumb/seemail: %r\n");
	if((plumbshowmailfd = plumbopenfid("showmail", OREAD|OCEXEC)) == nil)
		fprint(2, "warning: open plumb/showmail: %r\n");

	shortmenu = 0;
	srvname = "mail";
	ARGBEGIN{
	case 's':
		shortmenu = 1;
		break;
	case 'S':
		shortmenu = 2;
		break;
	case 'o':
		outgoing = EARGF(usage());
		break;
	case 'm':
		smprint(maildir, "%s/", EARGF(usage()));
		break;
	case 'n':
		srvname = EARGF(usage());
		break;
	default:
		usage();
	}ARGEND

	acmefs = nsmount("acme",nil);
	if(acmefs == nil)
		error("cannot mount acme: %r");
	mailfs = nsmount(srvname, nil);
	if(mailfs == nil)
		error("cannot mount %s: %r", srvname);

	name = "mbox";

	newdir = 1;
	if(argc > 0){
		i = strlen(argv[0]);
		if(argc>2 || i==0)
			usage();
		/* see if the name is that of an existing /mail/fs directory */
		if(argc==1 && argv[0][0] != '/' && ismaildir(argv[0])){
			name = argv[0];
			mboxname = estrdup(name);
			newdir = 0;
		}else{
			if(argv[0][i-1] == '/')
				argv[0][i-1] = '\0';
			s = strrchr(argv[0], '/');
			if(s == nil)
				mboxname = estrdup(argv[0]);
			else{
				*s++ = '\0';
				if(*s == '\0')
					usage();
				mailboxdir = argv[0];
				mboxname = estrdup(s);
			}
			if(argc > 1)
				name = argv[1];
			else
				name = mboxname;
		}
	}

	user = getenv("user");
	if(user == nil)
		user = "******";
	home = getenv("home");
	if(home == nil)
		home = getenv("HOME");
	if(home == nil)
		error("can't find $home");
	if(mailboxdir == nil)
		mailboxdir = estrstrdup(home, "/mail");
	if(outgoing == nil)
		outgoing = estrstrdup(mailboxdir, "/outgoing");

	mbox.ctlfd = fsopen(mailfs, estrstrdup(mboxname, "/ctl"), OWRITE);
	if(mbox.ctlfd == nil)
		error("can't open %s: %r", estrstrdup(mboxname, "/ctl"));

	fsname = estrdup(name);
	if(newdir && argc > 0){
		s = emalloc(5+strlen(mailboxdir)+strlen(mboxname)+strlen(name)+10+1);
		for(i=0; i<10; i++){
			sprint(s, "open %s/%s %s", mailboxdir, mboxname, fsname);
			if(fswrite(mbox.ctlfd, s, strlen(s)) >= 0)
				break;
			err[0] = '\0';
			errstr(err, sizeof err);
			if(strstr(err, "mbox name in use") == nil)
				error("can't create directory %s for mail: %s", name, err);
			free(fsname);
			fsname = emalloc(strlen(name)+10);
			sprint(fsname, "%s-%d", name, i);
		}
		if(i == 10)
			error("can't open %s/%s: %r", mailboxdir, mboxname);
		free(s);
	}

	s = estrstrdup(fsname, "/");
	mbox.name = estrstrdup(maildir, s);
	mbox.level= 0;
	readmbox(&mbox, maildir, s);
	home = getenv("home");
	if(home == nil)
		home = "/";

	wbox = newwindow();
	winname(wbox, mbox.name);
	wintagwrite(wbox, "Put Mail Delmesg ", 3+1+4+1+7+1);
	threadcreate(mainctl, wbox, STACK);

	fmtstrinit(&fmt);
	fmtprint(&fmt, "Mail");
	if(shortmenu)
		fmtprint(&fmt, " -%c", "sS"[shortmenu-1]);
	if(outgoing)
		fmtprint(&fmt, " -o %s", outgoing);
	fmtprint(&fmt, " %s", name);
	cmd = fmtstrflush(&fmt);
	if(cmd == nil)
		sysfatal("out of memory");
	winsetdump(wbox, "/acme/mail", cmd);
	mbox.w = wbox;

	mesgmenu(wbox, &mbox);
	winclean(wbox);

/*	wctlfd = open("/dev/wctl", OWRITE|OCEXEC);	/* for acme window */
	wctlfd = -1;
	cplumb = chancreate(sizeof(Plumbmsg*), 0);
	cplumbshow = chancreate(sizeof(Plumbmsg*), 0);
	if(strcmp(name, "mbox") == 0){
		/*
		 * Avoid creating multiple windows to send mail by only accepting
		 * sendmail plumb messages if we're reading the main mailbox.
		 */
		plumbsendmailfd = plumbopenfid("sendmail", OREAD|OCEXEC);
		cplumbsend = chancreate(sizeof(Plumbmsg*), 0);
		proccreate(plumbsendproc, nil, STACK);
		threadcreate(plumbsendthread, nil, STACK);
	}
	/* start plumb reader as separate proc ... */
	proccreate(plumbproc, nil, STACK);
	proccreate(plumbshowproc, nil, STACK);
	threadcreate(plumbshowthread, nil, STACK);
	fswrite(mbox.ctlfd, "refresh", 7);
	/* ... and use this thread to read the messages */
	plumbthread();
}
Ejemplo n.º 10
0
int
mesgopen(Message *mbox, char *dir, char *s, Message *mesg, int plumbed, char *digest)
{
	char *t, *u, *v;
	Message *m;
	char *direlem[10];
	int i, ndirelem, reuse;

	/* find white-space-delimited first word */
	for(t=s; *t!='\0' && !isspace(*t); t++)
		;
	u = emalloc(t-s+1);
	memmove(u, s, t-s);
	/* separate it on slashes */
	ndirelem = tokenizec(u, direlem, nelem(direlem), "/");
	if(ndirelem <= 0){
    Error:
		free(u);
		return 0;
	}
	if(plumbed){
		write(wctlfd, "top", 3);
		write(wctlfd, "current", 7);
	}
	/* open window for message */
	m = mesglookup(mbox, direlem[0], digest);
	if(m == nil)
		goto Error;
	if(mesg!=nil && m!=mesg)	/* string looked like subpart but isn't part of this message */
		goto Error;
	if(m->opened == 0){
		if(m->w == nil){
			reuse = 0;
			m->w = newwindow();
		}else{
			reuse = 1;
			/* re-use existing window */
			if(winsetaddr(m->w, "0,$", 1)){
				if(m->w->data < 0)
					m->w->data = winopenfile(m->w, "data");
				write(m->w->data, "", 0);
			}
		}
		v = estrstrdup(mbox->name, m->name);
		winname(m->w, v);
		free(v);
		if(!reuse){
			if(m->deleted)
				wintagwrite(m->w, "Q Reply all UnDelmesg Save ", 2+6+4+10+5);
			else
				wintagwrite(m->w, "Q Reply all Delmesg Save ", 2+6+4+8+5);
		}
		threadcreate(mesgctl, m, STACK);
		winopenbody(m->w, OWRITE);
		mesgload(m, dir, m->name, m->w);
		winclosebody(m->w);
		winclean(m->w);
		m->opened = 1;
		if(ndirelem == 1){
			free(u);
			return 1;
		}
	}
	if(ndirelem == 1 && plumbport(m->type, m->filename) <= 0){
		/* make sure dot is visible */
		ctlprint(m->w->ctl, "show\n");
		return 0;
	}
	/* walk to subpart */
	dir = estrstrdup(dir, m->name);
	for(i=1; i<ndirelem; i++){
		m = mesglookup(m, direlem[i], digest);
		if(m == nil)
			break;
		dir = egrow(dir, m->name, nil);
	}
	if(m != nil && plumbport(m->type, m->filename) > 0)
		plumb(m, dir);
	free(dir);
	free(u);
	return 1;
}
Ejemplo n.º 11
0
int
acmecmd(Article *m, Window *w, char *s)
{
	int n;
	Biobuf *b;

//fprint(2, "cmd %s\n", s);

	s = skip(s, "");

	if(iscmd(s, "Del")){
		if(m == nil){	/* don't close dir until messages close */
			if(mlist != nil){
				ctlprint(mlist->w->ctl, "show\n");
				return 1;
			}
			if(windel(w, 0))
				threadexitsall(nil);
			return 1;
		}else{
			if(windel(w, 0))
				m->dead = 1;
			return 1;
		}
	}
	if(m==nil && iscmd(s, "More")){
		s = skip(s, "More");
		if(n = atoi(s))
			nshow = n;

		if(w->data < 0)
			w->data = winopenfile(w, "data");
		winsetaddr(w, "$", 1);
	
		fprint(w->ctl, "dirty\n");

		b = emalloc(sizeof(*b));
		Binit(b, w->data, OWRITE);
		lo = adddir(b, lo, 0, nshow);
		Bterm(b);
		free(b);		
		winclean(w);
		winsetaddr(w, ".,", 0);
	}
	if(m!=nil && !m->ispost && iscmd(s, "Headers")){
		m->headers = !m->headers;
		fillmesgwindow(-1, m);
		return 1;
	}
	if(iscmd(s, "Newpost")){
		m = newpost();
		winopenbody(m->w, OWRITE);
		Bprint(m->w->body, "%s\nsubject: \n\n", group);
		winclean(m->w);
		winselect(m->w, "$", 0);
		return 1;
	}
	if(m!=nil && !m->ispost && iscmd(s, "Reply")){
		replywindow(m);
		return 1;
	}
//	if(m!=nil && iscmd(s, "Replymail")){
//		fprint(2, "no replymail yet\n");
//		return 1;
//	}
	if(iscmd(s, "Post")){
		mesgpost(m);
		return 1;
	}
	return 0;
}
Ejemplo n.º 12
0
int
mboxcommand(Window *w, char *s)
{
	char *args[10], **targs, *save;
	Window *sbox;
	Message *m, *next;
	int ok, nargs, i, j;
	CFid *searchfd;
	char buf[128], *res;

	nargs = tokenize(s, args, nelem(args));
	if(nargs == 0)
		return 0;
	if(strcmp(args[0], "Mail") == 0){
		if(nargs == 1)
			mkreply(nil, "Mail", "", nil, nil);
		else
			mkreply(nil, "Mail", args[1], nil, nil);
		return 1;
	}
	if(strcmp(s, "Del") == 0){
		if(mbox.dirty){
			mbox.dirty = 0;
			fprint(2, "mail: mailbox not written\n");
			return 1;
		}
		if(w != mbox.w){
			windel(w, 1);
			return 1;
		}
		ok = 1;
		for(m=mbox.head; m!=nil; m=next){
			next = m->next;
			if(m->w){
				if(windel(m->w, 0))
					m->w = nil;
				else
					ok = 0;
			}
		}
		for(m=replies.head; m!=nil; m=next){
			next = m->next;
			if(m->w){
				if(windel(m->w, 0))
					m->w = nil;
				else
					ok = 0;
			}
		}
		if(ok){
			windel(w, 1);
			removeupasfs();
			threadexitsall(nil);
		}
		return 1;
	}
	if(strcmp(s, "Put") == 0){
		rewritembox(wbox, &mbox);
		return 1;
	}
	if(strcmp(s, "Get") == 0){
		fswrite(mbox.ctlfd, "refresh", 7);
		return 1;
	}
	if(strcmp(s, "Delmesg") == 0){
		save = nil;
		if(nargs > 1)
			save = args[1];
		s = winselection(w);
		if(s == nil)
			return 1;
		nargs = 1;
		for(i=0; s[i]; i++)
			if(s[i] == '\n')
				nargs++;
		targs = emalloc(nargs*sizeof(char*));	/* could be too many for a local array */
		nargs = getfields(s, targs, nargs, 1, "\n");
		for(i=0; i<nargs; i++){
			if(!isdigit(targs[i][0]))
				continue;
			j = atoi(targs[i]);	/* easy way to parse the number! */
			if(j == 0)
				continue;
			snprint(buf, sizeof buf, "%s%d", mbox.name, j);
			delmesg(buf, nil, 1, save);
		}
		free(s);
		free(targs);
		return 1;
	}
	if(strcmp(s, "Search") == 0){
		if(nargs <= 1)
			return 1;
		s = estrstrdup(mboxname, "/search");
		searchfd = fsopen(mailfs, s, ORDWR);
		if(searchfd == nil)
			return 1;
		save = estrdup(args[1]);
		for(i=2; i<nargs; i++)
			save = eappend(save, " ", args[i]);
		fswrite(searchfd, save, strlen(save));
		fsseek(searchfd, 0, 0);
		j = fsread(searchfd, buf, sizeof buf - 1);
 		if(j == 0){
			fprint(2, "[%s] search %s: no results found\n", mboxname, save);
			fsclose(searchfd);
			free(save);
			return 1;
		}
		free(save);
		buf[j] = '\0';
		res = estrdup(buf);
		j = fsread(searchfd, buf, sizeof buf - 1);
		for(; j != 0; j = fsread(searchfd, buf, sizeof buf - 1), buf[j] = '\0')
			res = eappend(res, "", buf);
		fsclose(searchfd);

		sbox = newwindow();
		winname(sbox, s);
		free(s);
		threadcreate(mainctl, sbox, STACK);
		winopenbody(sbox, OWRITE);

		/* show results in reverse order */
		m = mbox.tail;
		save = nil;
		for(s=strrchr(res, ' '); s!=nil || save!=res; s=strrchr(res, ' ')){
			if(s != nil){
				save = s+1;
				*s = '\0';
			}
			else save = res;
			save = estrstrdup(save, "/");
			for(; m && strcmp(save, m->name) != 0; m=m->prev);
			free(save);
			if(m == nil)
				break;
			fsprint(sbox->body, "%s%s\n", m->name, info(m, 0, 0));
			m = m->prev;
		}
		free(res);
		winclean(sbox);
		winclosebody(sbox);
		return 1;
	}
	return 0;
}
Ejemplo n.º 13
0
Archivo: xfid.c Proyecto: fr1tz/nadir
void
xfidctlwrite(Xfid *x, Window *w)
{
	Fcall fc;
	int i, m, n, nb, nr, nulls;
	Rune *r;
	char *err, *p, *pp, *q, *e;
	int isfbuf, scrdraw, settag;
	Text *t;

	err = nil;
	e = x->fcall.data+x->fcall.count;
	scrdraw = FALSE;
	settag = FALSE;
	isfbuf = TRUE;
	if(x->fcall.count < RBUFSIZE)
		r = fbufalloc();
	else{
		isfbuf = FALSE;
		r = emalloc(x->fcall.count*UTFmax+1);
	}
	x->fcall.data[x->fcall.count] = 0;
	textcommit(&w->tag, TRUE);
	for(n=0; n<x->fcall.count; n+=m){
		p = x->fcall.data+n;
		if(strncmp(p, "lock", 4) == 0){	/* make window exclusive use */
			qlock(&w->ctllock);
			w->ctlfid = x->f->fid;
			m = 4;
		}else
		if(strncmp(p, "unlock", 6) == 0){	/* release exclusive use */
			w->ctlfid = ~0;
			qunlock(&w->ctllock);
			m = 6;
		}else
		if(strncmp(p, "clean", 5) == 0){	/* mark window 'clean', seq=0 */
			t = &w->body;
			t->eq0 = ~0;
			filereset(t->file);
			t->file->mod = FALSE;
			w->dirty = FALSE;
			settag = TRUE;
			m = 5;
		}else
		if(strncmp(p, "dirty", 5) == 0){	/* mark window 'dirty' */
			t = &w->body;
			/* doesn't change sequence number, so "Put" won't appear.  it shouldn't. */
			t->file->mod = TRUE;
			w->dirty = TRUE;
			settag = TRUE;
			m = 5;
		}else
		if(strncmp(p, "show", 4) == 0){	/* show dot */
			t = &w->body;
			textshow(t, t->q0, t->q1, 1);
			m = 4;
		}else
		if(strncmp(p, "name ", 5) == 0){	/* set file name */
			pp = p+5;
			m = 5;
			q = memchr(pp, '\n', e-pp);
			if(q==nil || q==pp){
				err = Ebadctl;
				break;
			}
			*q = 0;
			nulls = FALSE;
			cvttorunes(pp, q-pp, r, &nb, &nr, &nulls);
			if(nulls){
				err = "nulls in file name";
				break;
			}
			for(i=0; i<nr; i++)
				if(r[i] <= ' '){
					err = "bad character in file name";
					goto out;
				}
out:
			seq++;
			filemark(w->body.file);
			winsetname(w, r, nr);
			m += (q+1) - pp;
		}else
		if(strncmp(p, "dump ", 5) == 0){	/* set dump string */
			pp = p+5;
			m = 5;
			q = memchr(pp, '\n', e-pp);
			if(q==nil || q==pp){
				err = Ebadctl;
				break;
			}
			*q = 0;
			nulls = FALSE;
			cvttorunes(pp, q-pp, r, &nb, &nr, &nulls);
			if(nulls){
				err = "nulls in dump string";
				break;
			}
			w->dumpstr = runetobyte(r, nr);
			m += (q+1) - pp;
		}else
		if(strncmp(p, "dumpdir ", 8) == 0){	/* set dump directory */
			pp = p+8;
			m = 8;
			q = memchr(pp, '\n', e-pp);
			if(q==nil || q==pp){
				err = Ebadctl;
				break;
			}
			*q = 0;
			nulls = FALSE;
			cvttorunes(pp, q-pp, r, &nb, &nr, &nulls);
			if(nulls){
				err = "nulls in dump directory string";
				break;
			}
			w->dumpdir = runetobyte(r, nr);
			m += (q+1) - pp;
		}else
		if(strncmp(p, "delete", 6) == 0){	/* delete for sure */
			colclose(w->col, w, TRUE);
			m = 6;
		}else
		if(strncmp(p, "del", 3) == 0){	/* delete, but check dirty */
			if(!winclean(w, TRUE)){
				err = "file dirty";
				break;
			}
			colclose(w->col, w, TRUE);
			m = 3;
		}else
		if(strncmp(p, "get", 3) == 0){	/* get file */
			get(&w->body, nil, nil, FALSE, XXX, nil, 0);
			m = 3;
		}else
		if(strncmp(p, "put", 3) == 0){	/* put file */
			put(&w->body, nil, nil, XXX, XXX, nil, 0);
			m = 3;
		}else
		if(strncmp(p, "dot=addr", 8) == 0){	/* set dot */
			textcommit(&w->body, TRUE);
			clampaddr(w);
			w->body.q0 = w->addr.q0;
			w->body.q1 = w->addr.q1;
			textsetselect(&w->body, w->body.q0, w->body.q1);
			settag = TRUE;
			m = 8;
		}else
		if(strncmp(p, "addr=dot", 8) == 0){	/* set addr */
			w->addr.q0 = w->body.q0;
			w->addr.q1 = w->body.q1;
			m = 8;
		}else
		if(strncmp(p, "limit=addr", 10) == 0){	/* set limit */
			textcommit(&w->body, TRUE);
			clampaddr(w);
			w->limit.q0 = w->addr.q0;
			w->limit.q1 = w->addr.q1;
			m = 10;
		}else
		if(strncmp(p, "nomark", 6) == 0){	/* turn off automatic marking */
			w->nomark = TRUE;
			m = 6;
		}else
		if(strncmp(p, "mark", 4) == 0){	/* mark file */
			seq++;
			filemark(w->body.file);
			settag = TRUE;
			m = 4;
		}else
		if(strncmp(p, "nomenu", 6) == 0){	/* turn off automatic menu */
			w->filemenu = FALSE;
			m = 6;
		}else
		if(strncmp(p, "menu", 4) == 0){	/* enable automatic menu */
			w->filemenu = TRUE;
			m = 4;
		}else
		if(strncmp(p, "noscroll", 8) == 0){	/* turn off automatic scrolling */
			w->noscroll = TRUE;
			m = 8;
		}else
		if(strncmp(p, "cleartag", 8) == 0){	/* wipe tag right of bar */
			wincleartag(w);
			settag = TRUE;
			m = 8;
		}else
		if(strncmp(p, "scroll", 6) == 0){	/* turn on automatic scrolling (writes to body only) */
			w->noscroll = FALSE;
			m = 6;
		}else{
			err = Ebadctl;
			break;
		}
		while(p[m] == '\n')
			m++;
	}

	if(isfbuf)
		fbuffree(r);
	else
		free(r);
	if(err)
		n = 0;
	fc.count = n;
	respond(x, &fc, err);
	if(settag)
		winsettag(w);
	if(scrdraw)
		textscrdraw(&w->body);
}
Ejemplo n.º 14
0
void
mkreply(Message *m, char *label, char *to, Plumbattr *attr, char *quotetext)
{
	char buf[100];
	CFid *fd;
	Message *r;
	char *dir, *t;
	int quotereply;
	Plumbattr *a;

	quotereply = (label[0] == 'Q');
	
	if(quotereply && m && m->replywinid > 0){
		snprint(buf, sizeof buf, "%d/body", m->replywinid);
		if((fd = fsopen(acmefs, buf, OWRITE)) != nil){
			dir = estrstrdup(mbox.name, m->name);
			quote(m, fd, dir, quotetext);
			free(dir);
			return;
		}
	}
	
	r = emalloc(sizeof(Message));
	r->isreply = 1;
	if(m != nil)
		r->replyname = estrdup(m->name);
	r->next = replies.head;
	r->prev = nil;
	if(replies.head != nil)
		replies.head->prev = r;
	replies.head = r;
	if(replies.tail == nil)
		replies.tail = r;
	r->name = emalloc(strlen(mbox.name)+strlen(label)+10);
	sprint(r->name, "%s%s%d", mbox.name, label, ++replyid);
	r->w = newwindow();
	if(m)
		m->replywinid = r->w->id;
	winname(r->w, r->name);
	ctlprint(r->w->ctl, "cleartag");
	wintagwrite(r->w, "fmt Look Post Undo", 4+5+5+4);
	r->tagposted = 1;
	threadcreate(mesgctl, r, STACK);
	winopenbody(r->w, OWRITE);
	if(to!=nil && to[0]!='\0')
		fsprint(r->w->body, "%s\n", to);
	for(a=attr; a; a=a->next)
		fsprint(r->w->body, "%s: %s\n", a->name, a->value);
	dir = nil;
	if(m != nil){
		dir = estrstrdup(mbox.name, m->name);
		if(to == nil && attr == nil){
			/* Reply goes to replyto; Reply all goes to From and To and CC */
			if(strstr(label, "all") == nil)
				fsprint(r->w->body, "To: %s\n", m->replyto);
			else{	/* Replyall */
				if(strlen(m->from) > 0)
					fsprint(r->w->body, "To: %s\n", m->from);
				if(strlen(m->to) > 0)
					fsprint(r->w->body, "To: %s\n", m->to);
				if(strlen(m->cc) > 0)
					fsprint(r->w->body, "CC: %s\n", m->cc);
			}
		}
		if(strlen(m->subject) > 0){
			t = "Subject: Re: ";
			if(strlen(m->subject) >= 3)
				if(tolower(m->subject[0])=='r' && tolower(m->subject[1])=='e' && m->subject[2]==':')
					t = "Subject: ";
			fsprint(r->w->body, "%s%s\n", t, m->subject);
		}
		if(!quotereply){
			fsprint(r->w->body, "Include: %sraw\n", dir);
			free(dir);
		}
	}
	fsprint(r->w->body, "\n");
	if(m == nil)
		fsprint(r->w->body, "\n");
	else if(quotereply){
		quote(m, r->w->body, dir, quotetext);
		free(dir);
	}
	winclosebody(r->w);
	if(m==nil && (to==nil || to[0]=='\0'))
		winselect(r->w, "0", 0);
	else
		winselect(r->w, "$", 0);
	winclean(r->w);
	windormant(r->w);
}
Ejemplo n.º 15
0
void
mesgsend(Message *m)
{
	char *s, *body, *to;
	int i, j, h, n, natt, p[2];
	struct Exec *e;
	Channel *sync;
	int first, nfld, delit, ofd;
	char *copy, *fld[100], *now;

	body = winreadbody(m->w, &n);
	/* assemble to: list from first line, to: line, and cc: line */
	nto = 0;
	natt = 0;
	ncc = 0;
	nbcc = 0;
	first = 1;
	to = body;
	for(;;){
		for(s=to; *s!='\n'; s++)
			if(*s == '\0'){
				free(body);
				return;
			}
		if(s++ == to)	/* blank line */
			break;
		/* make copy of line to tokenize */
		copy = emalloc(s-to);
		memmove(copy, to, s-to);
		copy[s-to-1] = '\0';
		nfld = tokenizec(copy, fld, nelem(fld), ", \t");
		if(nfld == 0){
			free(copy);
			break;
		}
		n -= s-to;
		switch(h = whichheader(fld[0])){
		case TO:
		case FROM:
			delit = 1;
			commas(to+strlen(fld[0]), s-1);
			for(i=1; i<nfld && nto<nelem(tolist); i++)
				if(!addressed(fld[i]))
					tolist[nto++] = estrdup(fld[i]);
			break;
		case BCC:
			delit = 1;
			commas(to+strlen(fld[0]), s-1);
			for(i=1; i<nfld && nbcc<nelem(bcclist); i++)
				if(!addressed(fld[i]))
					bcclist[nbcc++] = estrdup(fld[i]);
			break;
		case CC:
			delit = 1;
			commas(to+strlen(fld[0]), s-1);
			for(i=1; i<nfld && ncc<nelem(cclist); i++)
				if(!addressed(fld[i]))
					cclist[ncc++] = estrdup(fld[i]);
			break;
		case ATTACH:
		case INCLUDE:
			delit = 1;
			for(i=1; i<nfld && natt<nelem(attlist); i++){
				attlist[natt] = estrdup(fld[i]);
				included[natt++] = (h == INCLUDE);
			}
			break;
		default:
			if(first){
				delit = 1;
				for(i=0; i<nfld && nto<nelem(tolist); i++)
					tolist[nto++] = estrdup(fld[i]);
			}else	/* ignore it */
				delit = 0;
			break;
		}
		if(delit){
			/* delete line from body */
			memmove(to, s, n+1);
		}else
			to = s;
		free(copy);
		first = 0;
	}

	ofd = open(outgoing, OWRITE|OCEXEC);	/* no error check necessary */
	if(ofd > 0){
		/* From dhog Fri Aug 24 22:13:00 EDT 2001 */
		now = ctime(time(0));
		seek(ofd, 0, 2);
		fprint(ofd, "From %s %s", user, now);
		fprint(ofd, "From: %s\n", user);
		fprint(ofd, "Date: %s", now);
		for(i=0; i<natt; i++)
			if(included[i])
				fprint(ofd, "Include: %s\n", attlist[i]);
			else
				fprint(ofd, "Attach: %s\n", attlist[i]);
		/* needed because mail is by default Latin-1 */
		fprint(ofd, "Content-Type: text/plain; charset=\"UTF-8\"\n");
		fprint(ofd, "Content-Transfer-Encoding: 8bit\n");
	}

	e = emalloc(sizeof(struct Exec));
	if(pipe(p) < 0)
		error("can't create pipe: %r");
	e->p[0] = p[0];
	e->p[1] = p[1];
	e->prog = unsharp("#9/bin/upas/marshal");
	e->argv = emalloc((1+1+2+4*natt+1)*sizeof(char*));
	e->argv[0] = estrdup("marshal");
	e->argv[1] = estrdup("-8");
	j = 2;
	if(m->replyname){
		e->argv[j++] = estrdup("-R");
		e->argv[j++] = estrstrdup(mbox.name, m->replyname);
	}
	for(i=0; i<natt; i++){
		if(included[i])
			e->argv[j++] = estrdup("-A");
		else
			e->argv[j++] = estrdup("-a");
		e->argv[j++] = estrdup(attlist[i]);
	}
	sync = chancreate(sizeof(int), 0);
	e->sync = sync;
	proccreate(execproc, e, EXECSTACK);
	recvul(sync);
	/* close(p[0]); */

	/* using marshal -8, so generate rfc822 headers */
	if(nto > 0){
		print2(p[1], ofd, "To: ");
		for(i=0; i<nto-1; i++)
			print2(p[1], ofd, "%s, ", tolist[i]);
		print2(p[1], ofd, "%s\n", tolist[i]);
	}
	if(ncc > 0){
		print2(p[1], ofd, "CC: ");
		for(i=0; i<ncc-1; i++)
			print2(p[1], ofd, "%s, ", cclist[i]);
		print2(p[1], ofd, "%s\n", cclist[i]);
	}
	if(nbcc > 0){
		print2(p[1], ofd, "BCC: ");
		for(i=0; i<nbcc-1; i++)
			print2(p[1], ofd, "%s, ", bcclist[i]);
		print2(p[1], ofd, "%s\n", bcclist[i]);
	}

	i = strlen(body);
	if(i > 0)
		write2(p[1], ofd, body, i, 1);

	/* guarantee a blank line, to ensure attachments are separated from body */
	if(i==0 || body[i-1]!='\n')
		write2(p[1], ofd, "\n\n", 2, 0);
	else if(i>1 && body[i-2]!='\n')
		write2(p[1], ofd, "\n", 1, 0);

	/* these look like pseudo-attachments in the "outgoing" box */
	if(ofd>0 && natt>0){
		for(i=0; i<natt; i++)
			if(included[i])
				fprint(ofd, "=====> Include: %s\n", attlist[i]);
			else
				fprint(ofd, "=====> Attach: %s\n", attlist[i]);
	}
	if(ofd > 0)
		write(ofd, "\n", 1);

	for(i=0; i<natt; i++)
		free(attlist[i]);
	close(ofd);
	close(p[1]);
	free(body);

	if(m->replyname != nil)
		mesgmenumark(mbox.w, m->replyname, "\t[replied]");
	if(m->name[0] == '/')
		s = estrdup(m->name);
	else
		s = estrstrdup(mbox.name, m->name);
	s = egrow(s, "-R", nil);
	winname(m->w, s);
	free(s);
	winclean(m->w);
	/* mark message unopened because it's no longer the original message */
	m->opened = 0;
}
Ejemplo n.º 16
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);
}
Ejemplo n.º 17
0
int
fillmesgwindow(int fd, Article *m)
{
	Biobuf *b;
	char *p, tmp[40];
	int i, inhdr, copy, xfd;
	Window *w;

	xfd = -1;
	if(fd == -1){
		sprint(tmp, "%d/article", m->n);
		p = estrstrdup(dir, tmp);
		if((xfd = open(p, OREAD)) < 0){
			free(p);	
			return 0;
		}
		free(p);
		fd = xfd;
	}

	w = m->w;
	if(w->data < 0)
		w->data = winopenfile(w, "data");
	if(winsetaddr(w, ",", 0))
		write(w->data, "", 0);

	winopenbody(m->w, OWRITE);
	b = emalloc(sizeof(*b));
	Binit(b, fd, OREAD);

	inhdr = 1;
	copy = 1;
	while(p = Brdline(b, '\n')){
		if(Blinelen(b)==1)
			inhdr = 0, copy=1;
		if(inhdr && !isspace(p[0])){
			copy = 1;
			if(!m->headers){
				if(cistrncmp(p, "from:", 5)==0){
					p[Blinelen(b)-1] = '\0';
					p = fixfrom(skip(p, "from:"));
					Bprint(m->w->body, "From: %s\n", p);
					free(p);
					copy = 0;
					continue;
				}
				for(i=0; i<nelem(skipheader); i++)
					if(cistrncmp(p, skipheader[i], strlen(skipheader[i]))==0)
						copy=0;
			}
		}
		if(copy)
			Bwrite(m->w->body, p, Blinelen(b));
	}
	Bterm(b);
	free(b);
	winclean(m->w);
	if(xfd != -1)
		close(xfd);
	return 1;
}