+ return lkopen(file, access, mode, datalocktype, failed_to_lock);
+}
+
+
+/*
+ * Locking using the spool locking algorithm
+ */
+
+int lkopenspool(const char *file, int access, mode_t mode, int *failed_to_lock)
+{
+ if (! spoollockinit) {
+ spoollocktype = init_locktype(spoollocking);
+
+ spoollockinit = 1;
+ }
+
+ return lkopen(file, access, mode, spoollocktype, failed_to_lock);
+}
+
+
+/*
+ * Versions of lkopen that return a FILE *
+ */
+
+FILE *
+lkfopendata(const char *file, const char *mode, int *failed_to_lock)
+{
+ FILE *fp;
+ int oflags = str2accbits(mode);
+ int fd;
+
+ if (oflags == -1) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ if ((fd = lkopendata(file, oflags, 0666, failed_to_lock)) == -1)
+ return NULL;
+
+ if ((fp = fdopen (fd, mode)) == NULL) {
+ close (fd);
+ return NULL;
+ }
+
+ return fp;
+}
+
+FILE *
+lkfopenspool(const char *file, const char *mode)
+{
+ FILE *fp;
+ int oflags = str2accbits(mode);
+ int failed_to_lock = 0;
+ int fd;
+
+ if (oflags == -1) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ if ((fd = lkopenspool(file, oflags, 0666, &failed_to_lock)) == -1)
+ return NULL;
+
+ if ((fp = fdopen (fd, mode)) == NULL) {
+ close (fd);
+ return NULL;
+ }
+
+ return fp;
+}
+
+
+/*
+ * Corresponding close functions.
+ *
+ * A note here: All of the kernel locking functions terminate the lock
+ * when the descriptor is closed, so why write the code to explicitly
+ * unlock the file? We only need to do this in the dot-locking case.
+ */
+
+int
+lkclosedata(int fd, const char *name)
+{
+ int rc = close(fd);
+
+ if (datalocktype == DOT_LOCKING)
+ lkclose_dot(fd, name);
+
+ return rc;
+}
+
+int
+lkfclosedata(FILE *f, const char *name)
+{
+ int fd, rc;
+
+ if (f == NULL)
+ return 0;
+
+ fd = fileno(f);
+ rc = fclose(f);
+
+ if (datalocktype == DOT_LOCKING)
+ lkclose_dot(fd, name);
+
+ return rc;
+}
+
+int
+lkclosespool(int fd, const char *name)
+{
+ int rc = close(fd);
+
+ if (spoollocktype == DOT_LOCKING)
+ lkclose_dot(fd, name);
+
+ return rc;
+}
+
+int
+lkfclosespool(FILE *f, const char *name)
+{
+ int fd, rc;
+
+ if (f == NULL)
+ return 0;
+
+ fd = fileno(f);
+ rc = fclose(f);
+
+ if (spoollocktype == DOT_LOCKING)
+ lkclose_dot(fd, name);
+
+ return rc;
+}
+
+
+/*
+ * Convert fopen() mode argument to open() bits
+ */
+
+static int
+str2accbits(const char *mode)
+{
+ if (strcmp (mode, "r") == 0)
+ return O_RDONLY;
+ if (strcmp (mode, "r+") == 0)
+ return O_RDWR;
+ if (strcmp (mode, "w") == 0)
+ return O_WRONLY | O_CREAT | O_TRUNC;
+ if (strcmp (mode, "w+") == 0)
+ return O_RDWR | O_CREAT | O_TRUNC;
+ if (strcmp (mode, "a") == 0)
+ return O_WRONLY | O_CREAT | O_APPEND;
+ if (strcmp (mode, "a+") == 0)
+ return O_RDWR | O_CREAT | O_APPEND;
+
+ errno = EINVAL;
+ return -1;