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);
}