diff -u --recursive --new-file dosemu0.53pl28/ChangeLog dosemu0.53pl29/ChangeLog
--- dosemu0.53pl28/ChangeLog	Wed Oct 19 22:28:19 1994
+++ dosemu0.53pl29/ChangeLog	Tue Nov  1 23:02:57 1994
@@ -1,3 +1,48 @@
+Tue Nov 01 1994 JES
+
+-	Tested that Helppc ran.
+-	Added STI to keyboard int16 of bios.S. One fix for PIC, for 
+	now :-).
+-	Changed && -> & in pic_request() if pic_iret().
+
+Wed Oct 25 1994 JES
+
+- 	Latest v-net app from Vinod + ipxbridges.
+
+From: Rod May <stoke@melbourne.DIALix.oz.au>
+Hi there,
+	here's a patch (to pl28) which makes the use of "mkpartition" 
+unnecessary for direct partition access. Also the partition number is no
+longer required. i.e. instead of specifying:
+	disk { partition "/dev/hda3" 3 }  and running "mkpartition",
+you only have to specify:
+	disk { partition "/dev/hda3" }
+The MBR is read from the appropriate hard drive during start-up.
+Not only does this simplyfy things but stops potential mistakes
+including: out of date MBRs, specifying hda instead of hda3 etc. 
+These were not flagged before and could lead to "interesting" results. 
+Using the old format will get you a config warning but otherwise
+the partition number will just be ignored,
+	Ciao,
+		Rod May,
+		stoke@melbourne.dialix.oz.au
+
+
+Hope this patch is useful, next effort might be read_sectors() which
+needs a bit of work!
+		bye for now,
+				Rod.
+
+
+Sat Oct 22 1994 JES
+
+-	More xinstallvgafont.sh fixups with thanks to :
+	> Kang-Jin Lee
+	> lee@tengu.in-berlin.de
+-	Makefile enhancements from Marty.
+-	Detach updates by n1046128@student.fit.qut.edu.au (WAYNE P MEISSNER)
+-	Modified ports.h by Markky
+
 Wed Oct 19 1994 JES
 
 -	Release pre53_28.tgz
diff -u --recursive --new-file dosemu0.53pl28/Configure dosemu0.53pl29/Configure
--- dosemu0.53pl28/Configure	Wed Oct 19 22:28:19 1994
+++ dosemu0.53pl29/Configure	Tue Nov  1 23:02:58 1994
@@ -1,12 +1,14 @@
 #!/bin/sh
 #
-# Configure 0.2
+# Configure 0.3
 # configuration program for dosemu
-# WARNIG : This program is pre-alpha !
+# WARNIG : This program is alpha !
 #
 # If you have any problems or bugs with this program, 
 # please let me know.
 #
+# This script needs dialog 0.4
+# 
 # (c) 1994 Jan 'TWP' VANDENBERGHE
 #          jvdbergh@wins.uia.ac.be
 #
@@ -28,10 +30,8 @@
    cp $CONFIG_BACK $CONFIG
    exit
 fi
-
 }
 
-
 # deleteds part of config. file
 delete_part() {
 
@@ -124,7 +124,6 @@
    esac
 done
 
-# radiolist
 dialog  --title "MISCALLENOUS" --radiolist "select cpu-type to emulate" 10 40 3\
    1 80286 off\
    2 80386 off \
@@ -139,7 +138,6 @@
    3) echo "cpu 80486" >> $CONFIG;;
 esac
 
-# radiolist
 dialog  --title "MISCALLENOUS" --checklist "mathcoprocessor on durin DOSEMU\
 ? : " 8 50 1 \
    1 "mathcoprocessor on" on 2> $TEMP
@@ -152,7 +150,6 @@
    "") echo "mathco off" >> $CONFIG;;
 esac
 
-# radiolist
 dialog  --title "MISCALLENOUS" --radiolist "boot from" 9 30 2\
    1 "boot from A" off\
    2 "boot from C" on 2> $TEMP
@@ -174,7 +171,6 @@
 delete_part "## KEYBOARD ##"
 echo "## KEYBOARD ##" >> $CONFIG
 
-# radiolist
 dialog --title "KEYBOARD" --radiolist "select a keyboard layout" 24 60 17 \
   1 us off \
   2 uk off \
@@ -259,15 +255,6 @@
 }
 
 
-select_miscallenous2() {
-
-echo "## MISCALLENOUS ##" >> $CONFIG
-
-
-echo "" >> $CONFIG  
-}
-
-
 select_memory() {
 
 delete_part "## MEMORY ##"
@@ -301,7 +288,6 @@
 delete_part "## SPEAKER ##"
 echo "## SPEAKER ##" >> $CONFIG
 
-# radiolist
 dialog  --title "SPEAKER" --radiolist "select an option :\n\
   native      Enable DOSEMU direct access to the speaker ports.\n\
   emulated    Enable simple beeps at the terminal.\n\
@@ -325,7 +311,6 @@
 
 select_mouse() {
 
-# radiolist
 dialog  --title "MOUSE" --radiolist "select mouseport" 11 30 4 \
    1 "com 1" on\
    2 "com 2" off \
@@ -346,7 +331,6 @@
 
 echo  "device /dev/mouse }" >> $CONFIG
 
-# radiolist
 dialog  --title "MOUSE" --radiolist "select mousetype" 15 30 8 \
    1 "microsoft" on\
    2 "logitech" off \
@@ -381,7 +365,6 @@
 
 select_modem() {
 
-# radiolist
 dialog  --title "MODEM" --radiolist "select modemport" 11 30 4 \
    1 "com 1" on\
    2 "com 2" off \
@@ -468,7 +451,6 @@
 delete_part "## VIDEO ##"
 echo "## VIDEO ##" >> $CONFIG
 
-# radiolist
 dialog  --title "VIDEO" --radiolist "select videomode" 11 30 4\
    1 "vga" on\
    2 "ega" off \
@@ -490,7 +472,6 @@
 
 echo -n "console  "  >> $CONFIG
 
-# radiolist
 dialog  --title "VIDEO" --checklist "graphics ?" 8 30 1\
    1 "graphics on" on 2> $TEMP
 
@@ -501,7 +482,6 @@
    \"1\") echo -n "graphics " >> $CONFIG;;
 esac
 
-# radiolist
 dialog  --title "VIDEO" --radiolist "select chipset" 12 30 5\
    1 "standard" on\
    2 "trident" off \
@@ -558,7 +538,6 @@
 delete_part "## FLOPPY DISKS ##"
 echo "## FLOPPY DISKS ##" >> $CONFIG
 
-# radiolist
 dialog  --title "FLOPPY DISKS" --radiolist "                 floppy drive A:\n\
 FOR SAFETY, UNMOUNT ALL FLOPPY DRIVES FROM YOUR FILESYSTEM BEFORE\n\
 STARTING UP DOSEMU!  DAMAGE TO THE FLOPPY MAY RESULT OTHERWISE!" 12 70 3\
@@ -578,7 +557,6 @@
    esac
 fi
 
-# radiolist
 dialog  --title "FLOPPY DISKS" --radiolist "                 floppy drive B:\n\
 FOR SAFETY, UNMOUNT ALL FLOPPY DRIVES FROM YOUR FILESYSTEM BEFORE\n\
 STARTING UP DOSEMU!  DAMAGE TO THE FLOPPY MAY RESULT OTHERWISE!" 12 70 3\
@@ -654,6 +632,7 @@
    - Format a diskette with 'FORMAT A: /S'
    - Copy C:\DOS\FDISK.EXE to the diskette.
    - Copy C:\DOS\SYS.COM to the diskette." 10 50
+   clear
    exit
 else
    dialog --title "HARD DISKS" --msgbox "Please insert the DOS disk in drive
@@ -685,7 +664,6 @@
 dialog --title "HARD DISKS" --yesno "Do you want to use a DISKIMAGE file ?"\
  5 50 
 
-
 if [ "$?" = "0" ]
 then
    select_image
@@ -778,8 +756,8 @@
  check_status
  choice=`cat $TEMP`
  case $choice in
-   1) echo -n "methode fast  " >> $CONFIG;;
-   2) echo -n "methode ncurses  " >> $CONFIG;;
+   1) echo -n "method fast  " >> $CONFIG;;
+   2) echo -n "method ncurses  " >> $CONFIG;;
  esac
 
  dialog --title "TERMINAL" --radiolist "Enable/disable printing of the\
@@ -802,15 +780,21 @@
 }
 
 
-
-
-
 select_printers() {
 
 delete_part "## PRINTERS ##"
 echo "## PRINTERS ##" >> $CONFIG
 
+echo -n "printer { " >> $CONFIG
 
+dialog --title "PRINTERS" --yesno "Do you want DOSEMU to 'lpr' ?" 5 50
+
+if [ "$?" = "0" ]
+then
+   echo  "options \"-p %s\"  command \"lpr\"  timeout 10 }" >> $CONFIG
+else   
+   echo "file \"lpt3\" }" >> $CONFIG
+fi
 
 echo "" >> $CONFIG
 
@@ -940,7 +924,7 @@
 then echo "" 
 else 
     cp -b $CONFIG $CONFIG_BACK
-    echo  "## configuration file for DOSEMU created by dosconfig 0.2 ##" > $CONFIG
+    echo  "## configuration file for DOSEMU created by dosconfig 0.3 ##" > $CONFIG
     echo -e "##                 please do not edit                     ##\n" >> $CONFIG
 fi
 
diff -u --recursive --new-file dosemu0.53pl28/Makefile dosemu0.53pl29/Makefile
--- dosemu0.53pl28/Makefile	Wed Oct 19 22:28:19 1994
+++ dosemu0.53pl29/Makefile	Tue Nov  1 23:02:57 1994
@@ -21,7 +21,7 @@
 # fi
 
 #Change the following line if the right kernel includes reside elsewhere
-LINUX_INCLUDE = /usr/src/linux/include
+LINUX_INCLUDE = /usr/src/linux/include # why not
 export LINUX_INCLUDE  
 
 #Change the following line if the your X is elsewhere.
@@ -61,22 +61,29 @@
 # Uncomment the next line to try new pic code on keyboard, timer, and serial.
 # NOTE:  The serial pic code is known to have bugs.
 NEW_PIC = -DNEW_PIC=2
-#ifdef NEW_PIC
-PICOBJS = timer.o
+ifdef NEW_PIC
+PICOBJS = libtimer.a
 export NEW_PIC
 export PICOBJS
-#endif
-
+endif
 
-#ifdef DEBUG
-#STATIC=1
-#DOSOBJS=$(OBJS)
-#SHLIBOBJS=
+# do_DEBUG=true
+ifdef do_DEBUG
+CC         = gcc -g # I use gcc-specific features (var-arg macros, fr'instance)
+LD         = gcc
+COPTFLAGS	= -O
+STATIC=1
+DOSOBJS=$(OBJS) $(DPMIOBJS)
+SHLIBOBJS=
 #DOSLNK=-lncurses -lipc
-#CDEBUGOPTS=-g -DSTATIC=1
-#LNKOPTS=
-#else
-#STATIC=0
+CDEBUGOPTS=-g -DSTATIC=1
+LNKOPTS=
+else
+CC         = gcc 
+LD         = gcc
+COPTFLAGS  = -N -s -O2 -funroll-loops
+# -Wall -fomit-frame-pointer # -ansi -pedantic -Wmissing-prototypes -Wstrict-prototypes
+STATIC=0
 DOSOBJS=
 SHLIBOBJS=$(OBJS)
 DOSLNK=
@@ -83,12 +90,12 @@
 #LNKOPTS=-s
 # LNKOPTS=-Ttext
 #MAGIC=-zmagic
-#endif
+endif
 
 # dosemu version
 EMUVER  =   0.53
 VERNUM  =   0x53
-PATCHL  =   28
+PATCHL  =   29
 LIBDOSEMU = libdosemu$(EMUVER)pl$(PATCHL)
 
 # DON'T CHANGE THIS: this makes libdosemu start high enough to be safe. 
@@ -97,7 +104,7 @@
 
 ENDOFDOSMEM = 0x110000     # 1024+64 Kilobytes
 
-DPMIOBJS = dpmi/dpmi.o
+DPMIOBJS = libdpmi.a
 
 # For testing the internal IPX code
 #IPX = ipxutils
@@ -126,7 +133,7 @@
 
 CLIENTSSUB=clients
 
-OPTIONALSUBDIRS = examples sig v-net syscallmgr emumod
+OPTIONALSUBDIRS =examples sig v-net syscallmgr emumod
 
 SUBDIRS= periph video mouse include boot commands drivers \
 	$(DPMISUB) $(CLIENTSSUB) timer init net $(IPX) kernel \
@@ -160,9 +167,10 @@
 
 ###################################################################
 
-OBJS=emu.o termio.o disks.o keymaps.o timers.o cmos.o mouse.o \
+OBJS=emu.o termio.o disks.o keymaps.o timers.o cmos.o libmouse.a \
      dosio.o cpu.o xms.o mfs.o bios_emm.o lpt.o $(PICOBJS)\
-     serial.o dyndeb.o sigsegv.o video.o bios.o init.o net.o detach.o $(XOBJS)
+     serial.o dyndeb.o sigsegv.o libvideo.a bios.o libinit.a libnet.a \
+     detach.o $(XOBJS)
 
 OPTIONAL   = # -DDANGEROUS_CMOS=1
 CONFIGS    = $(CONFIG_FILE) $(DOSEMU_USERS_FILE)
@@ -171,11 +179,6 @@
 	     -DLIBSTART=$(LIBSTART) -DVERNUM=$(VERNUM) -DVERSTR=\"$(EMUVER)\" \
 	     -DPATCHSTR=\"$(PATCHL)\"
 
-CC         = gcc # I use gcc-specific features (var-arg macros, fr'instance)
-LD         = ld
-COPTFLAGS  = -N -s -O2 -funroll-loops
-
-# -Wall -fomit-frame-pointer # -ansi -pedantic -Wmissing-prototypes -Wstrict-prototypes
  
 ifdef DPMIOBJS
 DPMI = -DDPMI
@@ -207,6 +210,18 @@
 DISTFILE=$(DISTBASE)/pre$(EMUVER)_$(PATCHL).tgz
 endif
 
+
+ifdef do_DEBUG
+# first target for debugging build
+ifneq (config.h,$(wildcard config.h))
+firstsimple:	config dep simple
+endif
+
+simple:	dossubdirs dos
+
+endif
+
+
 warning: warning2
 	@echo "To compile DOSEMU, type 'make doeverything'"
 	@echo "To compile DOSEMU if you dont want to use TeX, type 'make most'"
@@ -264,10 +279,9 @@
 x2dos.o: config.h x2dos.c
 	$(CC) -I/usr/openwin/include -c x2dos.c
 
-dos:	dos.c $(DOSOBJS)
+dos:	dos.o $(DOSOBJS)
 	@echo "Including dos.o " $(DOSOBJS)
-	$(CC) $(DOSLNK) $(LDFLAGS) -N -o $@ $< $(DOSOBJS) \
-              $(XLIBS)
+	$(LD) $(LDFLAGS) -o $@ $^ -lncurses
 
 x2dos: x2dos.c
 	@echo "Including x2dos.o "
@@ -282,7 +296,7 @@
 	@cat xtermdos.sh >> xtermdos
 
 xinstallvgafont:	xinstallvgafont.sh
-	@echo "#!/bin/sh" > xintallvgafont
+	@echo "#!/bin/sh" > xinstallvgafont
 	@echo >> xinstallvgafont
 	@echo X11ROOTDIR=$(X11ROOTDIR) >> xinstallvgafont
 	@echo >> xinstallvgafont
@@ -290,19 +304,21 @@
 
 $(LIBDOSEMU):	$(SHLIBOBJS) $(DPMIOBJS)
 	$(LD) $(LDFLAGS) $(MAGIC) -Ttext $(LIBSTART) -o $(LIBDOSEMU) \
-	   $(SHLIBOBJS) $(DPMIOBJS) $(SHLIBS) $(XLIBS) -lncurses -lc
+	   -nostdlib $(SHLIBOBJS) $(DPMIOBJS) $(SHLIBS) $(XLIBS) -lncurses -lc
+
+.PHONY:	dossubdirs optionalsubdirs docsubdirs
 
-dossubdirs: dummy
+dossubdirs:
 	@for i in $(SUBDIRS); do \
-	    (cd $$i && echo $$i && $(MAKE)) || exit; \
+	    $(MAKE) -C  $$i || exit; \
 	done
 
 optionalsubdirs:
 	@for i in $(OPTIONALSUBDIRS); do \
-	    (cd $$i && echo $$i && $(MAKE)) || exit; \
+	    $(MAKE) -C $$i || exit; \
 	done
 
-docsubdirs: dummy
+docsubdirs: 
 	@for i in $(DOCS); do \
 	    (cd $$i && echo $$i && $(MAKE)) || exit; \
 	done
@@ -310,7 +326,7 @@
 config: dosconfig
 	@./dosconfig $(CONFIGINFO) > config.h
 
-installnew: dummy
+installnew: 
 	$(MAKE) install
 
 install: all
@@ -389,7 +405,7 @@
 	cp TODO.JES $(DISTPATH)/.todo.jes
 	cp .indent.pro $(DISTPATH)/.indent.pro
 	install -m 0644 hdimages/hdimage.dist $(DISTPATH)/hdimage.dist
-	@for i in $(SUBDIRS) $(DOCS) dpmi ipxutils $(OPTIONALSUBDIRS); do \
+	@for i in $(SUBDIRS) $(DOCS) dpmi ipxutils $(OPTIONALSUBDIRS) ipxbridge; do \
 	    (cd $$i && echo $$i && $(MAKE) dist) || exit; \
 	done
 	(cd $(DISTBASE); tar cf - $(DISTNAME) | gzip -9 >$(DISTFILE))
@@ -404,6 +420,7 @@
 	  $(MAKE) -C $$i clean; \
 	done
 
+# isn't this redudenant? No, I don't think so, it does realclean not clean.
 realclean:      clean
 	-rm -f config.h .depend
 	-@for i in $(SUBDIRS) $(OPTIONALSUBDIRS); do \
@@ -425,7 +442,6 @@
 	cd dpmi;$(CPP) -MM -I../ -I../include $(CFLAGS) *.c > .depend
 endif
 
-dummy:
 #
 # include a dependency file if one exists
 #
diff -u --recursive --new-file dosemu0.53pl28/bios.S dosemu0.53pl29/bios.S
--- dosemu0.53pl28/bios.S	Wed Oct 19 22:28:19 1994
+++ dosemu0.53pl29/bios.S	Tue Nov  1 23:02:57 1994
@@ -42,9 +42,9 @@
 
 	pushl	%eax
 	movb    $0x16,%al
+	sti
 	int     $0xe6				/* sti with return to dosemu code */
 	popl	%eax
-
 	jmp     L2
 L3:	.byte   0x8b, 0x07			/* movw   [%bx],%ax */
 	incl    %ebx
diff -u --recursive --new-file dosemu0.53pl28/detach.c dosemu0.53pl29/detach.c
--- dosemu0.53pl28/detach.c	Wed Oct 19 22:28:18 1994
+++ dosemu0.53pl29/detach.c	Tue Nov  1 23:02:57 1994
@@ -2,82 +2,202 @@
 #include <fcntl.h>
 #include <sys/vt.h>
 #include <sys/kd.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <sys/param.h>
+
+/* 
+ * Update to do console disallocation on exit of dosemu
+ * (C) 1994 under GPL: Wayne Meissner
+ * 
+ */
+
+/* the new VT for dosemu - only needed by detach() and disallocate_vt() */
+static int dosemu_vt = 0;
+
+static struct stat orig_stat; /* original info of the VT */
+
+/* One of these has to work */
+const char * CONSOLE[] =   { 
+  "/dev/console",
+  "/dev/tty0",
+  "/dev/vt00",
+  "/dev/systty",
+  0 
+};
+
+const char vt_base[] = "/dev/tty";
+
+/* open a specific VT */
+
+static int open_vt (int vt)  {
+  char path[MAXPATHLEN];
+
+  int vt_fd = -1;
+  
+  sprintf(path, "%s%d", vt_base, vt);
+  return open (path, O_RDWR); 
+}
+
+/* open the main console */
+static int open_console (void)  {
+  int console = -1;
+  int pos;
+  for (pos = 0; CONSOLE[pos]; pos++)  {
+    errno = 0;
+    if ((console = open (CONSOLE[pos], O_WRONLY)) >= 0)  {
+      return console;
+    }
+  }
+  return -1;
+}
+
+unsigned short detach (void) {
+  
+  struct vt_stat vts;
+  int pid;
+  int fd;
+    struct stat statout, staterr;
+  
+  if ((fd = open_console()) < 0) {
+    fprintf(stderr, "Could not open current VT.\n");
+    return(0);
+  }
+  
+  if (ioctl(fd, VT_GETSTATE, &vts) < 0) {
+    perror("VT_GETSTATE");
+    return(0);
+  }
+  
+  if (ioctl(fd, VT_OPENQRY, &dosemu_vt) < 0) {
+    perror("VT_OPENQRY");
+    return(0);
+  }
+  
+  if (dosemu_vt < 1) {
+    fprintf(stderr, "No free vts to open\n");
+    return(0);
+  }
+    
+  if (ioctl(fd, VT_ACTIVATE, dosemu_vt) < 0) {
+    perror("VT_ACTIVATE");
+    return(0);
+  }
+  
+  if (ioctl(fd, VT_WAITACTIVE, dosemu_vt) < 0) {
+    perror("VT_WAITACTIVE");
+    return(0);
+  }
+  
+  if ((pid = fork()) < 0) {
+    perror("fork");
+    return(0);
+  }
+  
+  if (pid) {
+    exit(0);
+  }
+  
+  close(fd);
+  
+  /* only reassign stderr to the new VT if it isn't already redirected */
+  fstat(2, &statout);
+  fstat(1, &staterr);
+  if (staterr.st_ino == statout.st_ino) {
+    close (2);
+    open_vt (dosemu_vt);
+  }
+
+
+  close(1);
+  close(0);
+  
+  open_vt (dosemu_vt);
+  open_vt (dosemu_vt);
+    
+  /* save the uid, gid, mode of the VT */
+  fstat (0, &orig_stat);
+
+  /* now set the console as owned by this user */
+  if (geteuid() == 0)
+    fchown (0, getuid(), getgid());
+  
+  /* set the permissions to stop other people accessing the vt */
+  fchmod (0, S_IRUSR | S_IWUSR);
+
+  setsid();
+  return(vts.v_active); /* return old VT. */
+}
+
 
-unsigned short
-detach()
-{
-	struct vt_stat vts;
-	int pid;
-	int vt;
-	int fd;
-	char dev[16];
-
-	if ((fd = open("/dev/tty0", O_RDONLY)) < 0) {
-		fprintf(stderr, "Could not open current VT.\n");
-		return(0);
-	}
-
-	if (ioctl(fd, VT_GETSTATE, &vts) < 0) {
-		perror("VT_GETSTATE");
-		return(0);
-	}
-
-	if (ioctl(fd, VT_OPENQRY, &vt) < 0) {
-		perror("VT_OPENWRY");
-		return(0);
-	}
-
-	if (vt < 1) {
-		fprintf(stderr, "No free vts to open\n");
-		return(0);
-	}
-
-	sprintf(dev, "/dev/tty%d", vt);
-
-	if (ioctl(fd, VT_ACTIVATE, vt) < 0) {
-		perror("VT_ACTIVATE");
-		return(0);
-	}
-
-	if (ioctl(fd, VT_WAITACTIVE, vt) < 0) {
-		perror("VT_WAITACTIVE");
-		return(0);
-	}
-
-	if ((pid = fork()) < 0) {
-		perror("fork");
-		return(0);
-	}
-
-	if (pid) {
-		exit(0);
-	}
-
-	close(fd);
-	close(2);
-	close(1);
-	close(0);
-
-	(void)open(dev, O_RDWR);
-	(void)open(dev, O_RDWR);
-	(void)open(dev, O_RDWR);
+void restore_vt (unsigned short vt) {
+  
+  int console = 0;  /* stdin by default */
+  errno = 0;
+  
+  if (ioctl(console, VT_ACTIVATE, vt) < 0) {
+    
+    /* open the console manually and try again */
+    console = open_console();
+    if (ioctl(console, VT_ACTIVATE, vt) < 0) {
+      perror("VT_ACTIVATE");
+      close (console);
+      return;
+    }
+  }
+  
+  if (ioctl(console, VT_WAITACTIVE, vt) < 0) {
+    perror("VT_WAITACTIVE");
+    if (console > 0) 
+      close(console);
+    return;
+  }
+  if (console > 0) 
+    close (console);
 
-	(void)setsid();
-	return(vts.v_active); /* return old VT. */
 }
 
-restore_vt(vt)
-unsigned short vt;
-{
-
-	if (ioctl(0, VT_ACTIVATE, vt) < 0) {
-		perror("VT_ACTIVATE");
-		return;
-	}
-
-	if (ioctl(0, VT_WAITACTIVE, vt) < 0) {
-		perror("VT_WAITACTIVE");
-		return;
-	}
+/* its not really critical if this succeeds */
+void disallocate_vt (void) {
+#ifdef VT_DISALLOCATE /* only use for >1.1.54 */
+  int console;
+  int vt_fd;
+  struct stat statout, staterr;
+
+    
+  /* Restore the uid, gid, mode of the VC */
+  if ((vt_fd = open_vt (dosemu_vt)) >= 0) {
+    fchown (vt_fd, orig_stat.st_uid, orig_stat.st_gid);
+    fchmod (vt_fd, orig_stat.st_mode);
+    close (vt_fd);
+  }
+
+  
+  /* We have to close all fd attached to the console.
+   * I think this should really be taken care of by the caller (leavedos()?)
+   */
+  fstat(2, &statout);
+  fstat(1, &staterr);
+  if (staterr.st_ino == statout.st_ino) {
+    close (2);
+  }
+  close (1);
+  close (0);
+
+  console = open_console();
+  
+  if (console < 0) {
+    return;
+  }
+  
+  
+  if (ioctl (console, VT_DISALLOCATE, dosemu_vt) < 0) {
+    perror ("VT_DISALLOCATE");
+    close (console);
+    return;
+  }
 
+  close (console);
+#endif /* VT_DISALLOCATE */
 }
diff -u --recursive --new-file dosemu0.53pl28/disks.c dosemu0.53pl29/disks.c
--- dosemu0.53pl28/disks.c	Wed Oct 19 22:28:18 1994
+++ dosemu0.53pl29/disks.c	Tue Nov  1 23:02:56 1994
@@ -315,6 +315,7 @@
 {
   int part_fd, i;
   unsigned char tmp_mbr[SECTOR_SIZE];
+  char *hd_name;
   void set_part_ent(struct disk *, char *);
 
 #define PART_BYTE(p,b)  *((unsigned char *)tmp_mbr + PART_INFO_START + \
@@ -327,22 +328,24 @@
 
   d_printf("PARTITION SETUP for %s\n", dp->dev_name);
 
-  c_printf("CONFIG: Using partion file %s\n", dp->part_info.file);
+  hd_name = strdup(dp->dev_name);
+  hd_name[8] = '\0';			/* i.e.  /dev/hda6 -> /dev/hda */
 
-  if ((part_fd = DOS_SYSCALL(open(dp->part_info.file, O_RDONLY))) == -1) {
-    error("ERROR: cannot open file %s for PARTITION %s\n",
-	  dp->part_info.file, dp->dev_name);
+  if ((part_fd = DOS_SYSCALL(open(hd_name, O_RDONLY))) == -1) {
+    error("ERROR: opening device %s to read MBR for PARTITION %s\n",
+	  hd_name, dp->dev_name);
     leavedos(22);
   }
-
   RPT_SYSCALL(read(part_fd, tmp_mbr, SECTOR_SIZE));
-
   close(part_fd);
+  d_printf("Using MBR from %s for PARTITION %s (part#=%d).\n",
+           hd_name, dp->dev_name, PNUM);
+  free(hd_name);
 
   /* check for logical partition, if so simulate as primary part#1 */
-  if (dp->part_info.number > 4 ) {
+  if (PNUM > 4 ) {
     d_printf("LOGICAL PARTITION - will be simulated as physical partition 1\n");
-    dp->part_info.number = 1;
+    PNUM = 1;
     set_part_ent(dp, tmp_mbr);
   }
   dp->part_info.beg_head = PART_BYTE(PNUM, 1);
@@ -400,7 +403,7 @@
 }
 
 /* XXX - this function constructs a primary partition table entry for the device
- *       dp->dev_name which can be primary, extended or logical. This is done by
+ *       dp->dev_name which should be a logical DOS partition. This is done by
  *       knowing the preceding sectors & length in sectors, and the geometry
  *       of the drive. The physical h/s/c start and end are calculated and
  *       put in the dp->part_info.number'th entry in the part table.
@@ -427,7 +430,7 @@
   d_printf("Calculated physical start: head=%4d sect=%4d cyl=%4d,\n",
 	HEAD(dp->start), SECT(dp->start), CYL(dp->start));
   end = dp->start+length-1;
-  d_printf("Calculated physical end:   head=%4d sect=%4d cyl=%4d.\n\n",
+  d_printf("Calculated physical end:   head=%4d sect=%4d cyl=%4d.\n",
 	HEAD(end), SECT(end), CYL(end));
 
   /* get address of where to put new part table entry */
diff -u --recursive --new-file dosemu0.53pl28/disks.h dosemu0.53pl29/disks.h
--- dosemu0.53pl28/disks.h	Wed Oct 19 22:28:18 1994
+++ dosemu0.53pl29/disks.h	Tue Nov  1 23:02:57 1994
@@ -11,8 +11,6 @@
 #define PART_NOBOOT	0
 #define PART_BOOT	0x80
 
-#define PARTITION_PATH	"/var/lib/dosemu/partition"
-
 /* disk file types */
 typedef enum {
   NODISK = -1,
@@ -31,7 +29,6 @@
   long num_secs;		/* sectors in partition */
   char *mbr;			/* fake Master Boot Record */
   int mbr_size;			/* usu. 1 sector */
-  char *file;                   /* file with original partition table */
 };
 
 struct disk {
diff -u --recursive --new-file dosemu0.53pl28/dosio.c dosemu0.53pl29/dosio.c
--- dosemu0.53pl28/dosio.c	Wed Oct 19 22:28:18 1994
+++ dosemu0.53pl29/dosio.c	Tue Nov  1 23:02:56 1994
@@ -486,8 +486,6 @@
 do_irq1(void) {
    parent_nextscan();
    do_irq(); /* do dos interrupt */
-             /* reschedule if queue not empty */
-   if (scan_queue_start!=scan_queue_end) pic_request(PIC_IRQ1); 
 }
 #endif
 
@@ -568,7 +566,16 @@
       inschr = 0;
     }
   }
-  k_printf("parent nextscan found inschr=0x%04x, lastchr = 0x%04x, *LASTSCAN_ADD = 0x%04x\n", inschr, lastchr, *LASTSCAN_ADD);
+#ifdef NEW_PIC
+  /* reschedule if queue not empty */
+  if (scan_queue_start!=scan_queue_end) { 
+    k_printf("KBD: Requesting next keyboard interrupt startstop %d:%d\n", 
+      scan_queue_start, scan_queue_end);
+    pic_request(PIC_IRQ1); 
+    *LASTSCAN_ADD=1;
+  }
+#endif
+  k_printf("set keybaord bios inschr=0x%04x, lastchr = 0x%04x, *LASTSCAN_ADD = 0x%04x\n", inschr, lastchr, *LASTSCAN_ADD);
   k_printf("MOVING   key 96 0x%02x, 97 0x%02x, kbc1 0x%02x, kbc2 0x%02x\n",
 	   *(u_char *)KEYFLAG_ADDR , *(u_char *)(KEYFLAG_ADDR +1), *(u_char *)KBDFLAG_ADDR, *(u_char *)(KBDFLAG_ADDR+1));
 }
@@ -582,6 +589,8 @@
   else
     keepkey = 0;
 
+  k_printf("KBD: Finishing up call\n");
+
   if (inschr && keepkey) {
     k_printf("IPC/KBD: (child) putting key in buffer\n");
     if (InsKeyboard(inschr))
@@ -597,7 +606,7 @@
 
   keys_ready = 0;
 #ifdef NEW_PIC
-  if(*LASTSCAN_ADD==1)   /* make sure last character has been read */
+  if(*LASTSCAN_ADD==1) {  /* make sure last character has been read */
 #endif
   if (scan_queue_start != scan_queue_end) {
     keys_ready = 1;
@@ -611,6 +620,9 @@
        *LASTSCAN_ADD = lastchr;
     }
   }
+  }
+  else
+    k_printf("Parent Nextscan Key not Read!\n");
   k_printf("Parent Nextscan key 96 0x%02x, 97 0x%02x, kbc1 0x%02x, kbc2 0x%02x\n",
 	   *(u_char *) 0x496, *(u_char *) 0x497, *(u_char *) 0x417, *(u_char *) 0x418);
   k_printf("start=%d, end=%d, LASTSCAN=%x\n", scan_queue_start, scan_queue_end, *LASTSCAN_ADD);
diff -u --recursive --new-file dosemu0.53pl28/dpmi/Makefile dosemu0.53pl29/dpmi/Makefile
--- dosemu0.53pl28/dpmi/Makefile	Wed Oct 19 22:28:32 1994
+++ dosemu0.53pl29/dpmi/Makefile	Tue Nov  1 23:03:14 1994
@@ -13,8 +13,19 @@
 ALL = dpmi.c dpmi.h \
 	testdpmi.S
 
-all: dpmi.o testdpmi.com
+SUBDIR=dpmi
 
+OBJS = $(SUBDIR).o
+
+LIB=../lib$(SUBDIR).a
+
+all:  $(LIB) testdpmi.com
+
+$(LIB): $(OBJS)
+	-rm $@
+	$(AR) cr $@ $^
+	ranlib $@
+
 dpmi.o:
 	$(CC) -DDPMI $(INCDIR) -N -O6 -c dpmi.c
 
@@ -24,7 +35,7 @@
 	-co -l $(ALL) Makefile TODO
 
 clean:
-	rm -f *.o *.com
+	rm -f *.o *.com ../lib$(SUBDIR).a
 
 realclean:
 	rm -f .depend
@@ -32,8 +43,8 @@
 install:
 
 dist: $(ALL) Makefile
-	install -d $(DISTPATH)/dpmi
-	install -m 0644 $(ALL) Makefile TODO $(DISTPATH)/dpmi
+	install -d $(DISTPATH)/$(SUBDIR)
+	install -m 0644 $(ALL) Makefile TODO $(DISTPATH)/$(SUBDIR)
 
 depend dep: $(CFILES) $(HFILES)
 	$(CPP) -MM $(CFLAGS) *.c $(INCDIR) > .depend
diff -u --recursive --new-file dosemu0.53pl28/emu.c dosemu0.53pl29/emu.c
--- dosemu0.53pl28/emu.c	Wed Oct 19 22:28:17 1994
+++ dosemu0.53pl29/emu.c	Tue Nov  1 23:02:56 1994
@@ -520,6 +520,10 @@
 #include "int.h"
 #endif
 
+extern void restore_vt (unsigned short);
+extern void disallocate_vt (void);
+extern unsigned short detach (void);
+
 extern void getKeys(void);
 
 extern void setup_low_mem(void);
@@ -779,6 +783,7 @@
 {
   sigset_t blockset;
 
+  return; /* Should be OK now */
   sigfillset(&blockset);
   DOS_SYSCALL(sigprocmask(SIG_SETMASK, &blockset, &oldset));
 }
@@ -796,6 +801,7 @@
 {
   sigset_t blockset;
 
+  return; /* Should be OK now */
   DOS_SYSCALL(sigprocmask(SIG_SETMASK, &oldset, &blockset));
 }
 
@@ -850,7 +856,8 @@
    */
     in_vm86 = 1;
 #ifdef NEW_PIC
-    if(pic_icount) REG(eflags) |= (VIP);
+    if(pic_icount) 
+      REG(eflags) |= (VIP);
 #endif
     switch VM86_TYPE({retval=vm86(&vm86s); in_vm86=0; retval;}) {
 	case VM86_UNKNOWN:
@@ -1092,12 +1099,12 @@
 
   /* inline int09 routine */
   ptr = (u_char *) INT09_ADD;
-  memcpy(ptr, INT09_dummy_start, (unsigned long) INT09_dummy_end - (unsigned long) INT09_dummy_start);
+  memcpy(ptr, INT09_dummy_start, (unsigned long) INT09_dummy_end - (unsigned long) INT09_dummy_start + 1);
   SETIVEC(0x09, INT09_SEG, INT09_OFF);
 
   /* int08 */
   ptr = (u_char *) INT08_ADD;
-  memcpy(ptr, INT08_dummy_start, (unsigned long) INT08_dummy_end - (unsigned long) INT08_dummy_start);
+  memcpy(ptr, INT08_dummy_start, (unsigned long) INT08_dummy_end - (unsigned long) INT08_dummy_start + 1);
   SETIVEC(0x08, INT08_SEG, INT08_OFF);
 
   install_int_10_handler();	/* Install the handler for video-interrupt */
@@ -1196,8 +1203,9 @@
 
   /* Set OUTB_ADD to 1 */
   *OUTB_ADD = 1;
-  *LASTSCAN_ADD = 0;
+  *LASTSCAN_ADD = 1;
   REG(eflags) |= (IF | VIF | VIP);
+
   /* 
    * The banner helper actually gets called *after* the VGA card
    * is initialized (if it is) because we set up a return chain:
@@ -1681,6 +1689,7 @@
   config.vbios_seg = 0xc000;
   config.vbios_size = 0x10000;
   config.console_keyb = 0;
+  config.kbd_tty = 0;
   config.console_video = 0;
   config.fdisks = 0;
   config.hdisks = 0;
@@ -1711,7 +1720,7 @@
 
   config.speaker = SPKR_EMULATED;
 
-#if 0 /* This is too slow, but why? */
+#if 1 /* This is too slow, but why? */
   config.update = 54945;
 #else
   config.update = 27472;
@@ -2490,9 +2499,10 @@
   fflush(stderr);
   fflush(stdout);
 
-  if (config.detach)
-	restore_vt(config.detach);
-	
+   if (config.detach) {
+     restore_vt(config.detach);
+     disallocate_vt ();
+   }
   _exit(0);
 }
 
@@ -3431,6 +3441,14 @@
          unames.release[2] > 1 ) {
       use_sigio=FASYNC;
     }
+  }
+  /* Next Check input */
+  if (isatty(STDIN_FILENO)) {
+    k_printf("STDIN is tty\n");
+    config.kbd_tty = 0;
+  } else {
+    k_printf("STDIN not a tty\n");
+    config.kbd_tty = 1;
   }
 }
 
