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

📄 mail.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
  char *p, *q;  /* Here we copy until we reach the end of the letter (end of file or   * a line containing only a '.'). Postmarks (lines beginning with   * "From ") are copied with a ">" prepended. Here we also complicate   * things by not setting a line limit. */  state = '\n';  p = postmark;  while (EOF != (c = getc(fromfp))) {	switch (state) {	    case '\n':		if ('.' == c)	/* '.' at BOL */			state = '.';		else if (*p == c) {	/* start of postmark */			++p;			state = 'P';		} else {	/* anything else */			if ('\n' == c)				blankline = 1;			else {				state = '\0';				blankline = 0;			}			putc(c, tofp);		}		break;	    case '.':		if ('\n' == c) goto done;		state = '\0';		putc('.', tofp);		putc(c, tofp);		break;	    case 'P':		if (*p == c) {			if (*++p == '\0') {	/* successfully reached end */				p = postmark;				putc('>', tofp);				fputs(postmark, tofp);				state = '\0';				break;			}			break;	/* not there yet */		}		state = ('\n' == c) ? '\n' : '\0';		for (q = postmark; q < p; ++q) putc(*q, tofp);		putc(c, tofp);		blankline = 0;		p = postmark;		break;	    default:		state = ('\n' == c) ? '\n' : '\0';		putc(c, tofp);	}  }  if ('\n' != state) putc('\n', tofp);done:  if (!blankline) putc('\n', tofp);  if (ferror(tofp)) return -1;  return 0;}void readbox(){  char linebuf[512];  struct letter *let;  off_t current;  firstlet = lastlet = NULL;  if (access(mailbox, 4) < 0 || NULL == (boxfp = fopen(mailbox, "r"))) {	if (usedrop && ENOENT == errno) return;	fprintf(stderr, "can't access mailbox ");	perror(mailbox);	exit(1);  }  current = 0L;  while (1) {	if (NULL == fgets(linebuf, sizeof linebuf, boxfp)) break;	if (!strncmp(linebuf, "From ", (size_t)5)) {		if (NULL == (let = (struct letter *) malloc(sizeof(struct letter)))) {			fprintf(stderr, "Out of memory.\n");			exit(1);		}		if (NULL == lastlet) {			firstlet = let;			let->prev = NULL;		} else {			let->prev = lastlet;			lastlet->next = let;		}		lastlet = let;		let->next = NULL;		let->status = UNREAD;		let->location = current;		D(printf("letter at %ld\n", current));	}	current += strlen(linebuf);  }}void printall(){  struct letter *let;  let = reversemode ? firstlet : lastlet;  if (NULL == let) {	printf("No mail.\n");	return;  }  while (NULL != let) {	printlet(let, stdout);	let = reversemode ? let->next : let->prev;  }}void interact(){  char linebuf[512];		/* user input line */  struct letter *let, *next;	/* current and next letter */  int interrupted = 0;		/* SIGINT hit during letter print */  int needprint = 1;		/* need to print this letter */  char *savefile;		/* filename to save into */  if (NULL == firstlet) {	printf("No mail.\n");	return;  }  let = reversemode ? firstlet : lastlet;  while (1) {	next = reversemode ? let->next : let->prev;	if (NULL == next) next = let;	if (!quitmode) {		interrupted = setjmp(printjump);		signal(SIGINT, onint);	}	if (!interrupted && needprint) {		if (DELETED != let->status) let->status = READ;		printlet(let, stdout);	}	if (interrupted) putchar('\n');	needprint = 0;	fputs(PROMPT, stdout);	fflush(stdout);	if (fgets(linebuf, sizeof linebuf, stdin) == NULL) break;	if (!quitmode) signal(SIGINT, SIG_IGN);	switch (linebuf[0]) {	    case '\n':		let = next;		needprint = 1;		continue;	    case 'd':		let->status = DELETED;		if (next != let)/* look into this */			needprint = 1;		needupdate = 1;		let = next;		continue;	    case 'p':		needprint = 1;		continue;	    case '-':		next = reversemode ? let->prev : let->next;		if (NULL == next) next = let;		let = next;		needprint = 1;		continue;	    case 's':		for (savefile = strtok(linebuf + 1, " \t\n");		     savefile != NULL;		     savefile = strtok((char *) NULL, " \t\n")) {			savelet(let, savefile);		}		continue;	    case '!':		doshell(linebuf + 1);		continue;	    case '*':		dohelp();		continue;	    case 'q':		return;	    case 'x':		exit(0);	    default:		fprintf(stderr, "Illegal command\n");		continue;	}  }}void onint(dummy)int dummy;	/* to satisfy ANSI compilers */{  longjmp(printjump, 1);}void savelet(let, savefile)struct letter *let;char *savefile;{  int waitstat, pid;  FILE *savefp;  if ((pid = fork()) < 0) {	perror("mail: couldn't fork");	return;  } else if (pid != 0) {	/* parent */	wait(&waitstat);	return;  }  /* Child */  setgid(getgid());  setuid(getuid());  if ((savefp = fopen(savefile, "a")) == NULL) {	perror(savefile);	exit(0);  }  printlet(let, savefp);  if ((ferror(savefp) != 0) | (fclose(savefp) != 0)) {	fprintf(stderr, "savefile write error:");	perror(savefile);  }  exit(0);}void updatebox(){  FILE *tempfp;			/* fp for tempfile */  char lockname[PATHLEN];	/* maildrop lock */  int locktries = 0;		/* tries when box is locked */  struct letter *let;		/* current letter */  int c;  sprintf(lockname, LOCKNAME, whoami());  if (NULL == (tempfp = fopen(tempname, "w"))) {	perror("mail: can't create temporary file");	return;  }  for (let = firstlet; let != NULL; let = let->next) {	if (let->status != DELETED) {		printlet(let, tempfp);		D(printf("printed letter at %ld\n", let->location));	}  }  if (ferror(tempfp) || NULL == (tempfp = freopen(tempname, "r", tempfp))) {	perror("mail: temporary file write error");	unlink(tempname);	return;  }  /* Shut off signals during the update */  signal(SIGINT, SIG_IGN);  signal(SIGHUP, SIG_IGN);  signal(SIGQUIT, SIG_IGN);  if (usedrop) while (link(mailbox, lockname) != 0) {		if (++locktries >= LOCKTRIES) {			fprintf(stderr, "mail: couldn't lock maildrop for update\n");			return;		}		sleep(LOCKWAIT);	}  if (NULL == (boxfp = freopen(mailbox, "w", boxfp))) {	perror("mail: couldn't reopen maildrop");	fprintf(stderr, "mail may have been lost; look in %s\n", tempname);	if (usedrop) unlink(lockname);	return;  }  unlink(tempname);  while ((c = getc(tempfp)) != EOF) putc(c, boxfp);  fclose(boxfp);  if (usedrop) unlink(lockname);}void printlet(let, tofp)struct letter *let;FILE *tofp;{  off_t current, limit;  int c;  fseek(boxfp, (current = let->location), 0);  limit = (NULL != let->next) ? let->next->location : -1;  while (current != limit && (c = getc(boxfp)) != EOF) {	putc(c, tofp);	++current;  }}void doshell(command)char *command;{  int waitstat, pid;  char *shell;  if (NULL == (shell = getenv("SHELL"))) shell = SHELL;  if ((pid = fork()) < 0) {	perror("mail: couldn't fork");	return;  } else if (pid != 0) {	/* parent */	wait(&waitstat);	return;  }  /* Child */  setgid(getgid());  setuid(getuid());  umask(oldmask);  execl(shell, shell, "-c", command, (char *) NULL);  fprintf(stderr, "can't exec shell\n");  exit(127);}void usage(){  fprintf(stderr, "usage: mail [-v] user [...]\n");  fprintf(stderr, "       mail [-epqr] [-f file] [-t arg]\n");}char *basename(name)char *name;{  char *p;  if (NULL == (p = rindex(name, '/')))	return name;  else	return p + 1;}char *whoami(){  struct passwd *pw;  if (NULL != (pw = getpwuid(getuid())))	return pw->pw_name;  else	return "nobody";}void dohelp(){  FILE *fp;  char buffer[80];  if ( (fp = fopen(HELPFILE, "r")) == NULL)	fprintf(stdout, "can't open helpfile %s\n", HELPFILE);  else	while (fgets(buffer, 80, fp))		fputs(buffer, stdout);}int filesize(name)char *name ;{  struct stat buf;   if (stat(name, &buf) == -1)	buf.st_size = 0L;  return (buf.st_size ? 1 : 0);}

⌨️ 快捷键说明

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