From: MeyerGru@Informatik.TU-Muenchen.DE (Uwe Meyer-Gruhl)
Subject: NeXTstep 3.0 - too early? And some gift to the hackers. (long)
Keywords: bugs, frustration, NS 3.1, hacks
Followup-To: comp.sys.next.misc
Originator: meyergru@hpradigc.informatik.tu-muenchen.de
Organization: Technische Universitaet Muenchen, Germany
Date: Wed, 14 Oct 1992 16:10:55 GMT


Hi folks,

now, that I have had some hands-on experience with NS 3.0, I have got the
impression that NeXT should have spent some more time before releasing
it to the general public (even if one argues that NeXT users are not as
helpless as the 'general public' and can thus fix a few bugs themselves).

Some examples will stress my humble opinion:

1.  NS 3.0 is slower with some harddisk drives. Rumours say that the
    'scsi save data pointers' bug (e.g. with Micropolis drives) has
    been fixed. Maybe additional overhead with other drives has been
    generated by this. At least my HP C2247 now has a figure of
    1.2 MByte/sec instead of 1.7 MByte/sec operating with NS 2.1,
    whilst my Fujitsu M2624SB still does 1.3 MByte/sec. Maybe this is
    the reason why some people say that NS 3.0 is slower and others
    it is not.

2.  The support for non-NeXT printers is not as good as expected.
    The slogan 'support for hundreds of printers' applies to
    Postscript printers mostly.
    Only two dot-matrix printers (which can't be connected in a way
    that would be desireable, since there is 'no such thing' (TM) as
    a parallel port) are supported.
    O.K., one could change the tables and thus enable more printers,
    but why didn't NeXT do that for us??? I would have liked to have
    a PCL driver as well, but what did I see? Dozens of drivers for
    HP Laserjet varieties, however all with Postscript cartridges.
    I have not yet verified that the new 'lpd' supports 38400 baud.
    There was a bug in the old one which prevented use of the highest
    baud rate.
    Side-note: There will be a working version of DJF for the DeskJet
    500 in the near future. Reimer Mellin will post it.

3.  Some header files, such as <sys/table.h> have been removed. NeXT
    says that they are used only inside NeXT. At least they were
    neccessary for DJF. I know that there is some 'table.h' in
    'bsd/m68k'. It's not the right one. Period.
    Strolling through the remaining headers, I found that there are
    inconsistencies now.
    Applications (such as DJF) that rely on these headers can't even
    be created such that they figure out the OS version at compile
    time. The only difference between 2.1 and 3.0 that can be used is
    '#define __ARCHITECTURE__', which is but compiler-dependend,
    not OS-dependend. Where is '#define NS30'? Oh, by the way:
    The compiler now supports a '-O2' flag, according to the release
    notes. Why is this not used in '/NextDeveloper/Makefiles/app/app.make'?

4.  Some programs have been removed. The MusicKit is now unbundled,
    and thus there is no more 'dsp*'. Alright. Some other programs
    have been deleted, too, and in a way that looks like a
    'last-minute-action' to me. Look at '/etc/fsirand' and you'll
    see what I mean. It's now a symlink to a non-existent
    '/usr/etc/fsirand'

5.  The Apps may be very colorful, but I prefer them working.
    Librarian.app chokes on old indices and I have seen it panic the
    machine on some of these occasions. If you use a backtab in the
    text field of a Mail.app send window, you will paste whatever
    is in your pasteboard. The infamous disk ejection bug has been
    'fixed' recently by a daemon which signals the Workspace
    Mangler (tm). I would prefer a new executable over twiddling
    in the defaults databases of all users, wouldn't you?

6.  Changing the 'find' program in the manner NeXT did seems kinda
    brain-dead to me. It no longer adds implicit stars to the front
    and end of the search word, so you have to use 'find "*bozo*"'
    instead of 'find bozo'.
    If one ever needed full-word search in fast-find mode, NeXT could
    have used a switch for that.

7.  I don't understand the neccessity of /dev/sg[0-3]. Or do I? The
    scsitools package 'sense' utility can no longer be used together
    with redirection, or else the drive chokes badly. Don't try
    "sense -t1 -p63 >HPC2247.sense". What has been changed here?
    I also read something about CDPlayer.app not working when both
    scsi targets 0 and 1 are occupied. And, also see Note 1 about
    scsi drivers. Not speaking of general slowness of NeXT's
    scsi (Are you listening, Michael Carling?).

