-/* $Id: d1_read.c,v 1.8.2.2 2005-04-23 16:31:54 adam Exp $
+/* $Id: d1_read.c,v 1.8.2.3 2006-03-24 13:47:29 adam Exp $
Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004
Index Data Aps
const char *tocode,
const char *fromcode)
{
+ yaz_log(LOG_DEBUG, "data1_iconv tocode=%s fromcode=%s", tocode, fromcode);
if (yaz_matchstr (tocode, fromcode))
{
WRBUF wrbuf = wrbuf_alloc();
+<?xml version="1.0" encoding="iso-8859-1"?>
<gils>
<Title>
-UTAH EARTHQUAKE EPICENTERS
+UTAH EARTHQUAKE EPICENTERS æ
<Acronym>
UUCCSEIS
</Acronym>
noinst_HEADERS = bfile.h bset.h charmap.h d1_attset.h d1_map.h \
-data1.h dfa.h dict.h direntz.h isam-codec.h isamb.h isamc.h isamg.h \
-isam.h isams.h mfile.h passwddb.h recctrl.h \
-res.h rsbetween.h rsbool.h rset.h rsisamb.h rsisamc.h rsisam.h \
-rsisams.h rsm_or.h rsnull.h rsprox.h rstemp.h set.h \
-sortidx.h str.h zebra-lock.h zebramap.h zebrautl.h \
-zebra_xpath.h
+data1.h dfa.h dict.h direntz.h isamb.h isamc.h isamd.h isamg.h isam.h \
+isams.h mfile.h passwddb.h recctrl.h res.h rsbetween.h rsbool.h rset.h \
+rsisamb.h rsisamc.h rsisamd.h rsisam.h rsisams.h rsm_or.h rsnull.h \
+rsprox.h rstemp.h set.h sortidx.h str.h zebra-lock.h zebramap.h zebrautl.h \
+zebra_xpath.h zebra-flock.h
include_HEADERS = zebraapi.h zebraver.h
--- /dev/null
+/* $Id: zebra-flock.h,v 1.1.2.1 2006-03-24 13:47:29 adam Exp $
+ Copyright (C) 1995-2005
+ Index Data ApS
+
+This file is part of the Zebra server.
+
+Zebra is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Zebra; see the file LICENSE.zebra. If not, write to the
+Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.
+*/
+
+#include <yaz/yconfig.h>
+
+#ifndef FLOCK_H
+#define FLOCK_H
+
+YAZ_BEGIN_CDECL
+
+typedef struct zebra_lock_info *ZebraLockHandle;
+
+YAZ_EXPORT
+ZebraLockHandle zebra_lock_create(const char *dir, const char *file);
+
+YAZ_EXPORT
+void zebra_lock_destroy (ZebraLockHandle h);
+
+YAZ_EXPORT
+int zebra_unlock (ZebraLockHandle h);
+YAZ_EXPORT
+char *zebra_mk_fname (const char *dir, const char *name);
+
+YAZ_EXPORT
+int zebra_lock_w (ZebraLockHandle h);
+YAZ_EXPORT
+int zebra_lock_r (ZebraLockHandle h);
+
+YAZ_END_CDECL
+
+#endif
-## $Id: Makefile.am,v 1.24 2004-08-04 08:35:23 adam Exp $
+## $Id: Makefile.am,v 1.23.2.1 2006-03-24 13:47:29 adam Exp $
noinst_PROGRAMS = apitest kdump
noinst_LIBRARIES = libzebra.a
libzebra_a_SOURCES = dir.c dirs.c trav.c kinput.c kcompare.c \
- attribute.c symtab.c recindex.c recstat.c lockutil.c \
+ attribute.c symtab.c recindex.c recstat.c \
zebraapi.c zinfo.c invstat.c sortidx.c compact.c zsets.c zrpn.c \
rank1.c trunc.c retrieve.c extract.c livcode.c \
index.h recindex.h recindxp.h \
zebrasrv_SOURCES = zserver.c
zebrash_SOURCES = zebrash.c
apitest_SOURCES = apitest.c
-kdump_SOURCES = kdump.c
+kdump_SOURCES=kdump.c kcompare.c
AM_CPPFLAGS = -I$(srcdir)/../include $(YAZINC) $(TCL_INCLUDE) -DDEFAULT_PROFILE_PATH=\"$(pkgdatadir)/tab\"
-/* $Id: index.h,v 1.109.2.1 2005-05-09 19:57:38 adam Exp $
+/* $Id: index.h,v 1.109.2.2 2006-03-24 13:47:29 adam Exp $
Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003
Index Data Aps
#include "zinfo.h"
#include <passwddb.h>
#include <rset.h>
+#include <zebra-flock.h>
YAZ_BEGIN_CDECL
#define FNAME_ORG_LOCK "zebraorg.LCK"
#define FNAME_TOUCH_TIME "zebraidx.time"
-typedef struct zebra_lock_info *ZebraLockHandle;
-ZebraLockHandle zebra_lock_create(const char *dir,
- const char *file, int excl_flag);
-void zebra_lock_destroy (ZebraLockHandle h);
-int zebra_lock (ZebraLockHandle h);
-int zebra_lock_nb (ZebraLockHandle h);
-int zebra_unlock (ZebraLockHandle h);
-int zebra_lock_fd (ZebraLockHandle h);
void zebra_lock_prefix (Res res, char *dst);
-char *zebra_mk_fname (const char *dir, const char *name);
-
-int zebra_lock_w (ZebraLockHandle h);
-int zebra_lock_r (ZebraLockHandle h);
void zebra_load_atts (data1_handle dh, Res res);
+++ /dev/null
-/* $Id: lockidx.c,v 1.22 2002-08-02 19:26:55 adam Exp $
- Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002
- Index Data Aps
-
-This file is part of the Zebra server.
-
-Zebra is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
-version.
-
-Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License
-along with Zebra; see the file LICENSE.zebra. If not, write to the
-Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.
-*/
-
-
-#include <stdio.h>
-#include <assert.h>
-#ifdef WIN32
-#include <io.h>
-#else
-#include <unistd.h>
-#endif
-#include <fcntl.h>
-#include <string.h>
-#include <errno.h>
-
-#include "index.h"
-#include "zserver.h"
-
-static ZebraLockHandle server_lock_main = NULL;
-static ZebraLockHandle server_lock_cmt = NULL;
-static ZebraLockHandle server_lock_org = NULL;
-
-int zebraIndexWait (ZebraHandle zh, int commitPhase)
-{
- ZebraLockHandle h;
-
- if (server_lock_cmt)
- zebra_unlock (server_lock_cmt);
- else
- {
- char path[1024];
-
- zebra_lock_prefix (zh->service->res, path);
- strcat (path, FNAME_COMMIT_LOCK);
- server_lock_cmt = zebra_lock_create (path, 1);
- if (!server_lock_cmt)
- {
- logf (LOG_WARN|LOG_ERRNO, "cannot create lock %s", path);
- return -1;
- }
- }
- if (server_lock_org)
- zebra_unlock (server_lock_org);
- else
- {
- char path[1024];
-
- zebra_lock_prefix (zh->service->res, path);
- strcat (path, FNAME_ORG_LOCK);
- server_lock_org = zebra_lock_create (path, 1);
- if (!server_lock_org)
- {
- logf (LOG_WARN|LOG_ERRNO, "cannot create lock %s", path);
- return -1;
- }
- }
- if (commitPhase)
- h = server_lock_cmt;
- else
- h = server_lock_org;
- if (zebra_lock_nb (h))
- {
-#ifndef WIN32
- if (errno != EWOULDBLOCK)
- {
- logf (LOG_FATAL|LOG_ERRNO, "flock");
- exit (1);
- }
-#endif
- if (commitPhase)
- logf (LOG_LOG, "Waiting for lock cmt");
- else
- logf (LOG_LOG, "Waiting for lock org");
- if (zebra_lock (h) == -1)
- {
- logf (LOG_FATAL, "flock");
- exit (1);
- }
- }
- zebra_unlock (h);
- return 0;
-}
-
-
-void zebraIndexLockMsg (ZebraHandle zh, const char *str)
-{
- char path[1024];
- int l, r, fd;
-
- assert (server_lock_main);
- fd = zebra_lock_fd (server_lock_main);
- lseek (fd, 0L, SEEK_SET);
- l = strlen(str);
- r = write (fd, str, l);
- if (r != l)
- {
- logf (LOG_FATAL|LOG_ERRNO, "write lock file");
- exit (1);
- }
- zebra_lock_prefix (zh->service->res, path);
- strcat (path, FNAME_TOUCH_TIME);
- fd = creat (path, 0666);
- close (fd);
-}
-
-void zebraIndexUnlock (ZebraHandle zh)
-{
- char path[1024];
-
- zebra_lock_prefix (zh->service->res, path);
- strcat (path, FNAME_MAIN_LOCK);
-#ifdef WIN32
- zebra_lock_destroy (server_lock_main);
- if (unlink (path) && errno != ENOENT)
- logf (LOG_WARN|LOG_ERRNO, "unlink %s failed", path);
-#else
- if (unlink (path) && errno != ENOENT)
- logf (LOG_WARN|LOG_ERRNO, "unlink %s failed", path);
- zebra_lock_destroy (server_lock_main);
-#endif
- server_lock_main = 0;
-}
-
-int zebraIndexLock (BFiles bfs, ZebraHandle zh, int commitNow,
- const char *rval)
-{
- char path[1024];
- char buf[256];
- int r;
-
- if (server_lock_main)
- return 0;
-
- zebra_lock_prefix (zh->service->res, path);
- strcat (path, FNAME_MAIN_LOCK);
- while (1)
- {
- server_lock_main = zebra_lock_create (path, 2);
- if (!server_lock_main)
- {
- server_lock_main = zebra_lock_create (path, 1);
- if (!server_lock_main)
- {
- logf (LOG_FATAL, "couldn't obtain indexer lock");
- exit (1);
- }
- if (zebra_lock_nb (server_lock_main) == -1)
- {
-#ifdef WIN32
- logf (LOG_LOG, "waiting for other index process");
- zebra_lock (server_lock_main);
- zebra_unlock (server_lock_main);
- zebra_lock_destroy (server_lock_main);
- continue;
-#else
- if (errno == EWOULDBLOCK)
- {
- logf (LOG_LOG, "waiting for other index process");
- zebra_lock (server_lock_main);
- zebra_unlock (server_lock_main);
- zebra_lock_destroy (server_lock_main);
- continue;
- }
- else
- {
- logf (LOG_FATAL|LOG_ERRNO, "flock %s", path);
- exit (1);
- }
-#endif
- }
- else
- {
- int fd = zebra_lock_fd (server_lock_main);
-
- logf (LOG_WARN, "unlocked %s", path);
- r = read (fd, buf, 256);
- if (r == 0)
- {
- logf (LOG_WARN, "zero length %s", path);
- zebra_lock_destroy (server_lock_main);
- unlink (path);
- continue;
- }
- else if (r == -1)
- {
- logf (LOG_FATAL|LOG_ERRNO, "read %s", path);
- exit (1);
- }
- if (*buf == 'r')
- {
- logf (LOG_WARN, "previous transaction didn't"
- " reach commit");
- zebra_lock_destroy (server_lock_main);
- bf_commitClean (bfs, rval);
- unlink (path);
- continue;
- }
- else if (*buf == 'd')
- {
- logf (LOG_WARN, "commit file wan't deleted after commit");
- zebra_lock_destroy (server_lock_main);
- bf_commitClean (bfs, rval);
- unlink (path);
- continue;
- }
- else if (*buf == 'w')
- {
- logf (LOG_WARN,
- "The lock file indicates that your index is");
- logf (LOG_WARN, "inconsistent. Perhaps the indexer");
- logf (LOG_WARN, "terminated abnormally in the previous");
- logf (LOG_WARN, "run. You can try to proceed by");
- logf (LOG_WARN, "deleting the file %s", path);
- exit (1);
- }
- else if (*buf == 'c')
- {
- if (commitNow)
- {
- unlink (path);
- zebra_lock_destroy (server_lock_main);
- continue;
- }
- logf (LOG_FATAL, "previous transaction didn't"
- " finish commit. Commit now!");
- exit (1);
- }
- else
- {
- logf (LOG_FATAL, "unknown id 0x%02x in %s", *buf,
- path);
- exit (1);
- }
- }
- }
- else
- break;
- }
- zebra_lock (server_lock_main);
- return 0;
-}
-
+++ /dev/null
-/* $Id: lockutil.c,v 1.18 2004-01-22 11:27:21 adam Exp $
- Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002
- Index Data Aps
-
-This file is part of the Zebra server.
-
-Zebra is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
-version.
-
-Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License
-along with Zebra; see the file LICENSE.zebra. If not, write to the
-Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.
-*/
-
-
-#include <stdio.h>
-#include <assert.h>
-#include <string.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#ifdef WIN32
-#include <io.h>
-#include <sys/locking.h>
-#else
-#include <unistd.h>
-#endif
-
-#include "index.h"
-
-struct zebra_lock_info {
- int fd;
- int excl_flag;
-};
-
-char *zebra_mk_fname (const char *dir, const char *name)
-{
- int dlen = dir ? strlen(dir) : 0;
- char *fname = xmalloc (dlen + strlen(name) + 3);
-
-#ifdef WIN32
- if (dlen)
- {
- int last_one = dir[dlen-1];
-
- if (!strchr ("/\\:", last_one))
- sprintf (fname, "%s\\%s", dir, name);
- else
- sprintf (fname, "%s%s", dir, name);
- }
- else
- sprintf (fname, "%s", name);
-#else
- if (dlen)
- {
- int last_one = dir[dlen-1];
-
- if (!strchr ("/", last_one))
- sprintf (fname, "%s/%s", dir, name);
- else
- sprintf (fname, "%s%s", dir, name);
- }
- else
- sprintf (fname, "%s", name);
-#endif
- return fname;
-}
-
-ZebraLockHandle zebra_lock_create (const char *dir,
- const char *name, int excl_flag)
-{
- char *fname = zebra_mk_fname(dir, name);
- ZebraLockHandle h = (ZebraLockHandle) xmalloc (sizeof(*h));
-
- h->excl_flag = excl_flag;
- h->fd = -1;
-
-
-#ifdef WIN32
- if (!h->excl_flag)
- h->fd = open (name, O_BINARY|O_RDONLY);
- if (h->fd == -1)
- h->fd = open (fname, ((h->excl_flag > 1) ? O_EXCL : 0)|
- (O_BINARY|O_CREAT|O_RDWR), 0666);
-#else
- h->fd= open (fname, ((h->excl_flag > 1) ? O_EXCL : 0)|
- (O_BINARY|O_CREAT|O_RDWR), 0666);
-#endif
- if (h->fd == -1)
- {
- if (h->excl_flag <= 1)
- logf (LOG_WARN|LOG_ERRNO, "open %s", fname);
- xfree (h);
- h = 0;
- }
- xfree (fname);
- return h;
-}
-
-void zebra_lock_destroy (ZebraLockHandle h)
-{
- if (!h)
- return;
- if (h->fd != -1)
- close (h->fd);
- xfree (h);
-}
-
-void zebra_lock_prefix (Res res, char *path)
-{
- const char *lock_dir = res_get_def (res, "lockDir", "");
-
- strcpy (path, lock_dir);
- if (*path && path[strlen(path)-1] != '/')
- strcat (path, "/");
-}
-
-#ifndef WIN32
-static int unixLock (int fd, int type, int cmd)
-{
- struct flock area;
- area.l_type = type;
- area.l_whence = SEEK_SET;
- area.l_len = area.l_start = 0L;
- return fcntl (fd, cmd, &area);
-}
-#endif
-
-int zebra_lock_w (ZebraLockHandle h)
-{
-#ifdef WIN32
- return _locking (h->fd, _LK_LOCK, 1);
-#else
- return unixLock (h->fd, F_WRLCK, F_SETLKW);
-#endif
-}
-
-int zebra_lock_r (ZebraLockHandle h)
-{
-#ifdef WIN32
- return _locking (h->fd, _LK_LOCK, 1);
-#else
- return unixLock (h->fd, F_RDLCK, F_SETLKW);
-#endif
-}
-
-int zebra_lock (ZebraLockHandle h)
-{
-#ifdef WIN32
- return _locking (h->fd, _LK_LOCK, 1);
-#else
- return unixLock (h->fd, h->excl_flag ? F_WRLCK : F_RDLCK, F_SETLKW);
-#endif
-}
-
-int zebra_lock_nb (ZebraLockHandle h)
-{
-#ifdef WIN32
- return _locking (h->fd, _LK_NBLCK, 1);
-#else
- return unixLock (h->fd, h->excl_flag ? F_WRLCK : F_RDLCK, F_SETLK);
-#endif
-}
-
-int zebra_unlock (ZebraLockHandle h)
-{
-#ifdef WIN32
- return _locking (h->fd, _LK_UNLCK, 1);
-#else
- return unixLock (h->fd, F_UNLCK, F_SETLKW);
-#endif
-}
-
-int zebra_lock_fd (ZebraLockHandle h)
-{
- return h->fd;
-}
-/* $Id: zebraapi.c,v 1.120.2.10 2005-09-09 14:22:12 adam Exp $
+/* $Id: zebraapi.c,v 1.120.2.11 2006-03-24 13:47:29 adam Exp $
Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004
Index Data Aps
res_set (zh->res, "lockDir", zh->path_reg);
sprintf (fname, "norm.%s.LCK", zh->reg_name);
zh->lock_normal =
- zebra_lock_create (res_get(zh->res, "lockDir"), fname, 0);
+ zebra_lock_create (res_get(zh->res, "lockDir"), fname);
sprintf (fname, "shadow.%s.LCK", zh->reg_name);
zh->lock_shadow =
- zebra_lock_create (res_get(zh->res, "lockDir"), fname, 0);
+ zebra_lock_create (res_get(zh->res, "lockDir"), fname);
if (!zh->lock_normal || !zh->lock_shadow)
{
return sort_status;
}
+void zebra_lock_prefix (Res res, char *path)
+{
+ const char *lock_dir = res_get_def (res, "lockDir", "");
+
+ strcpy (path, lock_dir);
+ if (*path && path[strlen(path)-1] != '/')
+ strcat (path, "/");
+}
+
-# $Id: record.abs,v 1.3.2.3 2006-02-06 13:19:55 adam Exp $
+# $Id: record.abs,v 1.3.2.4 2006-03-24 13:47:30 adam Exp $
name marcxml
attset bib1.att
xpath disable
-#melm 010$a identifier-standard,identifier-standard:p
xelm /record/controlfield[@tag="001"] Material-type:w:range(data,3,1)
xelm /record/controlfield[@tag="008"] Code-Language:w
+melm 010$a identifier-standard,identifier-standard:p
xelm /record/datafield[@tag="100"]/subfield[@code="a"] author:w,author:s
xelm /record/datafield[@tag="245"]/subfield title:w
# Simple Zebra configuration file
-# $Id: zebra.cfg,v 1.2 2004-06-15 09:43:33 adam Exp $
+# $Id: zebra.cfg,v 1.2.2.1 2006-03-24 13:47:30 adam Exp $
#
# Where the schema files, attribute files, etc are located.
profilePath: ${srcdir:-.}:${srcdir:-.}/../../tab
attset: gils.att
attset: explain.att
+perm.anonymous: rw
+
recordtype: grs.xml
-#storekeys: 1
-#storedata: 1
-#recordId: (bib1,identifier-standard)
+storekeys: 1
+storedata: 1
+recordId: (bib1,identifier-standard)
isam: b
+
+shadow: shadow:1G
+register: register:1G
-## $Id: Makefile.am,v 1.9 2004-08-04 08:35:27 adam Exp $
+## $Id: Makefile.am,v 1.8.2.1 2006-03-24 13:47:30 adam Exp $
noinst_LIBRARIES = libutil.a
AM_CPPFLAGS = -I$(srcdir)/../include $(YAZINC) -DDEFAULT_PROFILE_PATH=\"$(pkgdatadir)/tab\"
LDADD = libutil.a $(YAZLIB) $(TCL_LIB)
-libutil_a_SOURCES = res.c charmap.c zebramap.c passwddb.c zebra-lock.c dirent.c xpath.c atoi_zn.c
+libutil_a_SOURCES = res.c flock.c charmap.c zebramap.c passwddb.c zebra-lock.c dirent.c xpath.c
passtest_SOURCES = passtest.c
--- /dev/null
+/* $Id: flock.c,v 1.4.2.1 2006-03-24 13:47:30 adam Exp $
+ Copyright (C) 1995-2005
+ Index Data ApS
+
+This file is part of the Zebra server.
+
+Zebra is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Zebra; see the file LICENSE.zebra. If not, write to the
+Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.
+*/
+
+
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#ifdef WIN32
+#include <io.h>
+#include <sys/locking.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <zebra-flock.h>
+#include <yaz/xmalloc.h>
+#include <yaz/log.h>
+
+struct zebra_lock_info {
+ int fd;
+ char *fname;
+};
+
+int log_level = 0 /* YLOG_LOG|YLOG_FLUSH */;
+
+char *zebra_mk_fname (const char *dir, const char *name)
+{
+ int dlen = dir ? strlen(dir) : 0;
+ char *fname = xmalloc (dlen + strlen(name) + 3);
+
+#ifdef WIN32
+ if (dlen)
+ {
+ int last_one = dir[dlen-1];
+
+ if (!strchr ("/\\:", last_one))
+ sprintf (fname, "%s\\%s", dir, name);
+ else
+ sprintf (fname, "%s%s", dir, name);
+ }
+ else
+ sprintf (fname, "%s", name);
+#else
+ if (dlen)
+ {
+ int last_one = dir[dlen-1];
+
+ if (!strchr ("/", last_one))
+ sprintf (fname, "%s/%s", dir, name);
+ else
+ sprintf (fname, "%s%s", dir, name);
+ }
+ else
+ sprintf (fname, "%s", name);
+#endif
+ return fname;
+}
+
+ZebraLockHandle zebra_lock_create (const char *dir, const char *name)
+{
+ char *fname = zebra_mk_fname(dir, name);
+ ZebraLockHandle h = (ZebraLockHandle) xmalloc (sizeof(*h));
+
+ h->fd = -1;
+#ifdef WIN32
+ h->fd = open (name, O_BINARY|O_RDONLY);
+ if (h->fd == -1)
+ h->fd = open (fname, (O_BINARY|O_CREAT|O_RDWR), 0666);
+#else
+ h->fd= open (fname, (O_BINARY|O_CREAT|O_RDWR), 0666);
+#endif
+ if (h->fd == -1)
+ {
+ xfree (h);
+ h = 0;
+ }
+ h->fname = fname;
+ yaz_log(log_level, "zebra_lock_create fd=%d p=%p fname=%s", h->fd, h, h->fname);
+ return h;
+}
+
+void zebra_lock_destroy (ZebraLockHandle h)
+{
+ if (!h)
+ return;
+ yaz_log(log_level, "zebra_lock_destroy fd=%d p=%p fname=%s", h->fd, h, h->fname);
+ if (h->fd != -1)
+ close (h->fd);
+ xfree (h->fname);
+ xfree (h);
+}
+
+#ifndef WIN32
+static int unixLock (int fd, int type, int cmd)
+{
+ struct flock area;
+ area.l_type = type;
+ area.l_whence = SEEK_SET;
+ area.l_len = area.l_start = 0L;
+ return fcntl (fd, cmd, &area);
+}
+#endif
+
+int zebra_lock_w (ZebraLockHandle h)
+{
+ int r;
+ yaz_log(log_level, "zebra_lock_w fd=%d p=%p fname=%s", h->fd, h, h->fname);
+#ifdef WIN32
+ while ((r = _locking (h->fd, _LK_LOCK, 1)))
+ ;
+#else
+ r = unixLock (h->fd, F_WRLCK, F_SETLKW);
+#endif
+ yaz_log(log_level, "zebra_lock_w fd=%d p=%p fname=%s OK", h->fd, h, h->fname);
+ return r;
+}
+
+int zebra_lock_r (ZebraLockHandle h)
+{
+ int r;
+ yaz_log(log_level, "zebra_lock_r fd=%d p=%p fname=%s", h->fd, h, h->fname);
+#ifdef WIN32
+ while ((r = _locking (h->fd, _LK_LOCK, 1)))
+ ;
+#else
+ r = unixLock (h->fd, F_RDLCK, F_SETLKW);
+#endif
+ yaz_log(log_level, "zebra_lock_r fd=%d p=%p fname=%s OK", h->fd, h, h->fname);
+ return r;
+}
+
+int zebra_unlock (ZebraLockHandle h)
+{
+ yaz_log(log_level, "zebra_unlock fd=%d p=%p fname=%s", h->fd, h, h->fname);
+#ifdef WIN32
+ return _locking (h->fd, _LK_UNLCK, 1);
+#else
+ return unixLock (h->fd, F_UNLCK, F_SETLKW);
+#endif
+}
+