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

📄 util.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
intisclient(char *role){	if(role == nil){		werrstr("role not specified");		return -1;	}	if(strcmp(role, "server") == 0)		return 0;	if(strcmp(role, "client") == 0)		return 1;	werrstr("unknown role %q", role);	return -1;}static inthasname(Attr *a0, Attr *a1, char *name){	return _findattr(a0, name) || _findattr(a1, name);}static inthasnameval(Attr *a0, Attr *a1, char *name, char *val){	Attr *a;	for(a=_findattr(a0, name); a; a=_findattr(a->next, name))		if(strcmp(a->val, val) == 0)			return 1;	for(a=_findattr(a1, name); a; a=_findattr(a->next, name))		if(strcmp(a->val, val) == 0)			return 1;	return 0;}intmatchattr(Attr *pat, Attr *a0, Attr *a1){	int type;	for(; pat; pat=pat->next){		type = pat->type;		if(ignoreattr(pat->name))			type = AttrDefault;		switch(type){		case AttrQuery:		/* name=something be present */			if(!hasname(a0, a1, pat->name))				return 0;			break;		case AttrNameval:	/* name=val must be present */			if(!hasnameval(a0, a1, pat->name, pat->val))				return 0;			break;		case AttrDefault:	/* name=val must be present if name=anything is present */			if(hasname(a0, a1, pat->name) && !hasnameval(a0, a1, pat->name, pat->val))				return 0;			break;		}	}	return 1;		}voidmemrandom(void *p, int n){	uchar *cp;	for(cp = (uchar*)p; n > 0; n--)		*cp++ = fastrand();}/* *  keep caphash fd open since opens of it could be disabled */static int caphashfd;voidinitcap(void){	caphashfd = open("#¤/caphash", OWRITE);//	if(caphashfd < 0)//		fprint(2, "%s: opening #¤/caphash: %r\n", argv0);}/* *  create a change uid capability  */char*mkcap(char *from, char *to){	uchar rand[20];	char *cap;	char *key;	int nfrom, nto;	uchar hash[SHA1dlen];	if(caphashfd < 0)		return nil;	/* create the capability */	nto = strlen(to);	nfrom = strlen(from);	cap = emalloc(nfrom+1+nto+1+sizeof(rand)*3+1);	sprint(cap, "%s@%s", from, to);	memrandom(rand, sizeof(rand));	key = cap+nfrom+1+nto+1;	enc64(key, sizeof(rand)*3, rand, sizeof(rand));	/* hash the capability */	hmac_sha1((uchar*)cap, strlen(cap), (uchar*)key, strlen(key), hash, nil);	/* give the kernel the hash */	key[-1] = '@';	if(write(caphashfd, hash, SHA1dlen) < 0){		free(cap);		return nil;	}	return cap;}intphaseerror(Fsstate *s, char *op){	char tmp[32];	werrstr("protocol phase error: %s in state %s", op, phasename(s, s->phase, tmp));		return RpcPhase;}char*phasename(Fsstate *fss, int phase, char *tmp){	char *name;	if(fss->phase == Broken)		name = "Broken";	else if(phase == Established)		name = "Established";	else if(phase == Notstarted)		name = "Notstarted";	else if(phase < 0 || phase >= fss->maxphase	|| (name = fss->phasename[phase]) == nil){		sprint(tmp, "%d", phase);		name = tmp;	}	return name;}static intoutin(char *prompt, char *def, int len){	char *s;	s = readcons(prompt, def, 0);	if(s == nil)		return -1;	if(s == nil)		sysfatal("s==nil???");	strncpy(def, s, len);	def[len-1] = 0;	free(s);	return strlen(def);}/* *  get host owner and set it */voidpromptforhostowner(void){	char owner[64], *p;	/* hack for bitsy; can't prompt during boot */	if(p = getenv("user")){		writehostowner(p);		free(p);		return;	}	free(p);	strcpy(owner, "none");	do{		outin("user", owner, sizeof(owner));	} while(*owner == 0);	writehostowner(owner);}char*estrappend(char *s, char *fmt, ...){	char *t;	va_list arg;	va_start(arg, fmt);	t = vsmprint(fmt, arg);	if(t == nil)		sysfatal("out of memory");	va_end(arg);	s = erealloc(s, strlen(s)+strlen(t)+1);	strcat(s, t);	free(t);	return s;}/* *  prompt for a string with a possible default response */char*readcons(char *prompt, char *def, int raw){	int fdin, fdout, ctl, n;	char line[10];	char *s;	fdin = open("/dev/cons", OREAD);	if(fdin < 0)		fdin = 0;	fdout = open("/dev/cons", OWRITE);	if(fdout < 0)		fdout = 1;	if(def != nil)		fprint(fdout, "%s[%s]: ", prompt, def);	else		fprint(fdout, "%s: ", prompt);	if(raw){		ctl = open("/dev/consctl", OWRITE);		if(ctl >= 0)			write(ctl, "rawon", 5);	} else		ctl = -1;	s = estrdup("");	for(;;){		n = read(fdin, line, 1);		if(n == 0){		Error:			close(fdin);			close(fdout);			if(ctl >= 0)				close(ctl);			free(s);			return nil;		}		if(n < 0)			goto Error;		if(line[0] == 0x7f)			goto Error;		if(n == 0 || line[0] == '\n' || line[0] == '\r'){			if(raw){				write(ctl, "rawoff", 6);				write(fdout, "\n", 1);			}			close(ctl);			close(fdin);			close(fdout);			if(*s == 0 && def != nil)				s = estrappend(s, "%s", def);			return s;		}		if(line[0] == '\b'){			if(strlen(s) > 0)				s[strlen(s)-1] = 0;		} else if(line[0] == 0x15) {	/* ^U: line kill */			if(def != nil)				fprint(fdout, "\n%s[%s]: ", prompt, def);			else				fprint(fdout, "\n%s: ", prompt);						s[0] = 0;		} else {			s = estrappend(s, "%c", line[0]);		}	}}/* * Insert a key into the keyring. * If the public attributes are identical to some other key, replace that one. */intreplacekey(Key *kn, int before){	int i;	Key *k;	for(i=0; i<ring->nkey; i++){		k = ring->key[i];		if(matchattr(kn->attr, k->attr, nil) && matchattr(k->attr, kn->attr, nil)){			closekey(k);			kn->ref++;			ring->key[i] = kn;			return 0;		}	}	if(ring->nkey%16 == 0)		ring->key = erealloc(ring->key, (ring->nkey+16)*sizeof(ring->key[0]));	kn->ref++;	if(before){		memmove(ring->key+1, ring->key, ring->nkey*sizeof ring->key[0]);		ring->key[0] = kn;		ring->nkey++;	}else		ring->key[ring->nkey++] = kn;	return 0;}char*safecpy(char *to, char *from, int n){	memset(to, 0, n);	if(n == 1)		return to;	if(from==nil)		sysfatal("safecpy called with from==nil, pc=%#p\n",			getcallerpc(&to));	strncpy(to, from, n-1);	return to;}Attr*setattr(Attr *a, char *fmt, ...){	char buf[1024];	va_list arg;	Attr *b;	va_start(arg, fmt);	vseprint(buf, buf+sizeof buf, fmt, arg);	va_end(arg);	b = _parseattr(buf);	a = setattrs(a, b);	setmalloctag(a, getcallerpc(&a));	_freeattr(b);	return a;}/* *  add attributes in list b to list a.  If any attributes are in *  both lists, replace those in a by those in b. */Attr*setattrs(Attr *a, Attr *b){	int found;	Attr **l, *freea;	for(; b; b=b->next){		found = 0;		for(l=&a; *l; ){			if(strcmp(b->name, (*l)->name) == 0){				switch(b->type){				case AttrNameval:					if(!found){						found = 1;						free((*l)->val);						(*l)->val = estrdup(b->val);						(*l)->type = AttrNameval;						l = &(*l)->next;					}else{						freea = *l;						*l = (*l)->next;						freea->next = nil;						_freeattr(freea);					}					break;				case AttrQuery:					goto continue2;				}			}else				l = &(*l)->next;		}		if(found == 0){			*l = _mkattr(b->type, b->name, b->val, nil);			setmalloctag(*l, getcallerpc(&a));		}continue2:;	}	return a;		}voidsetmalloctaghere(void *v){	setmalloctag(v, getcallerpc(&v));}Attr*sortattr(Attr *a){	int i;	Attr *anext, *a0, *a1, **l;	if(a == nil || a->next == nil)		return a;	/* cut list in halves */	a0 = nil;	a1 = nil;	i = 0;	for(; a; a=anext){		anext = a->next;		if(i++%2){			a->next = a0;			a0 = a;		}else{			a->next = a1;			a1 = a;		}	}	/* sort */	a0 = sortattr(a0);	a1 = sortattr(a1);	/* merge */	l = &a;	while(a0 || a1){		if(a1==nil){			anext = a0;			a0 = a0->next;		}else if(a0==nil){			anext = a1;			a1 = a1->next;		}else if(strcmp(a0->name, a1->name) < 0){			anext = a0;			a0 = a0->next;		}else{			anext = a1;			a1 = a1->next;		}		*l = anext;		l = &(*l)->next;	}	*l = nil;	return a;}inttoosmall(Fsstate *fss, uint n){	fss->rpc.nwant = n;	return RpcToosmall;}voidwritehostowner(char *owner){	int fd;	char *s;	if((s = strchr(owner,'@')) != nil){		*s++ = 0;		strncpy(secstore, s, (sizeof secstore)-1);	}	fd = open("#c/hostowner", OWRITE);	if(fd >= 0){		if(fprint(fd, "%s", owner) < 0)			fprint(2, "factotum: setting #c/hostowner to %q: %r\n",				owner);		close(fd);	}}intattrnamefmt(Fmt *fmt){	char *b, buf[1024], *ebuf;	Attr *a;	ebuf = buf+sizeof buf;	b = buf;	strcpy(buf, " ");	for(a=va_arg(fmt->args, Attr*); a; a=a->next){		if(a->name == nil)			continue;		b = seprint(b, ebuf, " %q?", a->name);	}	return fmtstrcpy(fmt, buf+1);}voiddisablekey(Key *k){	Attr *a;	if(sflag)	/* not on servers */		return;	for(a=k->attr; a; a=a->next){		if(a->type==AttrNameval && strcmp(a->name, "disabled") == 0)			return;		if(a->next == nil)			break;	}	if(a)		a->next = _mkattr(AttrNameval, "disabled", "by.factotum", nil);	else		k->attr = _mkattr(AttrNameval, "disabled", "by.factotum", nil);	/* not reached: always a proto attribute */}

⌨️ 快捷键说明

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