diff -u --recursive --new-file dosemu0.53pl28/emu.h dosemu0.53pl29/emu.h
--- dosemu0.53pl28/emu.h	Wed Oct 19 22:28:18 1994
+++ dosemu0.53pl29/emu.h	Tue Nov  1 23:02:57 1994
@@ -268,7 +268,7 @@
 int ext_fs(int, char *, char *, int);
 int outch(int c);
 void termioInit(void);
-__inline__ void run_vm86(void);
+extern __inline__ void run_vm86(void);
 
 #define NOWAIT  0
 #define WAIT    1
@@ -417,15 +417,29 @@
 	  errno, strerror(errno), __FILE__, __LINE__, #sc); \
   s_tmp; })
 
-#define RPT_SYSCALL(sc) ({ int s_tmp; \
+#define RPT_SYSCALL(sc) ({ int s_tmp, s_err; \
    do { \
+	  errno = s_err = 0; \
 	  s_tmp = sc; \
-      } while ((s_tmp == -1) && (errno == EINTR)); \
+	  if (errno == EINTR) {\
+	    s_err = errno; \
+	    g_printf("Recursive run_irqs() RPT_SYSCALL()\n"); \
+	    handle_signals(); \
+	/*    run_irqs(); */ \
+	  } \
+      } while ((s_tmp == -1) && (s_err == EINTR)); \
   s_tmp; })
 
 #define RPT_SYSCALL2(sc) ({ int s_tmp; \
    do { \
+	  errno = s_err = 0; \
 	  s_tmp = sc; \
+	  if (errno == EINTR) {\
+	    s_err = errno; \
+	    g_printf("Recursive run_irqs() RPT_SYSCALL2()\n"); \
+	    handle_signals(); \
+	/*    run_irqs(); */ \
+	  } \
       } while ((s_tmp == -1) ); \
   s_tmp; })
 
@@ -471,6 +485,7 @@
        u_short usesX;  /* !=0 if dosemu owns an X window */
 
        boolean console_keyb;
+       boolean kbd_tty;
        boolean X_keycode;	/* use keycode field of event structure */
        boolean exitearly;
        boolean mathco;
@@ -644,7 +659,7 @@
 			   just in case, and make it aligned  */ \
 			sa.sa_restorer = \
 			(void (*)()) (((unsigned int)(cstack) + sizeof(cstack) - 4) & ~3); \
-					sa.sa_flags = SA_RESTART; \
+					sa.sa_flags = 0 /* SA_RESTART  */; \
 					sigemptyset(&sa.sa_mask); \
 					sigaddset(&sa.sa_mask, SIGNALS_THAT_QUEUE); \
 					dosemu_sigaction(sig, &sa, NULL);
diff -u --recursive --new-file dosemu0.53pl28/emumod/Makefile dosemu0.53pl29/emumod/Makefile
--- dosemu0.53pl28/emumod/Makefile	Wed Oct 19 22:28:37 1994
+++ dosemu0.53pl29/emumod/Makefile	Tue Nov  1 23:03:20 1994
@@ -5,8 +5,8 @@
 
 # The following variables may go into the Makfile in the parent-directory
 
-CC   = gcc
-LD   = ld
+# CC   = gcc
+# LD   = ld
 USRSRCDIR=/usr/src
 
 # If INCDIR exists, it was exported from the master Makefile.
@@ -17,7 +17,8 @@
 # let gcc do extended checking
 
 
-CFLAGS=-Wall -I$(USRSRCDIR) -O2 -fomit-frame-pointer  -D__KERNEL__ -DLINUX
+
+# CFLAGS=-Wall -I$(USRSRCDIR) -O2 -fomit-frame-pointer  -D__KERNEL__ -DLINUX
  
 
 
@@ -29,7 +30,7 @@
 
 # Insert all source- and header-files here.
 
-ALL = $(CFILES) $(HFILES) $(OFILES)
+ALL = $(CFILES) $(HFILES) 
 
 # All object-files are included here.
 
@@ -45,13 +46,13 @@
 	ld -r -o emumodule.o $(OBJS)
 
 vm86.o:  vm86.c emumod.h $(USRSRCDIR)/linux/tools/version.h
-	$(CC) ${CFLAGS} -D_LOADABLE_VM86_ -c vm86.c -o vm86.o
+	$(CC) ${CFLAGS} -D_LOADABLE_VM86_ -D__KERNEL__ -c vm86.c -o vm86.o
 
 emumod.o:  emumod.c emumod.h $(USRSRCDIR)/linux/tools/version.h
-	$(CC) ${CFLAGS} -D_LOADABLE_VM86_  -c emumod.c -o emumod.o
+	$(CC) ${CFLAGS} -D_LOADABLE_VM86_ -D__KERNEL__ -c emumod.c -o emumod.o
 
 traps.o:  traps.c emumod.h $(USRSRCDIR)/linux/tools/version.h
-	$(CC) ${CFLAGS} -D_LOADABLE_VM86_  -c traps.c -o traps.o
+	$(CC) ${CFLAGS} -D_LOADABLE_VM86_ -D__KERNEL__ -c traps.c -o traps.o
 
 checkin:
 	-ci $(ALL) Makefile
