Sun Jul 30 23:06:50 ART 2006  Alberto Bertogli <albertogli@telpin.com.ar>
  tagged 0.17
Sun Jul 30 23:05:41 ART 2006  Alberto Bertogli <albertogli@telpin.com.ar>
  * Remove the "prerelease" script as it's no longer needed.
Sun Jul 30 22:44:45 ART 2006  Alberto Bertogli <albertogli@telpin.com.ar>
  * Use unsigned long for the thread ids to avoid a warning.
Sun Jul 30 21:04:23 ART 2006  Alberto Bertogli <albertogli@telpin.com.ar>
  * Make libold compile in Windows.
  Change libold to build natively under Windows, at least with the mingw
  compiler.
  
  Thanks a lot to Ron Burkey (rburkey2005@earthlink.net) who provided the code
  and tested the patch.
Sat Jul 15 12:35:37 ART 2006  Alberto Bertogli <albertogli@telpin.com.ar>
  * Clarify licensing terms.
Sat Jul 15 04:52:26 ART 2006  Alberto Bertogli <albertogli@telpin.com.ar>
  * Don't force the fd to be active in net_wakeup()
  net_wakeup() forces the file descriptor it's waking up to be active, by
  setting active_fd[fd] = 1.
  
  This can cause the following race:
  
   * Lock L is held by client A
   * Client B is connected and waiting for lock L to become available
   * Client B decides to disconnect, and closes the socket
   * This triggers net_close()
   * At this point, client A releases lock L, triggering net_wakeup()
  
  Now, here's how it could go:
  
    net_close()              net_wakeup()
      active_fd[fd] = 0
                               active_fd[fd] = 1
                               net_send_cmd[fd] returns OK because
                                 the socket is not closed yet
      close()
  
  
  And that leaves fd closed, but active_fd[fd] = 1, which will cause the
  select() loop to hang up indefinitely, because it gets a "Bad file descriptor"
  error (due to a fd on the read set being closed), which causes it to rebuild
  the read set and try again. But nothing will never remove that fd from the
  set, because nothing will set active_fd[fd] = 0.
  
  The fix is not setting active_fd[fd] = 1 in net_wakeup(), it has nothing
  to do there in the first place.
  
  
  Besides, check if the fd is active before calling net_send_cmd(), because we
  know it's going to fail.
  
  Thanks to Lloyd C. Cha for the report and testing.
Sat Jul 15 04:50:42 ART 2006  Alberto Bertogli <albertogli@telpin.com.ar>
  * Don't cleanup after net_send_cmd().
  net_send_cmd() calls clean_buffer() and net_close() when it gets a write
  error, so there's no need to do cleanup when it fails. But net_wakeup() does
  just that: when net_send_cmd() fails, it also calls clean_buffer() and
  net_close().
  
  This patch fixes that by removing both calls.
Sat Jul 15 04:17:33 ART 2006  Alberto Bertogli <albertogli@telpin.com.ar>
  * Compile with -fPIC.
Sun Dec  4 19:12:47 ART 2005  Alberto Bertogli <albertogli@telpin.com.ar>
  tagged 0.16
diff -rN -u old-old/doc/license new-old/doc/license
--- old-old/doc/license	2006-07-30 23:07:38.000000000 -0300
+++ new-old/doc/license	2006-07-30 23:07:38.000000000 -0300
@@ -4,13 +4,13 @@
 included here-in for easy reference) (that license itself is copyrighted by
 Larry Rosen).
 
-Note that the "Original Work" that this license covers is only the library
-itself and the client, along with the sample callbacks. Thus just the act of
-linking/importing this library into another program does NOT in itself make
-that program considered a derivative work of this Original Work.
+Note that the "Original Work" that this license covers is only the server and
+the library. The act of linking/importing the library into another program
+does NOT in itself make that program considered a derivative work of this
+Original Work.
 
 		Alberto Bertogli
-		20 May 2003
+		15 Jul 2006
 
 -------------------------------------------------------------------------
 
diff -rN -u old-old/lib/libold.c new-old/lib/libold.c
--- old-old/lib/libold.c	2006-07-30 23:07:38.000000000 -0300
+++ new-old/lib/libold.c	2006-07-30 23:07:38.000000000 -0300
@@ -7,18 +7,52 @@
  */
 
 #include <stdlib.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <string.h>
+#include <sys/types.h>
+
+#ifdef WIN32
+  #include <windows.h>
+  #include <winsock2.h>
+  #define SOCKET_LEVEL IPPROTO_TCP
+  #define OPTVAL_CAST (const char *)
+  typedef BOOL optval_t;
+  /* read() and write() don't work well in Windows, so #define them based on
+   * send()/recv() */
+  #define read(fd, buf, count) recv(fd, buf, count, 0)
+  #define write(fd, buf, count) send(fd, buf, count, 0)
+#else
+  #include <sys/socket.h>
+  #include <netdb.h>
+  #include <netinet/in.h>
+  #include <netinet/tcp.h>
+  #define SOCKET_LEVEL SOL_TCP
+  #define OPTVAL_CAST (void *)
+  typedef int optval_t;
+#endif
 
 #include "compiler.h"
 #include "old.h"
 
