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

📄 dest.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include "common.h"#include "send.h"static String* s_parseq(String*, String*);/* exports */dest *dlist;extern dest*d_new(String *addr){	dest *dp;	dp = (dest *)mallocz(sizeof(dest), 1);	if (dp == 0) {		perror("d_new");		exit(1);	}	dp->same = dp;	dp->nsame = 1;	dp->nchar = 0;	dp->next = dp;	dp->addr = escapespecial(addr);	dp->parent = 0;	dp->repl1 = dp->repl2 = 0;	dp->status = d_undefined;	return dp;}extern voidd_free(dest *dp){	if (dp != 0) {		s_free(dp->addr);		s_free(dp->repl1);		s_free(dp->repl2);		free((char *)dp);	}}/* The following routines manipulate an ordered list of items.  Insertions * are always to the end of the list.  Deletions are from the beginning. * * The list are circular witht the `head' of the list being the last item * added. *//*  Get first element from a circular list linked via 'next'. */extern dest *d_rm(dest **listp){	dest *dp;	if (*listp == 0)		return 0;	dp = (*listp)->next;	if (dp == *listp)		*listp = 0;	else		(*listp)->next = dp->next;	dp->next = dp;	return dp;}/*  Insert a new entry at the end of the list linked via 'next'. */extern voidd_insert(dest **listp, dest *new){	dest *head;	if (*listp == 0) {		*listp = new;		return;	}	if (new == 0)		return;	head = new->next;	new->next = (*listp)->next;	(*listp)->next = head;	*listp = new;	return;}/*  Get first element from a circular list linked via 'same'. */extern dest *d_rm_same(dest **listp){	dest *dp;	if (*listp == 0)		return 0;	dp = (*listp)->same;	if (dp == *listp)		*listp = 0;	else		(*listp)->same = dp->same;	dp->same = dp;	return dp;}/* Look for a duplicate on the same list */intd_same_dup(dest *dp, dest *new){	dest *first = dp;	if(new->repl2 == 0)		return 1;	do {		if(strcmp(s_to_c(dp->repl2), s_to_c(new->repl2))==0)			return 1;		dp = dp->same;	} while(dp != first);	return 0;}/* Insert an entry into the corresponding list linked by 'same'.  Note that * the basic structure is a list of lists. */extern voidd_same_insert(dest **listp, dest *new){	dest *dp;	int len;	if(new->status == d_pipe || new->status == d_cat) {		len = new->repl2 ? strlen(s_to_c(new->repl2)) : 0;		if(*listp != 0){			dp = (*listp)->next;			do {				if(dp->status == new->status				&& strcmp(s_to_c(dp->repl1), s_to_c(new->repl1))==0){					/* remove duplicates */					if(d_same_dup(dp, new))						return;					/* add to chain if chain small enough */					if(dp->nsame < MAXSAME					&& dp->nchar + len < MAXSAMECHAR){						new->same = dp->same;						dp->same = new;						dp->nchar += len + 1;						dp->nsame++;						return;					}				}				dp = dp->next;			} while (dp != (*listp)->next);		}		new->nchar = strlen(s_to_c(new->repl1)) + len + 1;	}	new->next = new;	d_insert(listp, new);}/* *  Form a To: if multiple destinations. *  The local! and !local! checks are artificial intelligence, *  there should be a better way. */extern String*d_to(dest *list){	dest *np, *sp;	String *s;	int i, n;	char *cp;	s = s_new();	s_append(s, "To: ");	np = list;	i = n = 0;	do {		np = np->next;		sp = np;		do {			sp = sp->same;			cp = s_to_c(sp->addr);			/* hack to get local! out of the names */			if(strncmp(cp, "local!", 6) == 0)				cp += 6;			if(n > 20){	/* 20 to appease mailers complaining about long lines */				s_append(s, "\n\t");				n = 0;			}			if(i != 0){				s_append(s, ", ");				n += 2;			}			s_append(s, cp);			n += strlen(cp);			i++;		} while(sp != np);	} while(np != list);	return unescapespecial(s);}/* expand a String of destinations into a linked list of destiniations */extern dest *s_to_dest(String *sp, dest *parent){	String *addr;	dest *list=0;	dest *new;	if (sp == 0)		return 0;	addr = s_new();	while (s_parseq(sp, addr)!=0) {		addr = escapespecial(addr);		if(shellchars(s_to_c(addr))){			while(new = d_rm(&list))				d_free(new);			break;		}		new = d_new(addr);		new->parent = parent;		new->authorized = parent->authorized;		d_insert(&list, new);		addr = s_new();	}	s_free(addr);	return list;}#define isspace(c) ((c)==' ' || (c)=='\t' || (c)=='\n')/*  Get the next field from a String.  The field is delimited by white space. *  Anything delimited by double quotes is included in the string. */static String*s_parseq(String *from, String *to){	int c;	if (*from->ptr == '\0')		return 0;	if (to == 0)		to = s_new();	for (c = *from->ptr;!isspace(c) && c != 0; c = *(++from->ptr)){		s_putc(to, c);		if(c == '"'){			for (c = *(++from->ptr); c && c != '"'; c = *(++from->ptr))				s_putc(to, *from->ptr);			s_putc(to, '"');			if(c == 0)				break;		}	}	s_terminate(to);	/* crunch trailing white */	while(isspace(*from->ptr))		from->ptr++;	return to;}

⌨️ 快捷键说明

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