summaryrefslogtreecommitdiffstats
path: root/crypto/heimdal/appl/popper/pop_updt.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/heimdal/appl/popper/pop_updt.c')
-rw-r--r--crypto/heimdal/appl/popper/pop_updt.c199
1 files changed, 199 insertions, 0 deletions
diff --git a/crypto/heimdal/appl/popper/pop_updt.c b/crypto/heimdal/appl/popper/pop_updt.c
new file mode 100644
index 0000000..0130132
--- /dev/null
+++ b/crypto/heimdal/appl/popper/pop_updt.c
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 1989 Regents of the University of California.
+ * All rights reserved. The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+#include <popper.h>
+RCSID("$Id: pop_updt.c,v 1.19 1998/04/23 18:36:51 joda Exp $");
+
+static char standard_error[] =
+ "Error error updating primary drop. Mailbox unchanged";
+
+/*
+ * updt: Apply changes to a user's POP maildrop
+ */
+
+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));
+}
OpenPOWER on IntegriCloud