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

📄 folder.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include <u.h>#include <libc.h>#include <bio.h>#include <auth.h>#include "imap4d.h"static	int	copyData(int ffd, int tfd, MbLock *ml);static	MbLock	mLock ={	.fd = -1};static char curDir[MboxNameLen];voidresetCurDir(void){	curDir[0] = '\0';}intmyChdir(char *dir){	if(strcmp(dir, curDir) == 0)		return 0;	if(dir[0] != '/' || strlen(dir) > MboxNameLen)		return -1;	strcpy(curDir, dir);	if(chdir(dir) < 0){		werrstr("mychdir failed: %r");		return -1;	}	return 0;}intcdCreate(char *dir, char *file, int mode, ulong perm){	if(myChdir(dir) < 0)		return -1;	return create(file, mode, perm);}Dir*cdDirstat(char *dir, char *file){	if(myChdir(dir) < 0)		return nil;	return dirstat(file);}intcdExists(char *dir, char *file){	Dir *d;	d = cdDirstat(dir, file);	if(d == nil)		return 0;	free(d);	return 1;}intcdDirwstat(char *dir, char *file, Dir *d){	if(myChdir(dir) < 0)		return -1;	return dirwstat(file, d);}intcdOpen(char *dir, char *file, int mode){	if(myChdir(dir) < 0)		return -1;	return open(file, mode);}intcdRemove(char *dir, char *file){	if(myChdir(dir) < 0)		return -1;	return remove(file);}/* * open the one true mail lock file */MbLock*mbLock(void){	if(mLock.fd >= 0)		bye("mail lock deadlock");	mLock.fd = openLocked(mboxDir, "L.mbox", OREAD);	if(mLock.fd >= 0)		return &mLock;	return nil;}voidmbUnlock(MbLock *ml){	if(ml != &mLock)		bye("bad mail unlock");	if(ml->fd < 0)		bye("mail unlock when not locked");	close(ml->fd);	ml->fd = -1;}voidmbLockRefresh(MbLock *ml){	char buf[1];	seek(ml->fd, 0, 0);	read(ml->fd, buf, 1);}intmbLocked(void){	return mLock.fd >= 0;}char*impName(char *name){	char *s;	int n;	if(cistrcmp(name, "inbox") == 0)		name = "mbox";	n = strlen(name) + STRLEN(".imp") + 1;	s = binalloc(&parseBin, n, 0);	if(s == nil)		return nil;	snprint(s, n, "%s.imp", name);	return s;}/* * massage the mailbox name into something valid * eliminates all .', and ..',s, redundatant and trailing /'s. */char *mboxName(char *s){	char *ss;	ss = mutf7str(s);	if(ss == nil)		return nil;	cleanname(ss);	return ss;}char *strmutf7(char *s){	char *m;	int n;	n = strlen(s) * MUtf7Max + 1;	m = binalloc(&parseBin, n, 0);	if(m == nil)		return nil;	if(encmutf7(m, n, s) < 0)		return nil;	return m;}char *mutf7str(char *s){	char *m;	int n;	/*	 * n = strlen(s) * UTFmax / (2.67) + 1	 * UTFMax / 2.67 == 3 / (8/3) == 9 / 8	 */	n = strlen(s);	n = (n * 9 + 7) / 8 + 1;	m = binalloc(&parseBin, n, 0);	if(m == nil)		return nil;	if(decmutf7(m, n, s) < 0)		return nil;	return m;}voidsplitr(char *s, int c, char **left, char **right){	char *d;	int n;	n = strlen(s);	d = binalloc(&parseBin, n + 1, 0);	if(d == nil)		parseErr("out of memory");	strcpy(d, s);	s = strrchr(d, c);	if(s != nil){		*left = d;		*s++ = '\0';		*right = s;	}else{		*right = d;		*left = d + n;	}}/* * create the mailbox and all intermediate components * a trailing / implies the new mailbox is a directory; * otherwise, it's a file. * * return with the file open for write, or directory open for read. */intcreateBox(char *mbox, int dir){	char *m;	int fd;	fd = -1;	for(m = mbox; *m; m++){		if(*m == '/'){			*m = '\0';			if(access(mbox, AEXIST) < 0){				if(fd >= 0)					close(fd);				fd = cdCreate(mboxDir, mbox, OREAD, DMDIR|0775);				if(fd < 0)					return -1;			}			*m = '/';		}	}	if(dir)		fd = cdCreate(mboxDir, mbox, OREAD, DMDIR|0775);	else		fd = cdCreate(mboxDir, mbox, OWRITE, 0664);	return fd;}/* * move one mail folder to another * destination mailbox doesn't exist. * the source folder may be a directory or a mailbox, * and may be in the same directory as the destination, * or a completely different directory. */intmoveBox(char *from, char *to){	Dir *d;	char *fd, *fe, *td, *te, *fimp;	splitr(from, '/', &fd, &fe);	splitr(to, '/', &td, &te);	/*	 * in the same directory: try rename	 */	d = cdDirstat(mboxDir, from);	if(d == nil)		return 0;	if(strcmp(fd, td) == 0){		nulldir(d);		d->name = te;		if(cdDirwstat(mboxDir, from, d) >= 0){			fimp = impName(from);			d->name = impName(te);			cdDirwstat(mboxDir, fimp, d);			free(d);			return 1;		}	}	/*	 * directory copy is too hard for now	 */	if(d->mode & DMDIR)		return 0;	free(d);	return copyBox(from, to, 1);}/* * copy the contents of one mailbox to another * either truncates or removes the source box if it succeeds. */intcopyBox(char *from, char *to, int doremove){	MbLock *ml;	char *fimp, *timp;	int ffd, tfd, ok;	if(cistrcmp(from, "inbox") == 0)		from = "mbox";	ml = mbLock();	if(ml == nil)		return 0;	ffd = openLocked(mboxDir, from, OREAD);	if(ffd < 0){		mbUnlock(ml);		return 0;	}	tfd = createBox(to, 0);	if(tfd < 0){		mbUnlock(ml);		close(ffd);		return 0;	}	ok = copyData(ffd, tfd, ml);	close(ffd);	close(tfd);	if(!ok){		mbUnlock(ml);		return 0;	}	fimp = impName(from);	timp = impName(to);	if(fimp != nil && timp != nil){		ffd = cdOpen(mboxDir, fimp, OREAD);		if(ffd >= 0){			tfd = cdCreate(mboxDir, timp, OWRITE, 0664);			if(tfd >= 0){				copyData(ffd, tfd, ml);				close(tfd);			}			close(ffd);		}	}	cdRemove(mboxDir, fimp);	if(doremove)		cdRemove(mboxDir, from);	else		close(cdOpen(mboxDir, from, OWRITE|OTRUNC));	mbUnlock(ml);	return 1;}/* * copies while holding the mail lock, * then tries to copy permissions and group ownership */static intcopyData(int ffd, int tfd, MbLock *ml){	Dir *fd, td;	char buf[BufSize];	int n;	for(;;){		n = read(ffd, buf, BufSize);		if(n <= 0){			if(n < 0)				return 0;			break;		}		if(write(tfd, buf, n) != n)			return 0;		mbLockRefresh(ml);	}	fd = dirfstat(ffd);	if(fd != nil){		nulldir(&td);		td.mode = fd->mode;		if(dirfwstat(tfd, &td) >= 0){			nulldir(&td);			td.gid = fd->gid;			dirfwstat(tfd, &td);		}	}	return 1;}

⌨️ 快捷键说明

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