cdb_seek.c
author "Tomas Zeman <tomas.zeman@sun.com>"
Fri, 19 Oct 2007 14:06:22 +0200
changeset 0 068428edee47
permissions -rw-r--r--
Imported qmail-1.03
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
     1
#include <sys/types.h>
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
     2
#include <errno.h>
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
     3
extern int errno;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
     4
#include "cdb.h"
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
     5
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
     6
#ifndef SEEK_SET
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
     7
#define SEEK_SET 0
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
     8
#endif
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
     9
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    10
int cdb_bread(fd,buf,len)
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    11
int fd;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    12
char *buf;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    13
int len;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    14
{
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    15
  int r;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    16
  while (len > 0) {
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    17
    do
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    18
      r = read(fd,buf,len);
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    19
    while ((r == -1) && (errno == EINTR));
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    20
    if (r == -1) return -1;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    21
    if (r == 0) { errno = EIO; return -1; }
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    22
    buf += r;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    23
    len -= r;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    24
  }
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    25
  return 0;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    26
}
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    27
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    28
static int match(fd,key,len)
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    29
int fd;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    30
char *key;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    31
unsigned int len;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    32
{
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    33
  char buf[32];
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    34
  int n;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    35
  int i;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    36
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    37
  while (len > 0) {
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    38
    n = sizeof(buf);
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    39
    if (n > len) n = len;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    40
    if (cdb_bread(fd,buf,n) == -1) return -1;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    41
    for (i = 0;i < n;++i) if (buf[i] != key[i]) return 0;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    42
    key += n;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    43
    len -= n;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    44
  }
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    45
  return 1;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    46
}
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    47
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    48
int cdb_seek(fd,key,len,dlen)
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    49
int fd;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    50
char *key;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    51
unsigned int len;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    52
uint32 *dlen;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    53
{
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    54
  char packbuf[8];
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    55
  uint32 pos;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    56
  uint32 h;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    57
  uint32 lenhash;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    58
  uint32 h2;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    59
  uint32 loop;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    60
  uint32 poskd;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    61
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    62
  h = cdb_hash(key,len);
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    63
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    64
  pos = 8 * (h & 255);
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    65
  if (lseek(fd,(off_t) pos,SEEK_SET) == -1) return -1;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    66
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    67
  if (cdb_bread(fd,packbuf,8) == -1) return -1;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    68
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    69
  pos = cdb_unpack(packbuf);
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    70
  lenhash = cdb_unpack(packbuf + 4);
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    71
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    72
  if (!lenhash) return 0;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    73
  h2 = (h >> 8) % lenhash;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    74
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    75
  for (loop = 0;loop < lenhash;++loop) {
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    76
    if (lseek(fd,(off_t) (pos + 8 * h2),SEEK_SET) == -1) return -1;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    77
    if (cdb_bread(fd,packbuf,8) == -1) return -1;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    78
    poskd = cdb_unpack(packbuf + 4);
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    79
    if (!poskd) return 0;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    80
    if (cdb_unpack(packbuf) == h) {
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    81
      if (lseek(fd,(off_t) poskd,SEEK_SET) == -1) return -1;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    82
      if (cdb_bread(fd,packbuf,8) == -1) return -1;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    83
      if (cdb_unpack(packbuf) == len)
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    84
	switch(match(fd,key,len)) {
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    85
	  case -1:
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    86
	    return -1;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    87
	  case 1:
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    88
	    *dlen = cdb_unpack(packbuf + 4);
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    89
	    return 1;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    90
	}
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    91
    }
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    92
    if (++h2 == lenhash) h2 = 0;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    93
  }
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    94
  return 0;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    95
}