Patch: Solaris port + bugfixes

Patrik Rådman <[email protected]>
Newsgroups gmane.network.sn
Message-ID <[email protected]>
Hi,

Attached to this e-mail you'll find an 'experimental' patch for 0.3.3 which
allows sn to compile and run on Solaris. (Tested on Solaris 2.6.)

I had to make a bunch of adjustments here and there, but the biggest change to
the code was that I replaced all calls to flock() with lockf(). The changed
code should work pretty much the same on Linux, but has the advantage of
compiling without problems on Solaris too.

Porting can also be a useful exercise in code review... :) I found and
squashed a few bugs along the way, including the infamous "snget -m doesn't
work" bug. As far as I can tell, the patched 0.3.3 is now running smoothly
on both Linux and Solaris, so I'm sending this patch out into the world so
that other people can test it.

Note: If you try to compile on a non-Linux system, use GNU tools! The default
make probably won't work, you need gmake. Apart from that, just follow the
instructions in the Makefile.

I'd appreciate e-mail reports of any weird things you notice with this patch,
or if you successfully got it to run on a non-Linux system.


  - Patrik

PS. All your news are belong to sn.  ;)

-- 
  Patrik Rådman    ·    [email protected]    ·    http://www.iki.fi/patrik/
  "We're not in the past or the present anymore.  This is the future!"
sn-0.3.3-solaris-port-080301.diff (text/plain, 15.7 KB)
diff -urN sn-0.3.3/Makefile sn-0.3.3-modified/Makefile
--- sn-0.3.3/Makefile	Thu Nov 23 02:17:36 2000
+++ sn-0.3.3-modified/Makefile	Thu Mar  8 17:04:39 2001
@@ -20,12 +20,23 @@
 DEFAULT_ADMIN_EMAIL =newsmaster
 
 #
+# OS-specific settings. Uncomment only one section below.
+#
+
+## For Linux:
+INSTALL =install
+LIBS =-L./lib  -lstuff
+
+## For Solaris:
+#INSTALL =ginstall
+#LIBS =-L./lib -lstuff -lxnet
+
+#
 # Stuff you probably won't need to edit.
 #
 
-CC =cc
-LD =cc
-LIBS =-L./lib -lstuff
+CC =gcc
+LD =gcc
 
 #
 # You can stop editing here.
@@ -125,8 +136,8 @@
 	strip $^
 
 install: all $(SNROOT) $(BINDIR) $(MANDIR)/man8
-	install $(PROGS) $(BINDIR)
-	install *.8 $(MANDIR)/man8
+	$(INSTALL) $(PROGS) $(BINDIR)
+	$(INSTALL) *.8 $(MANDIR)/man8
 	-cd $(BINDIR); rm -f sncat; ln -s snscan sncat
 	-cd $(BINDIR); rm -f sncancel; ln -s snscan sncancel
 	-cd $(BINDIR); rm -f snstore; ln -s snsend snstore
diff -urN sn-0.3.3/allocate.c sn-0.3.3-modified/allocate.c
--- sn-0.3.3/allocate.c	Tue Feb  8 18:52:21 2000
+++ sn-0.3.3-modified/allocate.c	Thu Mar  1 05:53:12 2001
@@ -36,7 +36,7 @@
 #include <sys/mman.h>
 #include <sys/types.h>
 #include <sys/time.h>
-#include <sys/file.h>
+/*#include <sys/file.h>*/
 #include "config.h"
 #include "allocate.h"
 
@@ -157,8 +157,8 @@
   if( -1 == fstat(table.fd, &st) )goto fail;
   table.size = rounduptopagesize(st.st_size);
   table.map =
-    mmap(0, table.size, table.mprot, MAP_FILE|MAP_SHARED, table.fd, 0);
-  if( ! table.map || table.map == (char *)-1 )goto fail;
+    mmap(0, table.size, table.mprot, MAP_SHARED, table.fd, 0);
+  if( ! table.map || table.map == MAP_FAILED )goto fail;
 
   return(0);
 
