コード例 #1
0
ファイル: mesg.c プロジェクト: Requaos/harvey
/* add message to box, in increasing numerical order */
int
mesgadd(Message *mbox, char *dir, Dir *d, char *digest)
{
	Message *m;
	char *name;
	int loaded;

	m = emalloc(sizeof(Message));
	m->name = estrstrdup(d->name, "/");
	m->next = nil;
	m->prev = mbox->tail;
	m->level= mbox->level+1;
	m->recursed = 0;
	name = estrstrdup(dir, m->name);
	loaded = loadinfo(m, name);
	free(name);
	/* if two upas/fs are running, we can get misled, so check digest before accepting message */
	if(loaded==0 || (digest!=nil && m->digest!=nil && strcmp(digest, m->digest)!=0)){
		mesgfreeparts(m);
		free(m);
		return 0;
	}
	if(mbox->tail != nil)
		mbox->tail->next = m;
	mbox->tail = m;
	if(mbox->head == nil)
		mbox->head = m;

	if (m->level != 1){
		m->recursed = 1;
		readmbox(m, dir, m->name); 
	}
	return 1;
}
コード例 #2
0
ファイル: tester.c プロジェクト: 99years/plan9
void
main(int argc, char **argv)
{
	char *err;
	char *mboxfile;

	ARGBEGIN{
	}ARGEND;

	if(argc > 0)
		mboxfile = argv[0];
	else
		mboxfile = "./mbox";

	root = newmessage(nil);

	err = readmbox(mboxfile, &root->part);
	if(err != nil){
		fprint(2, "boom: %s\n", err);
		exits(0);
	}

	info(0, 1, root);

	exits(0);
}
コード例 #3
0
ファイル: pop3.c プロジェクト: npe9/harvey
static int
dologin(char *response)
{
	AuthInfo *ai;
	static int tries;
	static uint32_t delaysecs = 5;

	chs->user = user;
	chs->resp = response;
	chs->nresp = strlen(response);
	if((ai = auth_response(chs)) == nil){
		if(tries >= 20){
			senderr("authentication failed: %r; server exiting");
			exits(nil);
		}
		if(++tries == 3)
			syslog(0, "pop3", "likely password guesser from %s",
				peeraddr);
		delaysecs *= 2;
		if (delaysecs > 30*60)
			delaysecs = 30*60;		/* half-hour max. */
		sleep(delaysecs * 1000); /* prevent beating on our auth server */
		return senderr("authentication failed");
	}

	if(auth_chuid(ai, nil) < 0){
		senderr("chuid failed: %r; server exiting");
		exits(nil);
	}
	auth_freeAI(ai);
	auth_freechal(chs);
	chs = nil;

	loggedin = 1;
	if(newns(user, 0) < 0){
		senderr("newns failed: %r; server exiting");
		exits(nil);
	}
	syslog(0, "pop3", "user %s logged in", user);
	enableaddr();
	if(readmbox(box) < 0)
		exits(nil);
	return sendok("mailbox is %s", box);
}
コード例 #4
0
ファイル: mesg.c プロジェクト: Requaos/harvey
void
mesgload(Message *m, char *rootdir, char *file, Window *w)
{
	char *s, *subdir, *name, *dir;
	Message *mp, *thisone;
	int n;

	dir = estrstrdup(rootdir, file);

	if(strcmp(m->type, "message/rfc822") != 0){	/* suppress headers of envelopes */
		if(strlen(m->from) > 0){
			Bprint(w->body, "From: %s\n", m->from);
			mesgline(m, "Date", m->date);
			mesgline(m, "To", m->to);
			mesgline(m, "CC", m->cc);
			mesgline(m, "Subject", m->subject);
			printheader(dir, w->body, extraheaders);
		}else{
			printheader(dir, w->body, okheaders);
			printheader(dir, w->body, extraheaders);
		}
		Bprint(w->body, "\n");
	}

	if(m->level == 1 && m->recursed == 0){
		m->recursed = 1;
		readmbox(m, rootdir, m->name);
	}
	if(m->head == nil){	/* single part message */
		if(strcmp(m->type, "text")==0 || strncmp(m->type, "text/", 5)==0){
			mimedisplay(m, m->name, rootdir, w, 1);
			s = readbody(m->type, dir, &n);
			winwritebody(w, s, n);
			free(s);
		}else
			mimedisplay(m, m->name, rootdir, w, 0);
	}else{
		/* multi-part message, either multipart or message/rfc822 */
		thisone = nil;
		if(strcmp(m->type, "multipart/alternative") == 0){
			thisone = bestalt(m, dir);
			if(thisone == nil){
				thisone = m->head; /* in case we can't find a good one */
				for(mp=m->head; mp!=nil; mp=mp->next)
					if(isprintable(mp->type)){
						thisone = mp;
						break;
					}
			}
		}
		for(mp=m->head; mp!=nil; mp=mp->next){
			if(thisone!=nil && mp!=thisone)
				continue;
			subdir = estrstrdup(dir, mp->name);
			name = estrstrdup(file, mp->name);
			/* skip first element in name because it's already in window name */
			if(mp != m->head)
				Bprint(w->body, "\n===> %s (%s) [%s]\n",
					strchr(name, '/')+1, mp->type,
					mp->disposition);
			if(strcmp(mp->type, "text")==0 ||
			    strncmp(mp->type, "text/", 5)==0){
				mimedisplay(mp, name, rootdir, w, 1);
				printheader(subdir, w->body, okheaders);
				printheader(subdir, w->body, extraheaders);
				winwritebody(w, "\n", 1);
				s = readbody(mp->type, subdir, &n);
				winwritebody(w, s, n);
				free(s);
			}else{
				if(strncmp(mp->type, "multipart/", 10)==0 ||
				    strcmp(mp->type, "message/rfc822")==0){
					mp->w = w;
					mesgload(mp, rootdir, name, w);
					mp->w = nil;
				}else
					mimedisplay(mp, name, rootdir, w, 0);
			}
			free(name);
			free(subdir);
		}
	}
	free(dir);
}
コード例 #5
0
ファイル: mail.c プロジェクト: 00001/plan9port
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();
}
コード例 #6
0
ファイル: pop3.c プロジェクト: npe9/harvey
void
main(int argc, char **argv)
{
	int fd;
	char *arg, cmdbuf[1024];
	Cmd *c;

	rfork(RFNAMEG);
	Binit(&in, 0, OREAD);
	Binit(&out, 1, OWRITE);

	ARGBEGIN{
	case 'a':
		loggedin = 1;
		if(readmbox(EARGF(usage())) < 0)
			exits(nil);
		break;
	case 'd':
		debug++;
		if((fd = create(EARGF(usage()), OWRITE, 0666)) >= 0 && fd != 2){
			dup(fd, 2);
			close(fd);
		}
		break;
	case 'p':
		passwordinclear = 1;
		break;
	case 'r':
		strecpy(tmpaddr, tmpaddr+sizeof tmpaddr, EARGF(usage()));
		if(arg = strchr(tmpaddr, '!'))
			*arg = '\0';
		peeraddr = tmpaddr;
		break;
	case 't':
		tlscert = readcert(EARGF(usage()), &ntlscert);
		if(tlscert == nil){
			senderr("cannot read TLS certificate: %r");
			exits(nil);
		}
		break;
	}ARGEND

	/* do before TLS */
	if(peeraddr == nil)
		peeraddr = remoteaddr(0,0);

	hello();

	while(Bflush(&out), getcrnl(cmdbuf, sizeof cmdbuf) > 0){
		arg = nextarg(cmdbuf);
		for(c=cmdtab; c->name; c++)
			if(cistrcmp(c->name, cmdbuf) == 0)
				break;
		if(c->name == 0){
			senderr("unknown command %s", cmdbuf);
			continue;
		}
		if(c->needauth && !loggedin){
			senderr("%s requires authentication", cmdbuf);
			continue;
		}
		(*c->f)(arg);
	}
	exits(nil);
}