8.  The biggest bug of all, IMHO: 'open' is broke. I had received
    some uucp files and tried:
           cd /usr/spool/uucppublic
	   open *
    I got: "open: can't stat file: /spool/uucppublic/tttt".
    '/usr/spool' is a symlink to '/private/spool'. 'open'
    mis-constructs the real name of the file, and Reimer reported
    to me that 'find' does that too. Maybe it's a kernel bug?

9.  The new TeX is great. Nearly. First thing I noticed that since I
    was using GermanTeX, the binaries in /usr/bin had been changed,
    so that Upgrade.app didn't touch them.
    No big deal, just reinstall NeXTTeX.pkg. With that distribution,
    I tried to use 'psfig' and found it to be version 1.2, just like
    in the old days. I have waited so long for a new TeX, and now
    this. Under 2.1, psfig 1.9 could not be installed, since TeXview
    and dvips (even newer versions from usenet) choked on its
    output. I think there were problems in the display postscript,
    since it worked slightly better on a friend's mono station.
    I hoped for better in 3.0, so at first I was very disappointed.
    However, with the experiences I had with some other items in 3.0,
    I dug and finally found what I was looking for. 'psfig' version 1.9 is
    located in '/usr/lib/tex/src/dvips/contrib/psfig'. Somebody at
    NeXT just forgot to install it.

There are dozens of other examples, take the sybase server
configuration which should be set up for port numbers not less than 5000.
All show that NeXT shot a little fast with the 3.0 release. Are we going
to see 3.1 in January, NeXT? I sure would like to, and for free, too!

