www.pudn.com > DTMS.rar > OPEN.C
#include "mail.h"
/* Open or create a database. Same arguments as open(). */
MAIL *
mail_open(const char *username, int oflag, int mode)
{
MAIL *mail;
int i, len;
char asciiptr[PTR_SZ + 1],
hash[(NHASH_DEF + 1) * PTR_SZ + 2];
/* +2 for newline and null */
struct stat statbuff;
/* Allocate a MAIL structure, and the buffers it needs */
len = strlen(username);
if ( (mail = _mail_alloc(len)) == NULL)
err_dump("_mail_alloc error for mail");
mail->oflag = oflag; /* save a copy of the open flags */
/* Open index file */
strcpy(mail->name, username);
strcat(mail->name, ".idx");
if ( (mail->idxfd = open(mail->name, oflag, mode)) < 0) {
_mail_free(mail);
return(NULL);
}
/* Open data file */
strcpy(mail->name + len, ".dat");
if ( (mail->datfd = open(mail->name, oflag, mode)) < 0) {
_mail_free(mail);
return(NULL);
}
/* If the database was created, we have to initialize it */
if ((oflag & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC)) {
/* Write lock the entire file so that we can stat
the file, check its size, and initialize it,
as an atomic operation. */
if (writew_lock(mail->idxfd, 0, SEEK_SET, 0) < 0)
err_dump("writew_lock error");
if (fstat(mail->idxfd, &statbuff) < 0)
err_sys("fstat error");
if (statbuff.st_size == 0) {
/* We have to build a list of (NHASH_DEF + 1) chain
ptrs with a value of 0. The +1 is for the free
list pointer that precedes the hash table. */
sprintf(asciiptr, "%*d", PTR_SZ, 0);
hash[0] = 0;
for (i = 0; i < (NHASH_DEF + 1); i++)
strcat(hash, asciiptr);
strcat(hash, "\n");
i = strlen(hash);
if (write(mail->idxfd, hash, i) != i)
err_dump("write error initializing index file");
}
if (un_lock(mail->idxfd, 0, SEEK_SET, 0) < 0)
err_dump("un_lock error");
}
mail->nhash = NHASH_DEF;/* hash table size */
mail->hashoff = HASH_OFF; /* offset in index file of hash table */
/* free list ptr always at FREE_OFF */
mail_rewind(mail);
return(mail);
}