示例#1
0
int
pop_updt (POP *p)
{
    FILE                *   md;                     /*  Stream pointer for
                                                        the user's maildrop */
    int                     mfd;                    /*  File descriptor for
                                                        above */
    char                    buffer[BUFSIZ];         /*  Read buffer */

    MsgInfoList         *   mp;                     /*  Pointer to message
                                                        info list */
    int		            msg_num;                /*  Current message
                                                        counter */
    int			    status_written;         /*  Status header field
                                                        written */
    int                     nchar;                  /* Bytes read/written */

    long                    offset;                 /* New mail offset */

    int			    blank_line;

#ifdef DEBUG
    if (p->debug) {
        pop_log(p,POP_DEBUG,"Performing maildrop update...");
        pop_log(p,POP_DEBUG,"Checking to see if all messages were deleted");
    }
#endif /* DEBUG */

    if(IS_MAILDIR(p))
	return pop_maildir_update(p);

    if (p->msgs_deleted == p->msg_count) {
        /* Truncate before close, to avoid race condition,  DO NOT UNLINK!
           Another process may have opened,  and not yet tried to lock */
        ftruncate ((int)fileno(p->drop),0);
        fclose(p->drop) ;
        return (POP_SUCCESS);
    }

#ifdef DEBUG
    if (p->debug)
        pop_log(p,POP_DEBUG,"Opening mail drop \"%s\"",p->drop_name);
#endif /* DEBUG */

    /*  Open the user's real maildrop */
    if ((mfd = open(p->drop_name,O_RDWR|O_CREAT,0600)) == -1 ||
        (md = fdopen(mfd,"r+")) == NULL) {
        return pop_msg(p,POP_FAILURE,standard_error);
    }

    /*  Lock the user's real mail drop */
    if ( flock(mfd, LOCK_EX) == -1 ) {
        fclose(md) ;
        return pop_msg(p,POP_FAILURE, "flock: '%s': %s", p->temp_drop,
		       strerror(errno));
    }

    /* Go to the right places */
    offset = lseek((int)fileno(p->drop),0,SEEK_END) ;

    /*  Append any messages that may have arrived during the session
        to the temporary maildrop */
    while ((nchar=read(mfd,buffer,BUFSIZ)) > 0)
        if ( nchar != write((int)fileno(p->drop),buffer,nchar) ) {
            nchar = -1;
            break ;
        }
    if ( nchar != 0 ) {
        fclose(md) ;
        ftruncate((int)fileno(p->drop),(int)offset) ;
        fclose(p->drop) ;
        return pop_msg(p,POP_FAILURE,standard_error);
    }

    rewind(md);
    lseek(mfd,0,SEEK_SET);
    ftruncate(mfd,0) ;

    /* Synch stdio and the kernel for the POP drop */
    rewind(p->drop);
    lseek((int)fileno(p->drop),0,SEEK_SET);

    /*  Transfer messages not flagged for deletion from the temporary
        maildrop to the new maildrop */
#ifdef DEBUG
    if (p->debug)
        pop_log(p,POP_DEBUG,"Creating new maildrop \"%s\" from \"%s\"",
                p->drop_name,p->temp_drop);
#endif /* DEBUG */

    for (msg_num = 0; msg_num < p->msg_count; ++msg_num) {

        int doing_body;

        /*  Get a pointer to the message information list */
        mp = &p->mlp[msg_num];

        if (mp->flags & DEL_FLAG) {
#ifdef DEBUG
            if(p->debug)
                pop_log(p,POP_DEBUG,
                    "Message %d flagged for deletion.",mp->number);
#endif /* DEBUG */
            continue;
        }

        fseek(p->drop,mp->offset,0);

#ifdef DEBUG
        if(p->debug)
            pop_log(p,POP_DEBUG,"Copying message %d.",mp->number);
#endif /* DEBUG */
	blank_line = 1;
        for(status_written = doing_body = 0 ;
            fgets(buffer,MAXMSGLINELEN,p->drop);) {

            if (doing_body == 0) { /* Header */

                /*  Update the message status */
                if (strncasecmp(buffer,"Status:",7) == 0) {
                    if (mp->flags & RETR_FLAG)
                        fputs("Status: RO\n",md);
                    else
                        fputs(buffer, md);
                    status_written++;
                    continue;
                }
                /*  A blank line signals the end of the header. */
                if (*buffer == '\n') {
                    doing_body = 1;
                    if (status_written == 0) {
                        if (mp->flags & RETR_FLAG)
                            fputs("Status: RO\n\n",md);
                        else
                            fputs("Status: U\n\n",md);
                    }
                    else fputs ("\n", md);
                    continue;
                }
                /*  Save another header line */
                fputs (buffer, md);
            }
            else { /* Body */
                if (blank_line && strncmp(buffer,"From ",5) == 0) break;
                fputs (buffer, md);
		blank_line = (*buffer == '\n');
            }
        }
    }

    /* flush and check for errors now!  The new mail will writen
       without stdio,  since we need not separate messages */

    fflush(md) ;
    if (ferror(md)) {
        ftruncate(mfd,0) ;
        fclose(md) ;
        fclose(p->drop) ;
        return pop_msg(p,POP_FAILURE,standard_error);
    }

    /* Go to start of new mail if any */
    lseek((int)fileno(p->drop),offset,SEEK_SET);

    while((nchar=read((int)fileno(p->drop),buffer,BUFSIZ)) > 0)
        if ( nchar != write(mfd,buffer,nchar) ) {
            nchar = -1;
            break ;
        }
    if ( nchar != 0 ) {
        ftruncate(mfd,0) ;
        fclose(md) ;
        fclose(p->drop) ;
        return pop_msg(p,POP_FAILURE,standard_error);
    }

    /*  Close the maildrop and empty temporary maildrop */
    fclose(md);
    ftruncate((int)fileno(p->drop),0);
    fclose(p->drop);

    return(pop_quit(p));
}
示例#2
0
static int
popmail (char *mailbox, char *outfile, int preserve, char *password, int reverse_order)
{
  int nmsgs, nbytes;
  register int i;
  int mbfi;
  FILE *mbf;
  char *getenv (const char *);
  popserver server;
  int start, end, increment;
  char *user, *hostname;

  user = mailbox;
  if ((hostname = strchr (mailbox, ':')))
    *hostname++ = '\0';

  server = pop_open (hostname, user, password, POP_NO_GETPASS);
  if (! server)
    {
      error ("Error connecting to POP server: %s", pop_error, 0);
      return EXIT_FAILURE;
    }

  if (pop_stat (server, &nmsgs, &nbytes))
    {
      error ("Error getting message count from POP server: %s", pop_error, 0);
      return EXIT_FAILURE;
    }

  if (!nmsgs)
    {
      pop_close (server);
      return EXIT_SUCCESS;
    }

  mbfi = open (outfile, O_WRONLY | O_CREAT | O_EXCL, 0666);
  if (mbfi < 0)
    {
      pop_close (server);
      error ("Error in open: %s, %s", strerror (errno), outfile);
      return EXIT_FAILURE;
    }

  if (fchown (mbfi, getuid (), -1) != 0)
    {
      int fchown_errno = errno;
      struct stat st;
      if (fstat (mbfi, &st) != 0 || st.st_uid != getuid ())
	{
	  pop_close (server);
	  error ("Error in fchown: %s, %s", strerror (fchown_errno), outfile);
	  return EXIT_FAILURE;
	}
    }

  if ((mbf = fdopen (mbfi, "wb")) == NULL)
    {
      pop_close (server);
      error ("Error in fdopen: %s", strerror (errno), 0);
      close (mbfi);
      unlink (outfile);
      return EXIT_FAILURE;
    }

  if (reverse_order)
    {
      start = nmsgs;
      end = 1;
      increment = -1;
    }
  else
    {
      start = 1;
      end = nmsgs;
      increment = 1;
    }

  for (i = start; i * increment <= end * increment; i += increment)
    {
      mbx_delimit_begin (mbf);
      if (pop_retr (server, i, mbf) != OK)
	{
	  error ("%s", Errmsg, 0);
	  close (mbfi);
	  return EXIT_FAILURE;
	}
      mbx_delimit_end (mbf);
      fflush (mbf);
      if (ferror (mbf))
	{
	  error ("Error in fflush: %s", strerror (errno), 0);
	  pop_close (server);
	  close (mbfi);
	  return EXIT_FAILURE;
	}
    }

  /* On AFS, a call to write only modifies the file in the local
   *     workstation's AFS cache.  The changes are not written to the server
   *      until a call to fsync or close is made.  Users with AFS home
   *      directories have lost mail when over quota because these checks were
   *      not made in previous versions of movemail. */

#ifdef BSD_SYSTEM
  if (fsync (mbfi) < 0)
    {
      error ("Error in fsync: %s", strerror (errno), 0);
      return EXIT_FAILURE;
    }
#endif

  if (close (mbfi) == -1)
    {
      error ("Error in close: %s", strerror (errno), 0);
      return EXIT_FAILURE;
    }

  if (! preserve)
    for (i = 1; i <= nmsgs; i++)
      {
	if (pop_delete (server, i))
	  {
	    error ("Error from POP server: %s", pop_error, 0);
	    pop_close (server);
	    return EXIT_FAILURE;
	  }
      }

  if (pop_quit (server))
    {
      error ("Error from POP server: %s", pop_error, 0);
      return EXIT_FAILURE;
    }

  return EXIT_SUCCESS;
}
示例#3
0
文件: movemail.c 项目: fs814/emacs
static int
popmail (char *mailbox, char *outfile, int preserve, char *password, int reverse_order)
{
  int nmsgs, nbytes;
  register int i;
  int mbfi;
  FILE *mbf;
  popserver server;
  int start, end, increment;
  char *user, *hostname;

  user = mailbox;
  if ((hostname = strchr (mailbox, ':')))
    *hostname++ = '\0';

  server = pop_open (hostname, user, password, POP_NO_GETPASS);
  if (! server)
    {
      error ("Error connecting to POP server: %s", pop_error, 0);
      return EXIT_FAILURE;
    }

  if (pop_stat (server, &nmsgs, &nbytes))
    {
      error ("Error getting message count from POP server: %s", pop_error, 0);
      return EXIT_FAILURE;
    }

  if (!nmsgs)
    {
      pop_close (server);
      return EXIT_SUCCESS;
    }

  mbfi = open (outfile, O_WRONLY | O_BINARY | O_CREAT | O_EXCL, 0666);
  if (mbfi < 0)
    {
      pop_close (server);
      error ("Error in open: %s, %s", strerror (errno), outfile);
      return EXIT_FAILURE;
    }

  if (fchown (mbfi, getuid (), -1) != 0)
    {
      int fchown_errno = errno;
      struct stat st;
      if (fstat (mbfi, &st) != 0 || st.st_uid != getuid ())
	{
	  pop_close (server);
	  error ("Error in fchown: %s, %s", strerror (fchown_errno), outfile);
	  return EXIT_FAILURE;
	}
    }

  if ((mbf = fdopen (mbfi, "wb")) == NULL)
    {
      pop_close (server);
      error ("Error in fdopen: %s", strerror (errno), 0);
      close (mbfi);
      unlink (outfile);
      return EXIT_FAILURE;
    }

  if (reverse_order)
    {
      start = nmsgs;
      end = 1;
      increment = -1;
    }
  else
    {
      start = 1;
      end = nmsgs;
      increment = 1;
    }

  for (i = start; i * increment <= end * increment; i += increment)
    {
      mbx_delimit_begin (mbf);
      if (pop_retr (server, i, mbf) != OK)
	{
	  error ("%s", Errmsg, 0);
	  close (mbfi);
	  return EXIT_FAILURE;
	}
      mbx_delimit_end (mbf);
      fflush (mbf);
      if (ferror (mbf))
	{
	  error ("Error in fflush: %s", strerror (errno), 0);
	  pop_close (server);
	  close (mbfi);
	  return EXIT_FAILURE;
	}
    }

  if (fsync (mbfi) != 0 && errno != EINVAL)
    {
      error ("Error in fsync: %s", strerror (errno), 0);
      close (mbfi);
      return EXIT_FAILURE;
    }

  if (close (mbfi) != 0)
    {
      error ("Error in close: %s", strerror (errno), 0);
      return EXIT_FAILURE;
    }

  if (! preserve)
    for (i = 1; i <= nmsgs; i++)
      {
	if (pop_delete (server, i))
	  {
	    error ("Error from POP server: %s", pop_error, 0);
	    pop_close (server);
	    return EXIT_FAILURE;
	  }
      }

  if (pop_quit (server))
    {
      error ("Error from POP server: %s", pop_error, 0);
      return EXIT_FAILURE;
    }

  return EXIT_SUCCESS;
}