diff -u --recursive --new-file dosemu0.53pl28/emumod/emumod.c dosemu0.53pl29/emumod/emumod.c
--- dosemu0.53pl28/emumod/emumod.c	Wed Oct 19 22:28:37 1994
+++ dosemu0.53pl29/emumod/emumod.c	Tue Nov  1 23:03:20 1994
@@ -24,7 +24,7 @@
  *   (so, don't panic if you get a GCC warning "_kernel_version not used" )
  */
 #include <linux/module.h>
-#include "linux/tools/version.h"
+#include "../../linux/tools/version.h"
 static char kernel_version[] = UTS_RELEASE;
 
 struct redirect_db {
Binary files dosemu0.53pl28/emumod/emumod.o and dosemu0.53pl29/emumod/emumod.o differ
Binary files dosemu0.53pl28/emumod/traps.o and dosemu0.53pl29/emumod/traps.o differ
Binary files dosemu0.53pl28/emumod/vm86.o and dosemu0.53pl29/emumod/vm86.o differ
diff -u --recursive --new-file dosemu0.53pl28/include/inifile.h dosemu0.53pl29/include/inifile.h
--- dosemu0.53pl28/include/inifile.h	Wed Oct 19 22:28:23 1994
+++ dosemu0.53pl29/include/inifile.h	Tue Nov  1 23:03:03 1994
@@ -3,10 +3,10 @@
 /* Routines to modify INI files */
 /* by David V. Mortenson */
 
-void GetValueFromIniFile (char *file, char *section, char *variable, 
+extern void GetValueFromIniFile (char *file, char *section, char *variable, 
                char *value);
-void GetValueFromIniFilePath (char *file, char *section, char *variable, 
+extern void GetValueFromIniFilePath (char *file, char *section, char *variable, 
                char *value);
-void SetValueInIniFile (char *file, char* section, char* variable, 
+extern void SetValueInIniFile (char *file, char* section, char* variable, 
                char *value);
 
diff -u --recursive --new-file dosemu0.53pl28/init/Makefile dosemu0.53pl29/init/Makefile
--- dosemu0.53pl28/init/Makefile	Wed Oct 19 22:28:30 1994
+++ dosemu0.53pl29/init/Makefile	Tue Nov  1 23:03:11 1994
@@ -23,7 +23,7 @@
        -Wstrict-prototypes -ansi -pedantic -Wid-clash-31 -Wcast-qual
 #-Wwrite-strings
 
-CFILES = inifile.c parse.c
+CFILES = 
 LFILES = lexer.l
 YFILES = parser.y
 HFILES = 
@@ -34,17 +34,22 @@
 
 # All object-files are included here.
 
-OBJS = parser.o lex.yy.o inifile.o # parse.o 
+OBJS = parser.o lex.yy.o # parse.o 
 
 .c.o:
 	$(CC) $(CFLAGS) $(DEFINES) $(INCDIR) -c $<
 
-all: ../init.o
+SUBDIR=init
 
-../init.o: $(OBJS)
-	$(LD) -r -o ../init.o $(OBJS)
-#	$(LD) -r -o ../init.o parse.o
+LIB=../lib$(SUBDIR).a
 
+all:  $(LIB)
+
+$(LIB): $(OBJS)
+	-rm $@
+	$(AR) cr $@ $^
+	ranlib $@
+
 parser.c : parser.y
 	$(BISON) -do parser.c parser.y
 
@@ -58,7 +63,7 @@
 	-co -l $(ALL) Makefile 
 
 clean:
-	rm -f *.o parser.[ch] lex.yy.c
+	rm -f *.o parser.[ch] lex.yy.c ../lib$(SUBDIR).a
 
 realclean: clean
 	rm -f .depend
@@ -66,11 +71,10 @@
 install:
 
 dist: $(ALL) Makefile
-	install -d $(DISTPATH)/init
-	install -m 0644 $(ALL) Makefile $(DISTPATH)/init
+	install -d $(DISTPATH)/$(SUBDIR)
+	install -m 0644 $(ALL) Makefile $(DISTPATH)/$(SUBDIR)
 
-depend dep: $(CFILES)
-	$(CPP) -MM $(CFLAGS) *.c $(INCDIR) > .depend
+depend dep:
 
 dummy:
 
diff -u --recursive --new-file dosemu0.53pl28/init/inifile.c dosemu0.53pl29/init/inifile.c
--- dosemu0.53pl28/init/inifile.c	Wed Oct 19 22:28:30 1994
+++ dosemu0.53pl29/init/inifile.c
@@ -1,199 +0,0 @@
-/* inifile.c */
-
-/* Routines to modify INI files */
-/* by David V. Mortenson */
-
-#include <stdio.h>
-#include <stdlib.h>
-#define __USE_GNU
-#define __USE_SVID
-#include <string.h>
-#include <ctype.h>
-
-#define FALSE  0
-#define TRUE   1
-
-void GetValueFromIniFile (char *, char *, char *, char *);
-void GetValueFromIniFilePath (char *, char *, char *, char *);
-void SetValueInIniFile (char *, char *, char *, char *);
-
-/****************************************
- * An ini file should have the extension .INI, and is formatted
- * with sections and value strings.  The following is a sample
- * .INI file with 2 sections, each with 1 variable/value string:
- * 
- *      [test]
- *      teststring=Hello World
- *      [sample]
- *      value=on
- *
- * The use of the functions to retrieve the string values and
- * set them in the INI file should be apparent.  If an error
- * occurs, then the value string for the requested section and
- * variable will return with a length of 0.  Possible errors
- * include:
- *      1) file not found
- *      2) section not found (only for "get" operation)
- *      3) variable not found (only for "get" operation)
- *
- * GetValueFromIniFilePath is the same as GetValueFromIniFile, except
- * that the file paramter can hold a colon delimited path of locations
- * to look for the section and variable.  Each one is searched in turn.
- * This mechanism could be used to allow per-user variables to override
- * system defaults, for example.
- ****************************************/
-
-/**********************************************************************DVM***/
-void GetValueFromIniFile (char *file, char *section, char *variable, 
-               char *value)
-{
-   FILE *srcFile;
-   char line [512];
-   char *cptr;
-
-   strcpy (value, "");
-
-   srcFile = fopen (file, "rt");
-
-   cptr = fgets (line, 512, srcFile);
-
-   while (cptr)
-   {
-      /* Is this the requested section? */
-      if (  line[0] == '['  &&  
-            !strncasecmp (&line[1], section, strlen(section))  &&
-            line [strlen(section)+1] == ']'  )
-      {
-         cptr = fgets (line, 512, srcFile);
-         while (cptr)
-         {
-            /* Is this the requested variable? */
-            if (  !strncasecmp (line, variable, strlen (variable))  &&
-                  line [strlen(variable)] == '='  )
-            {
-               strcpy (value, &line[strlen(variable)+1]);
-               if (value[strlen(value)-1] == '\n')
-                  value[strlen(value)-1] = '\0';
-               fclose (srcFile);
-               return;
-            }
-
-            /* Have we entered a new section? */
-            if (line[0] == '[')
-            {
-               break;
-            }
-
-            cptr = fgets (line, 512, srcFile);
-         }
-      }
-      else
-      {
-         cptr = fgets (line, 512, srcFile);
-      }
-   }
-
-   fclose (srcFile);
-}
-
-/**********************************************************************TRB***/
-void GetValueFromIniFilePath (char *file, char *section, char *variable, 
-               char *value)
-{
-        char *filePtr, *lastPtr;
-	int done = FALSE;
-	char *fileString;
-
-			 
-	fileString = (char *)strdup( file );
-	lastPtr = file;        
-	filePtr = strtok( fileString, ":;" );
-	while( filePtr && !done ) {
-		GetValueFromIniFile( filePtr, section, variable, value );
-		if( strlen( value ) ) {
-			done = TRUE;
-		}
-		lastPtr = filePtr;
-		filePtr = strtok( NULL, ":;" );
-	}
-	free( fileString );
-}
-
-	       
-
-/**********************************************************************DVM***/
-void SetValueInIniFile (char *file, char* section, char* variable, 
-               char *value)
-{
-   char oldFile [250];
-   FILE *srcFile, *destFile;
-   char line [512];
-   char *cptr;
-   int operationComplete = FALSE;
-
-   /* Setup The File Path */
-
-   sprintf (oldFile, "%s%s", file, ".bak");
-
-   /* Open The Files */
-
-   remove (oldFile);
-   rename (file, oldFile);
-   srcFile = fopen (oldFile, "rt");
-   destFile = fopen (file, "wt");
-
-   cptr = fgets (line, 512, srcFile);
-   while (cptr)
-   {
-      /* Is this the requested section? */
-      if (  line[0] == '['  &&  
-            !strncasecmp (&line[1], section, strlen(section))  &&
-            line [strlen(section)+1] == ']'  )
-      {
-         fprintf (destFile, "%s", line);
-
-         cptr = fgets (line, 512, srcFile);
-         while (cptr)
-         {
-            /* Is this the requested variable? */
-            if (  !strncasecmp (line, variable, strlen (variable))  &&
-                  line [strlen(variable)] == '='  )
-            {
-               if (!operationComplete)
-                  fprintf (destFile, "%s=%s\n", variable, value);
-               operationComplete = TRUE;
-            }
-            /* Is this a new Section? */
-            else if (line[0] == '[')
-            {
-               if (!operationComplete)
-               {
-                  fprintf (destFile, "%s=%s\n", variable, value);
-                  operationComplete = TRUE;
-               }
-               break;
-            }
-            else
-            {
-               fprintf (destFile, "%s", line);
-            }
-
-            cptr = fgets (line, 512, srcFile);
-         }
-      }
-      else
-      {
-         fprintf (destFile, "%s", line);
-         cptr = fgets (line, 512, srcFile);
-      }
-   }
-
-   if (!operationComplete)
-   {
-      fprintf (destFile, "[%s]\n", section);
-      fprintf (destFile, "%s=%s\n", variable, value);
-   }
-
-   fclose (srcFile);
-   fclose (destFile);
-}
diff -u --recursive --new-file dosemu0.53pl28/init/parse.c dosemu0.53pl29/init/parse.c
--- dosemu0.53pl28/init/parse.c	Wed Oct 19 22:28:30 1994
+++ dosemu0.53pl29/init/parse.c
@@ -1,2163 +0,0 @@
-/* parse.c - for the Linux DOS emulator
- *  Robert Sanders, gt8134b@prism.gatech.edu
- *
- * Parsing of config-files for the Linux-DOSEmulator
- *
- * The parser is a hand-written state machine.
- *
- * $Date: 1994/10/14 18:03:04 $
- * $Source: /home/src/dosemu0.60/init/RCS/parse.c,v $
- * $Revision: 2.8 $
- * $State: Exp $
- *
- * $Log: parse.c,v $
- * Revision 2.8  1994/10/14  18:03:04  root
- * Prep for pre53_27.tgz
- *
- * Revision 2.7  1994/08/01  14:28:09  root
- * Prep for pre53_7  with Markks latest, EMS patch, and Makefile changes.
- *
- * Revision 2.6  1994/07/14  23:21:28  root
- * Markkk's patches.
- *
- * Revision 2.5  1994/07/05  22:00:34  root
- * NCURSES IS HERE.
- *
- * Revision 2.3  1994/06/24  14:52:20  root
- * Messing with parse_config.
- *
- * Revision 2.2  1994/06/17  00:14:45  root
- * Let's wrap it up and call it DOSEMU0.52.
- *
- * Revision 2.1  1994/06/12  23:18:22  root
- * Wrapping up prior to release of DOSEMU0.52.
- *
- * Revision 2.1  1994/06/12  23:18:22  root
- * Wrapping up prior to release of DOSEMU0.52.
- *
- * Revision 1.7  1994/06/03  00:59:58  root
- * pre51_23 prep, Daniel's fix for scrbuf malloc().
- *
- * Revision 1.6  1994/05/18  00:16:55  root
- * pre15_17
- *
- * Revision 1.5  1994/05/09  23:37:01  root
- * pre51_13.
- *
- * Revision 1.4  1994/05/04  22:18:36  root
- * Patches by Alan to mouse subsystem.
- *
- * Revision 1.3  1994/05/04  21:58:48  root
- * Prior to Alan's patches to mouse code.
- *
- * Revision 1.2  1994/04/29  23:53:26  root
- * Prior to Lutz's latest 94/04/29
- *
- * Revision 1.1  1994/04/25  21:06:39  root
- * Initial revision
- *
- * Revision 1.21  1994/04/18  22:52:19  root
- * Ready pre51_7.
- *
- * Revision 1.20  1994/04/16  01:28:47  root
- * Prep for pre51_6.
- *
- * Revision 1.19  1994/04/13  00:07:09  root
- * Jochen Patches.
- *
- * Revision 1.18  1994/04/07  20:50:59  root
- * More updates.
- *
- * Revision 2.9  1994/04/06  00:56:04  root
- * Made serial config more flexible, and up to 4 ports.
- *
- * Revision 1.1  1994/04/05  16:24:20  root
- * Initial revision
- *
- * Revision 1.16  1994/04/04  22:51:55  root
- * Patches for PS/2 mice.
- *
- * Revision 1.15  1994/03/30  22:12:30  root
- * Prep for 0.51 pre 2.
- *
- * Revision 1.14  1994/03/23  23:24:51  root
- * Prepare to split out do_int.
- *
- * Revision 1.13  1994/03/18  23:17:51  root
- * Prep for 0.50pl1.
- *
- * Revision 1.12  1994/03/13  01:07:31  root
- * Poor attempts to optimize.
- *
- * Revision 1.11  1994/03/04  15:23:54  root
- * Run through indent.
- *
- * Revision 1.10  1994/03/04  00:01:58  root
- * Readying for 0.50
- *
- * Revision 1.9  1994/02/21  20:28:19  root
- * Serial patches of Ronnie's
- *
- * Revision 1.8  1994/02/09  20:10:24  root
- * Added dosbanner config option for optionally displaying dosemu bannerinfo.
- * Added allowvideportaccess config option to deal with video ports.
- *
- * Revision 1.7  1994/01/31  21:05:04  root
- * Mouse now works with X for me.
- *
- * Revision 1.6  1994/01/31  18:44:24  root
- * Work on making mouse work
- *
- * Revision 1.5  1994/01/20  21:14:24  root
- * Indent.
- *
- * Revision 1.4  1993/12/30  11:18:32  root
- * Theadore T'so's patches to allow booting from a diskimage, and then
- * returning the floopy to dosemu.
- * Also his patches to serial.c
- *
- * Revision 1.3  1993/12/27  19:06:29  root
- * Added Diamond option.
- *
- * Revision 1.2  1993/11/30  21:26:44  root
- * Chips First set of patches, WOW!
- *
- * Revision 1.1  1993/11/12  12:32:17  root
- * Initial revision
- *
- * Revision 1.3  1993/07/07  21:42:04  root
- * minor changes for -Wall
- *
- * Revision 1.2  1993/07/07  01:32:28  root
- * added support for ~/.dosrc and parse_config() now takes a filename
- * argument to override .dosrc check.
- *
- * Revision 1.1  1993/07/07  00:49:06  root
- * Initial revision
- *
- * Revision 1.1  1993/05/04  05:29:22  root
- * Initial revision
- *
- */
-
-#include <stdlib.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <string.h>
-#include <setjmp.h>
-#include <sys/stat.h>                    /* structure stat       */
-#include <unistd.h>                      /* prototype for stat() */
-
-#include "config.h"
-#include "emu.h"
-#include "cpu.h"
-#include "disks.h"
-#include "lpt.h"
-#include "video.h"
-#include "mouse.h"
-#include "serial.h"
-#include "timers.h"
-#include "keymaps.h"
-
-extern int exchange_uids(void);
-
-extern char* strdup(const char *); /* Not defined in string.h :-( */
-
-extern struct config_info config;  /* Configuration information */
-
-int errors;               /* Number of errors detected while parsing */
-int warnings;             /* Number of warnings detected while parsing */
-
-jmp_buf exitpar;
-
-serial_t *sptr;
-serial_t nullser;
-mouse_t *mptr;
-mouse_t nullmouse;
-int c_ser = 0;
-int c_mouse = 0;
-
-struct disk *dptr;
-struct disk nulldisk;
-int c_hdisks = 0;
-int c_fdisks = 0;
-
-extern struct printer lpt[NUM_PRINTERS];
-struct printer *pptr;
-struct printer nullptr;
-int c_printers = 0;
-
-/***************************************************************/
-
-typedef enum {
-  NULLTOK = 0, LBRACE, RBRACE, TOP, SEC_COMMENT, SEC_FLOPPY,
-  SEC_DISK, D_HEADS, D_SECTORS, D_CYLINDERS, D_FLOPPY, D_HARD,
-  D_PARTITION, D_WHOLEDISK, D_OFFSET, D_FILE, D_FIVEINCH,
-  D_READONLY, D_HDIMAGE, D_THREEINCH, VAL_FASTFLOPPY, VAL_CPU,
-  VAL_XMS, VAL_EMS, VAL_DOSMEM, 
-  EOL_COMMENT, P_COMMAND, P_OPTIONS, P_TIMEOUT,
-  P_FILE, SEC_PORTS, PRT_RANGE, PRT_RDONLY, PRT_WRONLY,
-  PRT_RDWR, PRT_ANDMASK, PRT_ORMASK, VAL_SPEAKER,
-  VAL_PKTFLAGS, VAL_HOGTHRESHOLD, VAL_TIMER,
-  VAL_DOSBANNER, VAL_TIMINT, VAL_EMUBAT, VAL_EMUSYS,
-  SEC_BOOTDISK, VAL_DPMI, VAL_ALLOWVIDEOPORTACCESS,
-
-  SEC_PRINTER, VAL_MATHCO, VAL_IPXSUP, LCCOM, PRED_BOOTA, PRED_BOOTC,
-  
-  SEC_DEBUG, DBG_IO, DBG_VIDEO, DBG_SERIAL, DBG_CONFIG, DBG_DISK,
-             DBG_READ, DBG_WRITE, DBG_KEYB, DBG_PRINTER, DBG_WARNING,
-             DBG_GENERAL, DBG_XMS, DBG_DPMI, DBG_MOUSE, DBG_HARDWARE,
-             DBG_IPC, DBG_EMS, DBG_NET,
-  
-  SEC_KEYBOARD, KEYB_RAWKEYBOARD, KEYB_LAYOUT, KEYB_KEYBINT,
-
-  SEC_TERMINAL, T_METHOD, T_UPDATELINES, T_UPDATEFREQ, T_CHARSET, T_COLOR,
-                T_CORNER,
-  
-  SEC_VIDEO, V_CHIPSET, V_MDA, V_VGA, V_CGA, V_EGA, V_VBIOSF,
-             V_VBIOSC, V_CONSOLE, V_FULLREST, V_PARTIALREST, V_GRAPHICS,
-             V_MEMSIZE, V_VBIOSM, V_VBIOS_SEG,
-  
-  SEC_SERIAL, S_DEVICE, S_PORT, S_BASE, S_IRQ, S_MODEM, S_MOUSE,
-
-  SEC_MOUSE, M_INTDRV, M_BAUDRATE, M_DEVICE, M_MICROSOFT, M_PS2, 
-             M_MOUSESYSTEMS, M_MMSERIES, M_LOGITECH, M_BUSMOUSE, 
-             M_MOUSEMAN, M_HITACHI, M_CLEARDTR
-} tok_t;
-
-typedef enum {
-  NULLFORM = 0, ODELIM, CDELIM, COMMENT, SECTION, PRED,
-  VALUE, VALUE2, VALUEN
-} form_t;
-
-typedef int arg_t;
-
-typedef struct word_struct {
-  char *name;
-  tok_t token;
-  form_t form;
-  int (*func) (struct word_struct *, arg_t p1, arg_t p2);
-  void (*start) (struct word_struct *, arg_t p1, arg_t p2);
-  void (*stop) (struct word_struct *, arg_t p1, arg_t p2);
-  struct word_struct *sub_words;
-  arg_t p1, p2;
-} word_t;
-
-typedef struct syn_struct {
-  char *syn;
-  char *trans;
-} syn_t;
-
-/***************************************************************/
-
-int do_top(word_t *, arg_t, arg_t);
-int do_num(word_t *, arg_t, arg_t);
-void parse_file(word_t *, FILE *);
-char *get_name(FILE *);
-
-int do_comment(word_t *, arg_t, arg_t);
-
-int do_disk(word_t *, arg_t, arg_t);
-void start_disk(word_t *, arg_t, arg_t);
-void stop_disk(word_t *, arg_t, arg_t);
-
-int do_printer(word_t *, arg_t, arg_t);
-void start_printer(word_t *, arg_t, arg_t);
-void stop_printer(word_t *, arg_t, arg_t);
-
-int do_video(word_t *, arg_t, arg_t);
-void stop_video(word_t *, arg_t, arg_t);
-
-int do_terminal(word_t *, arg_t, arg_t);
-void stop_terminal(word_t *, arg_t, arg_t);
-
-int do_serial(word_t *, arg_t, arg_t);
-void start_serial(word_t *, arg_t, arg_t);
-void stop_serial(word_t *, arg_t, arg_t);
-
-int do_mouse(word_t *, arg_t, arg_t);
-void start_mouse(word_t *, arg_t, arg_t);
-void stop_mouse(word_t *, arg_t, arg_t);
-
-int do_debug(word_t *, arg_t, arg_t);
-void start_debug(word_t *, arg_t, arg_t);
-void stop_debug(word_t *, arg_t, arg_t);
-
-int do_keyboard(word_t *, arg_t, arg_t);
-void start_keyboard(word_t *, arg_t, arg_t);
-void stop_keyboard(word_t *, arg_t, arg_t);
-
-int do_ports(word_t *, arg_t, arg_t);
-
-int glob_bad(word_t *, arg_t, arg_t);
-int porttok(word_t *, arg_t, arg_t);
-
-extern int allow_io(int, int, int, int, int);
-
-void parse_error(char *s);
-void parse_warning(char *s);
-int read_until_rtn_previous(FILE * fd, int goal);
-int same_name(char *str1, char *str2);
-char *synonym(syn_t * syntable, char *str);
-char *get_arg(FILE * fd);
-word_t *match_name(word_t * words, char *name);
-FILE *open_file(char *filename);
-void close_file(FILE * file);
-
-#define do_delim 0
-
-#define NULL_WORD	{NULL,NULLTOK,NULLFORM,glob_bad,0,0,}
-#define NULL_SYN	{NULL,NULL}
-
-word_t null_words[] =
-{
-  NULL_WORD,
-  NULL_WORD
-};
-
-word_t video_words[] =
-{
-  NULL_WORD,
-  {"{", LBRACE, ODELIM, do_video},
-  {"}", RBRACE, CDELIM, do_video},
-  {"chipset", V_CHIPSET, VALUE, do_video},
-  {"console", V_CONSOLE, PRED, do_video},
-  {"fullrestore", V_FULLREST, PRED, do_video},
-  {"partialrestore", V_PARTIALREST, PRED, do_video},
-  {"graphics", V_GRAPHICS, PRED, do_video},
-  {"memsize", V_MEMSIZE, VALUE, do_video},
-  {"vga", V_VGA, PRED, do_video},
-  {"ega", V_EGA, PRED, do_video},
-  {"cga", V_CGA, PRED, do_video},
-  {"mda", V_MDA, PRED, do_video},
-  {"vbios_file", V_VBIOSF, VALUE, do_video},
-  {"vbios_copy", V_VBIOSC, PRED, do_video},
-  {"vbios_mmap", V_VBIOSM, PRED, do_video},
-  {"vbios_seg", V_VBIOS_SEG, VALUE, do_video},
-  NULL_WORD
-};
-
-word_t terminal_words[] = 
-{
-  NULL_WORD,
-  {"{", LBRACE, ODELIM, do_terminal},
-  {"}", RBRACE, CDELIM, do_terminal},
-  {"method", T_METHOD, VALUE, do_terminal},
-  {"updatelines", T_UPDATELINES, VALUE, do_terminal},
-  {"updatefreq", T_UPDATEFREQ, VALUE, do_terminal},
-  {"charset", T_CHARSET, VALUE, do_terminal},
-  {"color", T_COLOR, VALUE, do_terminal},
-  {"corner", T_CORNER, VALUE, do_terminal},
-  NULL_WORD
-};
-
-word_t serial_words[] =
-{
-  NULL_WORD,
-  {"{", LBRACE, ODELIM, do_serial},
-  {"}", RBRACE, CDELIM, do_serial},
-  {"mouse", S_MOUSE, PRED, do_serial},	 		/* Mouse flag */
-  {"device", S_DEVICE, VALUE, do_serial}, 		/* Device file */
-  {"com", S_PORT, VALUE, do_serial}, 			/* COM port number */
-  {"base", S_BASE, VALUE, do_serial},			/* Base port address */
-  {"irq", S_IRQ, VALUE, do_serial}, 			/* IRQ line */
-  {"interrupt", S_IRQ, VALUE, do_serial}, 		/* XXXXX obsolete */
-  NULL_WORD
-};
-
-word_t mouse_words[] =
-{
-  NULL_WORD,
-  {"{", LBRACE, ODELIM, do_mouse},
-  {"}", RBRACE, CDELIM, do_mouse},
-  {"internaldriver", M_INTDRV, PRED, do_mouse},
-  {"baudrate", M_BAUDRATE, VALUE, do_mouse},
-  {"device", M_DEVICE, VALUE, do_mouse},
-  {"microsoft", M_MICROSOFT, PRED, do_mouse},
-  {"ps2", M_PS2, PRED, do_mouse},
-  {"mousesystems", M_MOUSESYSTEMS, PRED, do_mouse},
-  {"mmseries", M_MMSERIES, PRED, do_mouse},
-  {"logitech", M_LOGITECH, PRED, do_mouse},
-  {"busmouse", M_BUSMOUSE, PRED, do_mouse},
-  {"mouseman", M_MOUSEMAN, PRED, do_mouse},
-  {"hitachi", M_HITACHI, PRED, do_mouse},
-  {"cleardtr", M_CLEARDTR, PRED, do_mouse},
-  NULL_WORD
-};
-
-word_t debug_words[] =
-{
-  NULL_WORD,
-  {"{", LBRACE, ODELIM, do_debug},
-  {"}", RBRACE, CDELIM, do_debug},
-  {"io", DBG_IO, VALUE, do_debug},
-  {"port", DBG_IO, VALUE, do_debug},
-  {"video", DBG_VIDEO, VALUE, do_debug},
-  {"serial", DBG_SERIAL, VALUE, do_debug},
-  {"config", DBG_CONFIG, VALUE, do_debug},
-  {"disk", DBG_DISK, VALUE, do_debug},
-  {"read", DBG_READ, VALUE, do_debug},
-  {"write", DBG_WRITE, VALUE, do_debug},
-  {"keyboard", DBG_KEYB, VALUE, do_debug},
-  {"keyb", DBG_KEYB, VALUE, do_debug},
-  {"printer", DBG_PRINTER, VALUE, do_debug},
-  {"warning", DBG_WARNING, VALUE, do_debug},
-  {"general", DBG_GENERAL, VALUE, do_debug},
-  {"xms", DBG_XMS, VALUE, do_debug},
-  {"dpmi", DBG_DPMI, VALUE, do_debug},
-  {"mouse", DBG_MOUSE, VALUE, do_debug},
-  {"hardware", DBG_HARDWARE, VALUE, do_debug},
-  {"ipc", DBG_IPC, VALUE, do_debug},
-  {"ems", DBG_EMS, VALUE, do_debug},
-  {"network", DBG_NET, VALUE, do_debug},
-  NULL_WORD
-};
-
-word_t keyboard_words[] =
-{
-  {NULL, NULLTOK, NULLFORM, porttok},
-  {"{", LBRACE, ODELIM, do_ports,},
-  {"}", RBRACE, CDELIM, do_ports},
-  {"rawkeyboard", KEYB_RAWKEYBOARD, VALUE, do_keyboard},
-  {"layout", KEYB_LAYOUT, VALUE, do_keyboard},
-  {"keybint", KEYB_KEYBINT, VALUE, do_keyboard},
-  NULL_WORD
-};
-
-word_t comment_words[] =
-{
-  NULL_WORD,
-  {"*/", RBRACE, CDELIM, do_comment},
-  NULL_WORD
-};
-
-word_t port_words[] =
-{
-  {NULL, NULLTOK, NULLFORM, porttok},
-  {"{", LBRACE, ODELIM, do_ports,},
-  {"}", RBRACE, CDELIM, do_ports},
-  {"range", PRT_RANGE, VALUE2, do_ports},
-  {"readonly", PRT_RDONLY, PRED, do_ports},
-  {"writeonly", PRT_WRONLY, PRED, do_ports},
-  {"readwrite", PRT_RDWR, PRED, do_ports},
-  {"ormask", PRT_ORMASK, VALUE, do_ports},
-  {"andmask", PRT_ANDMASK, VALUE, do_ports},
-  NULL_WORD
-};
-
-word_t disk_words[] =
-{
-  NULL_WORD,
-  {"{", LBRACE, ODELIM, do_disk,},
-  {"}", RBRACE, CDELIM, do_disk},
-  {"device", D_FILE, VALUE, do_disk},
-  {"file", D_FILE, VALUE, do_disk},
-  {"offset", D_OFFSET, VALUE, do_disk},
-  {"header", D_OFFSET, VALUE, do_disk},
-  {"heads", D_HEADS, VALUE, do_disk},
-  {"sectors", D_SECTORS, VALUE, do_disk},
-  {"cylinders", D_CYLINDERS, VALUE, do_disk},
-  {"tracks", D_CYLINDERS, VALUE, do_disk},
-  {"floppy", D_FLOPPY, PRED, do_disk},
-  {"hard", D_HARD, VALUE, do_disk},
-  {"hdimage", D_HDIMAGE, VALUE, do_disk},
-  {"image", D_HDIMAGE, VALUE, do_disk},
-  {"partition", D_PARTITION, VALUE2, do_disk},
-  {"wholedisk", D_WHOLEDISK, VALUE, do_disk},
-  {"readonly", D_READONLY, PRED, do_disk},
-  {"fiveinch", D_FIVEINCH, PRED, do_disk},
-  {"threeinch", D_THREEINCH, PRED, do_disk},
-  NULL_WORD
-};
-
-word_t printer_words[] =
-{
-  NULL_WORD,
-  {"{", LBRACE, ODELIM, do_printer},
-  {"}", RBRACE, CDELIM, do_printer},
-  {"timeout", P_TIMEOUT, VALUE, do_printer},
-  {"command", P_COMMAND, VALUE, do_printer},
-  {"options", P_OPTIONS, VALUE, do_printer},
-  {"file", P_FILE, VALUE, do_printer},
-  NULL_WORD
-};
-
-word_t top_words[] =
-{
-  NULL_WORD,
-  {"{", LBRACE, ODELIM, do_delim, 0, 0, null_words},
-  {"}", RBRACE, CDELIM, do_delim, 0, 0, null_words},
-  {"/*", SEC_COMMENT, SECTION, do_comment, 0, 0, comment_words},
-  {"#", EOL_COMMENT, COMMENT, do_comment, 0, 0, comment_words},
-  {";", EOL_COMMENT, COMMENT, do_comment, 0, 0, comment_words},
-  {"disk", SEC_DISK, SECTION, do_top, start_disk, stop_disk, disk_words},
-  {"floppy", SEC_FLOPPY, SECTION, do_top, start_disk, stop_disk, disk_words},
-  {"bootdisk", SEC_BOOTDISK, SECTION, do_top, start_disk, stop_disk, disk_words},
-  {"video", SEC_VIDEO, SECTION, do_top, 0, stop_video, video_words},
-  {"terminal", SEC_TERMINAL, SECTION, do_top, 0, stop_terminal, terminal_words},
-  {"serial", SEC_SERIAL, SECTION, do_top, start_serial, stop_serial, serial_words},
-  {"mouse", SEC_MOUSE, SECTION, do_top, start_mouse, stop_mouse, mouse_words},
-  {"xms", VAL_XMS, VALUE, do_num, 0, 0, null_words},
-  {"ems", VAL_EMS, VALUE, do_num, 0, 0, null_words},
-  {"dpmi", VAL_DPMI, VALUE, do_num, 0, 0, null_words},
-  {"dosmem", VAL_DOSMEM, VALUE, do_num, 0, 0, null_words},
-  {"allowvideoportaccess", VAL_ALLOWVIDEOPORTACCESS, VALUE, do_num, 0, 0, null_words},
-  {"printer", SEC_PRINTER, SECTION, do_top, start_printer, stop_printer, printer_words},
-  {"mathco", VAL_MATHCO, VALUE, do_num, 0, 0, null_words},
-  {"ipxsupport", VAL_IPXSUP, VALUE, do_num, 0, 0, null_words},
-  {"pktdriver", VAL_PKTFLAGS, VALUE, do_num, 0, 0, null_words},
-  {"speaker", VAL_SPEAKER, VALUE, do_num, 0, 0, null_words},
-  {"boota", PRED_BOOTA, PRED, do_num, 0, 0, null_words},
-  {"bootc", PRED_BOOTC, PRED, do_num, 0, 0, null_words},
-  {"cpu", VAL_CPU, VALUE, do_num, 0, 0, null_words},
-  {"ports", SEC_PORTS, SECTION, do_top, 0, 0, port_words},
-  {"debug", SEC_DEBUG, SECTION, do_top, start_debug, stop_debug, debug_words},
-  {"messages", SEC_DEBUG, SECTION, do_num, start_debug, stop_debug, debug_words},
-  {"keyboard", SEC_KEYBOARD, SECTION, do_top, start_keyboard, stop_keyboard, keyboard_words},
-  {"hogthreshold", VAL_HOGTHRESHOLD, VALUE, do_num, 0, 0, null_words},
-  {"timer", VAL_TIMER, VALUE, do_num, 0, 0, null_words},
-  {"dosbanner", VAL_DOSBANNER, VALUE, do_num, 0, 0, null_words},
-  {"timint", VAL_TIMINT, VALUE, do_num, 0, 0, null_words},
-  {"fastfloppy", VAL_FASTFLOPPY, VALUE, do_num, 0, 0, null_words},
-  {"emusys", VAL_EMUSYS, VALUE, do_num, 0, 0, null_words},
-  {"emubat", VAL_EMUBAT, VALUE, do_num, 0, 0, null_words},
-  NULL_WORD
-};
-
-/* really should break this up into groups for each word, but there are
- * no conflicts yet
- */
-
-/* XXX - fix these synonyms! */
-syn_t global_syns[] =
-{
-  {"on",  "1"},
-  {"off", "0"},
-  {"yes", "1"},
-  {"no",  "0"},
-
-  {"8086",  "0"},              /* values from <linux/vm86.h> */
-  {"80186", "1"},
-  {"80286", "2"},
-  {"80386", "3"},
-  {"80486", "4"},
-  {"80586", "5"},
-
-  {"native",   "1"},		/* for speaker */
-  {"emulated", "2"},
-
-  {"plainvga", "0"},
-  {"trident",  "1"},
-  {"et4000",   "2"},
-  {"diamond",  "3"},
-  {"s3",       "4"},
-
-  {"novell_hack", "1"},               /* Novell 8137->802.3 hack */
-
-  {"finnish",       "0" },       /* Ugly, must match the defines in emu.h */
-  {"finnish-latin1","1" },
-  {"us",            "2" },
-  {"uk",            "3" },
-  {"gr",            "4" },
-  {"gr-latin1",     "5" },
-  {"fr",            "6" },
-  {"fr-latin1",     "7" },
-  {"dk",            "8" },
-  {"dk-latin1",     "9" },
-  {"dvorak",        "10" },
-  {"sg",            "11" },
-  {"sg-latin1",     "12" },
-  {"no",            "13" },
-  {"sf",            "15" },
-  {"sf-latin1",     "16" },
-  {"es",            "17" },
-  {"es-latin1",     "18" },
-  {"be",            "19" },
-  
-  {"latin",         "1" },   /* Ugly, must match CHARSET_* defines in video.h */
-  {"ibm",           "2" },   
-  {"fullibm",       "3" },
-  
-  {"fast",          "1" },   /* Ugly, must match METHOD_* defines in video.h */
-  {"ncurses",       "2" },
-
-  {"normal",        "1" },   /* Ugly, must match COLOR_* defines in video.h */
-  {"xterm",         "2" },
-
-  NULL_SYN
-};
-
-#define iscomment(c) (c=='#' || c=='!' || c==';')
-#define istoken(c) (!isspace(c) && !iscomment(c))
-#define read_until_eol(fd) read_until_rtn_previous(fd, '\n')
-
-void die(char *reason) NORETURN;
-
-/****************************** globals ************************/
-FILE *globl_file = NULL;
-tok_t state = TOP;
-char *statestr = "top";
-
-struct disk *dptr = NULL;
-int hdiskno = 0;
-int diskno = 0;
-
-/***************************** functions ***********************/
-
-/*
- * parse_error - print an error message and count the number of error
- *               that occured while parsing the config-file
- */
-
-void parse_error(char *s)
-{
-  fprintf(stderr, "ERROR: %s\n",s);
-  errors = errors + 1;
-}
-
-/*
- * parse_warinig - print a warning message and count the number of warnings
- *                 that occured while parsing the config-file
- */
-
-void parse_warning(char *s)
-{
-  fprintf(stderr, "WARNING: %s\n",s);
-  warnings++;
-}
-
-int
-read_until_rtn_previous(FILE * fd, int goal)
-{
-  static int previous = 0;
-  int here;
-
-  here = fgetc(fd);
-
-  while (!feof(fd) && here != goal) {
-    previous = here;
-    here = fgetc(fd);
-  }
-
-  if (feof(fd))
-    return EOF;
-  else
-    return previous;
-}
-
-/*
- * glob_bad - unknown token read from config-file
- */
-
-int glob_bad(word_t * word, arg_t a1, arg_t a2)
-{
-  char *str;
-
-  str = malloc(128);
-
-  sprintf(str,"glob_bad called: %s!", word->name);
-  parse_error(str);
-
-  free(str);
-
-  return word->token;
-}
-
-int ports_permission = IO_RDWR;
-unsigned int ports_ormask = 0;
-unsigned int ports_andmask = 0xFFFF;
-
-int
-porttok(word_t * word, arg_t a1, arg_t a2)
-{
-  long num;
-  char *end;
-
-  num = strtol(word->name, &end, 0);
-  allow_io(num, 1, ports_permission, ports_ormask, ports_andmask);
-  return 0;
-}
-
-int
-do_ports(word_t * word, arg_t a1, arg_t a2)
-{
-  char *arg = NULL, *arg2 = NULL;
-
-  /*  c_printf("do_ports: %s %d\n", word->name, word->token); */
-
-  switch (word->form) {
-  case ODELIM:
-  case CDELIM:
-    ports_permission = IO_RDWR;
-    ports_ormask = 0;
-    ports_andmask = 0xFFFF;
-    break;
-  case VALUE2:
-    arg = get_name(globl_file);
-    arg2 = get_name(globl_file);
-    break;
-  case VALUE:
-    arg = get_name(globl_file);
-    break;
-  case PRED:
-    break;
-  default:
-    break;
-  }
-
-  switch (word->token) {
-    char *end;
-
-  case PRT_RANGE:{
-      long num1, num2;
-
-      num1 = strtol(arg, &end, 0);
-      num2 = strtol(arg2, &end, 0);
-      c_printf("CONF: range of I/O ports 0x%04x-0x%04x\n",
-	       (unsigned short) num1, (unsigned short) num2);
-      allow_io(num1, num2 - num1 + 1, ports_permission, ports_ormask, ports_andmask);
-      break;
-    }
-  case PRT_RDONLY:
-    ports_permission = IO_READ;
-    break;
-  case PRT_WRONLY:
-    ports_permission = IO_WRITE;
-    break;
-  case PRT_RDWR:
-    ports_permission = IO_RDWR;
-    break;
-  case PRT_ORMASK:
-    ports_ormask = strtol(arg, &end, 0);
-    break;
-  case PRT_ANDMASK:
-    ports_andmask = strtol(arg, &end, 0);
-    break;
-  default:
-    break;
-  }
-  if (arg)
-    free(arg);
-  if (arg2)
-    free(arg2);
-  return word->token;
-}
-
-void die(char *reason)
-{
-  error("ERROR: par dead: %s\n", reason);
-  leavedos(0);
-}
-
-int
-do_comment(word_t * word, arg_t a1, arg_t a2)
-{
-  if (word->token == EOL_COMMENT)
-    read_until_eol(globl_file);
-  else {
-    int prev;
-
-    do {
-      if ((prev = read_until_rtn_previous(globl_file, '/')) == EOF)
-	die("unterminated /* comment!\n");
-    } while (prev != '*');
-  }
-
-  return word->token;
-}
-
-char *
-get_name(FILE * fd)
-{
-  char tmps[100], *p = tmps;
-  int tmpc;
-
-  *p = 0;
-
-  /* prime the pump */
-  tmpc = fgetc(fd);
-
-  while (!istoken(tmpc) && !feof(fd)) {
-    if (iscomment(tmpc))
-      read_until_eol(globl_file);
-    tmpc = fgetc(fd);
-  }
-
-#define QUOTE '"'
-
-  /* there is no escaping of quote marks yet...is there a need? */
-
-  if (tmpc == QUOTE) {
-    tmpc = fgetc(fd);
-    while (tmpc != QUOTE && !feof(fd)) {
-      *p++ = tmpc;
-      tmpc = fgetc(fd);
-    }
-  }
-  else {
-    while (istoken(tmpc) && !feof(fd)) {
-      *p++ = tmpc;
-      tmpc = fgetc(fd);
-    };
-    if (iscomment(tmpc))
-      read_until_eol(globl_file);
-  }
-
-  *p = 0;
-  if (strlen(tmps) == 0)
-    return 0;
-
-  p = malloc(strlen(tmps) + 1);
-  strcpy(p, tmps);
-  return p;
-}
-
-/* case-insensitive match of two strings */
-int
-same_name(char *str1, char *str2)
-{
-  for (; *str1 && *str2 && tolower(*str1) == tolower(*str2);
-       str1++, str2++)
-    /* empty loop */
-    ;
-
-  if (!*str1 && !*str2)
-    return 1;
-  else
-    return 0;
-}
-
-char *
-synonym(syn_t * syntable, char *str)
-{
-  int i;
-
-  for (i = 0; syntable[i].trans; i++)
-    if (same_name(syntable[i].syn, str))
-      break;
-
-  return syntable[i].trans;
-}
-
-char *
-get_arg(FILE * fd)
-{
-  char *str, *str2;
-
-  str = get_name(fd);
-  if ((str2 = synonym(global_syns, str))) {
-    free(str);
-    str = strdup(str2);
-  }
-
-  return str;
-}
-
-/*
- * open_file - opens the configuration-file named *filename and returns
- *             a file-pointer. The error/warning-counters are reset to zero.
- */
-
-FILE *open_file(char *filename)
-{
-  errors   = 0;                  /* Reset error counter */
-  warnings = 0;                  /* Reset counter for warnings */
-
-  return (globl_file = fopen(filename, "r")); /* Open config-file */
-}
-
-/*
- * close_file - Close the configuration file and issue a message about
- *              errors/warnings that occured. If there were errors, the
- *              flag early-exit is that, so dosemu won't really.
- */
-
-void close_file(FILE * file)
-{
-
-  fclose(file);                  /* Close the config-file */
-
-  fprintf(stderr, "%d error(s) detected while parsing the configuration-file\n",
-	 errors);
-  fprintf(stderr, "%d warning(s) detected while parsing the configuration-file\n",
-	 warnings);
-
-  if (errors != 0)               /* Exit dosemu on errors */
-    {
-      config.exitearly = TRUE;
-    }
-}
-
-word_t *
-match_name(word_t * words, char *name)
-{
-  int i;
-
-  for (i = 1; words[i].name; i++)
-    if (same_name(words[i].name, name))
-      return &words[i];
-
-  return NULL;
-}
-
-int
-do_num(word_t * word, arg_t farg1, arg_t farg2)
-{
-  char *arg = NULL;
-
-  switch (word->form) {
-  case PRED:
-    switch (word->token) {
-    case PRED_BOOTA:
-      config.hdiskboot = 0;
-      break;
-    case PRED_BOOTC:
-      config.hdiskboot = 1;
-      break;
-    default:
-      c_printf("PAR: set pred %s\n", word->name);
-      break;
-    }
-    break;
-
-  case VALUE:
-    arg = get_arg(globl_file);
-
-    switch (word->token) {
-    case VAL_EMUBAT:
-      config.emubat = strdup(arg);
-      c_printf("PAR: config.emubat %s\n", config.emubat);
-      break;
-    case VAL_EMUSYS:
-      config.emusys = strdup(arg);
-      c_printf("PAR: config.emusys %s\n", config.emusys);
-      break;
-    case VAL_FASTFLOPPY:
-      config.fastfloppy = atoi(arg);
-      break;
-    case VAL_CPU:
-      vm86s.cpu_type = atoi(arg);
-      break;
-    case VAL_HOGTHRESHOLD:
-      config.hogthreshold = atoi(arg);
-      break;
-    case VAL_TIMINT:
-      config.timers = atoi(arg);
-      c_printf("CONF: timers %s!\n", config.timers ? "on" : "off");
-      break;
-    case VAL_DOSBANNER:
-      config.dosbanner = atoi(arg);
-      c_printf("CONF: dosbanner %s!\n", config.dosbanner ? "on" : "off");
-      break;
-    case VAL_ALLOWVIDEOPORTACCESS:
-      config.allowvideoportaccess = atoi(arg);
-      c_printf("CONF: allowvideoportaccess %s!\n", config.allowvideoportaccess ? "on" : "off");
-      break;
-    case VAL_TIMER:
-      config.freq = atoi(arg);
-      config.update = 1000000 / config.freq;
-      break;
-    case VAL_EMS:
-      config.ems_size = atoi(arg);
-      break;
-    case VAL_XMS:
-      config.xms_size = atoi(arg);
-      break;
-    case VAL_DPMI:
-      config.dpmi_size = atoi(arg);
-      break;
-    case VAL_DOSMEM:
-      config.mem_size = atoi(arg);
-      break;
-    case VAL_MATHCO:
-      config.mathco = (atoi(arg) != 0);
-      break;
-    case VAL_IPXSUP:
-      config.ipxsup = (atoi(arg) != 0);
-      c_printf("CONF: ipx support is %s\n",
-        config.ipxsup?"ON":"OFF");
-      break;
-    case VAL_PKTFLAGS:
-      config.pktflags = atoi(arg);
-      break;
-    case VAL_SPEAKER:
-      config.speaker = atoi(arg);
-      if (config.speaker == SPKR_NATIVE) {
-	warn("CONF: allowing access to the speaker ports!\n");
-	allow_io(0x42, 1, IO_RDWR, 0, 0xFFFF);
-	allow_io(0x61, 1, IO_RDWR, 0, 0xFFFF);
-      }
-      else
-	c_printf("CONF: not allowing speaker port access\n");
-      break;
-    default:
-      c_printf("val %s set to %s\n", word->name, arg);
-      break;
-    }
-
-    if (arg)
-      free(arg);
-    break;
-  default:
-    c_printf("non-value in do_num!\n");
-  }
- return 0;
-}
-
-void
-stop_video(word_t * word, arg_t farg1, arg_t farg2)
-{
-  if ((config.cardtype != CARD_VGA) || !config.console_video) {
-    config.graphics = 0;
-    config.vga = 0;
-  }
-
-  if (config.vga) {
-    if (config.mem_size > 640)
-      config.mem_size = 640;
-    config.mapped_bios = 1;
-    config.console_video = 1;
-  }
-}
-
-int
-do_video(word_t * word, arg_t farg1, arg_t farg2)
-{
-  char *arg = NULL;
-  char *end;
-  /* c_printf("do_video: %s %d\n", word->name, word->token); */
-
-  switch (word->form) {
-  case VALUE:
-    arg = get_arg(globl_file);
-    break;
-  case PRED:
-    break;
-  default:
-    break;
-  }
-
-  switch (word->token) {
-  case RBRACE:
-  case LBRACE:
-    break;
-  case V_VGA:
-    config.cardtype = CARD_VGA;
-    break;
-  case V_EGA:
-  case V_CGA:
-    config.cardtype = CARD_CGA;
-    break;
-  case V_MDA:
-    config.cardtype = CARD_MDA;
-    break;
-  case V_CHIPSET:
-    config.chipset = atoi(arg);
-    c_printf("CHIPSET: %s %d\n", arg, config.chipset);
-    break;
-  case V_MEMSIZE:
-    config.gfxmemsize = atoi(arg);
-    break;
-  case V_GRAPHICS:
-    config.vga = 1;
-    break;
-  case V_CONSOLE:
-    config.console_video = 1;
-    break;
-  case V_FULLREST:
-    config.fullrestore = 1;
-    break;
-  case V_PARTIALREST:
-    config.fullrestore = 0;
-    break;
-  case V_VBIOSF:
-    config.vbios_file = strdup(arg);
-    config.mapped_bios = 1;
-    config.vbios_copy = 0;
-    break;
-  case V_VBIOSM:
-    config.vbios_file = NULL;
-    config.mapped_bios = 1;
-    config.vbios_copy = 0;
-    break;
-  case V_VBIOSC:
-    config.vbios_file = NULL;
-    config.vbios_copy = 1;
-    config.mapped_bios = 1;
-    break;
-  case V_VBIOS_SEG:
-    config.vbios_seg = strtol(arg,&end,0);
-    c_printf("CONF: VGA-BIOS-Segment %x\n", config.vbios_seg);
-    if ((config.vbios_seg != 0xe000) && (config.vbios_seg != 0xc000) )
-      {
-	config.vbios_seg = 0xc000;
-	c_printf("CONF: VGA-BIOS-Segment set to %x\n", config.vbios_seg);
-      }
-    break;
-  default:
-    error("CONF: unknown video token: %s\n", word->name);
-    break;
-  }
-
-  if (arg)
-    free(arg);
-  return (word->token);
-}
-
-void
-stop_terminal(word_t * word, arg_t farg1, arg_t farg2)
-{
-  if (config.term_updatefreq > 100) {
-    warn("CONF: terminal updatefreq too large (too slow)!");
-    config.term_updatefreq = 100;
-  } 
-}
-
-int
-do_terminal(word_t * word, arg_t farg1, arg_t farg2)
-{
-  char *arg = NULL;
-  /* c_printf("do_terminal: %s %d\n", word->name, word->token); */
-
-  switch (word->form) {
-  case VALUE:
-    arg = get_arg(globl_file);
-    break;
-  case PRED:
-    break;
-  default:
-    break;
-  }
-
-  switch (word->token) {
-  case RBRACE:
-  case LBRACE:
-    break;
-  case T_METHOD:
-    config.term_method = atoi(arg);
-    break;
-  case T_UPDATELINES:
-    config.term_updatelines = atoi(arg);
-    break;
-  case T_UPDATEFREQ:
-    config.term_updatefreq = atoi(arg);
-    break;
-  case T_CHARSET:
-    config.term_charset = atoi(arg);
-    break;
-  case T_COLOR:
-    config.term_color = atoi(arg);
-    break;
-  case T_CORNER:
-    config.term_corner = atoi(arg);
-    break;
-  default:
-    error("CONF: unknown terminal token: %s\n", word->name);
-    break;
-  }
-
-  if (arg)
-    free(arg);
-  return (word->token);
-}
-
-void
-start_mouse(word_t * word, arg_t farg1, arg_t farg2)
-{
-  if (c_mouse >= MAX_MOUSE)
-    mptr = &nullmouse;
-  else {
-    mptr = &mice[c_mouse];
-    mptr->fd = -1;
-  }
-}
-
-/*
- * Initialize the debug-configuration variables
- */
-
-void
-start_debug(word_t * word, arg_t farg1, arg_t farg2)
-{
-  int flag = 0;                 /* Default is no debugging output at all */
-
-  c_printf("CONF: start_debug\n");
-  d.video = flag;               /* For all options */
-  d.serial = flag;
-  d.config = flag;
-  d.disk = flag;
-  d.read = flag;
-  d.write = flag;
-  d.keyb = flag;
-  d.printer = flag;
-  d.io = flag;
-  d.warning = flag;
-  d.general = flag;
-  d.xms = flag;
-  d.dpmi = flag;
-  d.mouse = flag;
-  d.hardware = flag;
-  d.IPC = flag;
-  d.EMS = flag;
-  d.network = flag;
-}
-
-/*
- * Initialize the keyboard-configuration variables
- */
-
-void
-start_keyboard(word_t * word, arg_t farg1, arg_t farg2)
-{
-  /* Nothing special to do */
-  c_printf("CONF: start_keyboard\n");
-}
-
-void
-start_serial(word_t * word, arg_t farg1, arg_t farg2)
-{
-  if (c_ser >= MAX_SER)
-    sptr = &nullser;
-  else {
-    /* The defaults for interrupt, base_port, real_comport and dev are 
-    ** automatically filled in inside the do_ser_init routine of serial.c
-    */
-    sptr = &com[c_ser];
-    sptr->dev[0] = 0;
-    sptr->interrupt = 0; 
-    sptr->base_port = 0;
-    sptr->real_comport = 0;
-    sptr->fd = -1;
-    sptr->mouse = 0;
-  }
-}
-
-void
-stop_mouse(word_t * word, arg_t farg1, arg_t farg2)
-{
-  if (c_mouse >= MAX_MOUSE) {
-    c_printf("MOUSE: too many mice, ignoring %s\n", mptr->dev);
-    return;
-  }
-  c_mouse++;
-  config.num_mice = c_mouse;
-  c_printf("MOUSE: %s type %x using internaldriver: %s, baudrate: %d\n", 
-        mptr->dev, mptr->type, mptr->intdrv ? "yes" : "no", mptr->baudRate);
-}
-
-/*
- * End of debugging configuration 
- */
-
-void
-stop_debug(word_t * word, arg_t farg1, arg_t farg2)
-{
-  c_printf("CONF: stop_debug\n");
-  /* Nothing to do for now */
-}
-
-/*
- * End of keyboard configuration 
- */
-
-void
-stop_keyboard(word_t * word, arg_t farg1, arg_t farg2)
-{
-  c_printf("CONF: stop_keyboard\n");
-  /* Nothing to do for now */
-}
-
-void
-stop_serial(word_t * word, arg_t farg1, arg_t farg2)
-{
-  if (c_ser >= MAX_SER) {
-    c_printf("SER: too many ports, ignoring %s\n", sptr->dev);
-    return;
-  }
-  c_ser++;
-  config.num_ser = c_ser;
-  c_printf("SER: %s port %x int %x\n", sptr->dev, sptr->base_port,
-	   sptr->interrupt);
-}
-
-int
-do_mouse(word_t * word, arg_t farg1, arg_t farg2)
-{
-  char *arg = NULL;
-
-  switch (word->form) {
-  case VALUE:
-    arg = get_name(globl_file);
-    break;
-  case PRED:
-    break;
-  default:
-    break;
-  }
-
-  switch (word->token) {
-  case RBRACE:
-  case LBRACE:
-    break;
-  case M_INTDRV:
-    mptr->intdrv = TRUE;
-    break;
-  case M_BAUDRATE:
-    mptr->baudRate = atoi(arg);
-    break; 
-  case M_DEVICE:
-    strcpy(mptr->dev, arg);   
-    break;
-  case M_MICROSOFT:
-    mptr->type = MOUSE_MICROSOFT;
-    mptr->flags = CS7 | CREAD | CLOCAL | HUPCL;
-    break;
-  case M_MOUSESYSTEMS:
-    mptr->type = MOUSE_MOUSESYSTEMS;
-    mptr->flags = CS8 | CSTOPB | CREAD | CLOCAL | HUPCL;
-    break;
-  case M_MMSERIES:
-    mptr->type = MOUSE_MMSERIES;
-    mptr->flags = CS8 | PARENB | PARODD | CREAD | CLOCAL | HUPCL;
-    break;
-  case M_LOGITECH:
-    mptr->type = MOUSE_LOGITECH;
-    mptr->flags = CS8 | CSTOPB | CREAD | CLOCAL | HUPCL;
-    break;
-  case M_PS2:
-    mptr->type = MOUSE_PS2;
-    mptr->flags = 0;
-    break;
-  case M_MOUSEMAN:
-    mptr->type = MOUSE_MOUSEMAN;
-    mptr->flags = CS7 | CREAD | CLOCAL | HUPCL;
-    break;
-  case M_HITACHI:
-    mptr->type = MOUSE_HITACHI;
-    mptr->flags = CS8 | CREAD | CLOCAL | HUPCL;
-    break;
-  case M_BUSMOUSE:
-    mptr->type = MOUSE_BUSMOUSE;
-    mptr->flags = 0;
-    break;
-  case M_CLEARDTR:
-    if (mptr->type == MOUSE_MOUSESYSTEMS)
-      mptr->cleardtr = TRUE;
-    else
-      parse_error("Option CLEARDTR is only valid for some MouseSystems-Mice");
-    break;
-  default:
-    error("CONF: Unknown mouse token: %s", word->name);
-    break;
-  }
-
-  if (arg)
-    free(arg);
-  return (word->token);
-}
-
-int
-do_debug(word_t * word, arg_t farg1, arg_t farg2)
-{
-  char *arg = NULL;
-
-  c_printf("CONF: do_debug\n");
-
-  switch (word->form) {
-  case VALUE:
-    arg = get_arg(globl_file);
-    break;
-  case PRED:
-    break;
-  default:
-    break;
-  }
-
-  switch (word->token) {
-  case RBRACE:
-  case LBRACE:
-    break;
-  case DBG_IO:
-    d.io = (atoi(arg) != 0);
-    c_printf("DEBUG: IO-Port %s!\n", d.io ? "on" : "off");
-    break;
-  case DBG_VIDEO:
-    d.video = atoi(arg); 
-    c_printf("DEBUG: Video %s!\n", d.video ? "on" : "off");
-    break;
-  case DBG_SERIAL:
-    d.serial = atoi(arg); 
-    c_printf("DEBUG: Serial %s!\n", d.serial ? "on" : "off");
-    break;
-  case DBG_CONFIG:
-    d.config = atoi(arg); 
-    c_printf("DEBUG: Config %s!\n", d.config ? "on" : "off");
-    break;
-  case DBG_DISK:
-    d.disk = atoi(arg); 
-    c_printf("DEBUG: Disk %s!\n", d.disk ? "on" : "off");
-    break;
-  case DBG_READ:
-    d.read = atoi(arg); 
-    c_printf("DEBUG: Read %s!\n", d.read ? "on" : "off");
-    break;
-  case DBG_WRITE:
-    d.write = atoi(arg); 
-    c_printf("DEBUG: Write %s!\n", d.write ? "on" : "off");
-    break;
-  case DBG_KEYB:
-    d.keyb = atoi(arg); 
-    c_printf("DEBUG: Keyboard %s!\n", d.keyb ? "on" : "off");
-    break;
-  case DBG_PRINTER:
-    d.printer = atoi(arg); 
-    c_printf("DEBUG: Printer %s!\n", d.printer ? "on" : "off");
-    break;
-  case DBG_WARNING:
-    d.warning = atoi(arg); 
-    c_printf("DEBUG: Warning %s!\n", d.warning ? "on" : "off");
-    break;
-  case DBG_GENERAL:
-    d.general = atoi(arg); 
-    c_printf("DEBUG: General %s!\n", d.general ? "on" : "off");
-    break;
-  case DBG_XMS:
-    d.xms = atoi(arg); 
-    c_printf("DEBUG: XMS %s!\n", d.xms ? "on" : "off");
-    break;
-  case DBG_DPMI:
-    d.dpmi = atoi(arg); 
-    c_printf("DEBUG: DPMI %s!\n", d.dpmi ? "on" : "off");
-    break;
-  case DBG_MOUSE:
-    d.mouse = atoi(arg); 
-    c_printf("DEBUG: Mouse %s!\n", d.mouse ? "on" : "off");
-    break;
-  case DBG_HARDWARE:
-    d.hardware = atoi(arg); 
-    c_printf("DEBUG: Hardware %s!\n", d.hardware ? "on" : "off");
-    break;
-  case DBG_IPC:
-    d.IPC = atoi(arg); 
-    c_printf("DEBUG: IPC %s!\n", d.IPC ? "on" : "off");
-    break;
-  case DBG_EMS:
-    d.EMS = atoi(arg); 
-    c_printf("DEBUG: EMS %s!\n", d.EMS ? "on" : "off");
-    break;
-  case DBG_NET:
-    d.network = atoi(arg); 
-    c_printf("DEBUG: network %s!\n", d.network ? "on" : "off");
-    break;
-  
-  default:
-    error("CONF: unknown debug token: %s\n", word->name);
-    break;
-    break;
-  }
-  if (arg)
-    free(arg);
-  return (word->token);
-}
-
-int
-do_keyboard(word_t * word, arg_t farg1, arg_t farg2)
-{
-  char *arg = NULL;
-
-  c_printf("CONF: do_keyboard\n");
-
-  switch (word->form) {
-  case VALUE:
-    arg = get_arg(globl_file);
-    break;
-  case PRED:
-    break;
-  default:
-    break;
-  }
-
-  switch (word->token) {
-  case RBRACE:
-  case LBRACE:
-    break;
-  case KEYB_LAYOUT:
-    switch (atoi(arg)) {
-    case KEYB_FINNISH:
-      c_printf("CONF: Keyboard-layout finnish\n");
-      config.keyboard  = KEYB_FINNISH;
-      config.key_map   = key_map_finnish;  /* pointer to the keyboard-map */
-      config.shift_map = shift_map_finnish;
-      config.alt_map   = alt_map_finnish;
-      config.num_table = num_table_comma;
-      break;
-    case KEYB_FINNISH_LATIN1:
-      c_printf("CONF: Keyboard-layout finnish-latin1\n");
-      config.keyboard  = KEYB_FINNISH_LATIN1;
-      config.key_map   = key_map_finnish_latin1;
-      config.shift_map = shift_map_finnish_latin1;
-      config.alt_map   = alt_map_finnish_latin1;
-      config.num_table = num_table_comma;
-      break;
-    case KEYB_US:
-      c_printf("CONF: Keyboard-layout us\n");
-      config.keyboard  = KEYB_US;
-      config.key_map   = key_map_us;  /* pointer to the keyboard-map */
-      config.shift_map = shift_map_us;
-      config.alt_map   = alt_map_us;
-      config.num_table = num_table_dot;
-      break;
-    case KEYB_UK:
-      c_printf("CONF: Keyboard-layout uk\n");
-      config.keyboard  = KEYB_UK;
-      config.key_map   = key_map_uk;  /* pointer to the keyboard-map */
-      config.shift_map = shift_map_uk;
-      config.alt_map   = alt_map_uk;
-      config.num_table = num_table_dot;
-      break;
-    case KEYB_GR:
-      c_printf("CONF: Keyboard-layout gr\n");
-      config.keyboard  = KEYB_GR;
-      config.key_map   = key_map_gr;  /* pointer to the keyboard-map */
-      config.shift_map = shift_map_gr;
-      config.alt_map   = alt_map_gr;
-      config.num_table = num_table_comma;
-      break;
-    case KEYB_GR_LATIN1:
-      c_printf("CONF: Keyboard-layout gr-latin1\n");
-      config.keyboard  = KEYB_GR_LATIN1;
-      config.key_map   = key_map_gr_latin1;  /* pointer to the keyboard-map */
-      config.shift_map = shift_map_gr_latin1;
-      config.alt_map   = alt_map_gr_latin1;
-      config.num_table = num_table_comma;
-      break;
-    case KEYB_FR:
-      c_printf("CONF: Keyboard-layout fr\n");
-      config.keyboard  = KEYB_FR;
-      config.key_map   = key_map_fr;  /* pointer to the keyboard-map */
-      config.shift_map = shift_map_fr;
-      config.alt_map   = alt_map_fr;
-      config.num_table = num_table_dot;
-      break;
-    case KEYB_FR_LATIN1:
-      c_printf("CONF: Keyboard-layout fr-latin1\n");
-      config.keyboard  = KEYB_FR_LATIN1;
-      config.key_map   = key_map_fr_latin1;  /* pointer to the keyboard-map */
-      config.shift_map = shift_map_fr_latin1;
-      config.alt_map   = alt_map_fr_latin1;
-      config.num_table = num_table_dot;
-      break;
-    case KEYB_DK:
-      c_printf("CONF: Keyboard-layout dk\n");
-      config.keyboard  = KEYB_DK;
-      config.key_map   = key_map_dk;  /* pointer to the keyboard-map */
-      config.shift_map = shift_map_dk;
-      config.alt_map   = alt_map_dk;
-      config.num_table = num_table_comma;
-      break;
-    case KEYB_DK_LATIN1:
-      c_printf("CONF: Keyboard-layout dk-latin1\n");
-      config.keyboard  = KEYB_DK_LATIN1;
-      config.key_map   = key_map_dk_latin1;  /* pointer to the keyboard-map */
-      config.shift_map = shift_map_dk_latin1;
-      config.alt_map   = alt_map_dk_latin1;
-      config.num_table = num_table_comma;
-      break;
-    case KEYB_DVORAK:
-      c_printf("CONF: Keyboard-layout dvorak\n");
-      config.keyboard  = KEYB_DVORAK;
-      config.key_map   = key_map_dvorak;  /* pointer to the keyboard-map */
-      config.shift_map = shift_map_dvorak;
-      config.alt_map   = alt_map_dvorak;
-      config.num_table = num_table_comma;
-      break;
-    case KEYB_SG:
-      c_printf("CONF: Keyboard-layout sg\n");
-      config.keyboard  = KEYB_SG;
-      config.key_map   = key_map_sg;  /* pointer to the keyboard-map */
-      config.shift_map = shift_map_sg;
-      config.alt_map   = alt_map_sg;
-      config.num_table = num_table_comma;
-      break;
-    case KEYB_SG_LATIN1:
-      c_printf("CONF: Keyboard-layout sg-latin1\n");
-      config.keyboard  = KEYB_SG_LATIN1;
-      config.key_map   = key_map_sg_latin1;  /* pointer to the keyboard-map */
-      config.shift_map = shift_map_sg_latin1;
-      config.alt_map   = alt_map_sg_latin1;
-      config.num_table = num_table_comma;
-      break;
-    case KEYB_NO:
-      c_printf("CONF: Keyboard-layout no\n");
-      config.keyboard  = KEYB_NO;
-      config.key_map   = key_map_no;  /* pointer to the keyboard-map */
-      config.shift_map = shift_map_no;
-      config.alt_map   = alt_map_no;
-      config.num_table = num_table_comma;
-      break;
-    case KEYB_SF:
-      c_printf("CONF: Keyboard-layout sf\n");
-      config.keyboard  = KEYB_SF;
-      config.key_map   = key_map_sf;  /* pointer to the keyboard-map */
-      config.shift_map = shift_map_sf;
-      config.alt_map   = alt_map_sf;
-      config.num_table = num_table_comma;
-      break;
-    case KEYB_SF_LATIN1:
-      c_printf("CONF: Keyboard-layout sf-latin1\n");
-      config.keyboard  = KEYB_SF_LATIN1;
-      config.key_map   = key_map_sf_latin1;  /* pointer to the keyboard-map */
-      config.shift_map = shift_map_sf_latin1;
-      config.alt_map   = alt_map_sf_latin1;
-      config.num_table = num_table_comma;
-      break;
-    case KEYB_ES:
-      c_printf("CONF: Keyboard-layout es\n");
-      config.keyboard  = KEYB_ES;
-      config.key_map   = key_map_es;  /* pointer to the keyboard-map */
-      config.shift_map = shift_map_es;
-      config.alt_map   = alt_map_es;
-      config.num_table = num_table_comma;
-      break;
-    case KEYB_ES_LATIN1:
-      c_printf("CONF: Keyboard-layout es-latin1\n");
-      config.keyboard  = KEYB_ES_LATIN1;
-      config.key_map   = key_map_es_latin1;  /* pointer to the keyboard-map */
-      config.shift_map = shift_map_es_latin1;
-      config.alt_map   = alt_map_es_latin1;
-      config.num_table = num_table_comma;
-      break;
-    case KEYB_BE:
-      c_printf("CONF: Keyboard-layout be\n");
-      config.keyboard  = KEYB_BE;
-      config.key_map   = key_map_be;  /* pointer to the keyboard-map */
-      config.shift_map = shift_map_be;
-      config.alt_map   = alt_map_be;
-      config.num_table = num_table_dot;
-      break;
-    default:
-      error("CONF: unknown keyboard layout: %s\n", word->name);
-      break;
-    }
-    break;
-  case KEYB_RAWKEYBOARD:
-    config.console_keyb = (atoi(arg) != 0);
-    c_printf("CONF: RawKeyboard %s!\n", config.console_keyb ? "on" : "off");
-    break;
-  case KEYB_KEYBINT:
-    config.keybint = atoi(arg);
-    c_printf("CONF: keybint %s!\n", config.keybint ? "on" : "off");
-    break;
-  default:
-    error("CONF: unknown debug token: %s\n", word->name);
-    break;
-  }
-  if (arg)
-    free(arg);
-  return (word->token);
-}
-
-int
-do_serial(word_t * word, arg_t farg1, arg_t farg2)
-{
-  char *arg = NULL;
-  char *end;
-
-  switch (word->form) {
-  case VALUE:
-    arg = get_name(globl_file);
-    break;
-  case PRED:
-    break;
-  default:
-    break;
-  }
-
-  switch (word->token) {
-  case RBRACE:
-  case LBRACE:
-    break;
-  case S_DEVICE:
-    strcpy(sptr->dev, arg);
-    break;
-  case S_PORT:
-    sptr->real_comport = strtol(arg, &end, 0);
-    com_port_used[sptr->real_comport] = 1;
-    break;
-  case S_BASE:
-    sptr->base_port = strtol(arg, &end, 0);
-    break;
-  case S_IRQ:
-    sptr->interrupt = strtol(arg, &end, 0);
-    break;
-  case S_MOUSE:
-    sptr->mouse = 1;
-    break;
-  default:
-    error("CONF: unknown serial token: %s\n", word->name);
-    break;
-  }
-  if (arg)
-    free(arg);
-  return (word->token);
-}
-
-void
-start_printer(word_t * word, arg_t farg1, arg_t farg2)
-{
-  if (c_printers >= NUM_PRINTERS)
-    pptr = &nullptr;
-  else {
-    pptr = &lpt[c_printers];
-    /* this causes crashes ?? */
-#if 0
-    pptr->prtcmd = strdup("lpr");
-    pptr->prtopt = strdup("%s");
-#else
-    pptr->prtcmd = NULL;
-    pptr->prtopt = NULL;
-#endif
-    pptr->dev = NULL;
-    pptr->file = NULL;
-    pptr->remaining = -1;
-    pptr->delay = 10;
-  }
-}
-
-void
-stop_printer(word_t * word, arg_t farg1, arg_t farg2)
-{
-  c_printf("CONF(LPT%d) f: %s   c: %s  o: %s  t: %d\n",
-	   c_printers, pptr->dev, pptr->prtcmd, pptr->prtopt, pptr->delay);
-  c_printers++;
-  config.num_lpt = c_printers;
-}
-
-int
-do_printer(word_t * word, arg_t farg1, arg_t farg2)
-{
-  char *arg = NULL;
-
-  /* c_printf("do_printer: %s %d\n", word->name, word->token, farg1, farg2); */
-
-  switch (word->form) {
-  case VALUE:
-    arg = get_name(globl_file);
-    break;
-  case PRED:
-    break;
-  default:
-    break;
-  }
-
-  switch (word->token) {
-  case RBRACE:
-  case LBRACE:
-    break;
-  case P_COMMAND:
-    pptr->prtcmd = strdup(arg);
-    break;
-  case P_OPTIONS:
-    pptr->prtopt = strdup(arg);
-    break;
-  case P_TIMEOUT:
-    pptr->delay = atoi(arg);
-    break;
-  case P_FILE:
-    pptr->dev = strdup(arg);
-    break;
-  default:
-    error("CONF: unknown printer token: %s\n", word->name);
-    break;
-  }
-
-  if (arg)
-    free(arg);
-  return (word->token);
-}
-
-int
-do_top(word_t * word, arg_t arg1, arg_t arg2)
-{
-  int oldstate = state;
-  char *oldstatestr = statestr;
-
-  /*  c_printf("do_top: called with %s %d\n", word->name, word->token); */
-
-  state = word->token;
-  statestr = word->name;
-
-  switch (word->form) {
-  case COMMENT:
-    read_until_eol(globl_file);
-    break;
-  case SECTION:
-    switch (word->token) {
-    case SEC_PORTS:
-    case SEC_COMMENT:
-    case SEC_DISK:
-    case SEC_FLOPPY:
-    case SEC_BOOTDISK:
-    case SEC_PRINTER:
-    case SEC_VIDEO:
-    case SEC_TERMINAL:
-    case SEC_SERIAL:
-    case SEC_MOUSE:
-    case SEC_DEBUG:
-    case SEC_KEYBOARD:
-      if (word->start)
-	(word->start) (word, 0, 0);
-      parse_file(word->sub_words, globl_file);
-      if (word->stop)
-	(word->stop) (word, 0, 0);
-      break;
-    default:
-      c_printf("bad top-level section token: %s %d\n", word->name,
-	       word->token);
-    }
-    break;
-
-  default:
-    c_printf("bad top-level form: %s %d\n", word->name,
-	     word->form);
-  }
-  state = oldstate;
-  statestr = oldstatestr;
-  return NULLFORM;
-}
-
-/*
- * start_disk - start parsing one disk-statement
- */
-
-void start_disk(word_t * word, arg_t arg1, arg_t arg2)
-{
-  switch(word->token)
-    {
-    case SEC_BOOTDISK:               /* bootdisk-section */
-      if (config.bootdisk)           /* Already a bootdisk configured ? */
-	parse_error("There is already a bootdisk configured");
-      
-      dptr = &bootdisk;              /* set pointer do bootdisk-struct */
-      
-      dptr->sectors = 0;             /* setup default-values           */
-      dptr->heads   = 0;
-      dptr->tracks  = 0;
-      dptr->type    = FLOPPY;
-      dptr->default_cmos = THREE_INCH_FLOPPY;
-      dptr->timeout = 0;
-      break;
-
-    case SEC_FLOPPY:                 /* floppy section */
-      if (c_fdisks >= MAX_FDISKS)
-	{
-	  parse_error("There are too many floppy disks defined");
-	  dptr = &nulldisk;          /* Dummy-Entry to avoid core-dumps */
-	}
-      else
-	dptr = &disktab[c_fdisks];
-
-      dptr->sectors = 0;             /* setup default values */
-      dptr->heads   = 0;
-      dptr->tracks  = 0;
-      dptr->type    = FLOPPY;
-      dptr->default_cmos = THREE_INCH_FLOPPY;
-      dptr->timeout = 0;
-      break;
-
-    case SEC_DISK:                   /* Hard-disk section */
-      if (c_hdisks >= MAX_HDISKS) 
-	{
-	  parse_error("There are too many hard disks defined");
-	  dptr = &nulldisk;          /* Dummy-Entry to avoid core-dumps */
-	}
-      else
-	dptr = &hdisktab[c_hdisks];
-      
-      dptr->type    =  NODISK;
-      dptr->sectors = -1;
-      dptr->heads   = -1;
-      dptr->tracks  = -1;
-      dptr->timeout = 0;
-      break;
-
-    default:
-      parse_error("unknown disk type in parsing a disk-section");
-      break;
-    }
-
-  dptr->dev_name = NULL;              /* default-values */
-  dptr->wantrdonly = 0;
-  dptr->header = 0;
-}
-
-/*
- * stop_disk - A disk-option has been parsed, do the last checks
- */
-
-void stop_disk(word_t * word, arg_t arg1, arg_t arg2)
-{
-  if (dptr == &nulldisk)              /* is there any disk? */
-    return;                           /* no, nothing to do */
-
-  if (!dptr->dev_name)                /* Is there a file/device-name? */
-    parse_error("disk: no device/file-name given!");
-  else                                /* check the file/device for existance */
-    {
-      struct stat file_status;        /* date for checking that file */
-
-      c_printf("device: %s ", dptr->dev_name);
-      if (stat(dptr->dev_name,&file_status) != 0) /* Does this file exist? */
-	{
-	  char *str;
-
-	  str = malloc(128);             /* No, issue an error-message */
-	  sprintf(str,"Disk-device/file %s doesn't exist.",dptr->dev_name);
-	  parse_error(str);
-
-	  free(str);
-	}
-    }
-
-  if (dptr->type == NODISK)    /* Is it one of bootdisk, floppy, harddisk ? */
-    parse_error("disk: no device/file-name given!"); /* No, error */
-  else
-    c_printf("type %d ", dptr->type);
-
-  if (dptr->type == PARTITION)
-    {
-      struct stat file_status;        /* date for checking that file */
-
-      c_printf("partition# %d ", dptr->part_info.number);
-      
-      if (stat(dptr->part_info.file,&file_status) != 0) /* check part_info */
-	{
-	  char *str;
-	  
-	  str = malloc(128);             /* issue an error-message */
-	  sprintf(str,"Partition-Info %s doesn't exist.",dptr->part_info.file);
-	  parse_error(str);
-	  
-	  free(str);
-	}
-    }
-
-  if (dptr->header)
-    c_printf("header_size: %ld ", (long) dptr->header);
-
-  c_printf("h: %d  s: %d   t: %d\n", dptr->heads, dptr->sectors,
-	   dptr->tracks);
-
-  if (word->token == SEC_BOOTDISK) {
-    config.bootdisk = 1;
-    use_bootdisk = 1;
-  }
-  else if (word->token == SEC_FLOPPY) {
-    c_fdisks++;
-    config.fdisks = c_fdisks;
-  }
-  else {
-    c_hdisks++;
-    config.hdisks = c_hdisks;
-  }
-}
-
-/*
- * do_disk - parse a disk-section of a config-file.
- *           The sections for bootdisk, floppy and disk(harddisk)
- *           are very similar, so all these sections are parsed here.
- */
-
-int do_disk(word_t * word, arg_t farg1, arg_t farg2)
-{
-  char *arg = NULL, *arg2 = NULL;
-
-  /* c_printf("do_disk: %s %d\n", word->name, word->token, farg1, farg2); */
-
-  switch (word->form) {
-  case VALUE2:
-    arg = get_name(globl_file);
-    arg2 = get_name(globl_file);
-    break;
-  case VALUE:
-    arg = get_name(globl_file);
-    break;
-  case PRED:
-    break;
-  default:
-    break;
-  }
-
-  switch (word->token) {
-  case D_READONLY:
-    dptr->wantrdonly = 1;
-    break;
-  case D_FIVEINCH:
-    dptr->default_cmos = FIVE_INCH_FLOPPY;
-    break;
-  case D_THREEINCH:
-    dptr->default_cmos = THREE_INCH_FLOPPY;
-    break;
-  case D_SECTORS:
-    dptr->sectors = atoi(arg);
-    break;
-  case D_CYLINDERS:
-    dptr->tracks = atoi(arg);
-    break;
-  case D_HEADS:
-    dptr->heads = atoi(arg);
-    break;
-  case D_FILE:
-    if (dptr->dev_name != NULL)
-      parse_error("Two names for a disk-image file or device given.");
-    dptr->dev_name = arg;
-    arg = NULL;
-    break;
-  case D_HDIMAGE:
-    if (dptr->dev_name != NULL)
-      parse_error("Two names for a harddisk-image file given.");
-    dptr->type = IMAGE;
-    dptr->header = HEADER_SIZE;
-    dptr->dev_name = arg;
-    arg = NULL;
-    break;
-  case D_WHOLEDISK:
-  case D_HARD:
-    if (dptr->dev_name != NULL)
-      parse_error("Two names for a harddisk device given.");
-    dptr->type = HDISK;
-    dptr->dev_name = arg;
-    arg = NULL;
-    break;
-  case D_FLOPPY:
-    if (dptr->dev_name != NULL)
-      parse_error("Two names for a floppy-device given.");
-    dptr->type = FLOPPY;
-    dptr->dev_name = arg;
-    arg = NULL;
-    break;
-  case D_PARTITION:
-    if (dptr->dev_name != NULL)
-      parse_error("Two names for a partition given.");
-    dptr->type = PARTITION;
-    dptr->part_info.number = atoi(arg2);
-    dptr->dev_name = arg;
-
-    dptr->part_info.file = malloc(strlen(PARTITION_PATH ".")+10); 
-    dptr->part_info.file = strcpy(dptr->part_info.file,PARTITION_PATH "."); 
-    dptr->part_info.file = strcat(dptr->part_info.file,dptr->dev_name+5);
-
-    arg = NULL;
-    break;
-  case D_OFFSET:
-    dptr->header = atoi(arg);
-    break;
-  case RBRACE:
-    break;
-  default:
-    break;
-  }
-
-  if (arg)
-    free(arg);
-  if (arg2)
-    free(arg2);
-  return word->token;
-}
-
-void
-parse_file(word_t * words, FILE * fd)
-{
-  word_t *mword;
-  char *gn;
-  int funrtn = 0;
-
-  int oldstate = state;
-  char *oldstatestr = statestr;
-
-  gn = get_name(fd);
-
-  while (gn && (funrtn != RBRACE)) {
-    if ((mword = match_name(words, gn))) {
-      if (mword->func) {
-	funrtn = (mword->func) (mword, 0, 0);
-      }
-      else {
-	funrtn = mword->token;
-      }
-    }
-    else if (state != SEC_COMMENT) {
-      word_t badword;
-
-      badword.name = gn;
-      badword.token = NULLTOK;
-      badword.form = NULLFORM;
-      badword.func = 0;
-      badword.start = 0;
-      badword.start = 0;
-
-      if (words[0].func)
-	(words[0].func) (&badword, 0, 0);
-    }
-
-    free(gn);
-    if (funrtn != RBRACE)
-      gn = get_name(fd);
-  }
-
-  state = oldstate;
-  statestr = oldstatestr;
-}
-
-int
-parse_config(char *confname)
-{
-  FILE *volatile fd;
-
-  c_hdisks = 0;
-  c_fdisks = 0;
-
-  if (/* !fd && */ !(fd = open_file(CONFIG_FILE))) {
-    die("cannot open standard configuration file!");
-  }
-
-  if (!setjmp(exitpar))
-    parse_file(top_words, fd);
-
-  close_file(fd);
-
-  if (!exchange_uids()) die("Cannot exchange uids\n");
-  if (confname)
-    fd = open_file(confname);
-  else {
-    char *home = getenv("HOME");
-    char *name = malloc(strlen(home) + 20);
-
-    sprintf(name, "%s/.dosrc", home);
-    fd = open_file(name);
-    free(name);
-  }
-  if (!exchange_uids()) die("Cannot changeback uids\n");
-
-  if (!setjmp(exitpar))
-    parse_file(top_words, fd);
-
-  if (fd) close_file(fd);
-
-  return 1;
-}
-
-#if 0
-int
-main(int argc, char **argv)
-{
-  if (argc != 2)
-    die("no filename!");
-
-  if (!parse_config(argv[1]))
-    die("parse failed!\n");
-}
-
-#endif
diff -u --recursive --new-file dosemu0.53pl28/init/parser.y dosemu0.53pl29/init/parser.y
--- dosemu0.53pl28/init/parser.y	Wed Oct 19 22:28:30 1994
+++ dosemu0.53pl29/init/parser.y	Tue Nov  1 23:03:11 1994
@@ -72,6 +72,7 @@
 void stop_printer(void);
 void stop_terminal(void);
 void start_disk(void);
+void do_part(char *);
 void start_bootdisk(void);
 void start_floppy(void);
 void stop_disk(int token);
@@ -566,16 +567,13 @@
 		  }
 		| L_PARTITION STRING INTEGER
 		  {
-		  if (dptr->dev_name != NULL)
-		    yyerror("Two names for a partition given.");
-		  dptr->type = PARTITION;
-		  dptr->part_info.number = $3;
-		  dptr->dev_name = $2;
-
-		  dptr->part_info.file = malloc(strlen(PARTITION_PATH ".")+10); 
-		  dptr->part_info.file = strcpy(dptr->part_info.file,PARTITION_PATH "."); 
-		  dptr->part_info.file = strcat(dptr->part_info.file,dptr->dev_name+5);
+                  yywarn("CONF: { partition \"%s\" %d } the"
+			 " token '%d' is ignored and can be removed.",
+			 $2,$3,$3);
+		  do_part($2);
 		  }
+		| L_PARTITION STRING 
+		  { do_part($2); }
 		| STRING
 		    { yyerror("unrecognized disk flag '%s'\n", $1); free($1); }
 		| error
@@ -936,6 +934,18 @@
   dptr->header = 0;
 }
 
+void do_part(char *dev)
+{
+  if (dptr->dev_name != NULL)
+    yyerror("Two names for a partition given.");
+  dptr->type = PARTITION;
+  dptr->dev_name = dev;
+  dptr->part_info.number = atoi(dptr->dev_name+8);
+  if (dptr->part_info.number == 0) 
+    yyerror("ERROR: %s must be a PARTITION, can't find number suffix!\n",
+   	    dptr->dev_name);
+}
+
 void stop_disk(int token)
 {
   if (dptr == &nulldisk)              /* is there any disk? */
@@ -959,12 +969,7 @@
 
   if (dptr->type == PARTITION)
     {
-      struct stat file_status;        /* date for checking that file */
-
       c_printf("partition# %d ", dptr->part_info.number);
-      
-      if (stat(dptr->part_info.file,&file_status) != 0) /* check part_info */
-	  yyerror("Partition-Info %s doesn't exist.",dptr->part_info.file);
     }
 
   if (dptr->header)
diff -u --recursive --new-file dosemu0.53pl28/ipxbridge/Makefile dosemu0.53pl29/ipxbridge/Makefile
--- dosemu0.53pl28/ipxbridge/Makefile
+++ dosemu0.53pl29/ipxbridge/Makefile	Wed Oct 26 21:23:27 1994
@@ -0,0 +1,5 @@
+
+dist:
+	install -d $(DISTPATH)/ipxbridge
+	tar -zcvf - * |(cd $(DISTPATH)/ipxbridge;tar -zxvf -)
+
diff -u --recursive --new-file dosemu0.53pl28/ipxbridge/README dosemu0.53pl29/ipxbridge/README
--- dosemu0.53pl28/ipxbridge/README
+++ dosemu0.53pl29/ipxbridge/README	Wed Oct 26 21:09:36 1994
@@ -0,0 +1,56 @@
+Directories:
+ipxbridge-0.1 :  IPX bridging -- no intelligence. 
+    Status: Works.
+ipxbridge-0.1.1 :  IPX bridging -- no intelligence -- cleaned up code.
+    Status: Not tested thoroughly. Working for local set up. Give it a Try!
+ipxbridge-0.2 :  IPX bridging --  intelligence 
+    Status: Works, but under some unknown circumstances, sendto() fails 
+           continuously, and only way is to kill it and restart it again. 
+
+======================================================
+This is first  attempt to get IPX bridging and routing working
+for linux.
+
+This is pre-pre-alpha. This implementation is just to trigger off 
+the full fledged development. 
+
+ASSUMPTIONS:
+  1. Bridges between only two interfaces : eth0 and eth1. (Hardcoded)
+  2. The MTUs of both interfaces should remain equal.
+
+TODO:
+
+IPX bridging:
+
+1. Intelligent bridging
+2. Get most functionality into the kernel to minimise overheads 
+   (in the style of routing)
+
+IPX routing: 
+
+We are trying to port Mark Bush's <Mark.Bush@comlab.ox.ac.uk>
+IPXrouted.tar.gz   to linux. This package is IPX routed implementation
+for SUNs. It is available in ftp.comlab.ox.ac.uk archives.
+
+It handles IPX packets all by itself, without requiring any kernel support
+from the sun system (i.e. it reads all packets from /dev/nit interface).
+Hence, this package cannot make use of IPX sockets which are currently
+in the kernel. We will try to eventually adapt this package to make
+use of IPX sockets which are currently in the kernel.
+
+
+Note
+=====
+We are  still learning... All kinds of suggestions  are welcome.
+Are we doing some silly mistakes in network programming?
+And allow us to take our own time! 
+
+And anyone there who is interested?
+
+----------------------
+Amitay Isaac, project engr., Dept. of Aero Engg. , IIT Bombay INDIA.
+amitay@aero.iitb.ernet.in
+
+Vinod G Kulkarni, research scholar, Dept of CSE, IIT Bombay, INDIA.
+vinod@cse.iitb.ernet.in
+
diff -u --recursive --new-file dosemu0.53pl28/ipxbridge/ipxbridge-0.1/Makefile dosemu0.53pl29/ipxbridge/ipxbridge-0.1/Makefile
--- dosemu0.53pl28/ipxbridge/ipxbridge-0.1/Makefile
+++ dosemu0.53pl29/ipxbridge/ipxbridge-0.1/Makefile	Wed Oct 26 21:09:36 1994
@@ -0,0 +1,2 @@
+ipx_bridge : ipxbridge.c a.h Makefile
+	gcc -Wall ipxbridge.c -o ipxbridge #-DDEBUG
diff -u --recursive --new-file dosemu0.53pl28/ipxbridge/ipxbridge-0.1/a.h dosemu0.53pl29/ipxbridge/ipxbridge-0.1/a.h
--- dosemu0.53pl28/ipxbridge/ipxbridge-0.1/a.h
+++ dosemu0.53pl29/ipxbridge/ipxbridge-0.1/a.h	Wed Oct 26 21:09:36 1994
@@ -0,0 +1,128 @@
+#define MAX_PACK_LEN 66560  /* 65535 + sizeof ether_hdr + bit extra */
+
+#define ETHER_SIZE 14
+
+struct ether_hdr
+{
+  u_char dst_mac[6];
+  u_char src_mac[6];
+  u_char pkt_type[2];  /* 0x8137 */
+};
+
+struct ether_trail
+{
+  u_char length;
+  u_char *trailer;
+};
+
+/*
+ * IPX packet types - not to be trusted: use dst sock
+ */
+#define IPX_UNKNOWN   0x00
+#define IPX_RIP       0x01
+#define IPX_SAP       0x04
+#define IPX_SPX       0x05
+#define IPX_NCP       0x11
+#define IPX_NETBIOS   0x14
+
+/*
+ * IPX socket numbers - low address: high address always 0x04 for these
+ */
+#define IPX_S_NCP     0x51
+#define IPX_S_SAP     0x52
+#define IPX_S_RIP     0x53
+#define IPX_S_NETBIOS 0x55
+#define IPX_S_DIAG    0x56
+
+#define IPX_HDR_SIZE 30
+
+struct ipx_hdr
+{
+  u_char chk_sum[2];    /* always 0xffff */
+  u_char length[2];
+  u_char transport_ctl;
+  u_char pkt_type;
+  u_char dst_net[4];
+  u_char dst_node[6];
+  u_char dst_sock[2];
+  u_char src_net[4];
+  u_char src_node[6];
+  u_char src_sock[2];
+};
+
+/*
+ * IPX operations for RIP and SAP - high address always 0
+ */
+#define IPX_REQ    1
+#define IPX_RESP   2
+#define IPX_REQ_NEAR 3
+#define IPX_RESP_NEAR 4
+
+struct rip_ent
+{
+  u_char net_num[4];
+  u_char num_hops[2];
+  u_char num_ticks[2];
+};
+
+struct rip_pkt
+{
+  u_char op[2];
+  u_char num_ents;
+  struct rip_ent *net_ent;
+};
+
+struct sap_ent
+{
+  u_char serv_type[2];
+  u_char serv_name[48];
+  u_char net_num[4];
+  u_char net_node[6];
+  u_char net_sock[2];
+  u_char net_hops[2];
+};
+
+struct sap_pkt
+{
+  u_char op[2];
+  u_char num_ents;
+  struct sap_ent *serv_ent;
+};
+
+struct ipx_pkt
+{
+  u_char interface;
+  struct ether_hdr ipx_ether_hdr;
+  struct ipx_hdr  ipx_ipx_hdr;
+  union
+  {
+    struct sap_pkt ipx_sap;
+    struct rip_pkt ipx_rip;
+    char *ipx_other;
+  } packet;
+  struct ether_trail ipx_ether_trail;
+};
+
+struct route_entry
+{
+  u_char net_num[4];
+  u_char num_hops;
+  u_char num_ticks[2];
+  u_char interface;
+  u_char router[6];
+  u_char age;
+  struct route_entry *next;
+};
+
+struct server_entry
+{
+  u_char serv_type[2];
+  u_char serv_name[48];
+  u_char net_num[4];
+  u_char net_node[6];
+  u_char net_sock[2];
+  u_char num_hops;
+  u_char interface;
+  u_char age;
+  struct server_entry *next;
+};
Binary files dosemu0.53pl28/ipxbridge/ipxbridge-0.1/ipxbridge and dosemu0.53pl29/ipxbridge/ipxbridge-0.1/ipxbridge differ
diff -u --recursive --new-file dosemu0.53pl28/ipxbridge/ipxbridge-0.1/ipxbridge.c dosemu0.53pl29/ipxbridge/ipxbridge-0.1/ipxbridge.c
--- dosemu0.53pl28/ipxbridge/ipxbridge-0.1/ipxbridge.c
+++ dosemu0.53pl29/ipxbridge/ipxbridge-0.1/ipxbridge.c	Wed Oct 26 21:09:36 1994
@@ -0,0 +1,214 @@
+#include <stdio.h>
+#include <string.h>
+#include <malloc.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <linux/if.h>
+#include <linux/if_ether.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <signal.h>
+#include "a.h"
+
+#define DEVICE1		"eth0"
+#define DEVICE2		"dsn0"
+
+#define	max(i,j)	(((i)>(j)) ? (i) : (j))
+
+int promisc_mode(char *, int);
+void close_all(int);
+
+u_char *full_packet;
+int new_len;
+int max_fd, fd, fd1, fd2, fd3, fd4;
+
+void main(int argc, char *argv[])
+{
+fd_set fdset;
+struct sockaddr from, to;
+int len, from_len;
+u_char *pkt_type;
+struct ether_hdr *ether_header;
+int ipx_len;
+u_char *ptr;
+unsigned int type, frame_type;
+int set;
+
+	/* Set the exception handling */
+	signal(SIGINT, close_all);
+	signal(SIGKILL, close_all);
+
+	/* I am running as a daemon */
+	if(fork() != 0) exit(0); 
+
+	/* Open a Socket for reading *all* OR *IPX* packets */
+	fd1 = socket(AF_INET, SOCK_PACKET, htons(ETH_P_802_2));
+	if(fd1 < 0) {
+		fprintf(stderr, "Error in opening generic packet socket.\n");
+		exit(0);
+	}
+	fd2 = socket(AF_INET, SOCK_PACKET, htons(ETH_P_IPX));
+	if(fd2 < 0) {
+		fprintf(stderr, "Error in opening generic packet socket.\n");
+		exit(0);
+	}
+	fd3 = socket(AF_INET, SOCK_PACKET, htons(ETH_P_802_3));
+	if(fd3 < 0) {
+		fprintf(stderr, "Error in opening generic packet socket.\n");
+		exit(0);
+	}
+	fd4 = socket(AF_INET, SOCK_PACKET, htons(ETH_P_SNAP));
+	if(fd4 < 0) {
+		fprintf(stderr, "Error in opening generic packet socket.\n");
+		exit(0);
+	}
+
+	if(promisc_mode(DEVICE1, 1) < 0) {
+		exit(0);
+	}
+
+	if(promisc_mode(DEVICE2, 1) < 0) {
+		exit(0);
+	}
+
+	if((full_packet = (char *)malloc(MAX_PACK_LEN)) == NULL) {
+		fprintf(stderr, "Cannot allocate memory.\n");
+		exit(0);
+	}
+
+	max_fd = max(fd1, fd2);
+	max_fd = max(fd3, max_fd);
+	max_fd = max(fd4, max_fd) + 1;
+
+	for(;;) {
+		FD_ZERO(&fdset);
+		FD_SET(fd1, &fdset);
+		FD_SET(fd2, &fdset);
+		FD_SET(fd3, &fdset);
+		FD_SET(fd4, &fdset);
+
+		select(max_fd, &fdset, (fd_set *)NULL, (fd_set *)NULL, 
+				(struct timeval *)NULL);
+		
+		if(FD_ISSET(fd1, &fdset) == 1) fd = fd1;
+		else if(FD_ISSET(fd2, &fdset) == 1) fd = fd2;
+		else if(FD_ISSET(fd3, &fdset) == 1) fd = fd3;
+		else if(FD_ISSET(fd4, &fdset) == 1) fd = fd4;
+		else fprintf(stderr, "*** Unknown fd here ***\n");
+
+		len = recvfrom(fd, full_packet, MAX_PACK_LEN, 0, &from, &from_len);
+		if(len <= 0) continue;
+
+		/* Get the ethernet header */
+		ether_header = (struct ether_hdr *) full_packet;
+		pkt_type = ether_header->pkt_type;
+		type = pkt_type[0] << 8 | pkt_type[1];
+
+		/* Here we check the frame type and get the IPX related packets */
+		if(type >= 1536) frame_type = type;
+		else {
+			ptr = (u_char *) (full_packet + ETHER_SIZE);
+			if(ptr[0] == 0xFF && ptr[1] == 0xFF) frame_type = ETH_P_802_3;
+			if(ptr[0] == 0xAA && ptr[1] == 0xAA) frame_type = ETH_P_SNAP;
+			else frame_type = ETH_P_802_2;
+		}
+
+		ipx_len = ptr[2] << 8 | ptr[3];
+
+		set = 0;
+
+		switch(frame_type) {
+			case ETH_P_IPX :
+#ifdef DEBUG
+				fprintf(stderr, "Got IPX over DIX packet\n"); 
+#endif
+				set = 1;
+				break;
+			case ETH_P_802_2 :
+#ifdef DEBUG
+				fprintf(stderr, "Got Bluebook packet\n"); 
+#endif
+				set = 1;
+				break;
+			case ETH_P_802_3 :
+#ifdef DEBUG
+				fprintf(stderr, "Got IPX over DIX\n"); 
+#endif
+				set = 1;
+				break;
+			case ETH_P_SNAP :
+#ifdef DEBUG
+				fprintf(stderr, "Got Etherenet II SNAP\n"); 
+#endif
+				set = 1;
+				break;
+			default :
+				break;
+		}
+			
+		if(! set) continue;
+
+#ifdef DEBUG
+		fprintf(stderr, "device = %s, ether_len = %.4x, ipx_len = %.4x, type = %.4x\n", 
+				from.sa_data, len, ipx_len, type);
+#endif
+
+		if(strncmp(from.sa_data, DEVICE1, 4) == 0) 
+			strcpy(to.sa_data, DEVICE2);
+		else if(strncmp(from.sa_data, DEVICE2, 4) == 0) 
+			strcpy(to.sa_data, DEVICE1);
+		else
+			continue;
+
+		to.sa_family = AF_INET;
+
+	/* sendto function sends the packet *as is* to the network interface
+	   Only have to check if it adds the any of the MAC components to 
+	   the packet or not */
+
+		if(sendto(fd, full_packet, len, 0, &to, sizeof(to)) < 0) 
+		   perror("sendto");
+
+	/* After sending the packet we are waiting for some time before we
+	   start polling again. */
+	}
+}
+
+
+int promisc_mode(char *device, int flag)
+{
+struct ifreq if_data;
+
+	strcpy(if_data.ifr_name, device);
+	if(ioctl(fd1, SIOCGIFFLAGS, &if_data) < 0) {
+		fprintf(stderr, "Cannot get the flags for %s\n", device);
+		return -1;
+	}
+
+	if(flag) {
+		if_data.ifr_flags |= IFF_PROMISC;
+	}
+	else {
+		if_data.ifr_flags &= IFF_PROMISC;
+		if_data.ifr_flags ^= IFF_PROMISC;
+	}
+
+	if(ioctl(fd1, SIOCSIFFLAGS, &if_data) < 0) {
+		fprintf(stderr, "Cannot set promiscous mode for %s\n", device);
+		return -1;
+	}
+
+	return 1;
+}
+
+void close_all(int a)
+{
+	free(full_packet);
+	close(fd1);
+	close(fd2);
+}
+
diff -u --recursive --new-file dosemu0.53pl28/ipxbridge/ipxbridge-0.1.1/Makefile dosemu0.53pl29/ipxbridge/ipxbridge-0.1.1/Makefile
--- dosemu0.53pl28/ipxbridge/ipxbridge-0.1.1/Makefile
+++ dosemu0.53pl29/ipxbridge/ipxbridge-0.1.1/Makefile	Wed Oct 26 21:09:36 1994
@@ -0,0 +1,16 @@
+
+# Define ETH0_ETH1 if the two interfaces are eth0 and eth1. 
+# (Assumption is that they have 0 or 1 in  4th char position. 'eth' itself
+# is irrelevant.  In general, any two interfaces which differ in single
+# position can be used. Use CHANGED_POS to define that position.
+# Otherwise, define the two interfaces DEVICE0 and DEVICE1.
+
+#ETHOPT=-DETH0_ETH1 -DCHANGED_POS=3
+DEBUGOPT=-DDEBUG -DLDEBUG
+
+DEVICE0=-DDEVICE0=\"eth0\"
+DEVICE1=-DDEVICE1=\"dsn0\"
+
+ipxbridge : ipxbridge.c Makefile
+	gcc -Wall -O2 ipxbridge.c -o ipxbridge $(ETHOPT) $(DEBUGOPT) $(DEVICE0) $(DEVICE1) 
+
diff -u --recursive --new-file dosemu0.53pl28/ipxbridge/ipxbridge-0.1.1/README dosemu0.53pl29/ipxbridge/ipxbridge-0.1.1/README
--- dosemu0.53pl28/ipxbridge/ipxbridge-0.1.1/README
+++ dosemu0.53pl29/ipxbridge/ipxbridge-0.1.1/README	Wed Oct 26 21:09:36 1994
@@ -0,0 +1,46 @@
+This is first  attempt to get IPX bridging and routing working
+for linux.
+
+This is pre-pre-alpha. This implementation is just to trigger off 
+the full fledged development. 
+
+ASSUMPTIONS:
+  1. Bridges between only two interfaces : eth0 and eth1. (Hardcoded)
+  2. The MTUs of both interfaces should remain equal.
+
+TODO:
+
+IPX bridging:
+
+1. Intelligent bridging
+2. Get most functionality into the kernel to minimise overheads 
+   (in the style of routing)
+
+IPX routing: 
+
+We are trying to port Mark Bush's <Mark.Bush@comlab.ox.ac.uk>
+IPXrouted.tar.gz   to linux. This package is IPX routed implementation
+for SUNs. It is available in ftp.comlab.ox.ac.uk archives.
+
+It handles IPX packets all by itself, without requiring any kernel support
+from the sun system (i.e. it reads all packets from /dev/nit interface).
+Hence, this package cannot make use of IPX sockets which are currently
+in the kernel. We will try to eventually adapt this package to make
+use of IPX sockets which are currently in the kernel.
+
+
+Note
+=====
+We are  still learning... All kinds of suggestions  are welcome.
+Are we doing some silly mistakes in network programming?
+And allow us to take our own time! 
+
+And anyone there who is interested?
+
+----------------------
+Amitay Isaac, project engr., Dept. of Aero Engg. , IIT Bombay INDIA.
+amitay@aero.iitb.ernet.in
+
+Vinod G Kulkarni, research scholar, Dept of CSE, IIT Bombay, INDIA.
+vinod@cse.iitb.ernet.in
+
Binary files dosemu0.53pl28/ipxbridge/ipxbridge-0.1.1/ipxbridge and dosemu0.53pl29/ipxbridge/ipxbridge-0.1.1/ipxbridge differ
diff -u --recursive --new-file dosemu0.53pl28/ipxbridge/ipxbridge-0.1.1/ipxbridge.c dosemu0.53pl29/ipxbridge/ipxbridge-0.1.1/ipxbridge.c
--- dosemu0.53pl28/ipxbridge/ipxbridge-0.1.1/ipxbridge.c
+++ dosemu0.53pl29/ipxbridge/ipxbridge-0.1.1/ipxbridge.c	Wed Oct 26 21:09:36 1994
@@ -0,0 +1,291 @@
+/*
+     IPX bridging on Linux. 
+     Doesn't do intelligent bridging.  
+     (Sometimes, it may be faster than intelligent bridging!)
+
+     Authors: Amitay Issac , project engr, Dept. of Aerospace Engg
+              Vinod Kulkarni, research scholar, Dept. of Comp. Sc.
+                              IIT Bombay.
+
+     This version is placed in Public Domain.
+*/
+
+
+#include <stdio.h>
+#include <string.h>
+#include <malloc.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <linux/if.h>
+#include <linux/if_ether.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <signal.h>
+
+#define BRIDGE_ONLY
+
+#if !defined(ETH0_ETH1) && !defined(DEVICE0) && !defined(DEVICE1)
+#define ETH0_ETH1 
+#define DEVICE0		"eth0"
+#define DEVICE1		"eth1"
+#define  CHANGED_POS        3
+#endif
+
+#ifndef   DEVICE0 
+#define  DEVICE0		"eth0"
+#endif
+#ifndef   DEVICE1 
+#define  DEVICE1		"eth1"
+#endif
+
+#ifdef ETH0_ETH1
+#ifndef   CHANGED_POS 
+#define   CHANGED_POS 3 
+#endif
+#endif
+
+
+unsigned short len_device0, len_device1;
+
+#define MAX_PACK_LEN   20000  /* Sufficient for ethernet packets. */
+#define ETHER_SIZE     14
+struct ether_hdr
+{
+  u_char dst_mac[6];
+  u_char src_mac[6];
+  u_char pkt_type[2];  
+};
+
+#define	max(i,j)	(((i)>(j)) ? (i) : (j))
+
+int promisc_mode(char *, int);
+void close_all(int);
+
+union {
+  u_char full_packet[MAX_PACK_LEN];
+  struct ether_hdr ether_header;
+  struct eth_address_index  {
+       char da, db, dc, dd;   /* Destination address */
+       unsigned short int di;  /* size of short int = 4. */
+       char sa, sb, sc, sd;   /* Source address */
+       unsigned short int si;  /* size of short int = 4. */
+  } index;
+} a ;
+
+union {
+     unsigned short int i;
+     u_char b[2];      /* If i=0xab12, b[0]=12 and b[1]=ab. */
+} src_index, dst_index;
+
+int packet_length;
+int max_fd, fd, fd1, fd2, fd3, fd4;
+
+
+void main(int argc, char *argv[])
+{
+fd_set fdset;
+struct sockaddr from, to;
+int  from_len;
+unsigned char from_device_ch, to_device_ch;
+
+#ifdef ETH0_ETH1
+static unsigned char ascii_set[256];
+#endif
+
+	/* Set the exception handling */
+	signal(SIGINT, close_all);
+	signal(SIGKILL, close_all);
+
+
+        len_device0=strlen(DEVICE0);
+        len_device1=strlen(DEVICE1);
+
+#ifdef ETH0_ETH1
+        ascii_set[ (u_char)DEVICE1[CHANGED_POS] ] = DEVICE0[CHANGED_POS]; 
+        ascii_set[ (u_char)DEVICE0[CHANGED_POS] ] = DEVICE1[CHANGED_POS]; 
+#endif
+        fprintf(stderr,"Opening sockets ...\n");
+	/* Open a Socket for reading *all* IPX packets */
+	fd1 = socket(AF_INET, SOCK_PACKET, htons(ETH_P_IPX));
+	if(fd1 < 0) {
+		fprintf(stderr, "Error in opening generic packet socket.\n");
+		exit(0);
+	}
+	fd2 = socket(AF_INET, SOCK_PACKET, htons(ETH_P_802_3));
+	if(fd2 < 0) {
+		fprintf(stderr, "Error in opening generic packet socket.\n");
+		exit(0);
+	}
+	fd3 = socket(AF_INET, SOCK_PACKET, htons(ETH_P_802_2));
+	if(fd3 < 0) {
+		fprintf(stderr, "Error in opening generic packet socket.\n");
+		exit(0);
+	}
+	fd4 = socket(AF_INET, SOCK_PACKET, htons(ETH_P_SNAP));
+	if(fd4 < 0) {
+		fprintf(stderr, "Error in opening generic packet socket.\n");
+		exit(0);
+	}
+
+        fprintf(stderr,"Setting promiscuos mode ...\n");
+	if(promisc_mode(DEVICE0, 1) < 0) {
+		fprintf(stderr, "Can't set device 0 to promiscuous mode.\n");
+		exit(0);
+	}
+
+	if(promisc_mode(DEVICE1, 1) < 0) {
+		fprintf(stderr, "Can't set device 1 to promiscuous mode.\n");
+		exit(0);
+	}
+
+	max_fd = max(fd1, fd2);
+	max_fd = max(fd3, max_fd);
+	max_fd = max(fd4, max_fd) + 1;
+
+	from.sa_family = AF_INET;  
+	to.sa_family = AF_INET;  
+
+#ifdef ETH0_ETH1
+        strcpy(from.sa_data , DEVICE0) ;  
+        strcpy(to.sa_data , DEVICE1) ; 
+        /* This is Required because we only change particular characters 
+           from these array variables. 
+        */
+#endif
+        fprintf(stderr, "Now running as daemon.\n");
+	if(fork() != 0) exit(0); 
+
+	for(;;) {
+		FD_ZERO(&fdset);
+		FD_SET(fd1, &fdset);
+		FD_SET(fd2, &fdset);
+		FD_SET(fd3, &fdset);
+		FD_SET(fd4, &fdset);
+
+		select(max_fd, &fdset, (fd_set *)NULL, (fd_set *)NULL, 
+				(struct timeval *)NULL);
+		
+		if(FD_ISSET(fd1, &fdset) == 1) fd = fd1;
+		else if(FD_ISSET(fd2, &fdset) == 1) fd = fd2;
+		else if(FD_ISSET(fd3, &fdset) == 1) fd = fd3;
+		else if(FD_ISSET(fd4, &fdset) == 1) fd = fd4;
+		else { 
+                       fprintf(stderr, "*** Unknown fd in select ***\n");
+                       continue;
+                }
+
+		packet_length = recvfrom(fd, a.full_packet, MAX_PACK_LEN, 0, &from, &from_len);
+		if(packet_length <= 0) continue;
+
+#ifdef LDEBUG
+		fprintf(stderr, "device = %s, ether_len = %.4x, type = %4.4x\n", 
+				from.sa_data, packet_length, a.ether_header.pkt_type);
+#endif
+
+#ifdef ETH0_ETH1
+                from_device_ch = from.sa_data[ CHANGED_POS ];
+#else
+                from_device_ch = 
+                      (memcmp(&from.sa_data[0], DEVICE0, len_device0))? '1':'0';
+#endif
+
+#ifdef ETH0_ETH1
+                to.sa_data[CHANGED_POS] = ascii_set[ from_device_ch ];
+#else
+                strcpy(to.sa_data, (from_device_ch=='0')? DEVICE1: DEVICE0 );
+#endif                
+		fprintf(stderr, "to-device = %s\n", to.sa_data);
+	        if(sendto(fd, a.full_packet, packet_length, 0, &to, sizeof(to)) < 0) 
+		          perror("sendto");
+
+	} /* for loop. */
+}
+
+
+int promisc_mode(char *device, int flag)
+{
+struct ifreq if_data;
+
+	strcpy(if_data.ifr_name, device);
+	if(ioctl(fd1, SIOCGIFFLAGS, &if_data) < 0) {
+		fprintf(stderr, "Cannot get the flags for %s\n", device);
+		return -1;
+	}
+
+	if(flag) {
+		if_data.ifr_flags |= IFF_PROMISC;
+	}
+	else {
+		if_data.ifr_flags &= IFF_PROMISC;
+		if_data.ifr_flags ^= IFF_PROMISC;
+	}
+
+	if(ioctl(fd1, SIOCSIFFLAGS, &if_data) < 0) {
+		fprintf(stderr, "Cannot set promiscous mode for %s\n", device);
+		return -1;
+	}
+
+	return 1;
+}
+
+#ifdef DEBUG
+void debug(void)
+{
+int set;
+int ipx_len;
+u_char *pkt_type;
+unsigned int type, frame_type;
+u_char *ptr;
+               /* This is a long DEBUG code to see if particular packets are getting
+                          accepted. */
+		pkt_type = a.ether_header.pkt_type;
+		type = pkt_type[0] << 8 | pkt_type[1];
+
+		ptr = (u_char *) (a.full_packet + ETHER_SIZE); 
+		/* Here we check the frame type and get the IPX related packets */
+		if(type >= 1536) frame_type = type;
+		else {
+			if(ptr[0] == 0xFF && ptr[1] == 0xFF) frame_type = ETH_P_802_3;
+			if(ptr[0] == 0xAA && ptr[1] == 0xAA) frame_type = ETH_P_SNAP;
+			else frame_type = ETH_P_802_2;
+		}
+		ipx_len = ptr[2] << 8 | ptr[3];
+		set = 0;
+		switch(frame_type) {
+			case ETH_P_IPX :
+				fprintf(stderr, "Got IPX over DIX packet\n"); 
+				set = 1;
+				break;
+			case ETH_P_802_2 :
+				fprintf(stderr, "Got Bluebook packet\n"); 
+				set = 1;
+				break;
+			case ETH_P_802_3 :
+				fprintf(stderr, "Got IPX over DIX\n"); 
+				set = 1;
+				break;
+			case ETH_P_SNAP :
+				fprintf(stderr, "Got Etherenet II SNAP\n"); 
+				set = 1;
+				break;
+			default :
+				break;
+		}
+		if(! set) return;
+		fprintf(stderr, "device = %s, ether_len = %.4x, ipx_len = %.4x, type = %.4x\n", 
+				a.full_packet, packet_length, ipx_len, type);
+
+    /* That was a long DEBUG code to see if particular packets are getting
+       accepted. */
+}
+#endif
+
+void close_all(int a)
+{
+	close(fd1);
+	close(fd2);
+}
diff -u --recursive --new-file dosemu0.53pl28/ipxbridge/ipxbridge-0.1.1/ipxbridge.h dosemu0.53pl29/ipxbridge/ipxbridge-0.1.1/ipxbridge.h
--- dosemu0.53pl28/ipxbridge/ipxbridge-0.1.1/ipxbridge.h
+++ dosemu0.53pl29/ipxbridge/ipxbridge-0.1.1/ipxbridge.h	Wed Oct 26 21:09:36 1994
@@ -0,0 +1,128 @@
+#define MAX_PACK_LEN 66560  /* 65535 + sizeof ether_hdr + bit extra */
+
+#define ETHER_SIZE 14
+
+struct ether_hdr
+{
+  u_char dst_mac[6];
+  u_char src_mac[6];
+  u_char pkt_type[2];  /* 0x8137 */
+};
+
+struct ether_trail
+{
+  u_char length;
+  u_char *trailer;
+};
+
+/*
+ * IPX packet types - not to be trusted: use dst sock
+ */
+#define IPX_UNKNOWN   0x00
+#define IPX_RIP       0x01
+#define IPX_SAP       0x04
+#define IPX_SPX       0x05
+#define IPX_NCP       0x11
+#define IPX_NETBIOS   0x14
+
+/*
+ * IPX socket numbers - low address: high address always 0x04 for these
+ */
+#define IPX_S_NCP     0x51
+#define IPX_S_SAP     0x52
+#define IPX_S_RIP     0x53
+#define IPX_S_NETBIOS 0x55
+#define IPX_S_DIAG    0x56
+
+#define IPX_HDR_SIZE 30
+
+struct ipx_hdr
+{
+  u_char chk_sum[2];    /* always 0xffff */
+  u_char length[2];
+  u_char transport_ctl;
+  u_char pkt_type;
+  u_char dst_net[4];
+  u_char dst_node[6];
+  u_char dst_sock[2];
+  u_char src_net[4];
+  u_char src_node[6];
+  u_char src_sock[2];
+};
+
+/*
+ * IPX operations for RIP and SAP - high address always 0
+ */
+#define IPX_REQ    1
+#define IPX_RESP   2
+#define IPX_REQ_NEAR 3
+#define IPX_RESP_NEAR 4
+
+struct rip_ent
+{
+  u_char net_num[4];
+  u_char num_hops[2];
+  u_char num_ticks[2];
+};
+
+struct rip_pkt
+{
+  u_char op[2];
+  u_char num_ents;
+  struct rip_ent *net_ent;
+};
+
+struct sap_ent
+{
+  u_char serv_type[2];
+  u_char serv_name[48];
+  u_char net_num[4];
+  u_char net_node[6];
+  u_char net_sock[2];
+  u_char net_hops[2];
+};
+
+struct sap_pkt
+{
+  u_char op[2];
+  u_char num_ents;
+  struct sap_ent *serv_ent;
+};
+
+struct ipx_pkt
+{
+  u_char interface;
+  struct ether_hdr ipx_ether_hdr;
+  struct ipx_hdr  ipx_ipx_hdr;
+  union
+  {
+    struct sap_pkt ipx_sap;
+    struct rip_pkt ipx_rip;
+    char *ipx_other;
+  } packet;
+  struct ether_trail ipx_ether_trail;
+};
+
+struct route_entry
+{
+  u_char net_num[4];
+  u_char num_hops;
+  u_char num_ticks[2];
+  u_char interface;
+  u_char router[6];
+  u_char age;
+  struct route_entry *next;
+};
+
+struct server_entry
+{
+  u_char serv_type[2];
+  u_char serv_name[48];
+  u_char net_num[4];
+  u_char net_node[6];
+  u_char net_sock[2];
+  u_char num_hops;
+  u_char interface;
+  u_char age;
+  struct server_entry *next;
+};
diff -u --recursive --new-file dosemu0.53pl28/ipxbridge/ipxbridge-0.2/Makefile dosemu0.53pl29/ipxbridge/ipxbridge-0.2/Makefile
--- dosemu0.53pl28/ipxbridge/ipxbridge-0.2/Makefile
+++ dosemu0.53pl29/ipxbridge/ipxbridge-0.2/Makefile	Wed Oct 26 21:09:36 1994
@@ -0,0 +1,16 @@
+
+# Define ETH0_ETH1 if the two interfaces are eth0 and eth1. 
+# (Assumption is that they have 0 or 1 in  4th char position. 'eth' itself
+# is irrelevant.  In general, any two interfaces which differ in single
+# position can be used. Use CHANGED_POS to define that position.
+# Otherwise, define the two interfaces DEVICE0 and DEVICE1.
+
+ETHOPT=-DETH0_ETH1 -DCHANGED_POS=4
+#DEBUGOPT=-DDEBUG -DLDEBUG
+
+#DEVICE0=-DDEVICE0=\"eth0\"
+#DEVICE1=-DDEVICE1=\"eth1\"
+
+ipxbridge : ipxbridge.c Makefile
+	gcc -Wall -O2 ipxbridge.c -o ipxbridge $(ETHOPT) $(DEBUGOPT) $(DEVICE0) $(DEVICE1) 
+
Binary files dosemu0.53pl28/ipxbridge/ipxbridge-0.2/ipxbridge and dosemu0.53pl29/ipxbridge/ipxbridge-0.2/ipxbridge differ
diff -u --recursive --new-file dosemu0.53pl28/ipxbridge/ipxbridge-0.2/ipxbridge.c dosemu0.53pl29/ipxbridge/ipxbridge-0.2/ipxbridge.c
--- dosemu0.53pl28/ipxbridge/ipxbridge-0.2/ipxbridge.c
+++ dosemu0.53pl29/ipxbridge/ipxbridge-0.2/ipxbridge.c	Wed Oct 26 21:09:36 1994
@@ -0,0 +1,375 @@
+#include <stdio.h>
+#include <string.h>
+#include <malloc.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <linux/if.h>
+#include <linux/if_ether.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <signal.h>
+
+
+#if !defined(ETH0_ETH1) && !defined(DEVICE0) && !defined(DEVICE1)
+#define ETH0_ETH1 
+#define DEVICE0		"eth0"
+#define DEVICE1		"eth1"
+#define  CHANGED_POS        3
+#endif
+
+#ifndef   DEVICE0 
+#define  DEVICE0		"eth0"
+#endif
+#ifndef   DEVICE1 
+#define  DEVICE1		"eth1"
+#endif
+
+#ifdef ETH0_ETH1
+#ifndef   CHANGED_POS 
+#define   CHANGED_POS 3 
+#endif
+#endif
+
+
+unsigned short len_device0, len_device1;
+
+#define MAX_PACK_LEN   20000  /* Sufficient for ethernet packets. */
+#define ETHER_SIZE     14
+struct ether_hdr
+{
+  u_char dst_mac[6];
+  u_char src_mac[6];
+  u_char pkt_type[2];  
+};
+
+#define	max(i,j)	(((i)>(j)) ? (i) : (j))
+
+int promisc_mode(char *, int);
+void close_all(int);
+
+union {
+  u_char full_packet[MAX_PACK_LEN];
+  struct ether_hdr ether_header;
+  struct eth_address_index  {
+       char da, db, dc, dd;   /* Destination address */
+       unsigned short int di;  /* size of short int = 4. */
+       char sa, sb, sc, sd;   /* Source address */
+       unsigned short int si;  /* size of short int = 4. */
+  } index;
+} a ;
+
+union {
+     unsigned short int i;
+     u_char b[2];      /* If i=0xab12, b[0]=12 and b[1]=ab. */
+} src_index, dst_index;
+
+int new_len;
+int max_fd, fd, fd1, fd2, fd3, fd4;
+
+/* Hash table:  Ethernet address is aa:bb:cc:dd:ee:ff. 
+
+   Hash table is of 64K. So each byte of it can be addressed by 16-bit
+   number.  However, we address using only 15 bits, with last bit 
+   set to zero. So an addressible  "block" would be of 2 bytes.
+   We however store the interface no. and 5 bytes of the ethernet address
+   in 6 bytes. (It could be written over by next address in sequence, but
+   we guarantee that if there is a match between 5 bytes, then 6th one
+   will be proper interface.)
+   Given ethernet address of aa:bb:cc:dd:ee:ff, We can use any two
+   bytes for hashing. Requirement: Most random but pairs of them shouldn't
+   occur.  Usually ee:ff are most random since people buy cards in bulk
+   from same manufacturer. Further, we use index= ff * 256 + ee and
+   shift left it by 1. i.e. ee gets shifted left. 
+   So addresses of the form ee:ff,(ee+1):ff , (ee+2):ff destroy each
+   others' ethernet addresses.  
+
+   But this memory should not be swapped out any time! This can be ensured
+   by setting 't' bit using chmod. (I think). 
+
+   After every n seconds of time, it should set all elements of hash table 
+   to zero so as to dynamically "learn" . 
+
+   Broadcast address: LSB of 2nd byte of destination should equal 1.
+   First 3 bytes are meant to identify manufacturer ID.
+
+*/
+u_char hash_table[ (unsigned short int)0xFFFF ] ;  /* Can't we avoid it? */
+  /* Assumption: Linux initialises all variables to zero ... 
+     We don't want to calloc. Helps the compiler to optimise.
+   */
+
+void main(int argc, char *argv[])
+{
+fd_set fdset;
+struct sockaddr from, to;
+int len, from_len;
+unsigned char from_device_ch, to_device_ch;
+
+#ifdef ETH0_ETH1
+static unsigned char ascii_set[256];
+#endif
+
+	/* Set the exception handling */
+	signal(SIGINT, close_all);
+	signal(SIGKILL, close_all);
+
+
+        len_device0=strlen(DEVICE0);
+        len_device1=strlen(DEVICE1);
+
+#ifdef ETH0_ETH1
+        ascii_set[ (u_char)DEVICE1[CHANGED_POS] ] = DEVICE0[CHANGED_POS]; 
+        ascii_set[ (u_char)DEVICE0[CHANGED_POS] ] = DEVICE1[CHANGED_POS]; 
+#endif
+        fprintf(stderr,"Opening sockets ...\n");
+	/* Open a Socket for reading *all* IPX packets */
+	fd1 = socket(AF_INET, SOCK_PACKET, htons(ETH_P_IPX));
+	if(fd1 < 0) {
+		fprintf(stderr, "Error in opening generic packet socket.\n");
+		exit(0);
+	}
+	fd2 = socket(AF_INET, SOCK_PACKET, htons(ETH_P_802_3));
+	if(fd2 < 0) {
+		fprintf(stderr, "Error in opening generic packet socket.\n");
+		exit(0);
+	}
+	fd3 = socket(AF_INET, SOCK_PACKET, htons(ETH_P_802_2));
+	if(fd3 < 0) {
+		fprintf(stderr, "Error in opening generic packet socket.\n");
+		exit(0);
+	}
+	fd4 = socket(AF_INET, SOCK_PACKET, htons(ETH_P_SNAP));
+	if(fd4 < 0) {
+		fprintf(stderr, "Error in opening generic packet socket.\n");
+		exit(0);
+	}
+
+        fprintf(stderr,"Setting promiscuos mode ...\n");
+	if(promisc_mode(DEVICE0, 1) < 0) {
+		fprintf(stderr, "Can't set device 1 to promiscuous mode.\n");
+		exit(0);
+	}
+
+	if(promisc_mode(DEVICE1, 1) < 0) {
+		fprintf(stderr, "Can't set device 1 to promiscuous mode.\n");
+		exit(0);
+	}
+
+        fprintf(stderr,"Setting hash memory to all zero ...\n");
+        memset(hash_table, '\0', 0xffff ); 
+
+	max_fd = max(fd1, fd2);
+	max_fd = max(fd3, max_fd);
+	max_fd = max(fd4, max_fd) + 1;
+
+	from.sa_family = AF_INET;  
+	to.sa_family = AF_INET;  
+
+#ifdef ETH0_ETH1
+        strcpy(from.sa_data , DEVICE0) ;  
+        strcpy(to.sa_data , DEVICE1) ; 
+        /* This is Required because we only change particular characters 
+           from these array variables. 
+        */
+#endif
+        fprintf(stderr, "Now running as daemon.\n");
+	if(fork() != 0) exit(0); 
+
+	for(;;) {
+		FD_ZERO(&fdset);
+		FD_SET(fd1, &fdset);
+		FD_SET(fd2, &fdset);
+		FD_SET(fd3, &fdset);
+		FD_SET(fd4, &fdset);
+
+		select(max_fd, &fdset, (fd_set *)NULL, (fd_set *)NULL, 
+				(struct timeval *)NULL);
+		
+		if(FD_ISSET(fd1, &fdset) == 1) fd = fd1;
+		else if(FD_ISSET(fd2, &fdset) == 1) fd = fd2;
+		else if(FD_ISSET(fd3, &fdset) == 1) fd = fd3;
+		else if(FD_ISSET(fd4, &fdset) == 1) fd = fd4;
+		else { 
+                       fprintf(stderr, "*** Unknown fd in select ***\n");
+                       continue;
+                }
+
+		len = recvfrom(fd, a.full_packet, MAX_PACK_LEN, 0, &from, &from_len);
+		if(len <= 0) continue;
+
+
+#ifdef ETH0_ETH1
+                from_device_ch = from.sa_data[ CHANGED_POS ];
+#else
+                from_device_ch = 
+                      (memcmp(&from.sa_data[0], DEVICE0, len_device0))? '1':'0';
+#endif
+
+                /* check if it is broadcast packet. */
+                if (  (a.index.db & 0x01) == 0x01 )
+                     to_device_ch=0;
+                else {
+                     /* No it is not broadcast. Get the destination interface 
+                        from the hash tables. Use the destination address to 
+                        index the hash table */ 
+
+                     dst_index.i = a.index.di;  
+                           /* Last two bytes are in this variable now. */
+                     dst_index.b[0] <<= 1; /* Shift left LSB by 1 bit. */  
+
+                     /* This may be invalid if next text fails! ... */
+                     to_device_ch = hash_table[ dst_index.i ];
+                }
+#ifdef LDEBUG
+                fprintf(stderr,"From=%c  To:%c \n", from_device_ch, to_device_ch );
+#endif
+                /* Determine if it can be filtered. */ 
+                /* Long int is 4 bytes. This statement should compare first 4
+                   bytes of destination ethernet address with the same of
+                   entry in hash table. -- followed by  comparing the last 
+                   byte of destination address  
+                   If the to_device doesn't match, no need to go further
+                   in the test! Or else, compare 5 bytes ...
+                */ 
+                if (    (from_device_ch == to_device_ch)  
+                     && !memcmp(&hash_table[ dst_index.i + 1 ], &a.ether_header.dst_mac[0], 5)) 
+                { 
+#ifdef LDEBUG
+                        fprintf(stderr,"filtered\n");
+#endif
+                        continue;
+                }
+
+                /* if it comes here, it couldn't be filtered.
+                   So choose the other interface. */  
+#ifdef ETH0_ETH1
+                to.sa_data[CHANGED_POS] = ascii_set[ from_device_ch ];
+#else
+                strcpy(to.sa_data, (from_device_ch=='0')? DEVICE1: DEVICE0 );
+#endif                
+	        if(sendto(fd, a.full_packet, len, 0, &to, sizeof(to)) < 0) 
+		          perror("sendto");
+
+                /*=============Insert source address in hash table=========*/
+
+                /* Use last two bytes of source address to index the hash 
+                   table and store its interface in hash table. */
+                src_index.i = a.index.si;  
+
+                /* i[0]=5th_byte=b[0], i[1]=6th_byte=b[1] of ethernet address. 
+                   0th byte of integer is its LSB 8 bits. 
+                   So index= 6th_byte * 256 + 5th_byte.
+                */
+
+                src_index.b[0] <<= 1; /* Shift left LSB byte by 1 bit. */  
+
+                /* Check if it is already in hash table. For this do only
+                   single char compare of 0th byte, which gives the interface. 
+                   If this byte is 0 (null), it is empty location. If some
+                   other address has occupied it from other interface, overwrite
+                   it.
+                */
+                if( hash_table[ src_index.i ] == '\0' )
+                {  
+                     memcpy( &hash_table[ src_index.i + 1 ], &a.ether_header.src_mac[0], 5);
+                     /* Moved first 5 bytes of source ethernet address into hash 
+                        table. 6th byte was used 'as is' to access the hash table,
+                        so it neednot be stored.
+                      */
+                      /* Next, move the interface number into 0'th position. 
+                         We use ascii '0' or '1' if the names don't differ
+                         in same position. 
+                      */
+                      hash_table[ src_index.i ] = from_device_ch;
+                }  
+	} /* for loop. */
+}
+
+
+int promisc_mode(char *device, int flag)
+{
+struct ifreq if_data;
+
+	strcpy(if_data.ifr_name, device);
+	if(ioctl(fd1, SIOCGIFFLAGS, &if_data) < 0) {
+		fprintf(stderr, "Cannot get the flags for %s\n", device);
+		return -1;
+	}
+
+	if(flag) {
+		if_data.ifr_flags |= IFF_PROMISC;
+	}
+	else {
+		if_data.ifr_flags &= IFF_PROMISC;
+		if_data.ifr_flags ^= IFF_PROMISC;
+	}
+
+	if(ioctl(fd1, SIOCSIFFLAGS, &if_data) < 0) {
+		fprintf(stderr, "Cannot set promiscous mode for %s\n", device);
+		return -1;
+	}
+
+	return 1;
+}
+
+#ifdef DEBUG
+void debug(void)
+{
+int set;
+int ipx_len;
+u_char *pkt_type;
+unsigned int type, frame_type;
+u_char *ptr;
+               /* This is a long DEBUG code to see if particular packets are getting
+                          accepted. */
+		pkt_type = a.ether_header->pkt_type;
+		type = pkt_type[0] << 8 | pkt_type[1];
+
+		ptr = (u_char *) (a.full_packet + ETHER_SIZE); 
+		/* Here we check the frame type and get the IPX related packets */
+		if(type >= 1536) frame_type = type;
+		else {
+			if(ptr[0] == 0xFF && ptr[1] == 0xFF) frame_type = ETH_P_802_3;
+			if(ptr[0] == 0xAA && ptr[1] == 0xAA) frame_type = ETH_P_SNAP;
+			else frame_type = ETH_P_802_2;
+		}
+		ipx_len = ptr[2] << 8 | ptr[3];
+		set = 0;
+		switch(frame_type) {
+			case ETH_P_IPX :
+				fprintf(stderr, "Got IPX over DIX packet\n"); 
+				set = 1;
+				break;
+			case ETH_P_802_2 :
+				fprintf(stderr, "Got Bluebook packet\n"); 
+				set = 1;
+				break;
+			case ETH_P_802_3 :
+				fprintf(stderr, "Got IPX over DIX\n"); 
+				set = 1;
+				break;
+			case ETH_P_SNAP :
+				fprintf(stderr, "Got Etherenet II SNAP\n"); 
+				set = 1;
+				break;
+			default :
+				break;
+		}
+		if(! set) continue;
+		fprintf(stderr, "device = %s, ether_len = %.4x, ipx_len = %.4x, type = %.4x\n", 
+				from.sa_data, len, ipx_len, type);
+
+    /* That was a long DEBUG code to see if particular packets are getting
+       accepted. */
+}
+#endif
+
+void close_all(int a)
+{
+	close(fd1);
+	close(fd2);
+}
diff -u --recursive --new-file dosemu0.53pl28/ipxbridge/ipxbridge-0.2/test.c dosemu0.53pl29/ipxbridge/ipxbridge-0.2/test.c
--- dosemu0.53pl28/ipxbridge/ipxbridge-0.2/test.c
+++ dosemu0.53pl29/ipxbridge/ipxbridge-0.2/test.c	Wed Oct 26 21:09:36 1994
@@ -0,0 +1,20 @@
+
+main()
+{
+  unsigned char a=1;
+  long long int b=10;
+  char c='0';
+  printf ("Size of short int=%d, longint=%d , char=%d\n", sizeof(a), sizeof(b), sizeof(c) );
+  printf ("0=%x\n",c); 
+  a=1;
+  a= a + 0xff; 
+  printf ("a = %d\n", a);
+  a=a + 0xff; 
+  printf ("a = %d\n", a);
+  a=a + 0xff; 
+  printf ("a = %d\n", a);
+  a=a + 0xff; 
+  printf ("a = %d\n", a);
+  a=a + 0xff; 
+  printf ("a = %d\n", a);
+}
diff -u --recursive --new-file dosemu0.53pl28/mfs.c dosemu0.53pl29/mfs.c
--- dosemu0.53pl28/mfs.c	Wed Oct 19 22:28:18 1994
+++ dosemu0.53pl29/mfs.c	Tue Nov  1 23:02:57 1994
@@ -1534,22 +1534,9 @@
      DIR *dir;
 {
   struct direct *ret;
-  sigset_t newmask, oldmask;
 
-#if DOSEMU
-  sigfillset(&newmask);
+  ret = (struct direct *)RPT_SYSCALL(readdir(dir));
 
-  /* temporarily block our alarms so NFS reads don't choke */
-  sigprocmask(SIG_SETMASK, &newmask, &oldmask);
-#endif
-
-  ret = readdir(dir);
-
-#if DOSEMU
-  /* restore the blocked alarm */
-  sigprocmask(SIG_SETMASK, &oldmask, NULL);
-#endif
-
   return (ret);
 }
 
@@ -1560,24 +1547,13 @@
      int cnt;
 {
   int ret;
-  sigset_t newmask, oldmask;
 
   if (cnt <= 0)
     return (0);
 
-#if DOSEMU
-  sigfillset(&newmask);
-
-  /* temporarily block our alarms so NFS reads don't choke */
-  sigprocmask(SIG_SETMASK, &newmask, &oldmask);
-#endif
-
-  ret = read(fd, data, cnt);
-
-#if DOSEMU
-  /* restore the blocked alarm */
-  sigprocmask(SIG_SETMASK, &oldmask, NULL);
-#endif
+  Debug0((dbg_fd, "About to do it!\n"));
+  ret = RPT_SYSCALL(read(fd, data, cnt));
+  Debug0((dbg_fd, "After doing it!\n"));
 
   return (ret);
 }
@@ -1594,22 +1570,10 @@
   if (cnt <= 0)
     return (0);
 
-#if DOSEMU
-  sigfillset(&newmask);
-
-  /* temporarily block our alarms so NFS reads don't choke */
-  sigprocmask(SIG_SETMASK, &newmask, &oldmask);
-#endif
-
-  ret = write(fd, data, cnt);
+  ret = RPT_SYSCALL(write(fd, data, cnt));
 
   Debug0((dbg_fd, "Wrote %10.10s\n", data));
 
-#if DOSEMU
-  /* restore the blocked alarm */
-  sigprocmask(SIG_SETMASK, &oldmask, NULL);
-#endif
-
   return (ret);
 }
 
@@ -2736,6 +2700,7 @@
       Debug0((dbg_fd, "Actual pos %d\n",
 	      itisnow));
       ret = dos_read(fd, dta, cnt);
+
       Debug0((dbg_fd, "Read returned : %d\n",
 	      ret));
       if (ret < 0) {
@@ -3013,6 +2978,9 @@
     else if (mode == READ_WRITE_ACC) {
       mode = O_RDWR;
     }
+    else if (mode == 0x40) {
+      mode = O_RDWR;
+    }
     else {
       Debug0((dbg_fd, "Illegal access_mode 0x%x\n", mode));
       mode = O_RDONLY;
@@ -3030,7 +2998,7 @@
 	return (FALSE);
       }
     }
-    else if ((fd = open(fpath, mode)) < 0) {
+    else if ((fd = open(fpath, mode )) < 0) {
       Debug0((dbg_fd, "access denied:'%s'\n", fpath));
       SETWORD(&(state->eax), ACCESS_DENIED);
       return (FALSE);
diff -u --recursive --new-file dosemu0.53pl28/mouse/Makefile dosemu0.53pl29/mouse/Makefile
--- dosemu0.53pl28/mouse/Makefile	Wed Oct 19 22:28:22 1994
+++ dosemu0.53pl29/mouse/Makefile	Tue Nov  1 23:03:02 1994
@@ -14,7 +14,7 @@
 
 # let gcc do extended checking
 
-CFLAGS=-O2 -Wall # -Wmissing-prototypes \
+# CFLAGS=-O2 -Wall # -Wmissing-prototypes \
 #       -Wstrict-prototypes -ansi -pedantic 
 
 # The following define enables the ClearDTR-Support at mouse-initialisation.
@@ -38,11 +38,17 @@
 
 .c.o:
 	$(CC) $(CFLAGS) $(XDEFS) $(INCDIR) -c $<
+
+SUBDIR=mouse
  
-all: ../$(SUBDIR).o
+LIB=../lib$(SUBDIR).a
+
+all:  $(LIB)
 
-../$(SUBDIR).o: $(OBJS)
-	$(LD) -r -o ../$(SUBDIR).o $(OBJS)
+$(LIB): $(OBJS)
+	-rm $@
+	$(AR) cr $@ $^
+	ranlib $@
 
 checkin:
 	-ci $(ALL) Makefile
diff -u --recursive --new-file dosemu0.53pl28/net/Makefile dosemu0.53pl29/net/Makefile
--- dosemu0.53pl28/net/Makefile	Wed Oct 19 22:28:30 1994
+++ dosemu0.53pl29/net/Makefile	Tue Nov  1 23:03:12 1994
@@ -19,26 +19,30 @@
 
 # ANSI isn't possible right now, because some header-file aren't ANSI
 
-CFILES = ipx.c ipxglt.c libpacket.c pktnew.c
+CFILES = ipx.c ipxglt.c libpacket.c pktnew.c inifile.c
 HFILES =       libpacket.h pktdrvr.h
 
 # Insert all source- and header-files here.
 
 ALL = $(CFILES) $(HFILES) libpacket.c.multi libpacket.c.single \
-	pktnew.c.multi pktnew.c.single
+	pktnew.c.multi pktnew.c.single README
 
 # All object-files are included here.
 
-OBJS = ipx.o ipxglt.o libpacket.o pktnew.o
+OBJS = ipx.o ipxglt.o libpacket.o pktnew.o inifile.o
 
 .c.o:
 	$(CC) $(CFLAGS) $(INCDIR) -c $<
- 
-all: ../$(SUBDIR).o
 
-../$(SUBDIR).o: $(OBJS)
-	$(LD) -r -o ../$(SUBDIR).o $(OBJS)
+LIB=../lib$(SUBDIR).a
 
+all:  $(LIB)
+
+$(LIB): $(OBJS)
+	-rm $@
+	$(AR) cr $@ $^
+	ranlib $@
+
 checkin:
 	echo $(ALL)
 	-ci $(ALL) Makefile
@@ -47,7 +51,7 @@
 	-co -l $(ALL) Makefile
 
 clean:
-	rm -f *.o ../$(SUBDIR).o
+	rm -f *.o ../lib$(SUBDIR).a
 
 realclean: clean
 	rm -f .depend
diff -u --recursive --new-file dosemu0.53pl28/net/README dosemu0.53pl29/net/README
--- dosemu0.53pl28/net/README
+++ dosemu0.53pl29/net/README	Tue Nov  1 23:03:12 1994
@@ -0,0 +1,36 @@
+
+-- Added support for multiple type handling. 
+   So it does type demultiplexing within dosemu.
+
+   So we are able to run telbin and pdipx/netx  simultaneously ;-)
+
+-- Changed the code for F_DRIVER_INFO. If the handle is '0', it need not
+   be valid handle (when input to this function).  At least CUTCP simply
+   set this value to zero when it requests for info for the first
+   time. The current code wrongly treated it as valid handle, and
+   returned the class of first registered type.
+
+-- Some things still to be done ...
+    -- Novell Hack is currently diabled. 
+    -- Compare class along with type when a new packet arrives.
+    -- Lots of clean ups required. (I have put in lots of pd_printf's.)
+       Need to be removed even if debug is not used because function
+       call within packet handler is very costly ...
+    -- change all 'dsn0' / 'dosnet' to vnet (i.e. virtual net.) or so. 
+and 
+    -- Use of SIGIO ...
+    -- Special protocol stack to do demultiplexing of types??
+    -- Use of devices instead of the current mechanism of implementing
+       v-net?
+
+NOTE: THERE ARE STILL BUGS.  The dosemu session just hangs. -- 
+      Usually when in CUTCP. (And specially when I open two sessions.)
+      What is strange is, it seems to work fine for some time even when two
+      sessions are opened. 
+      I strongly feel  it is due to new PIC code because it is used
+      heavily by the network code ... (especially in interactive telnet
+      sessions.)
+
+Vinod
+vinod@cse.iitb.ernet.in
+
diff -u --recursive --new-file dosemu0.53pl28/net/inifile.c dosemu0.53pl29/net/inifile.c
--- dosemu0.53pl28/net/inifile.c
+++ dosemu0.53pl29/net/inifile.c	Tue Nov  1 23:03:12 1994
@@ -0,0 +1,205 @@
+/* inifile.c */
+
+/* Routines to modify INI files */
+/* by David V. Mortenson */
+
+#include <stdio.h>
+#include <stdlib.h>
+#if 0
+#define __USE_GNU
+#define __USE_SVID
+#endif
+#include <string.h>
+#include <ctype.h>
+
+#define FALSE  0
+#define TRUE   1
+
+#if 0
+extern void GetValueFromIniFile (char *, char *, char *, char *);
+extern void GetValueFromIniFilePath (char *, char *, char *, char *);
+extern void SetValueInIniFile (char *, char *, char *, char *);
+#else
+#include "inifile.h"
+#endif
+
+/****************************************
+ * An ini file should have the extension .INI, and is formatted
+ * with sections and value strings.  The following is a sample
+ * .INI file with 2 sections, each with 1 variable/value string:
+ * 
+ *      [test]
+ *      teststring=Hello World
+ *      [sample]
+ *      value=on
+ *
+ * The use of the functions to retrieve the string values and
+ * set them in the INI file should be apparent.  If an error
+ * occurs, then the value string for the requested section and
+ * variable will return with a length of 0.  Possible errors
+ * include:
+ *      1) file not found
+ *      2) section not found (only for "get" operation)
+ *      3) variable not found (only for "get" operation)
+ *
+ * GetValueFromIniFilePath is the same as GetValueFromIniFile, except
+ * that the file paramter can hold a colon delimited path of locations
+ * to look for the section and variable.  Each one is searched in turn.
+ * This mechanism could be used to allow per-user variables to override
+ * system defaults, for example.
+ ****************************************/
+
+/**********************************************************************DVM***/
+void GetValueFromIniFile (char *file, char *section, char *variable, 
+               char *value)
+{
+   FILE *srcFile;
+   char line [512];
+   char *cptr;
+
+   strcpy (value, "");
+
+   srcFile = fopen (file, "rt");
+
+   cptr = fgets (line, 512, srcFile);
+
+   while (cptr)
+   {
+      /* Is this the requested section? */
+      if (  line[0] == '['  &&  
+            !strncasecmp (&line[1], section, strlen(section))  &&
+            line [strlen(section)+1] == ']'  )
+      {
+         cptr = fgets (line, 512, srcFile);
+         while (cptr)
+         {
+            /* Is this the requested variable? */
+            if (  !strncasecmp (line, variable, strlen (variable))  &&
+                  line [strlen(variable)] == '='  )
+            {
+               strcpy (value, &line[strlen(variable)+1]);
+               if (value[strlen(value)-1] == '\n')
+                  value[strlen(value)-1] = '\0';
+               fclose (srcFile);
+               return;
+            }
+
+            /* Have we entered a new section? */
+            if (line[0] == '[')
+            {
+               break;
+            }
+
+            cptr = fgets (line, 512, srcFile);
+         }
+      }
+      else
+      {
+         cptr = fgets (line, 512, srcFile);
+      }
+   }
+
+   fclose (srcFile);
+}
+
+/**********************************************************************TRB***/
+void GetValueFromIniFilePath (char *file, char *section, char *variable, 
+               char *value)
+{
+        char *filePtr, *lastPtr;
+	int done = FALSE;
+	char *fileString;
+
+			 
+	fileString = (char *)strdup( file );
+	lastPtr = file;        
+	filePtr = strtok( fileString, ":;" );
+	while( filePtr && !done ) {
+		GetValueFromIniFile( filePtr, section, variable, value );
+		if( strlen( value ) ) {
+			done = TRUE;
+		}
+		lastPtr = filePtr;
+		filePtr = strtok( NULL, ":;" );
+	}
+	free( fileString );
+}
+
+	       
+
+/**********************************************************************DVM***/
+void SetValueInIniFile (char *file, char* section, char* variable, 
+               char *value)
+{
+   char oldFile [250];
+   FILE *srcFile, *destFile;
+   char line [512];
+   char *cptr;
+   int operationComplete = FALSE;
+
+   /* Setup The File Path */
+
+   sprintf (oldFile, "%s%s", file, ".bak");
+
+   /* Open The Files */
+
+   remove (oldFile);
+   rename (file, oldFile);
+   srcFile = fopen (oldFile, "rt");
+   destFile = fopen (file, "wt");
+
+   cptr = fgets (line, 512, srcFile);
+   while (cptr)
+   {
+      /* Is this the requested section? */
+      if (  line[0] == '['  &&  
+            !strncasecmp (&line[1], section, strlen(section))  &&
+            line [strlen(section)+1] == ']'  )
+      {
+         fprintf (destFile, "%s", line);
+
+         cptr = fgets (line, 512, srcFile);
+         while (cptr)
+         {
+            /* Is this the requested variable? */
+            if (  !strncasecmp (line, variable, strlen (variable))  &&
+                  line [strlen(variable)] == '='  )
+            {
+               if (!operationComplete)
+                  fprintf (destFile, "%s=%s\n", variable, value);
+               operationComplete = TRUE;
+            }
+            /* Is this a new Section? */
+            else if (line[0] == '[')
+            {
+               if (!operationComplete)
+               {
+                  fprintf (destFile, "%s=%s\n", variable, value);
+                  operationComplete = TRUE;
+               }
+               break;
+            }
+            else
+            {
+               fprintf (destFile, "%s", line);
+            }
+
+            cptr = fgets (line, 512, srcFile);
+         }
+      }
+      else
+      {
+         fprintf (destFile, "%s", line);
+         cptr = fgets (line, 512, srcFile);
+      }
+   }
+
+   if (!operationComplete)
+   {
+      fprintf (destFile, "[%s]\n", section);
+      fprintf (destFile, "%s=%s\n", variable, value);
+   }
+
+   fclose (srcFile);
+   fclose (destFile);
+}
diff -u --recursive --new-file dosemu0.53pl28/net/pktnew.c dosemu0.53pl29/net/pktnew.c
--- dosemu0.53pl28/net/pktnew.c	Wed Oct 19 22:28:30 1994
+++ dosemu0.53pl29/net/pktnew.c	Tue Nov  1 23:03:12 1994
@@ -40,11 +40,21 @@
 
 
 
-void Add_broadcast_rcv_handle(void);
+void Open_sockets(void);
 
+int  pkt_fd=-1, pkt_broadcast_fd=-1, max_pkt_fd;
+
 /* global data which is put at PKTDRV_SEG:PKTDRV_OFF */
 /* (not everything needs to be accessible from DOS space, but it is */
 /* often convenient to be able to look at it with DEBUG...) */
+#define MAX_PKT_TYPE_SIZE 10
+struct pkt_type {
+  int handle, no_of_chars;
+  char pkt_type[MAX_PKT_TYPE_SIZE];
+  int count;                           /* To sort the array based on counts of packet type. */
+} pkt_type_array[MAX_HANDLE]; 
+int max_pkt_type_array=0;
+
 
 struct pkt_globs
 {
@@ -60,8 +70,6 @@
     short size;				/* current packet's size */
     long receiver;			/* current receive handler */
     int helpvec;			/* vector number for helper */
-    int nfds;				/* number of fd's for select() */
-    fd_set sockset;			/* set of sockets for select() */
     unsigned char helper[72];		/* upcall helper */
 
     struct per_handle
@@ -70,7 +78,6 @@
 	char class;			/* class it was access_type'd with */
 	short packet_type_len;		/* length of packet type */
 	int flags;			/* per-packet-type flags */
-	int sock;			/* fd for the socket */
 	long receiver;			/* receive handler */
 	char packet_type[16];		/* packet type for this handle */
     } handle[MAX_HANDLE];          
@@ -114,8 +121,8 @@
 
     strcpy(pg->driver_name,"Linux$");
     DosnetGetDeviceHardwareAddress(devname,pg->hw_address);
-    pg->classes[0] = ETHER_CLASS;
-    pg->classes[1] = IEEE_CLASS;
+    pg->classes[0] = ETHER_CLASS;  /* == 1. */
+    pg->classes[1] = IEEE_CLASS;   /* == 11. */
     pg->type = 12;			/* dummy type (3c503) */
     pg->flags = config.pktflags;	/* global config flags */
 
@@ -127,7 +134,7 @@
     pg->param.rcv_bufs = 8 - 1;		/* a guess */
     pg->param.xmt_bufs = 2 - 1;
 
-    Add_broadcast_rcv_handle();   /* VINOD: Added to receive broadcasts
+    Open_sockets();   /* VINOD: Added to receive all packets 
                                      from dosnet device. These packets 
                                      are of special type and are reconverted
                                      into broadcast packets proper after being
@@ -192,6 +199,7 @@
 
 {
     struct per_handle *hdlp;
+    int hdlp_handle=-1;
 
 #if 0
     pd_printf("NPKT: AX=%04x BX=%04x CX=%04x DX=%04x FLAGS=%08x\n",
@@ -205,10 +213,16 @@
 
     NOCARRY;
 
-    /* when BX seems like a valid handle, set the handle info pointer */
+    /* when BX seems like a valid handle, set the handle info pointer.
+       Actually, BX could be  zero in some "default cases". For e.g.
+       if it is zero when getting the driver info, we can't say if it is
+       the "real" handle or general default value.
+     */
 
-    if (LWORD(ebx) < MAX_HANDLE)
+    if ((LWORD(ebx) > 0) && (LWORD(ebx) < MAX_HANDLE)) {
 	hdlp = &pg->handle[LWORD(ebx)];
+        hdlp_handle=LWORD(ebx);
+    }
     else
 	hdlp = NULL;
 
@@ -217,9 +231,15 @@
     switch (HI(ax))
     {
     case F_DRIVER_INFO:
+        pd_printf("Driver info called ...\n");
 	REG(eax) = 2;				/* basic+extended functions */
 	REG(ebx) = 1;				/* version */
-	if (hdlp != NULL && hdlp->in_use)
+
+        /* If  hdlp_handle == 0,  it is not always a valid handle. 
+	   At least in case of CUTCP it sets it to zero for the first
+	   time.
+	*/
+	if (hdlp_handle !=0 && hdlp != NULL && hdlp->in_use)
 	    REG(ecx) = (hdlp->class << 8) + 1;	/* class, number */
 	else
 	    REG(ecx) = (pg->classes[0] << 8) + 1;
@@ -226,6 +246,8 @@
 	REG(edx) = pg->type;			/* type (dummy) */
 	REG(ds) = PKTDRV_SEG;			/* driver name */
 	REG(esi) = PKTDRV_OFF + offsetof(struct pkt_globs,driver_name);
+        pd_printf("Class returned = %d, handle=%d, pg->classes[0]=%d \n", 
+                         REG(ecx)>>8, hdlp_handle, pg->classes[0] );
 	return 1;
 
     case F_ACCESS_TYPE:
@@ -318,18 +340,7 @@
 		    }
 		}
 	    }
-
-	    hdlp->sock = DosnetOpenNetworkType(type); /* open the socket */
-
-	    if (hdlp->sock < 0) {
-		hdlp->in_use = 0;		/* forget about this handle */
-		HI(dx) = E_BAD_TYPE;
-		break;
-	    }
-
-	    FD_SET(hdlp->sock,&pg->sockset);	/* keep track of sockets */
-	    if (hdlp->sock >= pg->nfds)
-		pg->nfds = hdlp->sock + 1;
+            Insert_Type(free_handle, hdlp->packet_type_len, hdlp->packet_type);
 
 	    REG(eax) = free_handle;		/* return the handle */
 	}
@@ -341,18 +352,9 @@
 	    break;
 	}
 
-	if (hdlp->in_use) {
-	    int i,n;
-
-	    DosnetCloseNetworkLink(hdlp->sock);	/* close the socket */
-	    FD_CLR(hdlp->sock,&pg->sockset);	/* keep track of sockets */
-	    n = pg->nfds;
-	    pg->nfds = 0;
-
-	    for (i = 0; i < n; i++)
-		if (FD_ISSET(i,&pg->sockset))
-		    pg->nfds = i + 1;
+        Remove_Type(hdlp_handle);
 
+	if (hdlp->in_use) {
 	    hdlp->in_use = 0;			/* no longer in use */
 	}
 	return 1;
@@ -366,6 +368,7 @@
 	/* find a handle which is in use, and use its socket for the send */
 	{
 	    int handle;
+            char *p;
 
 	    for (handle = 0; handle < MAX_HANDLE; handle++) {
 		hdlp = &pg->handle[handle];
@@ -392,8 +395,12 @@
 			    p[1] = (char)len;
 			}
 		    }
+                    /* Now we have to write to network. We need
+                       to check if it is broadcast, and if so, use the
+                       corresponding socket. */
+		    p = SEG_ADR((char *),ds,si);
 
-		    if (DosnetWriteToNetwork(hdlp->sock,devname,
+		    if (DosnetWriteToNetwork( pkt_fd, devname,
 				SEG_ADR((char *),ds,si),LWORD(ecx)) >= 0)
 		    {
 			/* send was okay, check for a reply to speedup */
@@ -402,7 +409,7 @@
 			return 1;
 		    } else {
 			warn("NPKT: DosnetWriteToNetwork(%d,\"%s\",buffer,%u): error %d\n",
-			    hdlp->sock,devname,LWORD(ecx),errno);
+			    pkt_fd,devname,LWORD(ecx),errno);
 			break;
 		    }
 		}
@@ -481,13 +488,11 @@
     /* fell through switch, indicate an error (DH set above) */
     CARRY;
 
-#if 0
-    pd_printf("ERR:  AX=%04x BX=%04x CX=%04x DX=%04x FLAGS=%08x\n",
+    pd_printf("PD ERR:  AX=%04x BX=%04x CX=%04x DX=%04x FLAGS=%08x\n",
 		LWORD(eax),LWORD(ebx),LWORD(ecx),LWORD(edx),REG(eflags));
     pd_printf("      SI=%04x DI=%04x BP=%04x SP=%04x CS=%04x DS=%04x ES=%04x SS=%04x\n",
 		LWORD(esi),LWORD(edi),LWORD(ebp),LWORD(esp),
 		LWORD(cs),LWORD(ds),LWORD(es),LWORD(ss));
-#endif
 
     return 1;
 }
@@ -499,40 +504,58 @@
 */
 
 void
-Add_broadcast_rcv_handle(void)
+Open_sockets(void)
 {
-     int handle = 0;			/* search from 1st */
-     struct per_handle *hdlp;
-
-     for (; handle < MAX_HANDLE; handle++) {
-	hdlp = &pg->handle[handle];
-	if( hdlp->in_use = 0 ) 
-        {
-	    /* we found a free handle, and allocate it */
-	    hdlp = &pg->handle[handle];
-	    memset(hdlp,0,sizeof(struct per_handle));
-	    hdlp->in_use = 1;
-	    hdlp->class == ETHER_CLASS;
+    pkt_broadcast_fd = DosnetOpenBroadcastNetworkType(); /* open the socket */
+    pkt_fd = DosnetOpenNetworkType( (u_short)0 );
+    max_pkt_fd = pkt_fd + 1;
+    if ( max_pkt_fd <= pkt_broadcast_fd ) max_pkt_fd = pkt_broadcast_fd + 1; 
+}
 
-	    /* This packet type is just to provide some type. This field should
-	    not be used at all. */
-            hdlp->packet_type_len = 2;
-	    *(unsigned short int *)&(hdlp->packet_type[0])=htons(DOSNET_BROADCAST_TYPE);
-
-	    hdlp->sock = DosnetOpenBroadcastNetworkType(); /* open the socket */
-
-	    if (hdlp->sock < 0) {
-		hdlp->in_use = 0;		/* forget about this handle */
-                return ;
-	    }
+/*  Find_Handle does type demultiplexing. 
+    Given a packet, it compares the type fields and finds out which 
+    handle should take the given packet.
+    An array of types is maintained.
+*/
+int 
+Insert_Type(int handle, int no_of_chars, char *pkt_type)
+{
+  int i,nchars;
+  if(no_of_chars > MAX_PKT_TYPE_SIZE) return -1;
+  if (max_pkt_type_array >= MAX_HANDLE) return -1;
+
+  pd_printf("Trying to insert: handle %d, no_of_chars=%d \n ",handle, no_of_chars);
+
+  /* Find if the type or handle is already present ... */
+  for( i=0; i<max_pkt_type_array; i++)
+  {
+     nchars=pkt_type_array[i].no_of_chars;
+     if ( (pkt_type_array[i].handle == handle) ||
+          ((nchars > 1) && !memcmp(&pkt_type_array[i].pkt_type, pkt_type, nchars))
+        )
+        return  -1;
+  }
+  pkt_type_array[max_pkt_type_array].no_of_chars=no_of_chars;
+  pkt_type_array[max_pkt_type_array].handle=handle;
+  pkt_type_array[max_pkt_type_array].count=0;
+  memcpy(&pkt_type_array[max_pkt_type_array].pkt_type, pkt_type, no_of_chars);
+  for(i=0; i<no_of_chars; i++) pd_printf(" --%.2x--", pkt_type_array[max_pkt_type_array].pkt_type[i]);
+  pd_printf("\n");
+  pd_printf("Succeded: inserted at %d\n", max_pkt_type_array);
+  max_pkt_type_array++;
+}
 
-	    FD_SET(hdlp->sock,&pg->sockset);	/* keep track of sockets */
-	    if (hdlp->sock >= pg->nfds)
-		pg->nfds = hdlp->sock + 1;
-            return ;
-        }
-     } 
-     /* could not allocate, but ignore. */
+int
+Remove_Type(int handle)
+{ 
+  int i, shift_up;
+  shift_up=0;
+  for( i=0; i<max_pkt_type_array; i++)
+  {
+     if( shift_up )
+            pkt_type_array[i-1]=pkt_type_array[i];
+     else if (pkt_type_array[i].handle == handle) shift_up=1; 
+  }
 }
 
 
@@ -541,7 +564,7 @@
 int timeout;
 
 {
-    int size,handle;
+    int size,handle, fd;
     struct per_handle *hdlp;
     char *p;
     struct timeval tv;
@@ -551,53 +574,83 @@
     if (pg == NULL)				/* packet driver intialized? */
 	return -1;
 
-    if (pg->nfds == 0)				/* no active sockets? */
-	return 0;
-
     if (pg->size != 0)				/* transfer area busy? */
 	return 1;
 
     tv.tv_sec = 0;				/* set a (small) timeout */
     tv.tv_usec = timeout;
-    readset = pg->sockset;
-
-    if (select(pg->nfds,&readset,NULL,NULL,&tv) <= 0) /* anything ready? */
-	return 0;
-
-    for (handle = 0; handle < MAX_HANDLE; handle++) {
-	hdlp = &pg->handle[handle];
 
-	if (hdlp->in_use && FD_ISSET(hdlp->sock,&readset)) {
-	    /* somethine is available on this handle's socket */
-	    /* attempt to read it.  that should always succeed... */
+    FD_SET(pkt_fd, &readset);
+    FD_SET(pkt_broadcast_fd, &readset);
 
-	    size = DosnetReadFromNetwork(hdlp->sock,device,pg->buf,sizeof(pg->buf));
+    if (select(max_pkt_fd,&readset,NULL,NULL,&tv) <= 0) /* anything ready? */
+	return 0;
 
-	    /* check if something has been received */
-	    /* there was a check for "not multicast" here, but I think */
-	    /* it should not be there... */
+    if( FD_ISSET(pkt_fd, &readset) ) 
+           fd = pkt_fd;
+    else if( FD_ISSET(pkt_broadcast_fd, &readset) ) 
+           fd = pkt_broadcast_fd;
+    else return 0;
 
-	    if (size >= 0) {
-		/* verify the source of the packet.  when not from eth0, */
-		/* discard it for now (multiple network cards are next) */
+    size = DosnetReadFromNetwork(fd,device,pg->buf,sizeof(pg->buf));
+    if (size < 0) {
+		pg->stats.errors_in++;		/* select() somehow lied */
+                return 0;
+    }
+    if (strcmp(device,devname)) return 0; 
+   
+    pd_printf("========Processing New packet======\n");
+    /* if( (handle = Find_Handle(pg->buf))== -1) return 0; */
+    /* Code for Find_Handle.  */
+    {
+	  int i,nchars;
+	  struct ethhdr *eth ; 
+	  u_char *p;
+
+          eth=(struct ethhdr *) pg -> buf;
+	  /* find this packet's frame type, and hence position to compare the type. */
+	  if (ntohs(eth->h_proto) >= 1536)
+	       p = pg->buf + 2 * ETH_ALEN;		/* Ethernet-II */
+	  else 
+	       p = pg->buf + 2 * ETH_ALEN + 2;       /* All the rest frame types. */
+
+          pd_printf("Received packet type: %.2x\n", ntohs(eth->h_proto));
+
+          handle=-1;
+	  for( i=0; i<max_pkt_type_array; i++)
+	  {
+	     nchars= pkt_type_array[i].no_of_chars;
+	     if ( /* (nchars < 2)   ||                 */
+		  !memcmp(&pkt_type_array[i].pkt_type, p, nchars) )
+             {
+		  handle=pkt_type_array[i].handle;
+                  break; 
+             }
+	  }
+          pd_printf("Found handle=: %d\n", handle);
+	  if( handle==-1) return(-1);
+    }   
+    hdlp = &pg->handle[handle];
+    if (hdlp->in_use) {
 
-		if (strcmp(device,devname))
-		    continue;
+           printbuf("received packet:", pg->buf); 
 
-                printbuf("received packet:", pg->buf); 
                 /* VINOD: If it is broadcast type, translate it back ... */
-                if ( memcmp(pg->buf, DOSNET_BROADCAST_ADDRESS, 4) == 0 )
-                {    
-                     printbuf("received broadcast packet:", pg->buf); 
+           if ( memcmp(pg->buf, DOSNET_BROADCAST_ADDRESS, 4) == 0 )
+           {    
+                     pd_printf("It is broadcast packet.");
                      if(memcmp((pg->buf + ETH_ALEN), pg->hw_address, ETH_ALEN) == 0)
                      {
-                        pd_printf("It was for myself.\n"); 
-                        continue; /* Ignore our own ethernet broadcast. */
+                        pd_printf("It was my own packet! Ignored.\n"); 
+                        return; /* Ignore our own ethernet broadcast. */
                      }
                      memcpy(pg->buf, "\x0ff\x0ff\x0ff\x0ff\x0ff\x0ff", ETH_ALEN);
                      printbuf("Translated:", pg->buf); 
-                }
+           }
 
+           /* No need to check the type again. Also, for now, NOVELL_HACK
+              is diabled... */
+           if ( 0 ) {
 		/* check if the packet's type matches the specified type */
 		/* in the ACCESS_TYPE call.  the position depends on the */
 		/* driver class! */
@@ -610,31 +663,51 @@
 		if (size >= ((p - pg->buf) + hdlp->packet_type_len) &&
 		    !memcmp(p,hdlp->packet_type,hdlp->packet_type_len))
 		{
-		    pg->stats.packets_in++;
-		    pg->stats.bytes_in += size;
-
+                }
 		    if (hdlp->flags & N_OPTION) {	/* Novell hack? */
 			*--p = (char)ETH_P_IPX;	/* overwrite length with type */
 			*--p = (char)(ETH_P_IPX >> 8);
 		    }
+             }
+             pg->stats.packets_in++;
+	     pg->stats.bytes_in += size;
 
 		    /* stuff things in global vars and queue a hardware */
 		    /* interrupt which will perform the upcall */
-		    pg->size = size;
-		    pg->receiver = hdlp->receiver;
-#if 0
-		    do_hard_int(pg->helpvec);
+	     pg->size = size;
+	     pg->receiver = hdlp->receiver;
+#ifndef PIC
+	     do_hard_int(pg->helpvec);
 #else
-		    run_int(pg->helpvec);
+	     run_int(pg->helpvec);
 #endif
-		    return 1;
-		} else
-		    pg->stats.packets_lost++;	/* not really lost... */
-	    } else
-		pg->stats.errors_in++;		/* select() somehow lied */
-	}
-    }
-
+             pd_printf("Called the helpvector ... \n");
+	     return 1;
+    } else
+	     pg->stats.packets_lost++;	/* not really lost... */
+    pd_printf("Handle not in use. Ignored this packet.\n");
     return 0;
 }
 
+
+int
+Find_Handle(u_char *buf)
+{
+  int i,nchars;
+  struct ethhdr *eth = (struct ethhdr *) buf;
+  u_char *p;
+  /* find this packet's frame type, and hence position to compare the type. */
+  if (ntohs(eth->h_proto) >= 1536)
+       p = buf + 2 * ETH_ALEN;		/* Ethernet-II */
+  else 
+       p = buf + 2 * ETH_ALEN + 2;       /* All the rest frame types. */
+
+  for( i=0; i<max_pkt_type_array; i++)
+  {
+     nchars= pkt_type_array[i].no_of_chars;
+     if ( (nchars < 2)   ||                 
+          !memcmp(&pkt_type_array[i].pkt_type, p, nchars) )
+         return i;
+  }
+  return(-1);
+}
diff -u --recursive --new-file dosemu0.53pl28/net/pktnew.c.multi dosemu0.53pl29/net/pktnew.c.multi
--- dosemu0.53pl28/net/pktnew.c.multi	Wed Oct 19 22:28:30 1994
+++ dosemu0.53pl29/net/pktnew.c.multi	Tue Nov  1 23:03:12 1994
@@ -40,11 +40,21 @@
 
 
 
-void Add_broadcast_rcv_handle(void);
+void Open_sockets(void);
 
+int  pkt_fd=-1, pkt_broadcast_fd=-1, max_pkt_fd;
+
 /* global data which is put at PKTDRV_SEG:PKTDRV_OFF */
 /* (not everything needs to be accessible from DOS space, but it is */
 /* often convenient to be able to look at it with DEBUG...) */
+#define MAX_PKT_TYPE_SIZE 10
+struct pkt_type {
+  int handle, no_of_chars;
+  char pkt_type[MAX_PKT_TYPE_SIZE];
+  int count;                           /* To sort the array based on counts of packet type. */
+} pkt_type_array[MAX_HANDLE]; 
+int max_pkt_type_array=0;
+
 
 struct pkt_globs
 {
@@ -60,8 +70,6 @@
     short size;				/* current packet's size */
     long receiver;			/* current receive handler */
     int helpvec;			/* vector number for helper */
-    int nfds;				/* number of fd's for select() */
-    fd_set sockset;			/* set of sockets for select() */
     unsigned char helper[72];		/* upcall helper */
 
     struct per_handle
@@ -70,7 +78,6 @@
 	char class;			/* class it was access_type'd with */
 	short packet_type_len;		/* length of packet type */
 	int flags;			/* per-packet-type flags */
-	int sock;			/* fd for the socket */
 	long receiver;			/* receive handler */
 	char packet_type[16];		/* packet type for this handle */
     } handle[MAX_HANDLE];          
@@ -114,8 +121,8 @@
 
     strcpy(pg->driver_name,"Linux$");
     DosnetGetDeviceHardwareAddress(devname,pg->hw_address);
-    pg->classes[0] = ETHER_CLASS;
-    pg->classes[1] = IEEE_CLASS;
+    pg->classes[0] = ETHER_CLASS;  /* == 1. */
+    pg->classes[1] = IEEE_CLASS;   /* == 11. */
     pg->type = 12;			/* dummy type (3c503) */
     pg->flags = config.pktflags;	/* global config flags */
 
@@ -127,7 +134,7 @@
     pg->param.rcv_bufs = 8 - 1;		/* a guess */
     pg->param.xmt_bufs = 2 - 1;
 
-    Add_broadcast_rcv_handle();   /* VINOD: Added to receive broadcasts
+    Open_sockets();   /* VINOD: Added to receive all packets 
                                      from dosnet device. These packets 
                                      are of special type and are reconverted
                                      into broadcast packets proper after being
@@ -192,6 +199,7 @@
 
 {
     struct per_handle *hdlp;
+    int hdlp_handle=-1;
 
 #if 0
     pd_printf("NPKT: AX=%04x BX=%04x CX=%04x DX=%04x FLAGS=%08x\n",
@@ -205,10 +213,16 @@
 
     NOCARRY;
 
-    /* when BX seems like a valid handle, set the handle info pointer */
+    /* when BX seems like a valid handle, set the handle info pointer.
+       Actually, BX could be  zero in some "default cases". For e.g.
+       if it is zero when getting the driver info, we can't say if it is
+       the "real" handle or general default value.
+     */
 
-    if (LWORD(ebx) < MAX_HANDLE)
+    if ((LWORD(ebx) > 0) && (LWORD(ebx) < MAX_HANDLE)) {
 	hdlp = &pg->handle[LWORD(ebx)];
+        hdlp_handle=LWORD(ebx);
+    }
     else
 	hdlp = NULL;
 
@@ -217,9 +231,15 @@
     switch (HI(ax))
     {
     case F_DRIVER_INFO:
+        pd_printf("Driver info called ...\n");
 	REG(eax) = 2;				/* basic+extended functions */
 	REG(ebx) = 1;				/* version */
-	if (hdlp != NULL && hdlp->in_use)
+
+        /* If  hdlp_handle == 0,  it is not always a valid handle. 
+	   At least in case of CUTCP it sets it to zero for the first
+	   time.
+	*/
+	if (hdlp_handle !=0 && hdlp != NULL && hdlp->in_use)
 	    REG(ecx) = (hdlp->class << 8) + 1;	/* class, number */
 	else
 	    REG(ecx) = (pg->classes[0] << 8) + 1;
@@ -226,6 +246,8 @@
 	REG(edx) = pg->type;			/* type (dummy) */
 	REG(ds) = PKTDRV_SEG;			/* driver name */
 	REG(esi) = PKTDRV_OFF + offsetof(struct pkt_globs,driver_name);
+        pd_printf("Class returned = %d, handle=%d, pg->classes[0]=%d \n", 
+                         REG(ecx)>>8, hdlp_handle, pg->classes[0] );
 	return 1;
 
     case F_ACCESS_TYPE:
@@ -318,18 +340,7 @@
 		    }
 		}
 	    }
