1: /*
   2:  * Copyright (c) 1989 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  */
   6: 
   7: #if !defined(lint) && defined(lint)
   8: static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n";
   9: static char SccsId[] = "@(#)@(#)pop_updt.c	2.3.1  (2.11BSD) 1996/3/21";
  10: #endif not lint
  11: 
  12: #include <errno.h>
  13: #include <stdio.h>
  14: #include <sys/types.h>
  15: #include <strings.h>
  16: #include <sys/stat.h>
  17: #include <sys/file.h>
  18: #include "popper.h"
  19: 
  20: static char standard_error[] =
  21:     "Error error updating primary drop. Mailbox unchanged";
  22: 
  23: /*
  24:  *  updt:   Apply changes to a user's POP maildrop
  25:  */
  26: 
  27: int pop_updt (p)
  28: POP     *   p;
  29: {
  30:     FILE                *   md;                     /*  Stream pointer for
  31:                                                         the user's maildrop */
  32:     int                     mfd;                    /*  File descriptor for
  33:                                                         above */
  34:     char                    buffer[BUFSIZ];         /*  Read buffer */
  35: 
  36:     MsgInfoList         *   mp;                     /*  Pointer to message
  37:                                                         info list */
  38:     register int            msg_num;                /*  Current message
  39:                                                         counter */
  40:     register int            status_written;         /*  Status header field
  41:                                                         written */
  42:     int                     nchar;                  /* Bytes read/written */
  43: 
  44:     long                    offset;                 /* New mail offset */
  45: 
  46: #ifdef DEBUG
  47:     if (p->debug) {
  48:         pop_log(p,POP_DEBUG,"Performing maildrop update...");
  49:         pop_log(p,POP_DEBUG,"Checking to see if all messages were deleted");
  50:     }
  51: #endif DEBUG
  52: 
  53:     if (p->msgs_deleted == p->msg_count) {
  54:         /* Truncate before close, to avoid race condition,  DO NOT UNLINK!
  55:            Another process may have opened,  and not yet tried to lock */
  56:         (void)ftruncate ((int)fileno(p->drop),0L);
  57:         (void)fclose(p->drop) ;
  58:         return (POP_SUCCESS);
  59:     }
  60: 
  61: #ifdef DEBUG
  62:     if (p->debug)
  63:         pop_log(p,POP_DEBUG,"Opening mail drop \"%s\"",p->drop_name);
  64: #endif DEBUG
  65: 
  66:     /*  Open the user's real maildrop */
  67:     if ((mfd = open(p->drop_name,O_RDWR|O_CREAT,0600)) == -1 ||
  68:         (md = fdopen(mfd,"r+")) == NULL) {
  69:         return pop_msg(p,POP_FAILURE,standard_error);
  70:     }
  71: 
  72:     /*  Lock the user's real mail drop */
  73:     if ( flock(mfd,LOCK_EX) == -1 ) {
  74:         (void)fclose(md) ;
  75:         return pop_msg(p,POP_FAILURE, "flock: '%s': %s", p->temp_drop,
  76:             strerror(errno));
  77:     }
  78: 
  79:     /* Go to the right places */
  80:     offset = lseek((int)fileno(p->drop),0L,L_XTND) ;
  81: 
  82:     /*  Append any messages that may have arrived during the session
  83:         to the temporary maildrop */
  84:     while ((nchar=read(mfd,buffer,BUFSIZ)) > 0)
  85:         if ( nchar != write((int)fileno(p->drop),buffer,nchar) ) {
  86:             nchar = -1;
  87:             break ;
  88:         }
  89:     if ( nchar != 0 ) {
  90:         (void)fclose(md) ;
  91:         (void)ftruncate((int)fileno(p->drop),offset) ;
  92:         (void)fclose(p->drop) ;
  93:         return pop_msg(p,POP_FAILURE,standard_error);
  94:     }
  95: 
  96:     rewind(md);
  97:     (void)ftruncate(mfd,0L) ;
  98: 
  99:     /* Synch stdio and the kernel for the POP drop */
 100:     rewind(p->drop);
 101:     (void)lseek((int)fileno(p->drop),0L,L_SET);
 102: 
 103:     /*  Transfer messages not flagged for deletion from the temporary
 104:         maildrop to the new maildrop */
 105: #ifdef DEBUG
 106:     if (p->debug)
 107:         pop_log(p,POP_DEBUG,"Creating new maildrop \"%s\" from \"%s\"",
 108:                 p->drop_name,p->temp_drop);
 109: #endif DEBUG
 110: 
 111:     for (msg_num = 0; msg_num < p->msg_count; ++msg_num) {
 112: 
 113:         int doing_body;
 114: 
 115:         /*  Get a pointer to the message information list */
 116:         mp = &p->mlp[msg_num];
 117: 
 118:         if (mp->del_flag) {
 119: #ifdef DEBUG
 120:             if(p->debug)
 121:                 pop_log(p,POP_DEBUG,
 122:                     "Message %u flagged for deletion.",mp->number);
 123: #endif DEBUG
 124:             continue;
 125:         }
 126: 
 127:         (void)fseek(p->drop,mp->offset,0);
 128: 
 129: #ifdef DEBUG
 130:         if(p->debug)
 131:             pop_log(p,POP_DEBUG,"Copying message %u.",mp->number);
 132: #endif DEBUG
 133:         for(status_written = doing_body = 0 ;
 134:             fgets(buffer,MAXMSGLINELEN,p->drop);) {
 135: 
 136:             if (doing_body == 0) { /* Header */
 137: 
 138:                 /*  Update the message status */
 139:                 if (strncasecmp(buffer,"Status:",7) == 0) {
 140:                     if (mp->retr_flag)
 141:                         (void)fputs("Status: RO\n",md);
 142:                     else
 143:                         (void)fputs(buffer, md);
 144:                     status_written++;
 145:                     continue;
 146:                 }
 147:                 /*  A blank line signals the end of the header. */
 148:                 if (*buffer == '\n') {
 149:                     doing_body = 1;
 150:                     if (status_written == 0) {
 151:                         if (mp->retr_flag)
 152:                             (void)fputs("Status: RO\n\n",md);
 153:                         else
 154:                             (void)fputs("Status: U\n\n",md);
 155:                     }
 156:                     else (void)fputs ("\n", md);
 157:                     continue;
 158:                 }
 159:                 /*  Save another header line */
 160:                 (void)fputs (buffer, md);
 161:             }
 162:             else { /* Body */
 163:                 if (strncmp(buffer,"From ",5) == 0) break;
 164:                 (void)fputs (buffer, md);
 165:             }
 166:         }
 167:     }
 168: 
 169:     /* flush and check for errors now!  The new mail will writen
 170:        without stdio,  since we need not separate messages */
 171: 
 172:     (void)fflush(md) ;
 173:     if (ferror(md)) {
 174:         (void)ftruncate(mfd,0L) ;
 175:         (void)fclose(md) ;
 176:         (void)fclose(p->drop) ;
 177:         return pop_msg(p,POP_FAILURE,standard_error);
 178:     }
 179: 
 180:     /* Go to start of new mail if any */
 181:     (void)lseek((int)fileno(p->drop),offset,L_SET);
 182: 
 183:     while((nchar=read((int)fileno(p->drop),buffer,BUFSIZ)) > 0)
 184:         if ( nchar != write(mfd,buffer,nchar) ) {
 185:             nchar = -1;
 186:             break ;
 187:         }
 188:     if ( nchar != 0 ) {
 189:         (void)ftruncate(mfd,0L) ;
 190:         (void)fclose(md) ;
 191:         (void)fclose(p->drop) ;
 192:         return pop_msg(p,POP_FAILURE,standard_error);
 193:     }
 194: 
 195:     /*  Close the maildrop and empty temporary maildrop */
 196:     (void)fclose(md);
 197:     (void)ftruncate((int)fileno(p->drop),0L);
 198:     (void)fclose(p->drop);
 199: 
 200:     return(pop_quit(p));
 201: }

Defined functions

pop_updt defined in line 27; used 1 times

Defined variables

SccsId defined in line 9; never used
copyright defined in line 8; never used
standard_error defined in line 20; used 4 times
Last modified: 1996-03-22
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3677
Valid CSS Valid XHTML 1.0 Strict