@@ -193,11 +193,11 @@
 static int
 lock(void)
 {
-  if( -1 == flock(table.fd, LOCK_EX|LOCK_NB) ){
+  if( -1 == lockf(table.fd, F_TLOCK, 0) ){
     do{
-      if( EWOULDBLOCK != errno )return(-1);
+      if( EAGAIN != errno )return(-1);
       else nap(0, 200);
-    }while( -1 == flock(table.fd, LOCK_EX|LOCK_NB) );
+    }while( -1 == lockf(table.fd, F_TLOCK, 0) );
     if( -1 == remapfile() )return(-1);
   }
   return(0);
@@ -206,7 +206,7 @@
 static void
 unlock(void)
 {
-  flock(table.fd, LOCK_UN);
+  lockf(table.fd, F_ULOCK, 0);
 }
 
 static int
diff -urN sn-0.3.3/art.c sn-0.3.3-modified/art.c
--- sn-0.3.3/art.c	Mon Jul 26 18:41:40 1999
+++ sn-0.3.3-modified/art.c	Thu Mar  1 05:59:10 2001
@@ -43,8 +43,8 @@
       len = strlen(path);
       if( (fp = malloc(sizeof(struct fileobj) + len + 1)) ){
         fp->size = ((st.st_size/pagesize) + 1) * pagesize; /* oversize */
-        fp->map = mmap(0, fp->size, PROT_READ, MAP_FILE|MAP_SHARED, fd, 0);
-        if( fp->map && (int)fp->map > 0 ){
+        fp->map = mmap(0, fp->size, PROT_READ, MAP_SHARED, fd, 0);
+        if( fp->map && fp->map != MAP_FAILED ){
           if( FILE_MAGIC == *(int *)fp->map ){
             close(fd);
             fp->path = strcpy((char *)fp + sizeof(struct fileobj), path);
diff -urN sn-0.3.3/config.h sn-0.3.3-modified/config.h
--- sn-0.3.3/config.h	Mon Jul 26 09:10:42 1999
+++ sn-0.3.3-modified/config.h	Thu Mar  1 05:43:42 2001
@@ -59,6 +59,10 @@
   You can stop editing now.
  */
 
+#ifdef __sun__   /* For Solaris */
+#define DONT_HAVE_DIRFD
+#endif
+
 extern int debug;
 #define LOG log
 #define LOG1 if( debug >= 1 )log
@@ -67,6 +71,9 @@
 #define FAIL fail
 
 #include <sys/param.h>
+#ifndef NAME_MAX   /* For Solaris */
+#define NAME_MAX (MAXNAMELEN - 1)
+#endif
 #if NAME_MAX > 512
 #define GROUPNAMELEN 512
 #else
diff -urN sn-0.3.3/dh_find.c sn-0.3.3-modified/dh_find.c
--- sn-0.3.3/dh_find.c	Sun Oct 24 19:42:00 1999
+++ sn-0.3.3-modified/dh_find.c	Wed Mar  7 22:32:24 2001
@@ -9,7 +9,7 @@
 #include <errno.h>
 #include <unistd.h>
 #include <fcntl.h>
-#include <sys/file.h>
+/*#include <sys/file.h>*/
 #include <sys/mman.h>
 #include <sys/stat.h>
 #include <string.h>
@@ -62,8 +62,8 @@
 {
   int i;
   for(i = 100; i--; ){
-    if( 0 == flock(dh_fd, LOCK_EX|LOCK_NB) )return(0);
-    if( EWOULDBLOCK != errno )return(-1);
+    if( 0 == lockf(dh_fd, F_TLOCK, 0) )return(0);
+    if( EAGAIN != errno )return(-1);
     nap(0, 500);
   }
   return(-1);
@@ -72,7 +72,7 @@
 int
 dhunlock(void)
 {
-  flock(dh_fd, LOCK_UN);
+  lockf(dh_fd, F_ULOCK, 0);
   return(0);
 }
 
@@ -104,18 +104,18 @@
 
   fd = open(dh_tablefile, O_RDWR|O_CREAT|O_EXCL, 0644);
   if( -1 == fd )return(-1);
-  if( -1 == flock(fd, LOCK_EX|LOCK_NB) ){
+  if( -1 == lockf(fd, F_TLOCK, 0) ){
     do{  /* wait until other process has initialized it */
-      if( EWOULDBLOCK == errno )nap(0, 200);
+      if( EAGAIN == errno )nap(0, 200);
       else goto fail;
-    }while( -1 == flock(fd, LOCK_EX|LOCK_NB) );
-    flock(fd, LOCK_UN);
+    }while( -1 == lockf(fd, F_TLOCK, 0) );
+    lockf(fd, F_ULOCK, 0);
     return(fd);
   }
   if( sizeof(int) != write(fd, &integer, sizeof(int)) )goto fail;
   for(i = 0; i < DH_SIZE; i++)
     if( sizeof(foo) != write(fd, foo, sizeof(foo)) )goto fail;
-  flock(fd, LOCK_UN);
+  lockf(fd, F_ULOCK, 0);
   return(fd);
 
 fail:
@@ -185,9 +185,9 @@
   if( -1 == ng_init() )goto fail;
 
   dh_table = (struct table *)
-    mmap(0, sizeof(struct table), prot, MAP_FILE|MAP_SHARED, dh_fd, 0);
+    mmap(0, sizeof(struct table), prot, MAP_SHARED, dh_fd, 0);
 
-  if( ! dh_table || dh_table == (struct table *)-1 ){
+  if( ! dh_table || dh_table == MAP_FAILED ){
     LOG("dh_open:mmap:%m?");
     dh_table = 0;
   }else if( dh_table->magic != DH_MAGIC )
diff -urN sn-0.3.3/flock.c sn-0.3.3-modified/flock.c
--- sn-0.3.3/flock.c	Tue Aug 10 07:11:08 1999
+++ sn-0.3.3-modified/flock.c	Wed Feb 28 03:24:45 2001
@@ -7,7 +7,7 @@
   flock() a file, for shell scripts.
  */
 #include <unistd.h>
-#include <sys/file.h>
+/*#include <sys/file.h>*/
 #include <string.h>
 #include <out.h>
 
@@ -23,6 +23,6 @@
       "%s always locks (using flock(2) descriptor 1, which should be open for writing."
       , progname, progname);
 
-  if( 0 == flock(1, LOCK_EX|LOCK_NB) )_exit(0);
+  if( 0 == lockf(1, F_TLOCK, 0) )_exit(0);
   _exit(2);
 }
diff -urN sn-0.3.3/get.c sn-0.3.3-modified/get.c
--- sn-0.3.3/get.c	Fri Sep  3 04:18:03 1999
+++ sn-0.3.3-modified/get.c	Thu Mar  1 03:49:48 2001
@@ -590,7 +590,7 @@
 
   readfile(".", ".serial", serialbuf);
   argv_snfetch[argc_snfetch++] = serialbuf;
-  if( ! *serialbuf ){
+  if( !strcmp(serialbuf, "0") ){   /* Bugfix: It's a string, not an int... */
     LOG3("sow:couldn't get a value from %s/.serial:%m?", jp->group);
     strcpy(serialbuf, "0");
     argv_snfetch[argc_snfetch++] = (optmax?optmax:"200");
diff -urN sn-0.3.3/group.c sn-0.3.3-modified/group.c
--- sn-0.3.3/group.c	Mon Jul 26 18:57:24 1999
+++ sn-0.3.3-modified/group.c	Thu Mar  1 06:00:18 2001
@@ -25,6 +25,10 @@
 #include <out.h>
 #include <openf.h>
 
+#ifdef DONT_HAVE_DIRFD
+#define dirfd(dirp) ((dirp)->dd_fd)
+#endif
+
 static const char rcsid[] = "$Id: group.c,v 1.21 1999/07/26 15:57:24 harold Exp $";
 
 static int desc = -1;
@@ -158,9 +162,9 @@
     if( -1 == fd ){
       LOG("refresh:open:%m"); return(-1); }
     lp->f = (struct file *)mmap(0, sizeof(struct file), PROT_READ,
-      MAP_FILE|MAP_SHARED, fd, 0);
+      MAP_SHARED, fd, 0);
     close(fd);
-    if( (int)lp->f <= 0 ){
+    if( lp->f == MAP_FAILED ){   /* Bugfix: <= 0 fails for large addresses! (High bit set) */
       LOG("refresh:mmap:%m"); return(-1); }
     lp->slotsfilled = 0;
     needreslot = 1;
diff -urN sn-0.3.3/key.c sn-0.3.3-modified/key.c
--- sn-0.3.3/key.c	Sun Jun 13 12:40:31 1999
+++ sn-0.3.3-modified/key.c	Wed Feb 28 07:18:14 2001
@@ -72,7 +72,7 @@
   }
   kp = (struct key *)keybuf;
   kp->len = len;
-  memcpy(*keyp = KEY(kp), key, len);
+  memcpy(*keyp = KEY(kp), key, len + 1);   /* Bugfix: +1 so that it copies the '\0' also. */
   kp->next = key_table[hv];
   key_table[hv] = kp;
   keybuf += size; avail -= size;
diff -urN sn-0.3.3/newsgroup.c sn-0.3.3-modified/newsgroup.c
--- sn-0.3.3/newsgroup.c	Sun Oct 24 19:42:22 1999
+++ sn-0.3.3-modified/newsgroup.c	Thu Mar  1 05:58:24 2001
@@ -10,7 +10,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/stat.h>
-#include <sys/file.h>
+/*#include <sys/file.h>*/
 #include <sys/mman.h>
 #include <errno.h>
 #include <stdlib.h>
@@ -131,8 +131,8 @@
     if( mapbuf )
       munmap((caddr_t)mapbuf, mapsize);
     mapsize = st.st_size + pagesize - (st.st_size % pagesize);
-    mapbuf = mmap(0, mapsize, PROT_READ, MAP_FILE|MAP_SHARED, groupfd, 0);
-    if( ! mapbuf || -1 == (int)mapbuf ){
+    mapbuf = mmap(0, mapsize, PROT_READ, MAP_SHARED, groupfd, 0);
+    if( ! mapbuf || mapbuf == MAP_FAILED ){
       log("reload:mmap:%m"); return(-1); }
   }
   /*
@@ -198,7 +198,7 @@
   int ident;
   char * buf;
 
-  if( -1 == flock(groupfd, LOCK_EX) ){
+  if( -1 == lockf(groupfd, F_LOCK, 0) ){
     log("ng_addgroup:flock(%s):%m", dh_groupfile); return(-1); }
   ident = -1;
   if( 0 == reload() )
@@ -220,6 +220,6 @@
       }else
         log("ng_addgroup:malloc for %s:%m", group);
     }
-  flock(groupfd, LOCK_UN);
+  lockf(groupfd, F_ULOCK, 0);
   return(ident);
 }
diff -urN sn-0.3.3/post.c sn-0.3.3-modified/post.c
--- sn-0.3.3/post.c	Fri Oct 29 06:20:55 1999
+++ sn-0.3.3-modified/post.c	Thu Mar  8 01:13:11 2001
@@ -48,19 +48,30 @@
 static int
 write_tmp(char * line, int len)
 {
+  static char env_control[1000];
+  static char env_newsgroups[1000];
+  
   if( error )return(0);
   if( 0 == strncasecmp(line, "X-sn-", 5) )return(0);
   else if( ! have_control && 0 == strncasecmp(line, "Control:", 8) )
-    if( setenv("CONTROL", getval(line), 1) )error = ER_MEM;
-    else have_control = 1;
+  {
+     strcpy(env_control, "CONTROL=");
+     strcat(env_control, getval(line));
+     if (putenv(env_control)) error = ER_MEM;
+     else
+        have_control = 1;
+  }
   if( -1 == write(tmpfd, line, len) )error = ER_WRITE;
   if( -1 == write(tmpfd, "\r\n", 2) )error = ER_WRITE;
   if( ! have_newsgroups && 0 == strncasecmp(line, "Newsgroups:", 11) ){
     char * p;
     for(line = p = getval(line); *p; p++)
       if( ',' == *p )*p = ' ';
-    if( setenv("NEWSGROUPS", line, 1) )error = ER_MEM;
-    else have_newsgroups = 1;
+    strcpy(env_newsgroups, "NEWSGROUPS=");
+    strcat(env_newsgroups, line);
+    if (putenv(env_newsgroups)) error = ER_MEM;
+    else
+       have_newsgroups = 1;
   }
   return(error);
 }
@@ -81,7 +92,7 @@
     unlink(buf);
   }
   have_control = error = have_newsgroups = 0;
-  unsetenv("CONTROL"); unsetenv("NEWSGROUPS");
+  putenv("CONTROL="); putenv("NEWSGROUPS=");
 
   args_write(1, "340 Go ahead\r\n");
 
diff -urN sn-0.3.3/snfetch.c sn-0.3.3-modified/snfetch.c
--- sn-0.3.3/snfetch.c	Wed Sep  8 04:56:33 1999
+++ sn-0.3.3-modified/snfetch.c	Thu Mar  1 04:08:22 2001
@@ -350,7 +350,7 @@
   else
     from = serial; /* normally taken */
 
-  if( max > 0 )if( to - from > max )from = to - max;
+  if( max > 0 )if( to - from > max )from = to - max - 1;   /* -1 added to make the number of arts downloaded == max. */
 
   nrhave = nrdup = 0;
   sendxhdr(from, to);
diff -urN sn-0.3.3/snscan.c sn-0.3.3-modified/snscan.c
--- sn-0.3.3/snscan.c	Mon Jul 26 18:46:27 1999
+++ sn-0.3.3-modified/snscan.c	Wed Mar  7 22:25:01 2001
@@ -22,7 +22,7 @@
 #include <time.h>  /* for time_t */
 #include <sys/uio.h>
 #include <sys/mman.h>
-#include <sys/file.h>
+/*#include <sys/file.h>*/
 #include <errno.h>
 #include "config.h"
 #include "artfile.h"
@@ -190,9 +190,9 @@
   er = 1;
   if( (fd = open(path, O_RDWR)) > -1 ){
     fp = (struct file *)mmap(0, sizeof(*fp), PROT_READ|PROT_WRITE,
-      MAP_FILE|MAP_SHARED, fd, 0);
-    if( fp && (int)fp > -1 ){
-      if( 0 == flock(fd, LOCK_EX) ){
+      MAP_SHARED, fd, 0);
+    if( fp && fp != MAP_FAILED ){
+      if( 0 == lockf(fd, F_LOCK, 0) ){
         slot = serial % ARTSPERFILE;
         fp->info[slot].hoffset = fp->info[slot].boffset = -1;
         d.messageid = id;
@@ -310,7 +310,7 @@
     case 'd': debug++; break;
     case 'n': gimme = getnoaliases; break;
     case 'V': version(); _exit(0);
-    case 'i': useid = 1; break;
+    case 'i': useid = 1; dhro = 0; break;   /* Can't lockf() if the DB is opened RO */
     case 'r': print = print_batch; break;
     case 'o':
       if( ! opt_arg )usage();
@@ -411,5 +411,6 @@
   }
   if( since )times_fin();
   group_fin();
+  if (!dhro) dh_close();
   _exit(errors?3:0);
 }
diff -urN sn-0.3.3/snsend.c sn-0.3.3-modified/snsend.c
--- sn-0.3.3/snsend.c	Tue Dec  7 04:35:47 1999
+++ sn-0.3.3-modified/snsend.c	Wed Feb 28 03:11:20 2001
@@ -17,7 +17,7 @@
 #include <sys/time.h>
 #include <sys/stat.h>
 #include <sys/param.h>
-#include <sys/file.h>
+/*#include <sys/file.h>*/
 #include "art.h"
 #include "unfold.h"
 #include "hostname.h"
@@ -194,7 +194,7 @@
   if( -1 == fd )fail(2, "store_fifo:open(%s):%m", path1);
   if( -1 == fcntl(fd, F_SETFL, O_WRONLY) )
     fail(2, "store_fifo:fcntl(%s):%m", path1);
-  flock(fd, LOCK_EX);
+  lockf(fd, F_LOCK, 0);
   if( -1 == writeart(fd) )
     fail(2, "store_fifo:write(%s):%m", path1);
   close(fd);
diff -urN sn-0.3.3/store.c sn-0.3.3-modified/store.c
--- sn-0.3.3/store.c	Fri Aug 13 07:26:39 1999
+++ sn-0.3.3-modified/store.c	Thu Mar  1 06:34:39 2001
@@ -29,7 +29,7 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/mman.h>
-#include <sys/file.h>
+/*#include <sys/file.h>*/
 #include "config.h"
 #include "times.h"
 #include "art.h"
@@ -143,9 +143,9 @@
     try too hard, since it isn't likely, and the consequences of it
     happening are not bad.
    */
-  if( -1 == flock(sp->fd, LOCK_EX|LOCK_NB) ){
+  if( -1 == lockf(sp->fd, F_TLOCK, 0) ){
     char * p;
-    if( EWOULDBLOCK != errno )p = "reorder:can't flock %s:%m";
+    if( EAGAIN != errno )p = "reorder:can't flock %s:%m";
     else p = "reorder:article in %s being cancelled?";
     log(p, sp->filename);
     goto fail;
@@ -243,7 +243,7 @@
   struct timeval tv;
 
   if( (fd = open(fn, O_RDWR)) > -1 ){
-    flock(fd, LOCK_EX);
+    lockf(fd, F_LOCK, 0);
     return(fd);
   }
   for(p = fn2, q = fn; (*p++ = *q++) != '/'; );
@@ -264,7 +264,7 @@
     static struct file f = {FILE_MAGIC, {{0,},},};
     if( 14 == i % 15 )log("tryopen:racing on %s", fn);
     if( (fd = open(fn2, O_RDWR|O_CREAT|O_EXCL, 0644)) > -1 ){
-      flock(fd, LOCK_EX);
+      lockf(fd, F_LOCK, 0);
       if( sizeof(f) == write(fd, (char *)&f, sizeof(f)) )
         if( 0 == link(fn2, fn) ){
           unlink(fn2);
@@ -275,7 +275,7 @@
     }
     /* probably EEXIST due to another process */
     if( (fd = open(fn, O_RDWR)) > -1 ){
-      flock(fd, LOCK_EX);
+      lockf(fd, F_LOCK, 0);
       return(fd);
     }
   }
@@ -303,7 +303,7 @@
 
   s.filename = filename;
   if( (sp = cache_find(desc, &s)) ){
-    flock(sp->fd, LOCK_EX);
+    lockf(sp->fd, F_LOCK, 0);
     return(sp);
   }
 
@@ -314,8 +314,8 @@
    */
 
   fp = (struct file *)mmap(0, sizeof(*fp),
-    PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, fd, 0);
-  if( ! fp || -1 == (int)fp )
+    PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+  if( ! fp || fp == MAP_FAILED )
     log("getstore:mmap(%s):%m", filename);
   else if( ! (sp = malloc(sizeof(*sp) + strlen(filename) + 1)) ){
     log("getstore:no memory");
@@ -373,7 +373,7 @@
     for(slot = 0; slot < ARTSPERFILE; slot++)
       if( 0 == sp->file->info[slot].hoffset )break;
     if( slot < ARTSPERFILE )break;
-    flock(sp->fd, LOCK_UN);
+    lockf(sp->fd, F_ULOCK, 0);
     cache_invalidate(desc, sp);
   }
 
@@ -439,7 +439,7 @@
   }else
     log("sto_add:lseek(%s):%m", sp->filename);
 
-  flock(sp->fd, LOCK_UN);
+  lockf(sp->fd, F_ULOCK, 0);
   if( slot == ARTSPERFILE-1 ){
     reorder(sp);
     cache_invalidate(desc, sp);
diff -urN sn-0.3.3/times.c sn-0.3.3-modified/times.c
--- sn-0.3.3/times.c	Mon Jul 26 18:44:12 1999
+++ sn-0.3.3-modified/times.c	Thu Mar  1 06:00:49 2001
@@ -66,8 +66,8 @@
     if( 0 == (st.st_size % sizeof(struct times)) ){
       size = (st.st_size + 2048) - (st.st_size % 1024);
       tp->times = (struct times *)mmap(0, size,
-        PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, tp->fd, 0);
-      if( (int)tp->times > 0 ){
+        PROT_READ|PROT_WRITE, MAP_SHARED, tp->fd, 0);
+      if( tp->times != MAP_FAILED ){
         tp->mapsize = size;
         break;
       }else
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.