-
-	    hdlp->sock = DosnetOpenNetworkType(type); /* open the socket */
-
-	    if (hdlp->sock < 0) {
-		hdlp->in_use = 0;		/* forget about this handle */
-		HI(dx) = E_BAD_TYPE;
-		break;
-	    }
-
-	    FD_SET(hdlp->sock,&pg->sockset);	/* keep track of sockets */
-	    if (hdlp->sock >= pg->nfds)
-		pg->nfds = hdlp->sock + 1;
+            Insert_Type(free_handle, hdlp->packet_type_len, hdlp->packet_type);
 
 	    REG(eax) = free_handle;		/* return the handle */
 	}
@@ -341,18 +352,9 @@
 	    break;
 	}
 
-	if (hdlp->in_use) {
-	    int i,n;
-
-	    DosnetCloseNetworkLink(hdlp->sock);	/* close the socket */
-	    FD_CLR(hdlp->sock,&pg->sockset);	/* keep track of sockets */
-	    n = pg->nfds;
-	    pg->nfds = 0;
-
-	    for (i = 0; i < n; i++)
-		if (FD_ISSET(i,&pg->sockset))
-		    pg->nfds = i + 1;
+        Remove_Type(hdlp_handle);
 
+	if (hdlp->in_use) {
 	    hdlp->in_use = 0;			/* no longer in use */
 	}
 	return 1;
@@ -366,6 +368,7 @@
 	/* find a handle which is in use, and use its socket for the send */
 	{
 	    int handle;
+            char *p;
 
 	    for (handle = 0; handle < MAX_HANDLE; handle++) {
 		hdlp = &pg->handle[handle];
@@ -392,8 +395,12 @@
 			    p[1] = (char)len;
 			}
 		    }
+                    /* Now we have to write to network. We need
+                       to check if it is broadcast, and if so, use the
+                       corresponding socket. */
+		    p = SEG_ADR((char *),ds,si);
 
-		    if (DosnetWriteToNetwork(hdlp->sock,devname,
+		    if (DosnetWriteToNetwork( pkt_fd, devname,
 				SEG_ADR((char *),ds,si),LWORD(ecx)) >= 0)
 		    {
 			/* send was okay, check for a reply to speedup */
@@ -402,7 +409,7 @@
 			return 1;
 		    } else {
 			warn("NPKT: DosnetWriteToNetwork(%d,\"%s\",buffer,%u): error %d\n",
-			    hdlp->sock,devname,LWORD(ecx),errno);
+			    pkt_fd,devname,LWORD(ecx),errno);
 			break;
 		    }
 		}
@@ -481,13 +488,11 @@
     /* fell through switch, indicate an error (DH set above) */
     CARRY;
 
-#if 0
-    pd_printf("ERR:  AX=%04x BX=%04x CX=%04x DX=%04x FLAGS=%08x\n",
+    pd_printf("PD ERR:  AX=%04x BX=%04x CX=%04x DX=%04x FLAGS=%08x\n",
 		LWORD(eax),LWORD(ebx),LWORD(ecx),LWORD(edx),REG(eflags));
     pd_printf("      SI=%04x DI=%04x BP=%04x SP=%04x CS=%04x DS=%04x ES=%04x SS=%04x\n",
 		LWORD(esi),LWORD(edi),LWORD(ebp),LWORD(esp),
 		LWORD(cs),LWORD(ds),LWORD(es),LWORD(ss));
-#endif
 
     return 1;
 }
@@ -499,40 +504,58 @@
 */
 
 void
-Add_broadcast_rcv_handle(void)
+Open_sockets(void)
 {
-     int handle = 0;			/* search from 1st */
-     struct per_handle *hdlp;
-
-     for (; handle < MAX_HANDLE; handle++) {
-	hdlp = &pg->handle[handle];
-	if( hdlp->in_use = 0 ) 
-        {
-	    /* we found a free handle, and allocate it */
-	    hdlp = &pg->handle[handle];
-	    memset(hdlp,0,sizeof(struct per_handle));
-	    hdlp->in_use = 1;
-	    hdlp->class == ETHER_CLASS;
+    pkt_broadcast_fd = DosnetOpenBroadcastNetworkType(); /* open the socket */
+    pkt_fd = DosnetOpenNetworkType( (u_short)0 );
+    max_pkt_fd = pkt_fd + 1;
+    if ( max_pkt_fd <= pkt_broadcast_fd ) max_pkt_fd = pkt_broadcast_fd + 1; 
+}
 
-	    /* This packet type is just to provide some type. This field should
-	    not be used at all. */
-            hdlp->packet_type_len = 2;
-	    *(unsigned short int *)&(hdlp->packet_type[0])=htons(DOSNET_BROADCAST_TYPE);
-
-	    hdlp->sock = DosnetOpenBroadcastNetworkType(); /* open the socket */
-
-	    if (hdlp->sock < 0) {
-		hdlp->in_use = 0;		/* forget about this handle */
-                return ;
-	    }
+/*  Find_Handle does type demultiplexing. 
+    Given a packet, it compares the type fields and finds out which 
+    handle should take the given packet.
+    An array of types is maintained.
+*/
+int 
+Insert_Type(int handle, int no_of_chars, char *pkt_type)
+{
+  int i,nchars;
+  if(no_of_chars > MAX_PKT_TYPE_SIZE) return -1;
+  if (max_pkt_type_array >= MAX_HANDLE) return -1;
+
+  pd_printf("Trying to insert: handle %d, no_of_chars=%d \n ",handle, no_of_chars);
+
+  /* Find if the type or handle is already present ... */
+  for( i=0; i<max_pkt_type_array; i++)
+  {
+     nchars=pkt_type_array[i].no_of_chars;
+     if ( (pkt_type_array[i].handle == handle) ||
+          ((nchars > 1) && !memcmp(&pkt_type_array[i].pkt_type, pkt_type, nchars))
+        )
+        return  -1;
+  }
+  pkt_type_array[max_pkt_type_array].no_of_chars=no_of_chars;
+  pkt_type_array[max_pkt_type_array].handle=handle;
+  pkt_type_array[max_pkt_type_array].count=0;
+  memcpy(&pkt_type_array[max_pkt_type_array].pkt_type, pkt_type, no_of_chars);
+  for(i=0; i<no_of_chars; i++) pd_printf(" --%.2x--", pkt_type_array[max_pkt_type_array].pkt_type[i]);
+  pd_printf("\n");
+  pd_printf("Succeded: inserted at %d\n", max_pkt_type_array);
+  max_pkt_type_array++;
+}
 
-	    FD_SET(hdlp->sock,&pg->sockset);	/* keep track of sockets */
-	    if (hdlp->sock >= pg->nfds)
-		pg->nfds = hdlp->sock + 1;
-            return ;
-        }
-     } 
-     /* could not allocate, but ignore. */
+int
+Remove_Type(int handle)
+{ 
+  int i, shift_up;
+  shift_up=0;
+  for( i=0; i<max_pkt_type_array; i++)
+  {
+     if( shift_up )
+            pkt_type_array[i-1]=pkt_type_array[i];
+     else if (pkt_type_array[i].handle == handle) shift_up=1; 
+  }
 }
 
 
@@ -541,7 +564,7 @@
 int timeout;
 
 {
-    int size,handle;
+    int size,handle, fd;
     struct per_handle *hdlp;
     char *p;
     struct timeval tv;
@@ -551,53 +574,83 @@
     if (pg == NULL)				/* packet driver intialized? */
 	return -1;
 
-    if (pg->nfds == 0)				/* no active sockets? */
-	return 0;
-
     if (pg->size != 0)				/* transfer area busy? */
 	return 1;
 
     tv.tv_sec = 0;				/* set a (small) timeout */
     tv.tv_usec = timeout;
-    readset = pg->sockset;
-
-    if (select(pg->nfds,&readset,NULL,NULL,&tv) <= 0) /* anything ready? */
-	return 0;
-
-    for (handle = 0; handle < MAX_HANDLE; handle++) {
-	hdlp = &pg->handle[handle];
 
-	if (hdlp->in_use && FD_ISSET(hdlp->sock,&readset)) {
-	    /* somethine is available on this handle's socket */
-	    /* attempt to read it.  that should always succeed... */
+    FD_SET(pkt_fd, &readset);
+    FD_SET(pkt_broadcast_fd, &readset);
 
-	    size = DosnetReadFromNetwork(hdlp->sock,device,pg->buf,sizeof(pg->buf));
+    if (select(max_pkt_fd,&readset,NULL,NULL,&tv) <= 0) /* anything ready? */
+	return 0;
 
-	    /* check if something has been received */
-	    /* there was a check for "not multicast" here, but I think */
-	    /* it should not be there... */
+    if( FD_ISSET(pkt_fd, &readset) ) 
+           fd = pkt_fd;
+    else if( FD_ISSET(pkt_broadcast_fd, &readset) ) 
+           fd = pkt_broadcast_fd;
+    else return 0;
 
-	    if (size >= 0) {
-		/* verify the source of the packet.  when not from eth0, */
-		/* discard it for now (multiple network cards are next) */
+    size = DosnetReadFromNetwork(fd,device,pg->buf,sizeof(pg->buf));
+    if (size < 0) {
+		pg->stats.errors_in++;		/* select() somehow lied */
+                return 0;
+    }
+    if (strcmp(device,devname)) return 0; 
+   
+    pd_printf("========Processing New packet======\n");
+    /* if( (handle = Find_Handle(pg->buf))== -1) return 0; */
+    /* Code for Find_Handle.  */
+    {
+	  int i,nchars;
+	  struct ethhdr *eth ; 
+	  u_char *p;
+
+          eth=(struct ethhdr *) pg -> buf;
+	  /* find this packet's frame type, and hence position to compare the type. */
+	  if (ntohs(eth->h_proto) >= 1536)
+	       p = pg->buf + 2 * ETH_ALEN;		/* Ethernet-II */
+	  else 
+	       p = pg->buf + 2 * ETH_ALEN + 2;       /* All the rest frame types. */
+
+          pd_printf("Received packet type: %.2x\n", ntohs(eth->h_proto));
+
+          handle=-1;
+	  for( i=0; i<max_pkt_type_array; i++)
+	  {
+	     nchars= pkt_type_array[i].no_of_chars;
+	     if ( /* (nchars < 2)   ||                 */
+		  !memcmp(&pkt_type_array[i].pkt_type, p, nchars) )
+             {
+		  handle=pkt_type_array[i].handle;
+                  break; 
+             }
+	  }
+          pd_printf("Found handle=: %d\n", handle);
+	  if( handle==-1) return(-1);
+    }   
+    hdlp = &pg->handle[handle];
+    if (hdlp->in_use) {
 
-		if (strcmp(device,devname))
-		    continue;
+           printbuf("received packet:", pg->buf); 
 
-                printbuf("received packet:", pg->buf); 
                 /* VINOD: If it is broadcast type, translate it back ... */
-                if ( memcmp(pg->buf, DOSNET_BROADCAST_ADDRESS, 4) == 0 )
-                {    
-                     printbuf("received broadcast packet:", pg->buf); 
+           if ( memcmp(pg->buf, DOSNET_BROADCAST_ADDRESS, 4) == 0 )
+           {    
+                     pd_printf("It is broadcast packet.");
                      if(memcmp((pg->buf + ETH_ALEN), pg->hw_address, ETH_ALEN) == 0)
                      {
-                        pd_printf("It was for myself.\n"); 
-                        continue; /* Ignore our own ethernet broadcast. */
+                        pd_printf("It was my own packet! Ignored.\n"); 
+                        return; /* Ignore our own ethernet broadcast. */
                      }
                      memcpy(pg->buf, "\x0ff\x0ff\x0ff\x0ff\x0ff\x0ff", ETH_ALEN);
                      printbuf("Translated:", pg->buf); 
-                }
+           }
 
+           /* No need to check the type again. Also, for now, NOVELL_HACK
+              is diabled... */
+           if ( 0 ) {
 		/* check if the packet's type matches the specified type */
 		/* in the ACCESS_TYPE call.  the position depends on the */
 		/* driver class! */
@@ -610,31 +663,51 @@
 		if (size >= ((p - pg->buf) + hdlp->packet_type_len) &&
 		    !memcmp(p,hdlp->packet_type,hdlp->packet_type_len))
 		{
-		    pg->stats.packets_in++;
-		    pg->stats.bytes_in += size;
-
+                }
 		    if (hdlp->flags & N_OPTION) {	/* Novell hack? */
 			*--p = (char)ETH_P_IPX;	/* overwrite length with type */
 			*--p = (char)(ETH_P_IPX >> 8);
 		    }
+             }
+             pg->stats.packets_in++;
+	     pg->stats.bytes_in += size;
 
 		    /* stuff things in global vars and queue a hardware */
 		    /* interrupt which will perform the upcall */
-		    pg->size = size;
-		    pg->receiver = hdlp->receiver;
+	     pg->size = size;
+	     pg->receiver = hdlp->receiver;
 #ifndef PIC
-		    do_hard_int(pg->helpvec);
+	     do_hard_int(pg->helpvec);
 #else
-		    run_int(pg->helpvec);
+	     run_int(pg->helpvec);
 #endif
-		    return 1;
-		} else
-		    pg->stats.packets_lost++;	/* not really lost... */
-	    } else
-		pg->stats.errors_in++;		/* select() somehow lied */
-	}
-    }
-
+             pd_printf("Called the helpvector ... \n");
+	     return 1;
+    } else
+	     pg->stats.packets_lost++;	/* not really lost... */
+    pd_printf("Handle not in use. Ignored this packet.\n");
     return 0;
 }
 
