⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nedmail.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 3 页
字号:
helpcmd(Cmd*, Message *m){	int i;	Bprint(&out, "Commands are of the form [<range>] <command> [args]\n");	Bprint(&out, "<range> := <addr> | <addr>','<addr>| 'g'<search>\n");	Bprint(&out, "<addr> := '.' | '$' | '^' | <number> | <search> | <addr>'+'<addr> | <addr>'-'<addr>\n");	Bprint(&out, "<search> := '/'<regexp>'/' | '?'<regexp>'?' | '%%'<regexp>'%%'\n");	Bprint(&out, "<command> :=\n");	for(i = 0; cmdtab[i].cmd != nil; i++)		Bprint(&out, "%s\n", cmdtab[i].help);	return m;}inttomailer(char **av){	Waitmsg *w;	int pid, i;	// start the mailer and get out of the way	switch(pid = fork()){	case -1:		fprint(2, "can't fork: %r\n");		return -1;	case 0:		Bprint(&out, "!/bin/upas/marshal");		for(i = 1; av[i]; i++){			if(strchr(av[i], ' ') != nil)				Bprint(&out, " '%s'", av[i]);			else				Bprint(&out, " %s", av[i]);		}		Bprint(&out, "\n");		Bflush(&out);		av[0] = "marshal";		chdir(wd);		exec("/bin/upas/marshal", av);		fprint(2, "couldn't exec /bin/upas/marshal\n");		exits(0);	default:		w = wait();		if(w == nil){			if(interrupted)				postnote(PNPROC, pid, "die");			waitpid();			return -1;		}		if(w->msg[0]){			fprint(2, "mailer failed: %s\n", w->msg);			free(w);			return -1;		}		free(w);		Bprint(&out, "!\n");		break;	}	return 0;}//// like tokenize but obey "" quoting//inttokenize822(char *str, char **args, int max){	int na;	int intok = 0, inquote = 0;	if(max <= 0)		return 0;		for(na=0; ;str++)		switch(*str) {		case ' ':		case '\t':			if(inquote)				goto Default;			/* fall through */		case '\n':			*str = 0;			if(!intok)				continue;			intok = 0;			if(na < max)				continue;			/* fall through */		case 0:			return na;		case '"':			inquote ^= 1;			/* fall through */		Default:		default:			if(intok)				continue;			args[na++] = str;			intok = 1;		}}Message*rcmd(Cmd *c, Message *m){	char *av[128];	int i, ai = 1;	Message *nm;	char *addr;	String *path = nil;	String *rpath;	String *subject = nil;	String *from;	if(m == &top){		Bprint(&out, "!address\n");		return nil;	}	addr = nil;	for(nm = m; nm != &top; nm = nm->parent){ 		if(*nm->replyto != 0){			addr = nm->replyto;			break;		}	}	if(addr == nil){		Bprint(&out, "!no reply address\n");		return nil;	}	if(nm == &top){		print("!noone to reply to\n");		return nil;	}	for(nm = m; nm != &top; nm = nm->parent){		if(*nm->subject){			av[ai++] = "-s";			subject = addrecolon(nm->subject);			av[ai++] = s_to_c(subject);;			break;		}	}	av[ai++] = "-R";	rpath = rooted(s_clone(m->path));	av[ai++] = s_to_c(rpath);	if(strchr(c->av[0], 'f') != nil){		fcmd(c, m);		av[ai++] = "-F";	}	if(strchr(c->av[0], 'R') != nil){		av[ai++] = "-t";		av[ai++] = "message/rfc822";		av[ai++] = "-A";		path = rooted(extendpath(m->path, "raw"));		av[ai++] = s_to_c(path);	}	for(i = 1; i < c->an && ai < nelem(av)-1; i++)		av[ai++] = c->av[i];	from = s_copy(addr);	ai += tokenize822(s_to_c(from), &av[ai], nelem(av) - ai);	av[ai] = 0;	if(tomailer(av) < 0)		m = nil;	s_free(path);	s_free(rpath);	s_free(subject);	s_free(from);	return m;}Message*mcmd(Cmd *c, Message *m){	char **av;	int i, ai;	String *path;	if(m == &top){		Bprint(&out, "!address\n");		return nil;	}	if(c->an < 2){		fprint(2, "!usage: M list-of addresses\n");		return nil;	}	ai = 1;	av = malloc(sizeof(char*)*(c->an + 8));	av[ai++] = "-t";	if(m->parent == &top)		av[ai++] = "message/rfc822";	else		av[ai++] = "mime";	av[ai++] = "-A";	path = rooted(extendpath(m->path, "raw"));	av[ai++] = s_to_c(path);	if(strchr(c->av[0], 'M') == nil)		av[ai++] = "-n";	for(i = 1; i < c->an; i++)		av[ai++] = c->av[i];	av[ai] = 0;	if(tomailer(av) < 0)		m = nil;	if(path != nil)		s_free(path);	free(av);	return m;}Message*acmd(Cmd *c, Message *m){	char *av[128];	int i, ai;	String *from, *to, *cc, *path = nil, *subject = nil;	if(m == &top){		Bprint(&out, "!address\n");		return nil;	}	ai = 1;	if(*m->subject){		av[ai++] = "-s";		subject = addrecolon(m->subject);		av[ai++] = s_to_c(subject);	}	if(strchr(c->av[0], 'A') != nil){		av[ai++] = "-t";		av[ai++] = "message/rfc822";		av[ai++] = "-A";		path = rooted(extendpath(m->path, "raw"));		av[ai++] = s_to_c(path);	}	for(i = 1; i < c->an && ai < nelem(av)-1; i++)		av[ai++] = c->av[i];	from = s_copy(m->from);	ai += tokenize822(s_to_c(from), &av[ai], nelem(av) - ai);	to = s_copy(m->to);	ai += tokenize822(s_to_c(to), &av[ai], nelem(av) - ai);	cc = s_copy(m->cc);	ai += tokenize822(s_to_c(cc), &av[ai], nelem(av) - ai);	av[ai] = 0;	if(tomailer(av) < 0)		return nil;	s_free(from);	s_free(to);	s_free(cc);	s_free(subject);	s_free(path);	return m;}String *relpath(char *path, String *to){	if (*path=='/' || strncmp(path, "./", 2) == 0			      || strncmp(path, "../", 3) == 0) {		to = s_append(to, path);	} else if(mbpath) {		to = s_append(to, s_to_c(mbpath));		to->ptr = strrchr(to->base, '/')+1;		s_append(to, path);	}	return to;}intappendtofile(Message *m, char *part, char *base, int mbox){	String *file, *h;	int in, out, rv;	file = extendpath(m->path, part);	in = open(s_to_c(file), OREAD);	if(in < 0){		fprint(2, "!message disappeared\n");		return -1;	}	s_reset(file);	relpath(base, file);	if(sysisdir(s_to_c(file))){		s_append(file, "/");		if(m->filename && strchr(m->filename, '/') == nil)			s_append(file, m->filename);		else {			s_append(file, "att.XXXXXXXXXXX");			mktemp(s_to_c(file));		}	}	if(mbox)		out = open(s_to_c(file), OWRITE);	else		out = open(s_to_c(file), OWRITE|OTRUNC);	if(out < 0){		out = create(s_to_c(file), OWRITE, 0666);		if(out < 0){			fprint(2, "!can't open %s: %r\n", s_to_c(file));			close(in);			s_free(file);			return -1;		}	}	if(mbox)		seek(out, 0, 2);	// put on a 'From ' line	if(mbox){		while(m->parent != &top)			m = m->parent;		h = file2string(m->path, "unixheader");		fprint(out, "%s", s_to_c(h));		s_free(h);	}	// copy the message escaping what we have to ad adding newlines if we have to	if(mbox)		rv = appendfiletombox(in, out);	else		rv = appendfiletofile(in, out);	close(in);	close(out);	if(rv >= 0)		print("!saved in %s\n", s_to_c(file));	s_free(file);	return rv;}Message*scmd(Cmd *c, Message *m){	char *file;	if(m == &top){		Bprint(&out, "!address\n");		return nil;	}	switch(c->an){	case 1:		file = "stored";		break;	case 2:		file = c->av[1];		break;	default:		fprint(2, "!usage: s filename\n");		return nil;	}	if(appendtofile(m, "raw", file, 1) < 0)		return nil;	m->stored = 1;	return m;}Message*wcmd(Cmd *c, Message *m){	char *file;	if(m == &top){		Bprint(&out, "!address\n");		return nil;	}	switch(c->an){	case 2:		file = c->av[1];		break;	case 1:		if(*m->filename == 0){			fprint(2, "!usage: w filename\n");			return nil;		}		file = strrchr(m->filename, '/');		if(file != nil)			file++;		else			file = m->filename;		break;	default:		fprint(2, "!usage: w filename\n");		return nil;	}	if(appendtofile(m, "body", file, 0) < 0)		return nil;	m->stored = 1;	return m;}char *specialfile[] ={	"pipeto",	"pipefrom",	"L.mbox",	"forward",	"names"};// return 1 if this is a special filestatic intspecial(String *s){	char *p;	int i;	p = strrchr(s_to_c(s), '/');	if(p == nil)		p = s_to_c(s);	else		p++;	for(i = 0; i < nelem(specialfile); i++)		if(strcmp(p, specialfile[i]) == 0)			return 1;	return 0;}// open the folder using the recipients account namestatic String*foldername(char *rcvr){	char *p;	int c;	String *file;	Dir *d;	int scarey;	file = s_new();	mboxpath("f", user, file, 0);	d = dirstat(s_to_c(file));	// if $mail/f exists, store there, otherwise in $mail	s_restart(file);	if(d && d->qid.type == QTDIR){		scarey = 0;		s_append(file, "f/");	} else {		scarey = 1;	}	free(d);	p = strrchr(rcvr, '!');	if(p != nil)		rcvr = p+1;	while(*rcvr && *rcvr != '@'){		c = *rcvr++;		if(c == '/')			c = '_';		s_putc(file, c);	}	s_terminate(file);	if(scarey && special(file)){		fprint(2, "!won't overwrite %s\n", s_to_c(file));		s_free(file);		return nil;	}	return file;}Message*fcmd(Cmd *c, Message *m){	String *folder;	if(c->an > 1){		fprint(2, "!usage: f takes no arguments\n");		return nil;	}	if(m == &top){		Bprint(&out, "!address\n");		return nil;	}	folder = foldername(m->from);	if(folder == nil)		return nil;	if(appendtofile(m, "raw", s_to_c(folder), 1) < 0){		s_free(folder);		return nil;	}	s_free(folder);	m->stored = 1;	return m;}voidsystem(char *cmd, char **av, int in){	int pid;	switch(pid=fork()){	case -1:		return;	case 0:		if(in >= 0){			close(0);			dup(in, 0);			close(in);		}		if(wd[0] != 0)			chdir(wd);		exec(cmd, av);		fprint(2, "!couldn't exec %s\n", cmd);		exits(0);	default:		if(in >= 0)			close(in);		while(waitpid() < 0){			if(!interrupted)				break;			postnote(PNPROC, pid, "die");			continue;		}		break;	}}Message*bangcmd(Cmd *c, Message *m){	char cmd[4*1024];	char *p, *e;	char *av[4];	int i;	cmd[0] = 0;	p = cmd;	e = cmd+sizeof(cmd);	for(i = 1; i < c->an; i++)		p = seprint(p, e, "%s ", c->av[i]);	av[0] = "rc";	av[1] = "-c";	av[2] = cmd;	av[3] = 0;	system("/bin/rc", av, -1);	Bprint(&out, "!\n");	return m;}Message*xpipecmd(Cmd *c, Message *m, char *part){	char cmd[128];	char *p, *e;	char *av[4];	String *path;	int i, fd;	if(c->an < 2){		Bprint(&out, "!usage: | cmd\n");		return nil;	}	if(m == &top){		Bprint(&out, "!address\n");		return nil;	}	path = extendpath(m->path, part);	fd = open(s_to_c(path), OREAD);	s_free(path);	if(fd < 0){	// compatibility with older upas/fs		path = extendpath(m->path, "raw");		fd = open(s_to_c(path), OREAD);		s_free(path);	}	if(fd < 0){		fprint(2, "!message disappeared\n");		return nil;	}	p = cmd;	e = cmd+sizeof(cmd);	cmd[0] = 0;	for(i = 1; i < c->an; i++)		p = seprint(p, e, "%s ", c->av[i]);	av[0] = "rc";	av[1] = "-c";	av[2] = cmd;	av[3] = 0;	system("/bin/rc", av, fd);	/* system closes fd */	Bprint(&out, "!\n");	return m;}Message*pipecmd(Cmd *c, Message *m){	return xpipecmd(c, m, "body");}Message*rpipecmd(Cmd *c, Message *m){	return xpipecmd(c, m, "rawunix");}voidclosemb(void){	int fd;	fd = open("/mail/fs/ctl", ORDWR);	if(fd < 0)		sysfatal("can't open /mail/fs/ctl: %r");	// close current mailbox	if(*mbname && strcmp(mbname, "mbox") != 0)		fprint(fd, "close %s", mbname);	close(fd);}intswitchmb(char *file, char *singleton){	char *p;	int n, fd;	String *path;	char buf[256];	// if the user didn't say anything and there	// is an mbox mounted already, use that one	// so that the upas/fs -fdefault default is honored.	if(file 	|| (singleton && access(singleton, 0)<0)	|| (!singleton && access("/mail/fs/mbox", 0)<0)){		if(file == nil)			file = "mbox";		// close current mailbox		closemb();		didopen = 1;		fd = open("/mail/fs/ctl", ORDWR);		if(fd < 0)			sysfatal("can't open /mail/fs/ctl: %r");			path = s_new();			// get an absolute path to the mail box		if(strncmp(file, "./", 2) == 0){			// resolve path here since upas/fs doesn't know			// our working directory			if(getwd(buf, sizeof(buf)-strlen(file)) == nil){				fprint(2, "!can't get working directory: %s\n", buf);				return -1;			}			s_append(path, buf);			s_append(path, file+1);		} else {			mboxpath(file, user, path, 0);		}			// make up a handle to use when talking to fs		p = strrchr(file, '/');		if(p == nil){			// if its in the mailbox directory, just use the name			strncpy(mbname, file, sizeof(mbname));			mbname[sizeof(mbname)-1] = 0;		} else {			// make up a mailbox name			p = strrchr(s_to_c(path), '/');			p++;			if(*p == 0){				fprint(2, "!bad mbox name");				return -1;			}			strncpy(mbname, p, sizeof(mbname));			mbname[sizeof(mbname)-1] = 0;			n = strlen(mbname);			if(n > Elemlen-12)				n = Elemlen-12;			sprint(mbname+n, "%ld", time(0));		}		if(fprint(fd, "open %s %s", s_to_c(path), mbname) < 0){			fprint(2, "!can't 'open %s %s': %r\n", file, mbname);			s_free(path);			return -1;		}		close(fd);	}else	if (singleton && access(singleton, 0)==0	    && strncmp(singleton, "/mail/fs/", 9) == 0){		if ((p = strchr(singleton +10, '/')) == nil){			fprint(2, "!bad mbox name");			return -1;		}		n = p-(singleton+9);		strncpy(mbname, singleton+9, n);		mbname[n+1] = 0;		path = s_reset(nil);		mboxpath(mbname, user, path, 0);	}else{		path = s_reset(nil);		mboxpath("mbox", user, path, 0);		strcpy(mbname, "mbox");	}	sprint(root, "/mail/fs/%s", mbname);	if(getwd(wd, sizeof(wd)) == 0)		wd[0] = 0;	if(singleton == nil && chdir(root) >= 0)		strcpy(root, ".");	rootlen = strlen(root);	if(mbpath != nil)		s_free(mbpath);	mbpath = path;	return 0;}// like tokenize but for into linesintlineize(char *s, char **f, int n){	int i;	for(i = 0; *s && i < n; i++){		f[i] = s;		s = strchr(s, '\n');		if(s == nil)			break;		*s++ = 0;	}	return i;}String*rooted(String *s){	static char buf[256];	if(strcmp(root, ".") != 0)		return s;	snprint(buf, sizeof(buf), "/mail/fs/%s/%s", mbname, s_to_c(s));	s_free(s);	return s_copy(buf);}intplumb(Message *m, Ctype *cp){	String *s;	Plumbmsg *pm;	static int fd = -2;	if(cp->plumbdest == nil)		return -1;	if(fd < -1)		fd = plumbopen("send", OWRITE);	if(fd < 0)		return -1;	pm = mallocz(sizeof(Plumbmsg), 1);	pm->src = strdup("mail");	if(*cp->plumbdest)		pm->dst = strdup(cp->plumbdest);	pm->wdir = nil;	pm->type = strdup("text");	pm->ndata = -1;	s = rooted(extendpath(m->path, "body"));	if(cp->ext != nil){		s_append(s, ".");		s_append(s, cp->ext);	}	pm->data = strdup(s_to_c(s));	s_free(s);	plumbsend(fd, pm);	plumbfree(pm);	return 0;}voidregerror(char*){}String*addrecolon(char *s){	String *str;	if(cistrncmp(s, "re:", 3) != 0){		str = s_copy("Re: ");		s_append(str, s);	} else		str = s_copy(s);	return str;}voidexitfs(char *rv){	if(startedfs)		unmount(nil, "/mail/fs");chdir("/sys/src/cmd/upas/ned");	exits(rv);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -