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

📄 copy.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include <u.h>#include <libc.h>#include <bio.h>#include <auth.h>#include <libsec.h>#include "imap4d.h"static int	saveMsg(char *dst, char *digest, int flags, char *head, int nhead, Biobuf *b, long n);static int	saveb(int fd, DigestState *dstate, char *buf, int nr, int nw);static long	appSpool(Biobuf *bout, Biobuf *bin, long n);/* * check if the message exists */intcopyCheck(Box *box, Msg *m, int uids, void *v){	int fd;	USED(box);	USED(uids);	USED(v);	if(m->expunged)		return 0;	fd = msgFile(m, "raw");	if(fd < 0){		msgDead(m);		return 0;	}	close(fd);	return 1;}intcopySave(Box *box, Msg *m, int uids, void *vs){	Dir *d;	Biobuf b;	vlong length;	char *head;	int ok, hfd, bfd, nhead;	USED(box);	USED(uids);	if(m->expunged)		return 0;	hfd = msgFile(m, "unixheader");	if(hfd < 0){		msgDead(m);		return 0;	}	head = readFile(hfd);	if(head == nil){		close(hfd);		return 0;	}	/*	 * clear out the header if it doesn't end in a newline,	 * since it is a runt and the "header" will show up in the raw file.	 */	nhead = strlen(head);	if(nhead > 0 && head[nhead-1] != '\n')		nhead = 0;	bfd = msgFile(m, "raw");	close(hfd);	if(bfd < 0){		msgDead(m);		return 0;	}	d = dirfstat(bfd);	if(d == nil){		close(bfd);		return 0;	}	length = d->length;	free(d);	Binit(&b, bfd, OREAD);	ok = saveMsg(vs, m->info[IDigest], m->flags, head, nhead, &b, length);	Bterm(&b);	close(bfd);	return ok;}/* * first spool the input into a temorary file, * and massage the input in the process. * then save to real box. */intappendSave(char *mbox, int flags, char *head, Biobuf *b, long n){	Biobuf btmp;	int fd, ok;	fd = imapTmp();	if(fd < 0)		return 0;	Bprint(&bout, "+ Ready for literal data\r\n");	if(Bflush(&bout) < 0)		writeErr();	Binit(&btmp, fd, OWRITE);	n = appSpool(&btmp, b, n);	Bterm(&btmp);	if(n < 0){		close(fd);		return 0;	}	seek(fd, 0, 0);	Binit(&btmp, fd, OREAD);	ok = saveMsg(mbox, nil, flags, head, strlen(head), &btmp, n);	Bterm(&btmp);	close(fd);	return ok;}/* * copy from bin to bout, * mapping "\r\n" to "\n" and "\nFrom " to "\n From " * return the number of bytes in the mapped file. * * exactly n bytes must be read from the input, * unless an input error occurs. */static longappSpool(Biobuf *bout, Biobuf *bin, long n){	int i, c;	c = '\n';	while(n > 0){		if(c == '\n' && n >= STRLEN("From ")){			for(i = 0; i < STRLEN("From "); i++){				c = Bgetc(bin);				if(c != "From "[i]){					if(c < 0)						return -1;					Bungetc(bin);					break;				}				n--;			}			if(i == STRLEN("From "))				Bputc(bout, ' ');			Bwrite(bout, "From ", i);		}		c = Bgetc(bin);		n--;		if(c == '\r' && n-- > 0){			c = Bgetc(bin);			if(c != '\n')				Bputc(bout, '\r');		}		if(c < 0)			return -1;		if(Bputc(bout, c) < 0)			return -1;	}	if(c != '\n')		Bputc(bout, '\n');	if(Bflush(bout) < 0)		return -1;	return Boffset(bout);}static intsaveMsg(char *dst, char *digest, int flags, char *head, int nhead, Biobuf *b, long n){	DigestState *dstate;	MbLock *ml;	uchar shadig[SHA1dlen];	char buf[BufSize + 1], digbuf[NDigest + 1];	int i, fd, nr, nw, ok;	ml = mbLock();	if(ml == nil)		return 0;	fd = openLocked(mboxDir, dst, OWRITE);	if(fd < 0){		mbUnlock(ml);		return 0;	}	seek(fd, 0, 2);	dstate = nil;	if(digest == nil)		dstate = sha1(nil, 0, nil, nil);	if(!saveb(fd, dstate, head, nhead, nhead)){		if(dstate != nil)			sha1(nil, 0, shadig, dstate);		mbUnlock(ml);		close(fd);		return 0;	}	ok = 1;	if(n == 0)		ok = saveb(fd, dstate, "\n", 0, 1);	while(n > 0){		nr = n;		if(nr > BufSize)			nr = BufSize;		nr = Bread(b, buf, nr);		if(nr <= 0){			saveb(fd, dstate, "\n\n", 0, 2);			ok = 0;			break;		}		n -= nr;		nw = nr;		if(n == 0){			if(buf[nw - 1] != '\n')				buf[nw++] = '\n';			buf[nw++] = '\n';		}		if(!saveb(fd, dstate, buf, nr, nw)){			ok = 0;			break;		}		mbLockRefresh(ml);	}	close(fd);	if(dstate != nil){		digest = digbuf;		sha1(nil, 0, shadig, dstate);		for(i = 0; i < SHA1dlen; i++)			snprint(digest+2*i, NDigest+1-2*i, "%2.2ux", shadig[i]);	}	if(ok){		fd = cdOpen(mboxDir, impName(dst), OWRITE);		if(fd < 0)			fd = emptyImp(dst);		if(fd >= 0){			seek(fd, 0, 2);			wrImpFlags(buf, flags, 1);			fprint(fd, "%.*s %.*lud %s\n", NDigest, digest, NUid, 0UL, buf);			close(fd);		}	}	mbUnlock(ml);	return 1;}static intsaveb(int fd, DigestState *dstate, char *buf, int nr, int nw){	if(dstate != nil)		sha1((uchar*)buf, nr, nil, dstate);	if(write(fd, buf, nw) != nw)		return 0;	return 1;}

⌨️ 快捷键说明

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