+
+int
+Find_Handle(u_char *buf)
+{
+  int i,nchars;
+  struct ethhdr *eth = (struct ethhdr *) buf;
+  u_char *p;
+  /* find this packet's frame type, and hence position to compare the type. */
+  if (ntohs(eth->h_proto) >= 1536)
+       p = buf + 2 * ETH_ALEN;		/* Ethernet-II */
+  else 
+       p = buf + 2 * ETH_ALEN + 2;       /* All the rest frame types. */
+
+  for( i=0; i<max_pkt_type_array; i++)
+  {
+     nchars= pkt_type_array[i].no_of_chars;
+     if ( (nchars < 2)   ||                 
+          !memcmp(&pkt_type_array[i].pkt_type, p, nchars) )
+         return i;
+  }
+  return(-1);
+}
diff -u --recursive --new-file dosemu0.53pl28/ports.h dosemu0.53pl29/ports.h
--- dosemu0.53pl28/ports.h	Wed Oct 19 22:28:19 1994
+++ dosemu0.53pl29/ports.h	Tue Nov  1 23:02:57 1994
@@ -105,8 +105,8 @@
  * 0 means disabled.
  * 1 means record all port accesses to 0x00 to 0xFF
  * 2 means record ANY port accesses!  (big fat debugfile!)
