示例#1
0
文件: alias.c 项目: wfp5p/elm
void alias(void)
{
/*
 *	Work with alias commands...
 */

	char name[NLEN], *address, buffer[SLEN];
	char *commap;
	static int  newaliases = 0;
	int  ch, i;
	int nutitle = 0;
	int too_long;

/*
 *	We're going to try to match the way elm does it at
 * 	he main menu.  I probably won't be able to use any
 *	main menu routines, but I will "borrow" from them. RLH
 */

	alias_main_state();		/* Save globals for return to main menu */

	open_alias_files(FALSE);	/* First, read the alias files. RLH */

	alias_screen(newaliases);

	while (1) {

	  redraw = 0;
	  nucurr = 0;
	  nufoot = 0;

	  prompt(nls_Prompt);
	  CleartoEOLN();
	  ch = GetKey(0);

	  MoveCursor(LINES-3,strlen(nls_Prompt)); CleartoEOS();

	  dprint(3, (debugfile, "\n-- Alias command: %c\n\n", ch));

	  switch (ch) {
	    case '?': redraw += alias_help();			break;

#ifdef ALLOW_SUBSHELL
	    case '!' : WriteChar('!');
	      alias_main_state(); /** reload index screen vars **/
	      redraw += subshell();
	      alias_main_state(); /** reload alias screen vars **/
	      break;
#endif /* ALLOW_SUBSHELL */

	    case '$': PutLine(-1, -1, catgets(elm_msg_cat,
					AliasesSet, AliasesResync,
					"Resynchronize aliases..."));
	           /*
	            * Process deletions and then see if we need to
	            * re-run the "newalias" routine.
	            */
		      if (resync_aliases(newaliases)) {
		        install_aliases();
	                newaliases = 0;
		        redraw++;
		      }
		      break;

	    case 'a': PutLine(-1, -1, catgets(elm_msg_cat,
					AliasesSet, AliasesAddCurrent,
					"Add address from current message..."));
		      clear_error();
		      if (add_current_alias()) {
		          newaliases++;
		          nutitle++;
		      }
		      break;

	    case 'c':
	              if (curr_alias > 0) {
			  PutLine(-1, -1, catgets(elm_msg_cat,
	                              AliasesSet, AliasesReplaceCurrent,
	                              "Replace current alias in database..."));
		          clear_error();
		          if (add_alias(TRUE, curr_alias-1)) {
		              newaliases++;
		              nutitle++;
		          }
	              }
	              else {
		          show_error(catgets(elm_msg_cat,
	                          AliasesSet, AliasesNoneToReplace,
				  "Warning: no aliases to replace!"));
	              }
		      break;

	    case 'e': PutLine(LINES-3, strlen(nls_Prompt),
	                  catgets(elm_msg_cat, AliasesSet, AliasesEdit,
	                      "Edit %s..."), ALIAS_TEXT);
	           /*
	            * Process aliases.text for deletions, etc.  You
	            * have to do this *before* checking current because
	            * all aliases could be marked for deletion.
	            */
	              (void) resync_aliases(newaliases);
	              if (edit_aliases_text()) {
	                  newaliases = 0;
	              }
		      redraw++;
		      break;

	    case 'm':
	              if (curr_alias > 0) {
			  PutLine(-1, -1, catgets(elm_msg_cat,
					  AliasesSet, AliasesMail, "Mail..."));
	                  redraw += a_sendmsg();
	              }
	              else {
		          show_error(catgets(elm_msg_cat,
	                          AliasesSet, AliasesNoneToMail,
				  "Warning: no aliases to send mail to!"));
	              }
		      break;

	    case 'n': PutLine(-1, -1, catgets(elm_msg_cat,
					AliasesSet, AliasesAddNew,
					"Add a new alias to database..."));
		      clear_error();
		      if (add_alias(FALSE, -1)) {
		          newaliases++;
		          nutitle++;
		      }
		      break;

	    case 'q':
	    case 'Q':
	    case 'i':
	    case 'I':
	    case 'r':
	    case 'R': PutLine(-1, -1, catgets(elm_msg_cat,
	    				AliasesSet, AliasesAddReturn,
					"Return to main menu..."));
	           /*
	            * leaving the alias system.  Must check for
	            * pending deletes, etc.  prompt is set to FALSE
	            * on uppercase letters so that deletions are
	            * NOT queried.
	            */
	              if (delete_aliases(newaliases, islower(ch))) {
	                install_aliases();
	                newaliases = 0;
	              }
		      clear_error();
		      alias_main_state();		/* Done with aliases. */
		      return;

	    case RETURN:
	    case LINE_FEED:
	    case ' ':
	    case 'v':
		      if (newaliases) {		/* Need this ?? */
		          show_error(catgets(elm_msg_cat,
	                          AliasesSet, AliasesNotInstalled,
				  "Warning: new aliases not installed yet!"));
	              }

	              if (curr_alias > 0) {
	                  if (aliases[curr_alias-1]->type & GROUP) {
	                      PutLine(LINES-1, 0, catgets(elm_msg_cat,
	                              AliasesSet, AliasesGroupAlias,
				      "Group alias: %-60.60s"),
	                          aliases[curr_alias-1]->address);
		          }
		          else {
	                      PutLine(LINES-1, 0, catgets(elm_msg_cat,
	                              AliasesSet, AliasesAliasedAddress,
				      "Aliased address: %-60.60s"),
	                          aliases[curr_alias-1]->address);
		          }
		      }
	              else {
		          show_error(catgets(elm_msg_cat,
	                          AliasesSet, AliasesNoneToView,
				  "Warning: no aliases to view!"));
		      }
		      break;

	    case 'x':
	    case 'X': PutLine(-1, -1, catgets(elm_msg_cat,
	    				AliasesSet, AliasesAddReturn,
					"Return to main menu..."));
	              exit_alias();
		      clear_error();
		      alias_main_state();		/* Done with aliases. */
		      return;

	    case 'f':
	    case 'F':
	              if (curr_alias > 0) {
		          clear_error();
		          strcpy(name, aliases[curr_alias-1]->alias);
		          if (ch == 'F') {
		              strcpy(buffer, catgets(elm_msg_cat,
	                              AliasesSet, AliasesFullyExpanded,
				      "Fully expand alias: "));
		              PutLine(LINES-2, 0, buffer);
			      if (enter_string(name, sizeof(name), -1, -1,
					  ESTR_REPLACE) < 0 || name[0] == '\0')
				break;
		          }
	                  too_long = FALSE;
		          address = get_alias_address(name, TRUE, &too_long);
		          if (address != NULL) {
		              while (TRUE) {
	                          ClearScreen();
			          PutLine(2,0, catgets(elm_msg_cat,
	                                  AliasesSet, AliasesAliasedFull,
					  "Aliased address for:\t%s\n\r"),
	                              name);
		                  i = 4;
		                  while (i < LINES-2) {
		                      if ((commap = strchr(address, (int)','))
	                                          == NULL) {
		                          PutLine(i, 4, address);
		                          break;
		                      }
		                      *commap = '\0';
		                      PutLine(i++, 4, address);
		                      address = commap+2;
		                  }
	                          PutLine(LINES-1, 0, catgets(elm_msg_cat,
	                                  AliasesSet, AliasesPressReturn,
					  "Press <return> to continue."));
			          (void) ReadCh();
		                  if (commap == NULL) {
			              redraw++;
		                      break;
		                  }
		              }
		          }
	                  else if (! too_long) {
			      show_error(catgets(elm_msg_cat,
	                              AliasesSet, AliasesNotFound,
				      "Not found."));
		          }
		      }
	              else {
		          show_error(catgets(elm_msg_cat,
	                          AliasesSet, AliasesNoneToView,
				  "Warning: no aliases to view!"));
		      }
		      break;

	  case KEY_REDRAW:
		      redraw = 1;
		      break;

	 /*
	  * None of the menu specific commands were chosen, therefore
	  * it must be a "motion" command (or an error).
	  */
	    default	: motion(ch);

	  }

	  if (redraw) {			/* Redraw screen if necessary */
	      alias_screen(newaliases);
	      nutitle = 0;
	  }

	  if (nutitle) {		/* Redraw title if necessary */
	      alias_title(newaliases);
	      nutitle = 0;
	  }

	  check_range();

	  if (nucurr == NEW_PAGE)
	    show_headers();
	  else if (nucurr == SAME_PAGE)
	    show_current();
	  else if (nufoot) {
	    if (mini_menu) {
	      MoveCursor(LINES-7, 0);
              CleartoEOS();
	      show_alias_menu();
	    }
	    else {
	      MoveCursor(LINES-4, 0);
	      CleartoEOS();
	    }
	    show_last_error();	/* for those operations that have to
				 * clear the footer except for a message.
				 */
	  }
	}			/* BIG while loop... */
}
示例#2
0
int delivery(const char *mailbox)
{
FormatMbox	format_mbox;

	if (format_mbox.HasMsg())	return (0);

DeliverDotLock	dotlock;
Buffer	b;

	if ( *mailbox == '!' || *mailbox == '|' )
	{
	Buffer	cmdbuf;

		if (*mailbox == '!')
		{
			b="SENDMAIL";

		const char *sendmail=GetVarStr(b);

			cmdbuf=sendmail;

			cmdbuf += " -f '' ";
			cmdbuf += mailbox+1;
		}
		else
			cmdbuf= mailbox+1;

		cmdbuf += '\0';

		if (VerboseLevel() > 0)
			merr << "maildrop: Delivering to |" <<
				(const char *)cmdbuf << "\n";

	PipeFds	pipe;

		if (pipe.Pipe())
			throw "Cannot create pipe.";

	pid_t	pid=fork();

		if (pid < 0)
			throw "Cannot fork.";

		if (pid == 0)
		{
			pipe.close1();
			dup2(pipe.fds[0], 0);
			pipe.close0();

			try
			{
				subshell(cmdbuf);
			}
			catch (const char *p)
			{
				if (write(2, p, strlen(p)) < 0 ||
				    write(2, "\n", 1) < 0)
					; /* ignored */
				_exit(100);
			}
#if NEED_NONCONST_EXCEPTIONS
			catch (char *p)
			{
				if (write(2, p, strlen(p)) < 0 ||
				    write(2, "\n", 1) < 0)
					; /* ignored */
				_exit(100);
			}
#endif
			catch (...)
			{
				_exit(100);
			}
		}

	Mio	pipemio;

		pipe.close0();
		pipemio.fd(pipe.fds[1]);
		pipe.fds[1]= -1;
		format_mbox.Init(0);

	int	rc=format_mbox.DeliverTo(pipemio);
	int	wait_stat;

		while (wait(&wait_stat) != pid)
			;

		if (wait_stat == 0)
			rc=0;

		log(mailbox, rc || wait_stat, format_mbox);

		{
		Buffer	name, val;

			if (rc)	wait_stat= -1;
			else wait_stat= WIFEXITED(wait_stat)
				? WEXITSTATUS(wait_stat):-1;

			val.append( (unsigned long)wait_stat);
			name="EXITCODE";
			SetVar(name, val);
		}

		if (rc)	return (-1);
	}
	else if (Maildir::IsMaildir(mailbox))
	{
	Maildir	deliver_maildir;
	Mio	deliver_file;

		if ( deliver_maildir.MaildirOpen(mailbox, deliver_file,
			maildrop.msgptr->MessageSize()) < 0)
		{
#if HAVE_COURIER
			throw 75;
#else
			throw 77;
#endif
		}

		format_mbox.Init(0);
		if (format_mbox.DeliverTo(deliver_file))
		{
			log(mailbox, -1, format_mbox);
			return (-1);
		}
		deliver_maildir.MaildirSave();
		log(mailbox, 0, format_mbox);
	}
	else		// Delivering to a mailbox (hopefully)
	{
		if (VerboseLevel() > 0)
			merr << "maildrop: Delivering to " << mailbox << "\n";

#if	USE_DOTLOCK
		dotlock.LockMailbox(mailbox);
#endif

		struct	stat	stat_buf;
		Mio	mio;
		Buffer name_buf;

		name_buf="UMASK";
		const char *um=GetVarStr(name_buf);
		unsigned int umask_val=077;

		sscanf(um, "%o", &umask_val);

		umask_val=umask(umask_val);

		if (mio.Open(mailbox, O_CREAT | O_WRONLY, 0666) < 0)
		{
			umask_val=umask(umask_val);
			throw "Unable to open mailbox.";
		}
		umask_val=umask(umask_val);

		if (fstat(mio.fd(), &stat_buf) < 0)
			throw "Unable to open mailbox.";

#if	USE_FLOCK

		if (VerboseLevel() > 4)
			merr << "maildrop: Flock()ing " << mailbox << ".\n";

		FileLock::do_filelock(mio.fd());
#endif
		if (S_ISREG(stat_buf.st_mode))
		{
			if (mio.seek(0L, SEEK_END) < 0)
				throw "Seek error on mailbox.";
			dotlock.trap_truncate(mio.fd(), stat_buf.st_size);
		}

		if (VerboseLevel() > 4)
			merr << "maildrop: Appending to " << mailbox << ".\n";

		try
		{
			format_mbox.Init(1);

			if ((stat_buf.st_size > 0 &&
			     mio.write(
#if	CRLF_TERM
				       "\r\n", 2
#else
				       "\n", 1
#endif
				       ) < 0) ||
			    format_mbox.DeliverTo(mio))
			{
				dotlock.truncate();
				log(mailbox, -1, format_mbox);
				return (-1);
			}
		}
		catch (...)
		{
			dotlock.truncate();
			log(mailbox, -1, format_mbox);
			throw;
		}
		log(mailbox, 0, format_mbox);
	}

	if (VerboseLevel() > 4)
		merr << "maildrop: Delivery complete.\n";

	return (0);
}