For those of you that are reading on to this point, there is a little
gift. Since my longish postings about kernel hacks and the like I
have seen some questions about how to use the ROM monitor to boot
with more than 16 buffers. Also, there was some discussion going on
about copy-protection and identifying individual machines (sorry to
disappoint you, but you can't, simply put).

The correct way to set the number of buffers from the monitor is:
              "b sd() sdmach nbuf=128"
There's no hyphens in it. Somebody got me wrong about the length of
the boot commands. There is a relevant limit in the length of boot
commands that you can _store_ into NVM and thus set permanently, not
in the commands issued from monitor.
This is the main reason to patch the kernel _after_ one has tried
some buffer sizes and determined the right number of buffers for one's
application profile.

So here we go again. This is the 'sdmach_3.0.binpatch'. The following
output was generated by applying 'cmp -l /sdmach.old /sdmach':

sdmach_3.0.binpatch:
---- CUT HERE ----
646462   0   1
646467  74  54
646468 266 170
662488   0 200
---- CUT HERE ----


The patch consists of two parts. The word at offset 662485 is the number
of buffers, which is set to 128(decimal = 200 octal) in this
case, so that 1 MByte of buffers are allocated. Only the last byte
(662488) has been changed. The second part is the table entry at
646462, which enables the otherwise nonfunctional 'sethostid()' call. The
original patch for NS 2.1 has been posted some time ago by Eric P. Scott,
if I remember right.

For those of you who want to patch /sdmach by means of 'Moni' or
'HexEditor', be warned. The offsets from 'cmp -l' start with '1', not '0'.
The byte values given are in octal. For those with less trust in their
capabilities (or simply lazy people), here is the 'binpatch' program,  
which has been posted a while ago together with the 'lpd' 38400 baud
patch by Marc A. Ullman.

binpatch.c:
---- CUT HERE ----
/*
 * binpatch.c - apply output of "cmp -l" to patch a binary file
 *
 * This simple program takes the output from "cmp -l" and applies it as a set
 * of patches to a given input file.  The input file itself is modified and no
 * backup file is created.  Thus if a backup of the original is desired (highly
 * recommended), create it before using binpatch.  An example of its use
 * follows:
 *
 * Assume that you have the file "lpd.diff" that resulted from:
 *	% cmp -l lpd.broken lpd.fixed > lpd.diff
 *
 * Now do the following to apply the patch:	
 *	% cp -p lpd lpd.broken
 *	% binpatch -f lpd.diff lpd
 *
 * lpd will now be identical to lpd.fixed.  This is of course useful when you
 * have only the original and the diff file and wish to recreate the patched
 * version.
 *
 * Compile using: cc -O -Wall -o binpatch binpatch.c
 *
 * Copyright (C) 1991 by Marc Ullman
 * All Rights Reserved
 * December 16, 1991
 */

static char rcsid[] = "$Header: /local/src/tools/binpatch/RCS/binpatch.c,v 1.1 91/12/16  
12:05:50 marc Exp $";

#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>

#define ARGUMENTS	"-f diff_file  input_file\n"	\
			"       The diff_file is created by \"cmp -l orig.file modified.file > diff.file\""

static char *program_name = NULL;
static char *input_file_name = NULL;

static char *diff_file_name = NULL;

/* Print error message while exiting due to unrecoverable error */
/* Use variable argument list to support multiple arguments to printf */
static void Error_Exit(char *error_msg, ...)
{
    va_list ap;

    va_start(ap, error_msg);

    fprintf(stderr, "%s: ", program_name);
    vfprintf(stderr, error_msg, ap);

    va_end(ap);

    exit(1);
}

static void Usage()
{
    fprintf(stderr, "Usage: %s %s\n", program_name, ARGUMENTS);
    exit(1); 

}

static void Process_Arguments(int argc, char *argv[])
{
    int i;

    for (i = 1; i <= (argc - 1); i++) {
        if (*argv[i] == '-') {
            switch (*(argv[i]+1)) {
                case 'f' :      /* diff_file */
                    if  (i < (argc - 1)) {
                        diff_file_name = argv[++i];
                    } else {
                        Usage();
                    }
                    break;
                default :
                    Error_Exit("invalid option '-%c'\n", *(argv[i]+1));
                    break;
            }
        } else {
            input_file_name = argv[i];
        }
    }
    /* Check that we got diff_file and  input file */
    if ((input_file_name == NULL) || (diff_file_name == NULL)) {
        Usage();
    }
}

void error_exit(FILE *diff_file, FILE *input_file)
{
    fclose(diff_file);
    fclose(input_file);
   

    exit(EXIT_FAILURE);
}

void main(int argc, char *argv[])
{
    FILE *diff_file;
    FILE *input_file;
    int	count = 0;
    unsigned long offset;
    unsigned int c1, c2, c;
   

    program_name = argv[0];

    Process_Arguments(argc, argv);
   

    if ((diff_file = fopen(diff_file_name, "r")) == NULL) {
        Error_Exit("can't read %s\n", diff_file_name);
    }
 

    if ((input_file = fopen(input_file_name, "r+")) == NULL) {
        Error_Exit("can't read %s\n", input_file_name);
    }
    

    do {
	count = fscanf(diff_file, "%lu %o %o", &offset, &c1, &c2);
	if (count == EOF) {
	    break;
	} else if (count != 3) {
	    printf("Error reading %s\n", diff_file_name);
	    error_exit(diff_file, input_file);
	}
	offset--;	/* cmp -l returns base 1 offsets */

#ifdef DEBUG
	printf("%.8x    %.2x    %.2x\n", offset, c1, c2);
#endif
	
	if (fseek(input_file, offset, SEEK_SET) != 0) {
	    printf("Error seeking in %s\n", input_file_name);
	    error_exit(diff_file, input_file);
	}
	
	c = fgetc(input_file);
	if (c1 != c) {
	    printf("Patch file differs from input file at offset %.8x:  %.2x  %.2x\n",
		offset, c, c1);
	} else {
	    fseek(input_file, offset, SEEK_SET);
	    fputc(c2, input_file);
	}
	
    } while (feof(diff_file) == 0);

    fclose(diff_file);
    fclose(input_file);
   

    exit(EXIT_SUCCESS);
}


---- CUT HERE ----

To patch /sdmach, extract the two included files above to some arbitrary
directory, 'chdir' there and then issue (as root):

	cc -O -Wall -o binpatch binpatch.c
	cp /sdmach /sdmach.old
	./binpatch -f sdmach_3.0.binpatch /sdmach

You will remain with the original version of /sdmach in /sdmach.old
(so you could always boot the old version with 'b sd() sdmach.old' from
the ROM monitor) and the newer version in /sdmach. Reboot and you're set.

As I already said: "Patch as patch can! And remember: No Guarantees!"


have fun, Uwe

Uwe Meyer-Gruhl                      Confucius say: 
Lehrstuhl Informatik IX              "Unlucky to play leapfrog with unicorn"
Technische Universitaet Muenchen     email:MeyerGru@Informatik.TU-Muenchen.DE
Orleansstr. 34, D-8000 Muenchen 80   tel: ++49 89 48095-209
Newsgroups: comp.sys.next.misc