+
+#ifdef WIN32
+static int network_initialized = 0;
+static int net_init() {
+	if (network_initialized)
+		return 0;
+	network_initialized = 1;
+	WSADATA wsaData;
+	return WSAStartup(MAKEWORD(2, 0), &wsaData);
+}
+#else
+static int net_init() {
+	return 0;
+}
+#endif
+
+
+
 /* FIXME: these two are only for little endian, make them generic */
 int send_cmd(int fd, unsigned int op, char *payload, int len) {
 	char header[4];
@@ -164,11 +198,14 @@
 }
 
 int old_connect(char *host, int port) {
-	int fd;
-	int rv;
+	int fd, i;
+	optval_t rv;
 	struct hostent *hinfo;
 	struct sockaddr_in sa;
 
+	if (net_init())
+		return -1;
+
 	hinfo = gethostbyname(host);
 	if (hinfo == NULL) {
 		return -1;
@@ -180,12 +217,12 @@
 
 	fd = socket(PF_INET, SOCK_STREAM, 0);
 
-	rv = 1;
-	if (setsockopt(fd, SOL_TCP, TCP_NODELAY, &rv, sizeof(rv)) < 0 ) {
+	i = setsockopt(fd, SOCKET_LEVEL, TCP_NODELAY, OPTVAL_CAST &rv,
+			sizeof(rv));
+	if (i < 0 ) {
 		return -1;
 	}
 
-
 	rv = connect(fd, (struct sockaddr *) &sa, sizeof(sa));
 	if (rv != 0) {
 		return -1;
diff -rN -u old-old/main.c new-old/main.c
--- old-old/main.c	2006-07-30 23:07:38.000000000 -0300
+++ new-old/main.c	2006-07-30 23:07:38.000000000 -0300
@@ -23,7 +23,7 @@
 
 int main(int argc, char **argv)
 {
-	int i, nthreads;
+	unsigned long i, nthreads;
 	pid_t pid;
 	pthread_t *threads;
 
diff -rN -u old-old/Make.conf new-old/Make.conf
--- old-old/Make.conf	2006-07-30 23:07:38.000000000 -0300
+++ new-old/Make.conf	2006-07-30 23:07:38.000000000 -0300
@@ -2,7 +2,7 @@
 VERSION = "0.16"
 
 CC = gcc
-CFLAGS += -Wall -O6 -D_XOPEN_SOURCE=500 -D_BSD_SOURCE=1 -D_SVID_SOURCE=1
+CFLAGS += -Wall -O3 -fPIC -D_XOPEN_SOURCE=500 -D_BSD_SOURCE=1 -D_SVID_SOURCE=1
 LIBS += -lpthread
 INCLUDES += -I$(PWD)/include
 
diff -rN -u old-old/Makefile new-old/Makefile
--- old-old/Makefile	2006-07-30 23:07:38.000000000 -0300
+++ new-old/Makefile	2006-07-30 23:07:38.000000000 -0300
@@ -15,7 +15,7 @@
 
 install: all lib_install man_install
 	install -g root -o root -m 0755 $(BUILD)/old $(PREFIX)/bin
-	
+
 
 $(BUILD)/old: ${OBJS}
 	$(CC) $(CFLAGS) -o $(BUILD)/old $(OBJS) $(LIBS)
diff -rN -u old-old/net.c new-old/net.c
--- old-old/net.c	2006-07-30 23:07:38.000000000 -0300
+++ new-old/net.c	2006-07-30 23:07:38.000000000 -0300
@@ -244,10 +244,11 @@
 
 /* processing loop, it's started always as a thread; see doc/multithread */
 void *net_proc_loop(void *tno) {
-	int fd, tid;
+	int fd;
+	unsigned long tid;
 	struct net_cmd *cmd = NULL;
 
-	tid = (int) tno;
+	tid = (unsigned long) tno;
 
 	for (;;) {
 		/* this lock gets unlocked by net_select_loop when we have an
@@ -549,7 +550,6 @@
 	do {
 		/* get the fd from the first of the list */
 		fd = h->wq->fd;
-		active_fd[fd] = 1;
 
 		/* then remove it from the waitqueue */
 		p = h->wq->next;
@@ -557,13 +557,16 @@
 		h->wq = p;
 		h->fd = fd;
 
+		if (active_fd[fd] == 0) {
+			/* it got bored and quit while it was waiting, so we
+			 * just skip it and move on */
+			continue;
+		}
+
 		rv = net_send_cmd(fd, REP_LOCK_ACQUIRED, h->objname, h->len);
 		if (!rv) {
-			/* the send failed; clean everything up and retry with
-			 * the next entry */
-			clean_buffer(fd);
-			net_close(fd);
-			perror("send failed:");
+			/* the send failed, retry with the next entry */
+			perror("send failed");
 			continue;
 		}
 
diff -rN -u old-old/README new-old/README
--- old-old/README	2006-07-30 23:07:38.000000000 -0300
+++ new-old/README	2006-07-30 23:07:38.000000000 -0300
@@ -38,8 +38,9 @@
 to talk to the server along with sample code; one in C and one in Python.
 These are documented in doc/libs.
 
-All of this is distributed under the Open Software License, and the libraries
-can be binary linked if you want.
+All of this is distributed under the Open Software License (which you can find
+in doc/license), and the libraries can be source or binary linked to whatever
+you want. If you're in doubt, please read the license or just ask me.
 
 If you're intrested, read the code to find out more; most of the documentation
 is there, and there's a nice description in doc/network and doc/internals.
diff -rN -u old-old/utils/prerelease new-old/utils/prerelease
--- old-old/utils/prerelease	2006-07-30 23:07:38.000000000 -0300
+++ new-old/utils/prerelease	1969-12-31 21:00:00.000000000 -0300
@@ -1,19 +0,0 @@
-#!/bin/bash
-
-if [ $# -ne 1 ]; then
-	echo "Usage: prerelease RELNUM"
-	exit
-fi
-
-echo "Creating the full patch"
-patchdesc $(cat ps/series) > ../old-$1.patch
-echo >> ../old-$1.patch
-echo >> ../old-$1.patch
-combine-series ../old-$1.patch-t1
-cat ../old-$1.patch-t1 >> ../old-$1.patch
-rm ../old-$1.patch-t1
-
-echo "Cleaning up"
-make clean
-
-