-#define PORT_DEBUG 0
  */ 
+#define PORT_DEBUG 0
 
 /* int port61 = 0xd0;           the pseudo-8255 device on AT's */
 int port61 = 0x0e;		/* the pseudo-8255 device on AT's */
@@ -281,20 +281,13 @@
 
   static unsigned int cga_r = 0;
   static unsigned int tmp = 0;
-  static unsigned int r = 0;
-
-#ifdef PORT_DEBUG
-#if PORT_DEBUG == 1
-  if (port < 0x100)
-#endif
-    fprintf(stderr,"PORT: Rd 0x%04x\n",port);
-#endif
+  static unsigned int r;
 
+  r = 0;
   port &= 0xffff;
   if (port_readable(port))
-    return (read_port(port) & 0xFF);
- 
-  if (config.usesX) {
+    r = (read_port(port) & 0xFF);
+  else if (config.usesX) {
     v_printf("HGC Portread: %d\n", (int) port);
     switch (port) {
     case 0x03b8:		/* mode-reg */
@@ -325,78 +318,85 @@
       set_ioperm(port, 1, 0);
       break;
     }
-    return r;
   }
-
 #if 1
-  if (config.chipset && port > 0x3b3 && port < 0x3df && config.mapped_bios)
-    return (video_port_in(port));
-  if ((config.chipset == S3) && ((port & 0x03fe) == s3_8514_base) && (port & 0xfc00)) {
-    int _v;
-
+  else if (config.chipset && port > 0x3b3 && port < 0x3df && config.mapped_bios)
+    r = (video_port_in(port));
+  else if ((config.chipset == S3) && ((port & 0x03fe) == s3_8514_base) && (port & 0xfc00)) {
     iopl(3);
-    _v = port_in(port) & 0xff;
+    r = port_in(port) & 0xff;
     iopl(0);
-    v_printf("S3 inb [0x%04x] = 0x%02x\n", port, _v);
-    return _v;
+    v_printf("S3 inb [0x%04x] = 0x%02x\n", port, r);
   }
 #endif
-
-  switch (port) {
+  else switch (port) {
 #ifdef NEW_PIC
   case 0x20:
   case 0x21:
-     return read_pic0(port-0x20);
+    r = read_pic0(port-0x20);
+    break;
   case 0xa0:
   case 0xa1:
-     return read_pic1(port-0xa0);
+    r = read_pic1(port-0xa0);
+    break; 
 #endif
   case 0x60:
-    if (keys_ready)
-      microsoft_port_check = 0;
+    if (keys_ready) microsoft_port_check = 0;
     k_printf("direct 8042 read1: 0x%02x microsoft=%d\n", *LASTSCAN_ADD, microsoft_port_check);
     if (microsoft_port_check)
-      return microsoft_port_check;
+      r = microsoft_port_check;
     else
-      return *LASTSCAN_ADD;
+      r = *LASTSCAN_ADD;
+    break;
 
   case 0x61:
-    k_printf("inb [0x61] =  0x%02x (8255 chip)\n", port61);
-    return port61;
+    k_printf("inb [0x61] = 0x%02x (8255 chip)\n", port61);
+    r = port61;
+    break;
 
   case 0x64:
-    tmp = 0x1c | (keys_ready || microsoft_port_check ? 1 : 0);	/* low bit set = sc ready */
+    r = 0x1c | (keys_ready || microsoft_port_check ? 1 : 0);	/* low bit set = sc ready */
     k_printf("direct 8042 0x64 status check: 0x%02x keys_ready=%d, microsoft=%d\n", tmp, keys_ready, microsoft_port_check);
-    return tmp;
+    break;
 
   case 0x70:
   case 0x71:
-    return cmos_read(port);
+    r = cmos_read(port);
+    break;
 
 #define COUNTER 2
+#if 1 /*Oct-21-94*/
+  case 0x40:
+    r = do_40(1, 0);
+    break;
+  case 0x41:
+    r = do_40(1, 0);
+    break;
+#else
   case 0x40:
-	return(do_40(1, 0));
     pit.CNTR0 -= COUNTER;
-    i_printf("inb [0x40] = 0x%02x  1st timer inb\n",
-	     pit.CNTR0);
-    return pit.CNTR0;
+    i_printf("inb [0x40] = 0x%02x  1st timer inb\n", pit.CNTR0);
+    r = pit.CNTR0;
+    break;
   case 0x41:
-	return(do_40(1, 0));
     pit.CNTR1 -= COUNTER;
-    i_printf("inb [0x41] = 0x%02x  2nd timer inb\n",
-	     pit.CNTR1);
-    return pit.CNTR1;
+    i_printf("inb [0x41] = 0x%02x  2nd timer inb\n", pit.CNTR1);
+    r = pit.CNTR1;
+    break;
+#endif
   case 0x42:
 #if 0
-	return(do_42(1, 0));
+    r = do_42(1, 0);
+    break;
 #else
     pit.CNTR2 -= COUNTER;
-    i_printf("inb [0x42] = 0x%02x  3rd timer inb\n",
-	     pit.CNTR2);
-    return pit.CNTR2;
+    i_printf("inb [0x42] = 0x%02x  3rd timer inb\n", pit.CNTR2);
+    r = pit.CNTR2;
+    break;
 #endif
   case 0x43:
-	return(do_43(1, 0));
+    r = do_43(1, 0);
+    break;
 
   case 0x3ba:
   case 0x3da:
@@ -403,31 +403,45 @@
     /* graphic status - many programs will use this port to sync with
      * the vert & horz retrace so as not to cause CGA snow */
     i_printf("3ba/3da port inb\n");
-    return (cga_r ^= 1) ? 0xcf : 0xc6;
+    r = (cga_r ^= 1) ? 0xcf : 0xc6;
+    break;
+
   case 0x3bc:
-    i_printf("printer port inb [0x3bc] = 0\n");
-    return 0;
-  case 0x3db:			/* light pen strobe reset */
-    return 0;
+    i_printf("printer port inb [0x3bc] = 0\n");    /* 0 by default */
+    break;
 
+  case 0x3db:			/* light pen strobe reset, 0 by default */
+    break;
+    
   default:
     /* SERIAL PORT I/O.  The base serial port must be a multiple of 8. */
     for (tmp = 0; tmp < config.num_ser; tmp++)
-      if ((port & ~7) == com[tmp].base_port)
-	return (do_serial_in(tmp, port));
+      if ((port & ~7) == com[tmp].base_port) {
+	r = do_serial_in(tmp, port);
+	break;
+      }
 
     /* The diamond bug */
     if (config.chipset == DIAMOND && (port >= 0x23c0) && (port <= 0x23cf)) {
       iopl(3);
-      tmp = port_in(port);
+      r = port_in(port);
       iopl(0);
-      i_printf(" Diamond inb [0x%x] = 0x%x\n", port, tmp);
-      return (tmp);
+      i_printf(" Diamond inb [0x%x] = 0x%x\n", port, r);
+      break;
     }
-    i_printf("default inb [0x%x] = 0x%02x\n", port,0x00);
-    return 0x00;
+    r = 0;
+    i_printf("default inb [0x%x] = 0x%02x\n", port, r);
   }
-  return 0;
+
+/* Now record the port and the read value to debugfile if needed */
+#if PORT_DEBUG > 0
+#if PORT_DEBUG == 1
+  if (port < 0x100)
+#endif
+    fprintf(stderr,"PORT: Rd 0x%04x -> 0x%02x\n",port,r);
+#endif
+
+  return r;    /* Return with port read value */
 }
 
 inline int
@@ -455,7 +469,7 @@
   port &= 0xffff;
   byte &= 0xff;
 
-#ifdef PORT_DEBUG
+#if PORT_DEBUG > 0
 #if PORT_DEBUG == 1
   if (port < 0x100)
 #endif
@@ -596,9 +610,9 @@
 #if 1				/* 94/05/11 */
     *OUTB_ADD = 1;
 #endif
-#endif  /* NEW_PIC */
     if (port == 0x20 && byte != 0x20)
       set_leds();
+#endif  /* NEW_PIC */
     break;
   case 0x60:
     k_printf("keyboard 0x60 outb = 0x%x\n", byte);
diff -u --recursive --new-file dosemu0.53pl28/sig/Makefile dosemu0.53pl29/sig/Makefile
--- dosemu0.53pl28/sig/Makefile	Wed Oct 19 22:28:35 1994
+++ dosemu0.53pl29/sig/Makefile	Tue Nov  1 23:03:18 1994
@@ -43,7 +43,7 @@
  
 all: sillyint.o
 
-sillyint.o:    int.c  $(LINUX_INCLUDE)/../tools/version.h
+sillyint.o:    int.c  # $(LINUX_INCLUDE)/../tools/version.h
 	$(CC) -Wall -I$(LINUX_INCLUDE) -DMAKE_LOADABLE_MODULE int.c -c -O6 -D__KERNEL__ -DLINUX -o sillyint.o
 
 checkin:
diff -u --recursive --new-file dosemu0.53pl28/termio.c dosemu0.53pl29/termio.c
--- dosemu0.53pl28/termio.c	Wed Oct 19 22:28:18 1994
+++ dosemu0.53pl29/termio.c	Tue Nov  1 23:02:56 1994
@@ -663,7 +663,7 @@
   struct stat chkbuf;
   int major, minor;
 
-  if (!config.X && !config.usesX) {
+  if (!config.X) {
      if (config.usesX) {
 	kbd_fd = dup(keypipe);
      }
@@ -679,9 +679,13 @@
      old_kbd_flags = fcntl(kbd_fd, F_GETFL);
      fcntl(kbd_fd, F_SETFL, O_RDONLY | O_NONBLOCK);
      
-     if (use_sigio)
-	k_printf("KBD: Using SIGIO\n");
-     add_to_io_select(kbd_fd, 1);
+     if (use_sigio && !config.kbd_tty) {
+       k_printf("KBD: Using SIGIO\n");
+       add_to_io_select(kbd_fd, 1);
+     } else {
+       k_printf("KBD: Not using SIGIO\n");
+       add_to_io_select(kbd_fd, 0);
+     }
 
      fstat(kbd_fd, &chkbuf);
      major = chkbuf.st_rdev >> 8;
diff -u --recursive --new-file dosemu0.53pl28/timer/Makefile dosemu0.53pl29/timer/Makefile
--- dosemu0.53pl28/timer/Makefile	Wed Oct 19 22:28:29 1994
+++ dosemu0.53pl29/timer/Makefile	Tue Nov  1 23:03:10 1994
@@ -5,15 +5,15 @@
 
 # The following variables may go into the Makfile in the parent-directory
 
-CC   = gcc
-LD   = ld
+# CC   = gcc
+# LD   = ld
 
 # INCDIR is exported from ..
-#INCDIR= -I../include -I..
+INCDIR= -I../include -I..
 
 # let gcc do extended checking
 
-CFLAGS=-O2 # -Wall # -Wmissing-prototypes \
+# CFLAGS=-O2 # -Wall # -Wmissing-prototypes \
 #       -Wstrict-prototypes # -ansi -pedantic 
 
 # ANSI isn't possible right now, because some header-file aren't ANSI
@@ -27,15 +27,21 @@
 
 # All object-files are included here.
 
-OBJS = pic.o
-
 .c.o:
 	$(CC) $(CFLAGS) $(INCDIR) -c $<
- 
-all: ../timer.o
+
+SUBDIR=timer
+
+OBJS = pic.o
+
+LIB=../lib$(SUBDIR).a
+
+all:  $(LIB)
 
-../timer.o: $(OBJS)
-	ld -r -o ../timer.o $(OBJS)
+$(LIB): $(OBJS)
+	-rm $@
+	$(AR) cr $@ $^
+	ranlib $@
 
 checkin:
 	-ci $(ALL) Makefile README.pic
@@ -44,7 +50,7 @@
 	-co -l $(ALL) Makefile README.pic
 
 clean:
-	rm -f *.o ../timer.o
+	rm -f *.o ../lib$(SUBDIR).o
 
 realclean: clean
 	rm -f .depend
@@ -52,8 +58,8 @@
 install:
 
 dist: $(ALL) Makefile
-	install -d $(DISTPATH)/timer
-	install -m 0644 $(ALL) Makefile README.pic $(DISTPATH)/timer
+	install -d $(DISTPATH)/$(SUBDIR)
+	install -m 0644 $(ALL) Makefile README.pic $(DISTPATH)/$(SUBDIR)
 
 depend dep: $(CFILES) $(HFILES)
 	$(CPP) -MM $(CFLAGS) *.c $(INCDIR) > .depend
diff -u --recursive --new-file dosemu0.53pl28/timer/pic.c dosemu0.53pl29/timer/pic.c
--- dosemu0.53pl28/timer/pic.c	Wed Oct 19 22:28:29 1994
+++ dosemu0.53pl29/timer/pic.c	Tue Nov  1 23:03:10 1994
@@ -1,6 +1,6 @@
 /*  DANG_BEGIN_MODULE
  *
- *  pic.c is a fairly complete emulation of both 8259 Priority Interrupt 
+ *  pic.c is a fairly co,plete emulation of both 8259 Priority Interrupt 
  *  Controllers.  It also includes provision for 16 lower level interrupts.
  *  This implementation supports the following i/o commands:
  *
@@ -450,7 +450,7 @@
 int inum;
 {
  if (pic_iinfo[inum].func == (void *)0) return; 
- if(pic_isr&&(1<<inum) || inum==pic_ilevel)  pic_pirr|=(1<<inum);
+ if(pic_isr&(1<<inum) || inum==pic_ilevel)  pic_pirr|=(1<<inum);
  else pic_irr|=(1<<inum);
  return;
 }
diff -u --recursive --new-file dosemu0.53pl28/v-net/Makefile dosemu0.53pl29/v-net/Makefile
--- dosemu0.53pl28/v-net/Makefile	Wed Oct 19 22:28:36 1994
+++ dosemu0.53pl29/v-net/Makefile	Tue Nov  1 23:03:18 1994
@@ -9,7 +9,7 @@
 endif
 
 CFILES = dosnet.c
-HFILES = 
+HFILES = dosnet.h
 
 # Insert all source- and header-files here.
 
@@ -19,14 +19,12 @@
 
 OBJS = dosnet.o
 
-all: $(OBJS) ipxbridge
+all: $(OBJS)
 
-.c.o:
-	$(CC) $(INCDIR) -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -c -o dosnet.o $<
+dosnet.o:  dosnet.c
+	$(CC) $(INCDIR) -D__KERNEL__ -Wall -Wstrict-prototypes -O6 \
+	-fomit-frame-pointer  -m486 -c -o dosnet.o dosnet.c 
 
-ipxbridge:
-	(cd ipxbridge0.1; $(CC) -o ../ipxbridge ipxbridge.c)
- 
 checkin:
 	-ci $(ALL) Makefile
 
@@ -34,9 +32,9 @@
 	-co -l $(ALL) Makefile
 
 clean:
-	rm -f *.o ipxbridge
+	rm -f *.o 
 
-realclean:
+realclean: clean
 	rm -f .depend
 
 install:
@@ -44,12 +42,6 @@
 dist: $(ALL) Makefile
 	install -d $(DISTPATH)/v-net
 	install -m 0644 $(ALL) Makefile $(DISTPATH)/v-net
-	(cd ipxbridge0.1; \
-	install -d $(DISTPATH)/v-net/ipxbridge0.1; \
-	install -m 0644 ipxbridge.c a.h $(DISTPATH)/v-net/ipxbridge0.1)
-	(cd ipxbridge0.2 ; \
-	install -d $(DISTPATH)/v-net/ipxbridge0.2 ; \
-	install -m 0644 ipxbridge.c $(DISTPATH)/v-net/ipxbridge0.2)
 
 depend dep: $(CFILES) $(HFILES)
 	$(CPP) -MM $(CFLAGS) $(CFILES) $(INCDIR) > .depend
diff -u --recursive --new-file dosemu0.53pl28/v-net/dosnet.README dosemu0.53pl29/v-net/dosnet.README
--- dosemu0.53pl28/v-net/dosnet.README	Wed Oct 19 22:28:36 1994
+++ dosemu0.53pl29/v-net/dosnet.README	Tue Nov  1 23:03:18 1994
@@ -63,6 +63,10 @@
             (both versions are alpha codes.)
             Actually IPX routing code is there in kernel.  Has anyone been 
             successful in using this?
+	    Yet another alternative is to use IPTunnelling of IPX
+	    packets (rfc 1234). Novell has NLMs for this on the netware
+	    side. On linux, we should run a daemon implementing this
+	    rfc.
 
   Virtual device 'dsn0': 
        Compile the module dosnet and insmod it, and give it an IP
@@ -70,9 +74,15 @@
        proper routing tables on all machines you want to connect to. 
        So linux side interface is easy to set up.
 
-       This device should be assigned a virtual ethernet address.
-       I have used a random one, please change it if required.
+       Note: Some 3 kernel symbols are used by the module, which are not
+       exported by kernel/ksyms.c in the kernel code. You could either
+       add these symbols there, or use Hans' improved 'insmod'  (part of 
+       syscall Manager package). (In that case, it will resolve the
+       symbols from the zSystem.map file.
 
+       This device is assigned a virtual ethernet address, defined in
+       dosnet.h.  
+
        This device is usual loadable module. (Someone please check if
        it can be made more efficient.) However, what is interesting is
        the way it allows access to user stacks (i.e. dosemu's.) i.e.
@@ -127,15 +137,21 @@
                 asks for same type. )
 
  Packet driver code:
-               Right now, only one protocol will run per dosemu session. 
-               ( i.e. you can access EITHER novell netware OR NCSA
-               telnet ... not both at once.)
-               Because I couldn't accomplish type switching from within
-                dosemu. When a packet arrives,  it arrives on single
-                SOCK_PACKET handle ; so we need to find out which 
-                of the registered protocols  should be handled this
-                code. If there is only one, this problem is not
-                there ;-)
+               I have add the code for handling multiple protocols.
+
+               When a packet arrives,  it arrives on  one of the two 
+	       SOCK_PACKET handle we need to find out which of the 
+	       registered protocols  should be handled this code. 
+               (Earlier code opened multiple sockets, one for each IPX type.
+		However it is not useful now because we use *any*
+		type.) When a new type is registered, it is added to a
+		Type list. When a new packet arrives, first we find out
+		the frame type(and hence the position of type field in the 
+		packet, and then try matching it with registered types.
+		[ ----  I missed comparing class; I will add it later.]
+		Then call the helper corresponding to the handle of that
+		type.
+
    Rob, you should help in the following:
       1. Packet driver code ... 
                 We should now open only two sockets: one specific to dosemu and
diff -u --recursive --new-file dosemu0.53pl28/v-net/dosnet.c dosemu0.53pl29/v-net/dosnet.c
--- dosemu0.53pl28/v-net/dosnet.c	Wed Oct 19 22:28:36 1994
+++ dosemu0.53pl29/v-net/dosnet.c	Tue Nov  1 23:03:18 1994
@@ -5,10 +5,14 @@
  *
  *		Pseudo-driver for the dosnet interface.
  *
- * Authors:	Vinod G Kulkarni    vinod@cse.iitb.ernet.in
- *              Adapted from the skeleton device driver for linux in the
- *              kernel sources.
+ * Version:	@(#)dosnet.c	1.0.4b	08/16/93
  *
+ * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
+ *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
+ *		Donald Becker, <becker@super.org>
+ *
+ *		Alan Cox	:	Fixed oddments for NET3.014
+ *
  *		This program 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
@@ -36,6 +40,7 @@
 #include <linux/skbuff.h>
 
 #define MODULE
+
 #ifdef MODULE
 #include <linux/module.h>
 #include "/usr/src/linux/tools/version.h"
@@ -43,7 +48,46 @@
 
 #include "dosnet.h"
 
-unsigned char *dsn_eth_address=DOSNET_FAKED_ETH_ADDRESS ;
+unsigned char *dsn_eth_address=DOSNET_DEVICE_ETH_ADDRESS;
+unsigned char *dosnet_generic_address=DOSNET_FAKED_ETH_ADDRESS ;
+
+  /* Finding out the "type" of the packet when called by routine
+     in dev.c to put it onto proper protocol stack . 
+     Gets called ONLY WHEN when a packet is transmitted by dsn0 device.
+      
+     There are many types of packets which can get generated by dsn0 device. 
+     Distinguished by source and destination being all possible combinations
+     of  dsn0, dosemu being source or destination. 
+
+     Source      Dest.   Type of packet      Action
+  1  dosemu      dsn0    normal              Send with orig. type field      
+  2  dsn0        dosemu  normal              Send with dosemu's type field      
+  3  dosemu      dosemu  normal              Send with dosemu's type field
+  4  dsn0        dsn0    normal              ignore
+
+  Broadcast packets: 
+         ***** A packet CAN have ffffffff  as destination. *******
+         dsn0 -> dosemu : Not a duplicated packet. But destination address 
+                          is changed, so it is covered by one of the above 4 
+                          cases.
+         dosemu -> dsn0 : Gives rise to a packet with destination ffffffff, and
+                          another (duplicated) with dest. generic broadcast
+                          address for dosemus. Former gives rise to 4 cases,
+                          latter is covered by first 4 cases. 
+     source      destination
+  5  dsn0        (dsn0)   broadcast           ignore 
+  6  dosemu	 ffffffff(dsn0)  broadcast     (duplicated packet) orig type field. 
+  7  dosemu	 (dosemu)  broadcast          ffff.. is absent, == case  4.
+  8  dsn0        (dosemu)  broadcast           same as 7. 
+
+                Cases                              Strong condition
+ Send with original type: cases 1 and 6.        source=dosemu && dest==(dsn0 or ffff). 
+ Send with dosemu's type: cases 2, 3.           dest == dosemu.
+ Ignore packets:      cases 4,5,7,8 == only 4   source=dsn0 && dest=dsn0.      
+
+ This means, that the source and dest. can only be dsn0, dosemu or broadcast.
+ If this is not the case, problems !
+*/
 
 
 /*
@@ -58,16 +102,29 @@
 	struct ethhdr *eth = (struct ethhdr *) skb->data;
 
         /* This is quite tricky. 
-           See the notes in dosnet_xmit.  */
-
-        /* cases 2,3,7,8: destination is dosnet */
-        if( (eth->h_dest[0] == dsn_eth_address[0]) &&
-                   (eth->h_dest[1] == dsn_eth_address[1]) ) {
+           See the notes in dosnet_xmit.
+        */
+        /* works properly: tested with proper printks. */ 
+
+        /* cases 2,3: destination is dosnet AND NOT dsn0 ! 
+           This is quite sensitive to the addresses assigned to dsn0 and
+           to dosemu's. Be sure to double check this!
+        */
+        if( (eth->h_dest[0] == dosnet_generic_address[0]) &&
+            (eth->h_dest[1] == dosnet_generic_address[1]) &&
+            (eth->h_dest[3] == dosnet_generic_address[3])   )
+        {
               return( htons(*(unsigned short int *)&(eth->h_dest[2])) );
         }
-        /* cases  {1,3,6,7} - {3,7} = {1,6} */
-        else if ( (eth->h_source[0] == dsn_eth_address[0]) &&
-                  (eth->h_source[1] == dsn_eth_address[1]) ) {
+               /* cases  1 and 6.
+                  Destination = dsn0 device or ffff is guaranteed.
+                  So check only if the Source is dosemu. If not, the source 
+                  should be dsn0, and hence ignored.
+                */
+        else if ( (eth->h_source[0] == dosnet_generic_address[0]) &&
+                  (eth->h_source[1] == dosnet_generic_address[1]) &&
+                  (eth->h_source[3] == dosnet_generic_address[3])  ) 
+        {
               return(eth_type_trans(skb, dev)); 	
         }
         /* cases 4 and 5 are ignored. */
@@ -93,27 +150,6 @@
   dev->tbusy = 1;
   sti();
   
-  /* Now the trickiest part. send this packet only if valid:
-     There are many types of packets received: 
-     Interfaces=linux and dosemu's. Distinguished using ethernet addresses.
-     Source      Dest.   Type of packet      Action
-  1  dosemu      linux   normal              Send with orig. type field      
-  2  linux       dosemu  normal              Send with dosemu's type field      
-  3  dosemu      dosemu  normal              Send with dosemu's type field
-  4  linux       linux   normal              ignore
-      Broadcast packets: dosemu -> linux : duplicate a packet. It gives rise
-      to these cases.
-  5  linux       linux   broadcast           ignore 
-  6  dosemu	 linux   broadcast           (duplicated packet) orig type field. 
-  7  dosemu	 dosemu  broadcast           send with dosemu's broadcast type field 
-  8  linux       dosemu  broadcast           same as 7. (no duplication.)
-
-     How to do this now??? 
-     OK, here we only need to check linux-linux ones and skip them.
-     But But But ... these don't come often so let us handle all cases at 
-     type_trans  only !
-  */
-
   new_skb = alloc_skb(skb->len, GFP_ATOMIC);
   if (new_skb == NULL) {
 	printk("%s: Memory squeeze, dropping packet.\n", dev->name);
@@ -130,26 +166,37 @@
   stats->tx_packets++;
   dev->tbusy = 0;
 
-  /* When it is a broadcast packet, we need to duplicate this packet under 
-     one special case - case 6. When dosemu broadcasts, it should be sent 
-     to all other dosemu's AND  linux. Duplicated packet -> no change in
-     dest address. Original broadcast packet: change dest. address.
+  /* When it is a broadcast packet, we need to 
+         duplicate this packet under one special case - case 6. 
+         And ignore it under case 5. 
+     When dosemu broadcasts, it should be sent to all other dosemu's 
+     AND  linux. 
+     Duplicated packet -> no change in dest address. 
+     Original broadcast packet: change dest. address.
   */
   eth = (struct ethhdr *) new_skb->data;
   if (  (eth->h_dest[0] == 0xff) && (eth->h_dest[1] == 0xff) ) {
-        if( (eth->h_source[0] == dsn_eth_address[0]) &&
-            (eth->h_source[1] == dsn_eth_address[1]) ) {
+        /* broadcast packet. */
+        /* Two cases: from dosemu OR from linux(i.e. dsn0). 
+           The dosemu is identified by first three bytes of ethernet 
+           address as follows.
+         */
+        if( (eth->h_source[0] == dosnet_generic_address[0]) &&
+            (eth->h_source[1] == dosnet_generic_address[1]) &&
+            (eth->h_source[3] == dosnet_generic_address[3]) 
+            ) {
                   /* Broadcast packet by dosemu. Duplicate and send to 
                      linux, and send to other dosemu's.
                   */
-		  new_skb2 = alloc_skb(new_skb->len, GFP_ATOMIC);
-		  if (new_skb2 != NULL) {
+            new_skb2 = alloc_skb(new_skb->len, GFP_ATOMIC);
+	    if (new_skb2 != NULL) {
 		     new_skb2->len = new_skb->len;
 		     new_skb2->dev = new_skb->dev;
-                  }
-            memcpy(new_skb2->data, new_skb->data, new_skb->len);
-            /* It is broadcast packet with source=dosemu, so retain it as is. */
-            netif_rx(new_skb2);
+            	     memcpy(new_skb2->data, new_skb->data, new_skb->len);
+                     /* It is broadcast packet with source=dosemu, so retain it as is. */
+                     netif_rx(new_skb2);  /* sent to linux side. */
+            } else
+	          stats->tx_dropped++;
         }
         memcpy(eth->h_dest, DOSNET_BROADCAST_ADDRESS, 6 );
   }
@@ -177,7 +224,8 @@
   int i;
   unsigned char dummyethaddr[6]= { 0x00, 0x00, 'U', 'M', 'M', 'Y' };
   for(i=0; i<6; i++) {
-    dev->dev_addr[i]=dummyethaddr[i];
+/*    dev->dev_addr[i]=dummyethaddr[i]; */
+    dev->dev_addr[i]=DOSNET_DEVICE_ETH_ADDRESS[i];
   }
 #ifdef MODULE
   MOD_INC_USE_COUNT;
@@ -238,17 +286,10 @@
 
 
 
-
-/*
- * Local variables:
- *  compile-command: "gcc -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer  -m486 -c -o 3c501.o 3c501.c"
- *  kept-new-versions: 5
- * End:
- */
 
 #ifdef MODULE
 char kernel_version[] = UTS_RELEASE;
-static char *devicename="dsn0";
+static char *devicename=DOSNET_DEVICE;
 static struct device *dev_dosnet = NULL;
 /*  {	"      " , 
 		0, 0, 0, 0,
@@ -281,3 +322,11 @@
 	}
 }
 #endif /* MODULE */
+
+
+/*
+ * Local variables:
+ *  compile-command: "gcc -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer  -m486 -c -o 3c501.o 3c501.c"
+ *  kept-new-versions: 5
+ * End:
+ */
diff -u --recursive --new-file dosemu0.53pl28/v-net/dosnet.h dosemu0.53pl29/v-net/dosnet.h
--- dosemu0.53pl28/v-net/dosnet.h
+++ dosemu0.53pl29/v-net/dosnet.h	Tue Nov  1 23:03:18 1994
@@ -0,0 +1,19 @@
+
+#define  DOSNET_DEVICE  "dsn0"
+
+/*  unsigned char dummyethaddr[6]= { 0x00, 0x00, 'U', 'M', 'M', 'Y' }; */
+#define  DOSNET_DEVICE_ETH_ADDRESS  "db\0\0db"
+
+#define  DOSNET_FAKED_ETH_ADDRESS   "dbx\x90xx"
+#define  DOSNET_BROADCAST_ADDRESS   "db\xff\x90xx"
+
+#define DOSNET_BROADCAST_TYPE   0x90ff
+#define DOSNET_INVALID_TYPE     0x90fe
+
+/* Each dosemu will use from 0x9000 onwards. */
+#define DOSNET_TYPE_BASE        0x9000
+
+/* It is very important to differentiate between a generic dosnet address
+   and address assigned to dsn0. If you change anything here, be sure
+   to change the test in device specific type extraction code in dosnet.c. 
+*/
diff -u --recursive --new-file dosemu0.53pl28/v-net/ipxbridge0.1/a.h dosemu0.53pl29/v-net/ipxbridge0.1/a.h
--- dosemu0.53pl28/v-net/ipxbridge0.1/a.h	Wed Oct 19 22:28:36 1994
+++ dosemu0.53pl29/v-net/ipxbridge0.1/a.h
@@ -1,128 +0,0 @@
-#define MAX_PACK_LEN 66560  /* 65535 + sizeof ether_hdr + bit extra */
-
-#define ETHER_SIZE 14
-
-struct ether_hdr
-{
-  u_char dst_mac[6];
-  u_char src_mac[6];
-  u_char pkt_type[2];  /* 0x8137 */
-};
-
-struct ether_trail
-{
-  u_char length;
-  u_char *trailer;
-};
-
-/*
- * IPX packet types - not to be trusted: use dst sock
- */
-#define IPX_UNKNOWN   0x00
-#define IPX_RIP       0x01
-#define IPX_SAP       0x04
-#define IPX_SPX       0x05
-#define IPX_NCP       0x11
-#define IPX_NETBIOS   0x14
-
-/*
- * IPX socket numbers - low address: high address always 0x04 for these
- */
-#define IPX_S_NCP     0x51
-#define IPX_S_SAP     0x52
-#define IPX_S_RIP     0x53
-#define IPX_S_NETBIOS 0x55
-#define IPX_S_DIAG    0x56
-
-#define IPX_HDR_SIZE 30
-
-struct ipx_hdr
-{
-  u_char chk_sum[2];    /* always 0xffff */
-  u_char length[2];
-  u_char transport_ctl;
-  u_char pkt_type;
-  u_char dst_net[4];
-  u_char dst_node[6];
-  u_char dst_sock[2];
-  u_char src_net[4];
-  u_char src_node[6];
-  u_char src_sock[2];
-};
-
-/*
- * IPX operations for RIP and SAP - high address always 0
- */
-#define IPX_REQ    1
-#define IPX_RESP   2
-#define IPX_REQ_NEAR 3
-#define IPX_RESP_NEAR 4
-
-struct rip_ent
-{
-  u_char net_num[4];
-  u_char num_hops[2];
-  u_char num_ticks[2];
-};
-
-struct rip_pkt
-{
-  u_char op[2];
-  u_char num_ents;
-  struct rip_ent *net_ent;
-};
-
-struct sap_ent
-{
-  u_char serv_type[2];
-  u_char serv_name[48];
-  u_char net_num[4];
-  u_char net_node[6];
-  u_char net_sock[2];
-  u_char net_hops[2];
-};
-
-struct sap_pkt
-{
-  u_char op[2];
-  u_char num_ents;
-  struct sap_ent *serv_ent;
-};
-
-struct ipx_pkt
-{
-  u_char interface;
-  struct ether_hdr ipx_ether_hdr;
-  struct ipx_hdr  ipx_ipx_hdr;
-  union
-  {
-    struct sap_pkt ipx_sap;
-    struct rip_pkt ipx_rip;
-    char *ipx_other;
-  } packet;
-  struct ether_trail ipx_ether_trail;
-};
-
-struct route_entry
-{
-  u_char net_num[4];
-  u_char num_hops;
-  u_char num_ticks[2];
-  u_char interface;
-  u_char router[6];
-  u_char age;
-  struct route_entry *next;
-};
-
-struct server_entry
-{
-  u_char serv_type[2];
-  u_char serv_name[48];
-  u_char net_num[4];
-  u_char net_node[6];
-  u_char net_sock[2];
-  u_char num_hops;
-  u_char interface;
-  u_char age;
-  struct server_entry *next;
-};
diff -u --recursive --new-file dosemu0.53pl28/v-net/ipxbridge0.1/ipxbridge.c dosemu0.53pl29/v-net/ipxbridge0.1/ipxbridge.c
--- dosemu0.53pl28/v-net/ipxbridge0.1/ipxbridge.c	Wed Oct 19 22:28:36 1994
+++ dosemu0.53pl29/v-net/ipxbridge0.1/ipxbridge.c
@@ -1,214 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <malloc.h>
-#include <unistd.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <errno.h>
-#include <linux/if.h>
-#include <linux/if_ether.h>
-#include <sys/ioctl.h>
-#include <fcntl.h>
-#include <signal.h>
-#include "a.h"
-
-#define DEVICE1		"eth0"
-#define DEVICE2		"dsn0"
-
-#define	max(i,j)	(((i)>(j)) ? (i) : (j))
-
-int promisc_mode(char *, int);
-void close_all(int);
-
-u_char *full_packet;
-int new_len;
-int max_fd, fd, fd1, fd2, fd3, fd4;
-
-void main(int argc, char *argv[])
-{
-fd_set fdset;
-struct sockaddr from, to;
-int len, from_len;
-u_char *pkt_type;
-struct ether_hdr *ether_header;
-int ipx_len;
-u_char *ptr;
-unsigned int type, frame_type;
-int set;
-
-	/* Set the exception handling */
-	signal(SIGINT, close_all);
-	signal(SIGKILL, close_all);
-
-	/* I am running as a daemon */
-	if(fork() != 0) exit(0); 
-
-	/* Open a Socket for reading *all* OR *IPX* packets */
-	fd1 = socket(AF_INET, SOCK_PACKET, htons(ETH_P_802_2));
-	if(fd1 < 0) {
-		fprintf(stderr, "Error in opening generic packet socket.\n");
-		exit(0);
-	}
-	fd2 = socket(AF_INET, SOCK_PACKET, htons(ETH_P_IPX));
-	if(fd2 < 0) {
-		fprintf(stderr, "Error in opening generic packet socket.\n");
-		exit(0);
-	}
-	fd3 = socket(AF_INET, SOCK_PACKET, htons(ETH_P_802_3));
-	if(fd3 < 0) {
-		fprintf(stderr, "Error in opening generic packet socket.\n");
-		exit(0);
-	}
-	fd4 = socket(AF_INET, SOCK_PACKET, htons(ETH_P_SNAP));
-	if(fd4 < 0) {
-		fprintf(stderr, "Error in opening generic packet socket.\n");
-		exit(0);
-	}
-
-	if(promisc_mode(DEVICE1, 1) < 0) {
-		exit(0);
-	}
-
-	if(promisc_mode(DEVICE2, 1) < 0) {
-		exit(0);
-	}
-
-	if((full_packet = (char *)malloc(MAX_PACK_LEN)) == NULL) {
-		fprintf(stderr, "Cannot allocate memory.\n");
-		exit(0);
-	}
-
-	max_fd = max(fd1, fd2);
-	max_fd = max(fd3, max_fd);
-	max_fd = max(fd4, max_fd) + 1;
-
-	for(;;) {
-		FD_ZERO(&fdset);
-		FD_SET(fd1, &fdset);
-		FD_SET(fd2, &fdset);
-		FD_SET(fd3, &fdset);
-		FD_SET(fd4, &fdset);
-
-		select(max_fd, &fdset, (fd_set *)NULL, (fd_set *)NULL, 
-				(struct timeval *)NULL);
-		
-		if(FD_ISSET(fd1, &fdset) == 1) fd = fd1;
-		else if(FD_ISSET(fd2, &fdset) == 1) fd = fd2;
-		else if(FD_ISSET(fd3, &fdset) == 1) fd = fd3;
-		else if(FD_ISSET(fd4, &fdset) == 1) fd = fd4;
-		else fprintf(stderr, "*** Unknown fd here ***\n");
-
-		len = recvfrom(fd, full_packet, MAX_PACK_LEN, 0, &from, &from_len);
-		if(len <= 0) continue;
-
-		/* Get the ethernet header */
-		ether_header = (struct ether_hdr *) full_packet;
-		pkt_type = ether_header->pkt_type;
-		type = pkt_type[0] << 8 | pkt_type[1];
-
-		/* Here we check the frame type and get the IPX related packets */
-		if(type >= 1536) frame_type = type;
-		else {
-			ptr = (u_char *) (full_packet + ETHER_SIZE);
-			if(ptr[0] == 0xFF && ptr[1] == 0xFF) frame_type = ETH_P_802_3;
-			if(ptr[0] == 0xAA && ptr[1] == 0xAA) frame_type = ETH_P_SNAP;
-			else frame_type = ETH_P_802_2;
-		}
-
-		ipx_len = ptr[2] << 8 | ptr[3];
-
-		set = 0;
-
-		switch(frame_type) {
-			case ETH_P_IPX :
-#ifdef DEBUG
-				fprintf(stderr, "Got IPX over DIX packet\n"); 
-#endif
-				set = 1;
-				break;
-			case ETH_P_802_2 :
-#ifdef DEBUG
-				fprintf(stderr, "Got Bluebook packet\n"); 
-#endif
-				set = 1;
-				break;
-			case ETH_P_802_3 :
-#ifdef DEBUG
-				fprintf(stderr, "Got IPX over DIX\n"); 
-#endif
-				set = 1;
-				break;
-			case ETH_P_SNAP :
-#ifdef DEBUG
-				fprintf(stderr, "Got Etherenet II SNAP\n"); 
-#endif
-				set = 1;
-				break;
-			default :
-				break;
-		}
-			
-		if(! set) continue;
-
-#ifdef DEBUG
-		fprintf(stderr, "device = %s, ether_len = %.4x, ipx_len = %.4x, type = %.4x\n", 
-				from.sa_data, len, ipx_len, type);
-#endif
-
-		if(strncmp(from.sa_data, DEVICE1, 4) == 0) 
-			strcpy(to.sa_data, DEVICE2);
-		else if(strncmp(from.sa_data, DEVICE2, 4) == 0) 
-			strcpy(to.sa_data, DEVICE1);
-		else
-			continue;
-
-		to.sa_family = AF_INET;
-
-	/* sendto function sends the packet *as is* to the network interface
-	   Only have to check if it adds the any of the MAC components to 
-	   the packet or not */
-
-		if(sendto(fd, full_packet, len, 0, &to, sizeof(to)) < 0) 
-		   perror("sendto");
-
-	/* After sending the packet we are waiting for some time before we
-	   start polling again. */
-	}
-}
-
-
-int promisc_mode(char *device, int flag)
-{
-struct ifreq if_data;
-
-	strcpy(if_data.ifr_name, device);
-	if(ioctl(fd1, SIOCGIFFLAGS, &if_data) < 0) {
-		fprintf(stderr, "Cannot get the flags for %s\n", device);
-		return -1;
-	}
-
-	if(flag) {
-		if_data.ifr_flags |= IFF_PROMISC;
-	}
-	else {
-		if_data.ifr_flags &= IFF_PROMISC;
-		if_data.ifr_flags ^= IFF_PROMISC;
-	}
-
-	if(ioctl(fd1, SIOCSIFFLAGS, &if_data) < 0) {
-		fprintf(stderr, "Cannot set promiscous mode for %s\n", device);
-		return -1;
-	}
-
-	return 1;
-}
-
-void close_all(int a)
-{
-	free(full_packet);
-	close(fd1);
-	close(fd2);
-}
-
diff -u --recursive --new-file dosemu0.53pl28/v-net/ipxbridge0.2/ipxbridge.c dosemu0.53pl29/v-net/ipxbridge0.2/ipxbridge.c
--- dosemu0.53pl28/v-net/ipxbridge0.2/ipxbridge.c	Wed Oct 19 22:28:36 1994
+++ dosemu0.53pl29/v-net/ipxbridge0.2/ipxbridge.c
@@ -1,322 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <malloc.h>
-#include <unistd.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <errno.h>
-#include <linux/if.h>
-#include <linux/if_ether.h>
-#include <sys/ioctl.h>
-#include <fcntl.h>
-#include <signal.h>
-
-#define LDEBUG
-
-#define DEVICE1		"eth0"
-#define DEVICE2		"dsn0"
-
-#define MAX_PACK_LEN   66560
-#define ETHER_SIZE     14
-struct ether_hdr
-{
-  u_char dst_mac[6];
-  u_char src_mac[6];
-  u_char pkt_type[2];  /* 0x8137 */
-};
-
-#define	max(i,j)	(((i)>(j)) ? (i) : (j))
-
-int promisc_mode(char *, int);
-void close_all(int);
-
-u_char *full_packet;
-int new_len;
-int max_fd, fd, fd1, fd2, fd3, fd4;
-
-/* Hash table:  Ethernet address is aa:bb:cc:dd:ee:ff. 
-
-   Hash table is of 64K. It is addressed using only 13 bits. So each addressed
-   location has total of 6 bytes for its usage. Of these, we store
-   the ethernet address in 5 bytes. (1 byte [+3bits] is matched when 
-   looking up). If it doesn't match, flood. 
-   Lookup Address = ee:(ff << 3).
-
-   But this memory should not be swapped out any time! This can be ensured
-   by setting t bit (I think). 
-
-   After every n seconds of time, it should set all elements of hash table 
-   to zero so as to dynamically "learn" . 
-
-   Broadcast address: LSB of 2nd byte of destination should equal 1.
-   First 3 bytes are meant to identify manufacturer ID.
-
-*/
-char hash_table[ 0xFFFF ] ;  /* Can't we avoid it? */
-  /* Assumption: Linux initialises all variables to zero ... 
-     We don't want to calloc. Helps the compiler to optimise.
-   */
-struct eth_address_index  {
-       char da, db, dc, dd;   /* Destination address */
-       unsigned short int di;  /* size of short int = 4. */
-       char sa, sb, sc, sd;   /* Source address */
-       unsigned short int si;  /* size of short int = 4. */
-} ;
-union {
-  unsigned short int i;
-  u_char a, b;
-} src_index, dst_index;
-
-void main(int argc, char *argv[])
-{
-fd_set fdset;
-struct sockaddr from, to;
-int len, from_len;
-unsigned short dummy123;  /* for pkt_type! don't use it ..*/
-u_char *pkt_type;
-u_char *ptr;
-struct ether_hdr *ether_header;
-int ipx_len;
-unsigned int type, frame_type;
-int set;
-static char ascii01[2]= {'1','0'};
-
-	/* Set the exception handling */
-	signal(SIGINT, close_all);
-	signal(SIGKILL, close_all);
-
-
-	/* I am running as a daemon */
-	/* if(fork() != 0) exit(0);  */
-
-
-	/* Open a Socket for reading *all* OR *IPX* packets */
-	fd1 = socket(AF_INET, SOCK_PACKET, htons(ETH_P_802_2));
-	if(fd1 < 0) {
-		fprintf(stderr, "Error in opening generic packet socket.\n");
-		exit(0);
-	}
-	fd2 = socket(AF_INET, SOCK_PACKET, htons(ETH_P_IPX));
-	if(fd2 < 0) {
-		fprintf(stderr, "Error in opening generic packet socket.\n");
-		exit(0);
-	}
-	fd3 = socket(AF_INET, SOCK_PACKET, htons(ETH_P_802_3));
-	if(fd3 < 0) {
-		fprintf(stderr, "Error in opening generic packet socket.\n");
-		exit(0);
-	}
-	fd4 = socket(AF_INET, SOCK_PACKET, htons(ETH_P_SNAP));
-	if(fd4 < 0) {
-		fprintf(stderr, "Error in opening generic packet socket.\n");
-		exit(0);
-	}
-
-	if(promisc_mode(DEVICE1, 1) < 0) {
-		exit(0);
-	}
-
-	if(promisc_mode(DEVICE2, 1) < 0) {
-		exit(0);
-	}
-
-	if((full_packet = (char *)malloc(MAX_PACK_LEN)) == NULL) {
-		fprintf(stderr, "Cannot allocate memory.\n");
-		exit(0);
-	}
-
-	max_fd = max(fd1, fd2);
-	max_fd = max(fd3, max_fd);
-	max_fd = max(fd4, max_fd) + 1;
-
-
-	from.sa_family = AF_INET;  
-        strcpy(from.sa_data , "eth0") ; 
-	to.sa_family = AF_INET;  
-        strcpy(to.sa_data , "eth0") ; 
-
-	for(;;) {
-		FD_ZERO(&fdset);
-		FD_SET(fd1, &fdset);
-		FD_SET(fd2, &fdset);
-		FD_SET(fd3, &fdset);
-		FD_SET(fd4, &fdset);
-
-		select(max_fd, &fdset, (fd_set *)NULL, (fd_set *)NULL, 
-				(struct timeval *)NULL);
-		
-		if(FD_ISSET(fd1, &fdset) == 1) fd = fd1;
-		else if(FD_ISSET(fd2, &fdset) == 1) fd = fd2;
-		else if(FD_ISSET(fd3, &fdset) == 1) fd = fd3;
-		else if(FD_ISSET(fd4, &fdset) == 1) fd = fd4;
-		else fprintf(stderr, "*** Unknown fd here ***\n");
-
-
-		len = recvfrom(fd, full_packet, MAX_PACK_LEN, 0, &from, &from_len);
-		if(len <= 0) continue;
-
-
-		/* Get the ethernet header */
-		ether_header = (struct ether_hdr *) full_packet;
-		pkt_type = ether_header->pkt_type;
-		type = pkt_type[0] << 8 | pkt_type[1];
-
-		/* Here we check the frame type and get the IPX related packets */
-		if(type >= 1536) frame_type = type;
-		else {
-			ptr = (u_char *) (full_packet + ETHER_SIZE); 
-			if(ptr[0] == 0xFF && ptr[1] == 0xFF) frame_type = ETH_P_802_3;
-			if(ptr[0] == 0xAA && ptr[1] == 0xAA) frame_type = ETH_P_SNAP;
-			else frame_type = ETH_P_802_2;
-		}
-
-		ipx_len = ptr[2] << 8 | ptr[3];
-
-		set = 0;
-
-		switch(frame_type) {
-			case ETH_P_IPX :
-#ifdef DEBUG
-				fprintf(stderr, "Got IPX over DIX packet\n"); 
-#endif
-				set = 1;
-				break;
-			case ETH_P_802_2 :
-#ifdef DEBUG
-				fprintf(stderr, "Got Bluebook packet\n"); 
-#endif
-				set = 1;
-				break;
-			case ETH_P_802_3 :
-#ifdef DEBUG
-				fprintf(stderr, "Got IPX over DIX\n"); 
-#endif
-				set = 1;
-				break;
-			case ETH_P_SNAP :
-#ifdef DEBUG
-				fprintf(stderr, "Got Etherenet II SNAP\n"); 
-#endif
-				set = 1;
-				break;
-			default :
-				break;
-		}
-			
-
-		if(! set) continue;
-#ifdef LDEBUG
-		fprintf(stderr, "device = %s, ether_len = %.4x, ipx_len = %.4x, type = %.4x\n", 
-				from.sa_data, len, ipx_len, type);
-#endif
-
-                /* Intellingent bridging now ... */
-
-                /*=============Insert source address in hash table=========*/
-                /* Use its source address to index the hash table and
-                   store its interface in hash table. */
-                src_index.i = ((struct eth_address_index *)ether_header)->si;  
-                        /* Last two bytes are in this variable now. */
-                src_index.b <<= 3; /* Shift left last byte by 3 bits. */  
-                /* Long int is 4 bytes. This statement should move first 4
-                   bytes of source ethernet address into hash table. */
-                (long int)hash_table[ src_index.i ] =  
-                       *(long int *)((char *)ether_header + 6) ;
-                /* Next, last byte of destination address should be moved into
-                   the hash table. */
-                (long int)hash_table[ src_index.i + 4 ] =  *(char *)((char *)ether_header + 11) ;
-                /* Next, move the interface number into the next position. 
-                   Note: this is ascii '0' or '1'. 
-                */
-                hash_table[ src_index.i + 5 ] = from.sa_data[3] ;
-                /*=======================================================*/
-
-
-                /*=============Handle broadcast addresses==================*/
-                /* Check if it is broadcast destination. */
-                if ( (((struct eth_address_index *)ether_header)->db & 0x01) == 0x01 )
-                { 
-                  /* Make eth0 -> eth1, and eth1 -> eth0. */
-                  /* ASSUMPTION: Only eth0 and eth1 are participating! */
-                  to.sa_data[3] = ascii01[ from.sa_data[3] - '0' ];
-                
-                  /* Now broadcast it on other segment. */
-		  if(sendto(fd, full_packet, len, 0, &to, sizeof(to)) < 0) 
-		          perror("sendto");
-                  continue;
-                }
-                /*=========================================================*/
-
-                /*=============Handle non-broadcast addresses==============*/
-                /* No it is not broadcast. Get the destination interface 
-                   from the hash tables. */ 
-
-                /* Use its destination address to index the hash table */ 
-                dst_index.i = ((struct eth_address_index *)ether_header)->di;  
-                       /* Last two bytes are in this variable now. */
-                dst_index.b <<= 3; /* Shift left last byte by 3 bits. */  
-                /* Long int is 4 bytes. This statement should compare first 4
-                   bytes of destination ethernet address with the same of
-                   entry in hash table. -- followed by  comparing the last 
-                   byte of destination address  */ 
-                if (  ( (long int)hash_table[ dst_index.i ] == 
-                                *(long int *)((char *)ether_header) ) &&
-                      ( (long int)hash_table[ dst_index.i + 4 ] ==  
-                                *(char *)((char *)ether_header + 5) ) ) {
-                     to.sa_data[3] = hash_table[ src_index.i + 5 ] ;
-                     /* This packet need not be sent if both interfaces 
-                        are same */
-                     if (to.sa_data[3] == from.sa_data[3])  {
-#ifdef LDEBUG
-                            fprintf(stderr,"Hey! a match at last! \n");
-#endif
-                            continue;
-                     }
-                } 
-                else{ 
-                     to.sa_data[3] = ascii01[ from.sa_data[3] - '0' ];
-                }
-#ifdef LDEBUG
-                fprintf(stderr,"No match: sending on interface %s\n",to.sa_data);
-#endif
-		if(sendto(fd, full_packet, len, 0, &to, sizeof(to)) < 0) 
-		          perror("sendto");
-
-	}
-}
-
-
-int promisc_mode(char *device, int flag)
-{
-struct ifreq if_data;
-
-	strcpy(if_data.ifr_name, device);
-	if(ioctl(fd1, SIOCGIFFLAGS, &if_data) < 0) {
-		fprintf(stderr, "Cannot get the flags for %s\n", device);
-		return -1;
-	}
-
-	if(flag) {
-		if_data.ifr_flags |= IFF_PROMISC;
-	}
-	else {
-		if_data.ifr_flags &= IFF_PROMISC;
-		if_data.ifr_flags ^= IFF_PROMISC;
-	}
-
-	if(ioctl(fd1, SIOCSIFFLAGS, &if_data) < 0) {
-		fprintf(stderr, "Cannot set promiscous mode for %s\n", device);
-		return -1;
-	}
-
-	return 1;
-}
-
-void close_all(int a)
-{
-	free(full_packet);
-	close(fd1);
-	close(fd2);
-}
diff -u --recursive --new-file dosemu0.53pl28/video/Makefile dosemu0.53pl29/video/Makefile
--- dosemu0.53pl28/video/Makefile	Wed Oct 19 22:28:22 1994
+++ dosemu0.53pl29/video/Makefile	Tue Nov  1 23:03:01 1994
@@ -21,7 +21,7 @@
 
 # let gcc do extended checking
 
-CFLAGS=-O2 -Wall # -Wmissing-prototypes \
+# CFLAGS=-O2 -Wall # -Wmissing-prototypes \
 #       -Wstrict-prototypes -ansi -pedantic 
 
 # ANSI isn't possible right now, because some header-file aren't ANSI
@@ -39,13 +39,19 @@
 OBJS = video.o vc.o vga.o et4000.o s3.o trident.o console.o \
        terminal.o int10.o $(XOBJS) hgc.o
 
+SUBDIR=video
+
 .c.o:
 	$(CC) $(CFLAGS) $(XDEFS) $(INCDIR) -c $<
  
-all: ../video.o
+LIB=../lib$(SUBDIR).a
+
+all:  $(LIB)
 
-../video.o: $(OBJS)
-	$(LD) -r -o ../video.o $(OBJS)
+$(LIB): $(OBJS)
+	-rm $@
+	$(AR) cr $@ $^
+	ranlib $@
 
 checkin:
 	-ci $(ALL) Makefile
@@ -54,7 +60,7 @@
 	-co -l $(ALL) Makefile
 
 clean:
-	rm -f *.o
+	rm -f *.o ../lib$(SUBDIR).a
 
 realclean:
 	rm -f .depend
@@ -62,8 +68,8 @@
 install:
 
 dist: $(ALL) Makefile
-	install -d $(DISTPATH)/video
-	install -m 0644 $(ALL) Makefile $(DISTPATH)/video
+	install -d $(DISTPATH)/$(SUBDIR)
+	install -m 0644 $(ALL) Makefile $(DISTPATH)/$(SUBDIR)
 
 depend dep: $(CFILES) $(HFILES)
 	$(CPP) -MM $(CFLAGS) $(CFILES) $(INCDIR) > .depend
