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

📄 queue.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
		return FALSE;	}	/* good file -- save this lock */	e->e_lockfp = qfp;	/* do basic system initialization */	initsys(e);	define('i', e->e_id, e);	LineNumber = 0;	e->e_flags |= EF_GLOBALERRS;	OpMode = MD_DELIVER;	if (Verbose)		printf("\nRunning %s\n", e->e_id);	ctladdr = NULL;	while ((bp = fgetfolded(buf, sizeof buf, qfp)) != NULL)	{		register char *p;		struct stat st;		if (tTd(40, 4))			printf("+++++ %s\n", bp);		switch (bp[0])		{		  case 'C':		/* specify controlling user */			ctladdr = setctluser(&bp[1]);			break;		  case 'R':		/* specify recipient */			(void) sendtolist(&bp[1], ctladdr, &e->e_sendqueue, e);			break;		  case 'E':		/* specify error recipient */			(void) sendtolist(&bp[1], ctladdr, &e->e_errorqueue, e);			break;		  case 'H':		/* header */			(void) chompheader(&bp[1], FALSE, e);			break;		  case 'M':		/* message */			/* ignore this; we want a new message next time */			break;		  case 'S':		/* sender */			setsender(newstr(&bp[1]), e, NULL, TRUE);			break;		  case 'B':		/* body type */			e->e_bodytype = newstr(&bp[1]);			break;		  case 'D':		/* data file name */			e->e_df = newstr(&bp[1]);			e->e_dfp = fopen(e->e_df, "r");			if (e->e_dfp == NULL)			{				syserr("readqf: cannot open %s", e->e_df);				e->e_msgsize = -1;			}			else if (fstat(fileno(e->e_dfp), &st) >= 0)				e->e_msgsize = st.st_size;			break;		  case 'T':		/* init time */			e->e_ctime = atol(&bp[1]);			break;		  case 'P':		/* message priority */			e->e_msgpriority = atol(&bp[1]) + WkTimeFact;			break;		  case 'F':		/* flag bits */			for (p = &bp[1]; *p != '\0'; p++)			{				switch (*p)				{				  case 'w':	/* warning sent */					e->e_flags |= EF_WARNING;					break;				  case 'r':	/* response */					e->e_flags |= EF_RESPONSE;					break;				}			}			break;		  case '$':		/* define macro */			define(bp[1], newstr(&bp[2]), e);			break;		  case '\0':		/* blank line; ignore */			break;		  default:			syserr("readqf: %s: line %d: bad line \"%s\"",				qf, LineNumber, bp);			fclose(qfp);			rename(qf, queuename(e, 'Q'));			return FALSE;		}		if (bp != buf)			free(bp);	}	/*	**  If we haven't read any lines, this queue file is empty.	**  Arrange to remove it without referencing any null pointers.	*/	if (LineNumber == 0)	{		errno = 0;		e->e_flags |= EF_CLRQUEUE | EF_FATALERRS | EF_RESPONSE;	}	return TRUE;}/***  PRINTQUEUE -- print out a representation of the mail queue****	Parameters:**		none.****	Returns:**		none.****	Side Effects:**		Prints a listing of the mail queue on the standard output.*/printqueue(){	register WORK *w;	FILE *f;	int nrequests;	char buf[MAXLINE];	/*	**  Check for permission to print the queue	*/	if (bitset(PRIV_RESTRICTMAILQ, PrivacyFlags) && RealUid != 0)	{		struct stat st;# ifdef NGROUPS		int n;		GIDSET_T gidset[NGROUPS];# endif		if (stat(QueueDir, &st) < 0)		{			syserr("Cannot stat %s", QueueDir);			return;		}# ifdef NGROUPS		n = getgroups(NGROUPS, gidset);		while (--n >= 0)		{			if (gidset[n] == st.st_gid)				break;		}		if (n < 0)# else		if (RealGid != st.st_gid)# endif		{			usrerr("510 You are not permitted to see the queue");			setstat(EX_NOPERM);			return;		}	}	/*	**  Read and order the queue.	*/	nrequests = orderq(TRUE);	/*	**  Print the work list that we have read.	*/	/* first see if there is anything */	if (nrequests <= 0)	{		printf("Mail queue is empty\n");		return;	}	CurrentLA = getla();	/* get load average */	printf("\t\tMail Queue (%d request%s", nrequests, nrequests == 1 ? "" : "s");	if (nrequests > QUEUESIZE)		printf(", only %d printed", QUEUESIZE);	if (Verbose)		printf(")\n--Q-ID-- --Size-- -Priority- ---Q-Time--- -----------Sender/Recipient-----------\n");	else		printf(")\n--Q-ID-- --Size-- -----Q-Time----- ------------Sender/Recipient------------\n");	for (w = WorkQ; w != NULL; w = w->w_next)	{		struct stat st;		auto time_t submittime = 0;		long dfsize = -1;		int flags = 0;		char message[MAXLINE];		char bodytype[MAXNAME];		printf("%8s", w->w_name + 2);		f = fopen(w->w_name, "r");		if (f == NULL)		{			printf(" (job completed)\n");			errno = 0;			continue;		}		if (!lockfile(fileno(f), w->w_name, NULL, LOCK_SH|LOCK_NB))			printf("*");		else if (shouldqueue(w->w_pri, w->w_ctime))			printf("X");		else			printf(" ");		errno = 0;		message[0] = bodytype[0] = '\0';		while (fgets(buf, sizeof buf, f) != NULL)		{			register int i;			register char *p;			fixcrlf(buf, TRUE);			switch (buf[0])			{			  case 'M':	/* error message */				if ((i = strlen(&buf[1])) >= sizeof message)					i = sizeof message - 1;				bcopy(&buf[1], message, i);				message[i] = '\0';				break;			  case 'B':	/* body type */				if ((i = strlen(&buf[1])) >= sizeof bodytype)					i = sizeof bodytype - 1;				bcopy(&buf[1], bodytype, i);				bodytype[i] = '\0';				break;			  case 'S':	/* sender name */				if (Verbose)					printf("%8ld %10ld%c%.12s %.38s",					    dfsize,					    w->w_pri,					    bitset(EF_WARNING, flags) ? '+' : ' ',					    ctime(&submittime) + 4,					    &buf[1]);				else					printf("%8ld %.16s %.45s", dfsize,					    ctime(&submittime), &buf[1]);				if (message[0] != '\0' || bodytype[0] != '\0')				{					printf("\n    %10.10s", bodytype);					if (message[0] != '\0')						printf("   (%.60s)", message);				}				break;			  case 'C':	/* controlling user */				if (Verbose)					printf("\n\t\t\t\t      (---%.34s---)",						&buf[1]);				break;			  case 'R':	/* recipient name */				if (Verbose)					printf("\n\t\t\t\t\t  %.38s", &buf[1]);				else					printf("\n\t\t\t\t   %.45s", &buf[1]);				break;			  case 'T':	/* creation time */				submittime = atol(&buf[1]);				break;			  case 'D':	/* data file name */				if (stat(&buf[1], &st) >= 0)					dfsize = st.st_size;				break;			  case 'F':	/* flag bits */				for (p = &buf[1]; *p != '\0'; p++)				{					switch (*p)					{					  case 'w':						flags |= EF_WARNING;						break;					}				}			}		}		if (submittime == (time_t) 0)			printf(" (no control file)");		printf("\n");		(void) fclose(f);	}}# endif /* QUEUE *//***  QUEUENAME -- build a file name in the queue directory for this envelope.****	Assigns an id code if one does not already exist.**	This code is very careful to avoid trashing existing files**	under any circumstances.****	Parameters:**		e -- envelope to build it in/from.**		type -- the file type, used as the first character**			of the file name.****	Returns:**		a pointer to the new file name (in a static buffer).****	Side Effects:**		If no id code is already assigned, queuename will**		assign an id code, create a qf file, and leave a**		locked, open-for-write file pointer in the envelope.*/char *queuename(e, type)	register ENVELOPE *e;	int type;{	static int pid = -1;	static char c0;	static char c1;	static char c2;	time_t now;	struct tm *tm;	static char buf[MAXNAME];	if (e->e_id == NULL)	{		char qf[20];		/* find a unique id */		if (pid != getpid())		{			/* new process -- start back at "AA" */			pid = getpid();			now = curtime();			tm = localtime(&now);			c0 = 'A' + tm->tm_hour;			c1 = 'A';			c2 = 'A' - 1;		}		(void) sprintf(qf, "qf%cAA%05d", c0, pid);		while (c1 < '~' || c2 < 'Z')		{			int i;			if (c2 >= 'Z')			{				c1++;				c2 = 'A' - 1;			}			qf[3] = c1;			qf[4] = ++c2;			if (tTd(7, 20))				printf("queuename: trying \"%s\"\n", qf);			i = open(qf, O_WRONLY|O_CREAT|O_EXCL, FileMode);			if (i < 0)			{				if (errno == EEXIST)					continue;				syserr("queuename: Cannot create \"%s\" in \"%s\" (euid=%d)",					qf, QueueDir, geteuid());				exit(EX_UNAVAILABLE);			}			if (lockfile(i, qf, NULL, LOCK_EX|LOCK_NB))			{				e->e_lockfp = fdopen(i, "w");				break;			}			/* a reader got the file; abandon it and try again */			(void) close(i);		}		if (c1 >= '~' && c2 >= 'Z')		{			syserr("queuename: Cannot create \"%s\" in \"%s\" (euid=%d)",				qf, QueueDir, geteuid());			exit(EX_OSERR);		}		e->e_id = newstr(&qf[2]);		define('i', e->e_id, e);		if (tTd(7, 1))			printf("queuename: assigned id %s, env=%x\n", e->e_id, e);		if (tTd(7, 9))		{			printf("  lockfd=");			dumpfd(fileno(e->e_lockfp), TRUE, FALSE);		}# ifdef LOG		if (LogLevel > 93)			syslog(LOG_DEBUG, "%s: assigned id", e->e_id);# endif /* LOG */	}	if (type == '\0')		return (NULL);	(void) sprintf(buf, "%cf%s", type, e->e_id);	if (tTd(7, 2))		printf("queuename: %s\n", buf);	return (buf);}/***  UNLOCKQUEUE -- unlock the queue entry for a specified envelope****	Parameters:**		e -- the envelope to unlock.****	Returns:**		none****	Side Effects:**		unlocks the queue for `e'.*/unlockqueue(e)	ENVELOPE *e;{	if (tTd(51, 4))		printf("unlockqueue(%s)\n", e->e_id);	/* if there is a lock file in the envelope, close it */	if (e->e_lockfp != NULL)		xfclose(e->e_lockfp, "unlockqueue", e->e_id);	e->e_lockfp = NULL;	/* don't create a queue id if we don't already have one */	if (e->e_id == NULL)		return;	/* remove the transcript */# ifdef LOG	if (LogLevel > 87)		syslog(LOG_DEBUG, "%s: unlock", e->e_id);# endif /* LOG */	if (!tTd(51, 104))		xunlink(queuename(e, 'x'));}/***  SETCTLUSER -- create a controlling address****	Create a fake "address" given only a local login name; this is**	used as a "controlling user" for future recipient addresses.****	Parameters:**		user -- the user name of the controlling user.****	Returns:**		An address descriptor for the controlling user.****	Side Effects:**		none.*/ADDRESS *setctluser(user)	char *user;{	register ADDRESS *a;	struct passwd *pw;	char *p;	/*	**  See if this clears our concept of controlling user.	*/	if (user == NULL || *user == '\0')		return NULL;	/*	**  Set up addr fields for controlling user.	*/	a = (ADDRESS *) xalloc(sizeof *a);	bzero((char *) a, sizeof *a);	p = strchr(user, ':');	if (p != NULL)		*p++ = '\0';	if (*user != '\0' && (pw = getpwnam(user)) != NULL)	{		if (strcmp(pw->pw_dir, "/") == 0)			a->q_home = "";		else			a->q_home = newstr(pw->pw_dir);		a->q_uid = pw->pw_uid;		a->q_gid = pw->pw_gid;		a->q_user = newstr(user);		a->q_flags |= QGOODUID;	}	else	{		a->q_user = newstr(DefUser);	}	a->q_flags |= QPRIMARY;		/* flag as a "ctladdr"  */	a->q_mailer = LocalMailer;	if (p == NULL)		a->q_paddr = a->q_user;	else		a->q_paddr = newstr(p);	return a;}

⌨️ 快捷键说明

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