www.pudn.com > DTMS.rar > READIDX.C


#include	"mail.h"
#include			/* struct iovec */

/* Read the next index record.  We start at the specified offset in
 * the index file.  We read the index record into mail->idxbuf and
 * replace the separators with null bytes.  If all is OK we set
 * mail->datoff and mail->datlen to the offset and length of the
 * corresponding data record in the data file.  */

off_t
_mail_readidx(MAIL *mail, off_t offset,int flag)
{
	int	i,sepno;
	char	*ptr1, *ptr2,*ptr3,keybuff[IDXLEN_MAX],space[2];
        char    *ptr,*dlen,*doff;
	char	asciiptr[PTR_SZ + 1], asciilen[IDXLEN_SZ + 1];
	struct iovec	iov[2];

	/* Position index file and record the offset.  mail_nextrec()
	   calls us with offset==0, meaning read from current offset.
	   We still need to call lseek() to record the current offset. */
	if ( (mail->idxoff = lseek(mail->idxfd, offset,
				 offset == 0 ? SEEK_CUR : SEEK_SET)) == -1)
		err_dump("lseek error");

		/* Read the ascii chain ptr and the ascii length at
		   the front of the index record.  This tells us the
		   remaining size of the index record. */
	iov[0].iov_base = asciiptr;
	iov[0].iov_len  = PTR_SZ;
	iov[1].iov_base = asciilen;
	iov[1].iov_len  = IDXLEN_SZ;
	if ( (i = readv(mail->idxfd, &iov[0], 2)) != PTR_SZ + IDXLEN_SZ) {
		if (i == 0 && offset == 0)
			return(-1);		/* EOF for mail_nextrec() */
		err_dump("readv error of index record");
	}

	asciiptr[PTR_SZ] = 0;			/* null terminate */
	mail->ptrval = atol(asciiptr);	/* offset of next key in chain */
				/* this is our return value; always >= 0 */
	asciilen[IDXLEN_SZ] = 0;		/* null terminate */
	if ( (mail->idxlen = atoi(asciilen)) < IDXLEN_MIN ||
						mail->idxlen > IDXLEN_MAX)
		err_dump("invalid length");

		/* Now read the actual index record.  We read it into the key
		   buffer that we malloced when we opened the database. */
	if ( (i = read(mail->idxfd, mail->idxbuf, mail->idxlen)) != mail->idxlen)
		err_dump("read error of indexc record");
	if (mail->idxbuf[mail->idxlen-1] != '\n')
		err_dump("missing newline");	/* sanity checks */
	mail->idxbuf[mail->idxlen-1] = 0;	/* replace newline with null */

         sepno=0;
        if( (ptr1=strchr(mail->idxbuf,SEP))==NULL)  
             err_dump("missing first separator");
           else{
             sepno++;
            *ptr1++=0; 
             }  
       
		/* Find the separators in the index record */
	if ( (ptr2 = strchr(ptr1, SEP)) == NULL)
		err_dump("missing second separator");
	   else{
                 sepno++;
                *ptr2++=0;
                 ptr=ptr2;
                 } 
				/* replace SEP with null */
     if ( (ptr3=strchr(ptr2, SEP))!= NULL)
          {
           sepno++;
           *ptr3++=0; 
           ptr=ptr3;
           }

     if (strchr(ptr, SEP) != NULL)
		err_dump("too many separators");
       
     if(flag==REALIDX || (sepno==3 && flag==ANYIDX))
          { 
            if(sepno!=3)  
            err_dump("missing third separator");
            
            hint=ptr1;				
            doff=ptr2;
            dlen=ptr3;   
           
           }
           else if(flag==FREEIDX ||(sepno==2 && flag==ANYIDX))
                 {
                   if(sepno!=2)
                    err_dump("error in read free index");
                   
                   doff=ptr1;
                   dlen=ptr2;
                  }
       
		/* Get the starting offset and length of the data record */
	if ( (mail->datoff = atol(doff)) < 0)
		err_dump("starting offset < 0");
	if ( (mail->datlen = atol(dlen)) <= 0 || mail->datlen > DATLEN_MAX)
		err_dump("invalid length");

        if(flag==REALIDX)
        {
         space[0]='|';
         space[1]='\0'; 
         mail->keybuf=strcpy(keybuff,mail->idxbuf);
         strcat(mail->idxbuf,ptr1);
         strcat(mail->idxbuf,space); 
         }
             
	return(mail->ptrval);		/* return offset of next key in chain */
}