DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T p

⟦ced4caea1⟧ TextFile

    Length: 6869 (0x1ad5)
    Types: TextFile
    Names: »pop_dropinfo.c«

Derivation

└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit
    └─⟦ac17ffda3⟧ »EurOpenD3/mail/popper-1.7b1.tar.Z« 
        └─⟦d6ac5563a⟧ 
            └─⟦this⟧ »pop_dropinfo.c« 

TextFile

/*
 * Copyright (c) 1989 Regents of the University of California.
 * All rights reserved.  The Berkeley software License Agreement
 * specifies the terms and conditions for redistribution.
 */

#ifndef lint
static char copyright[] = "@(#) Copyright (c) 1989 Regents of the University of California.\n\ All rights reserved.\n";
static char SccsId[] = "@(#)pop_dropinfo.c  1.7 5/15/90";
#endif not lint

#include <errno.h>
#include <stdio.h>
#include <sys/types.h>
#include <strings.h>
#include <sys/stat.h>
#include <sys/file.h>
#include "popper.h"

extern int      errno;
extern int      sys_nerr;
extern char    *sys_errlist[];

/* 
 *  dropinfo:   Extract information about the POP maildrop and store 
 *  it for use by the other POP routines.
 */

pop_dropinfo(p)
POP     *   p;
{
    int                     mfd;                    /*  File descriptor for 
                                                        the user's maildrop */
    int                     dfd;                    /*  File descriptor for 
                                                        the SERVER maildrop */
    struct stat             drop_stat;              /*  Mail drop file status 
                                                        information */
    char                    buffer[BUFSIZ];         /*  Read buffer */
    MsgInfoList         *   mp;                     /*  Pointer to message 
                                                        info list */
    register int            msg_num;                /*  Current message 
                                                        counter */
    long                    offset;                 /*  Old/New boundary */

    int                     nchar;                  /*  Bytes written/read */

    /*  Initialize maildrop status variables in the POP parameter block */
    p->msg_count = 0;
    p->msgs_deleted = 0;
    p->last_msg = 0;
    p->bytes_deleted = 0;
    p->drop_size = 0;

    /*  Set the file creation mask */
    umask (POP_UMASK);

    /*  Create a temporary maildrop into which to copy the updated maildrop */
    sprintf(p->temp_drop,POP_DROP,p->user);

#ifdef DEBUG
    if(p->debug)
        pop_log(p,POP_DEBUG,"Creating temporary maildrop '%s'",
            p->temp_drop);
#endif DEBUG

    /* Open for append,  this solves the crash recovery problem */
    if ((dfd = open(p->temp_drop,O_RDWR|O_APPEND|O_CREAT,0666)) == -1){
        pop_log(p,POP_PRIORITY,
            "Unable to create temporary maildrop '%s': %s",p->temp_drop,
                (errno < sys_nerr) ? sys_errlist[errno] : "") ;
        return (POP_FAILURE);
    }

    /*  Lock the temporary maildrop */
    if ( flock (dfd, LOCK_EX|LOCK_NB) == -1 ) 
    switch(errno) {
        case EWOULDBLOCK:
            return pop_msg(p,POP_FAILURE,
                "Maildrop lock busy!  Is another session active?") ;
            /* NOTREACHED */
        default:
            return pop_msg(p,POP_FAILURE, "flock: '%s': %s", p->temp_drop,
                (errno < sys_nerr) ? sys_errlist[errno] : "") ;
            /* NOTREACHED */
        }
    
    /* May have grown or shrunk between open and lock! */
    offset = lseek(dfd,0,2) ;

    /*  Open the users maildrop, If this fails,  no harm in assuming empty */

    if ((mfd = open(p->drop_name,O_RDWR)) > 0) {

        /*  Lock the maildrop */
        if (flock (mfd,LOCK_EX) == -1) {
            close(mfd) ;
            return pop_msg(p,POP_FAILURE, "flock: '%s': %s", p->temp_drop,
                (errno < sys_nerr) ? sys_errlist[errno] : "");
        }

        /*  Copy the actual mail drop into the temporary mail drop */
        while ( (nchar=read(mfd,buffer,BUFSIZ)) > 0 )
            if ( nchar != write(dfd,buffer,nchar) ) {
                nchar = -1 ;
                break ;
            }

        if ( nchar != 0 ) {
            /* Error adding new mail.  Truncate to original size,
               and leave the maildrop as is.  The user will not 
               see the new mail until the error goes away.
               Should let them process the current backlog,  in case
               the error is a quota problem requiring deletions! */
            ftruncate(fileno(p->drop),offset) ;
        } else {
            /* Mail transferred!  Zero the mail drop NOW,  that we
               do not have to do gymnastics to figure out what's new
               and what is old later */
            ftruncate(mfd,0) ;
        }

        /*  Close the actual mail drop */
        close (mfd);
    }

    if ( (p->drop = fdopen(dfd,"a+")) == NULL ) {
        close(dfd) ;
        return pop_msg(p,POP_FAILURE,"Cannot assign stream for %s",
            p->temp_drop);
    }

    rewind (p->drop);

    /*  Allocate memory for message information structures */
    p->mlp = (MsgInfoList *) calloc (p->msg_count = ALLOC_MSGS,
        sizeof(MsgInfoList));
    if (p->mlp == NULL){
        fclose (p->drop);
        p->msg_count = 0;
        return pop_msg (p,POP_FAILURE,
            "Can't build message list for '%s': Out of memory", p->user);
    }

    rewind (p->drop);

    /*  Scan the file, loading the message information list with 
        information about each message */

    for (msg_num = p->drop_size = 0, mp = p->mlp - 1;
             fgets(buffer,MAXMSGLINELEN,p->drop);) {

        nchar  = strlen(buffer);
        if (strncmp(buffer,"From ",5) == 0) {

#ifdef DEBUG
            if(p->debug && msg_num > 0)
                pop_log(p,POP_DEBUG,
                    "Msg %d at offset %d is %d octets long and has %u lines.",
                        mp->number,mp->offset,mp->length,mp->lines);
#endif DEBUG

            if (++msg_num > p->msg_count) {
                p->mlp=(MsgInfoList *) realloc(p->mlp,
                    (p->msg_count+=ALLOC_MSGS)*sizeof(MsgInfoList));
                if (p->mlp == NULL){
                    fclose (p->drop);
                    p->msg_count = 0;
                    return pop_msg (p,POP_FAILURE,
                        "Can't build message list for '%s': Out of memory",
                            p->user);
                }
                mp = p->mlp + msg_num - 1;
            }
            ++mp;
            mp->number = msg_num;
            mp->length = 0;
            mp->lines = 0;
            mp->offset = ftell(p->drop) - nchar;
            mp->del_flag = FALSE;
            mp->retr_flag = FALSE;
        }
        mp->length += nchar;
        p->drop_size += nchar;
        mp->lines++;
    }
    p->msg_count = msg_num;

#ifdef DEBUG
    /* Report size of last message on break from loop.
       NB,  Do this only when we have at least one message ! */
    if(p->debug && msg_num > 0)
        pop_log(p,POP_DEBUG,
            "Msg %d at offset %d is %d octets long and has %u lines.\n",
                mp->number,mp->offset,mp->length,mp->lines);
#endif DEBUG

    return(POP_SUCCESS);
}