9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
* [9fans] inferrno install, macos x, fails ...
@ 2004-04-04  1:58 ron minnich
  2004-04-04  3:03 ` Number Six
  0 siblings, 1 reply; 10+ messages in thread
From: ron minnich @ 2004-04-04  1:58 UTC (permalink / raw)
  To: 9fans

Darwin Ronald-Minnichs-Computer.local 7.2.0 Darwin Kernel Version 7.2.0: 
Thu Dec 11 16:20:23 PST 2003; root:xnu/xnu-517.3.7.obj~1/RELEASE_PPC  
Power Macintosh powerpc

This is Panther. 

works ok until emu starts, the emu goes to pieces with stuff like this:
malloc failed from 4b70c
arena main too large: size 64 cursize 3563808 arenasize 33554432 maxsize 
33554432

and so on. If I start emu it gets SIGBUS.

Anyone seen this?

ron



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [9fans] inferrno install, macos x, fails ...
  2004-04-04  1:58 [9fans] inferrno install, macos x, fails ron minnich
@ 2004-04-04  3:03 ` Number Six
  2004-04-04  6:56   ` Charles Forsyth
  0 siblings, 1 reply; 10+ messages in thread
From: Number Six @ 2004-04-04  3:03 UTC (permalink / raw)
  To: 9fans

On Sat, Apr 03, 2004 at 06:58:20PM -0700, ron minnich wrote:
> works ok until emu starts, the emu goes to pieces with stuff like this:
> malloc failed from 4b70c
> arena main too large: size 64 cursize 3563808 arenasize 33554432 maxsize 
> 33554432
> 
> and so on. If I start emu it gets SIGBUS.
> 
> Anyone seen this?
> 

Something's bolloxed in the VN emu binary for macos.  You need Jeff
Sickel's emu.  See:

<http://www.corpus-callosum.com/software.html>

	#6


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [9fans] inferrno install, macos x, fails ...
  2004-04-04  3:03 ` Number Six
@ 2004-04-04  6:56   ` Charles Forsyth
  2004-04-04 10:08     ` Geoff Collyer
  0 siblings, 1 reply; 10+ messages in thread
From: Charles Forsyth @ 2004-04-04  6:56 UTC (permalink / raw)
  To: 9fans

>>Something's bolloxed in the VN emu binary for macos.  You need Jeff
>>Sickel's emu.  See:

i suspected it was just old.  we ship what we last got from him.
(unless i failed to copy it in correctly, which could happen.)



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [9fans] inferrno install, macos x, fails ...
  2004-04-04  6:56   ` Charles Forsyth
@ 2004-04-04 10:08     ` Geoff Collyer
  2004-04-04 14:34       ` Jeff Sickel
  0 siblings, 1 reply; 10+ messages in thread
From: Geoff Collyer @ 2004-04-04 10:08 UTC (permalink / raw)
  To: 9fans

I had the JIT working and Vitanuova have my changes.



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [9fans] inferrno install, macos x, fails ...
  2004-04-04 10:08     ` Geoff Collyer
@ 2004-04-04 14:34       ` Jeff Sickel
  2004-04-04 23:00         ` Geoff Collyer
  0 siblings, 1 reply; 10+ messages in thread
From: Jeff Sickel @ 2004-04-04 14:34 UTC (permalink / raw)
  To: 9fans

I've never had the JIT working.  And though Charles sent me a snapshot 
of Geoff's changes at one point for V3, I either missed the JIT portion 
when merging the code lines or something else changed when moving to 
gcc 3.3 with the latest OS X.

I'd be happy to comb back over the source to finally get the JIT 
working for version 4 (and submit an audio driver as well).

jas

On Apr 4, 2004, at 5:08 AM, Geoff Collyer wrote:

> I had the JIT working and Vitanuova have my changes.



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [9fans] inferrno install, macos x, fails ...
  2004-04-04 14:34       ` Jeff Sickel
@ 2004-04-04 23:00         ` Geoff Collyer
  2004-04-05  2:17           ` Geoff Collyer
  0 siblings, 1 reply; 10+ messages in thread
From: Geoff Collyer @ 2004-04-04 23:00 UTC (permalink / raw)
  To: 9fans

It's been a while, but I think the important changes were to zero some
registers at start-up and maybe later too.  I'll see if I can find
them.



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [9fans] inferrno install, macos x, fails ...
  2004-04-04 23:00         ` Geoff Collyer
@ 2004-04-05  2:17           ` Geoff Collyer
  2004-04-05  2:46             ` ron minnich
  0 siblings, 1 reply; 10+ messages in thread
From: Geoff Collyer @ 2004-04-05  2:17 UTC (permalink / raw)
  To: 9fans

[-- Attachment #1: Type: text/plain, Size: 2974 bytes --]

It looks like my modified 3e comp-power.c didn't make it into
Vitanuova's tree.  I added code to generate instructions to zero R0:

; grep -ni 'set r0 to 0' `{files | grep '\.[cshy]$'}
./interp/comp-power.c:682: 	AIRR(Oaddi, Rzero, 0, 0);		/* set R0 to 0 */
./interp/comp-power.c:1550: 	AIRR(Oaddi, Rzero, 0, 0);		/* set R0 to 0 */
./interp/comp-power.c:1589: 	AIRR(Oaddi, Rzero, 0, 0);		/* set R0 to 0 */
./interp/comp-power.c:1742: 	AIRR(Oaddi, Rzero, 0, 0);		/* set R0 to 0 */
./interp/comp-power.c:1778: 	AIRR(Oaddi, Rzero, 0, 0);		/* set R0 to 0 */
./interp/comp-power.c:1816: 	AIRR(Oaddi, Rzero, 0, 0);		/* set R0 to 0 */

but these don't appear in December's preliminary 4e tree:

; cd /i/libinterp; grep -i airr comp-power.c | grep -i rzero
	AIRR(Oaddis, reg,Rzero,c>>16);
		AIRR(Oaddi, reg, Rzero, c);
		AIRR(Oaddis, reg,Rzero,c>>16);
				AIRR(Ostw, Rzero, Rreg,O(REG,st));
	AIRR(Ostw, Rzero, Ro1,O(Frame,mr));	// Ro1->mr = nil

Adding these instructions made the JIT start working on OS X.  Quoting
some mail from Charles about why the `zero R0' instructions are
necessary:

	i decided to define R0==0 in the Inferno compilers ([...]).
	the run time start up code and the native kernel load R0 with
	0 once or twice and keep it there.

	that could be done in preamble().  i haven't got my powepc
	handbook here, but i think this will do that much:
		s = code = malloc(PREFLEN*sizeof(*code));
		ldc((ulong)&R, Rreg);
		AIRR(Oaddi, Rzero, 0, 0);	/* set R0 to zero */
	in fact you need to add that line after every ldc((ulong)&R,
	Rreg); in punt, and several mac*, so that the zero value is
	reset after every call out to C code.

I'll send my comp-power.c to Charles and Jeff Sickel.

I'll keep looking through my changes, but I'm pretty sure that this is
the one that matters.

Speaking of changes getting missed, I've attached a bundle of a
program that I use a lot when merging trees.  It sounds dangerous, but
it's pretty cautious and I've used it for years without trouble.
Given an original tree and a modified tree, cd into the modified tree
(or a copy thereof if you want to preserve the modified tree), and run

	diff -rw /original/tree . >/tmp/diffs
	rmsame /original/tree

This removes all empty directories and all files in the current tree
that exactly match files in /original/tree.  (One could argue that it
should remove the matching contents of the argument tree instead, but
this is the way it's always been.  There may be a small performance
advantage to removing using relative path names in the current tree.)
Obvious attempts to shoot yourself in the foot, such as `rmsame .' and
`rmsame `{pwd}' are rejected.  The reason to run diff -r first is to
see if any files in the original tree had been removed from the
modified tree, if you care.

One can then prowl the remaining degenerate tree with acme or cd and
remove files as they are merged (or rejected) into the original tree.

[-- Attachment #2.1: Type: text/plain, Size: 319 bytes --]

The following attachment had content that we can't
prove to be harmless.  To avoid possible automatic
execution, we changed the content headers.
The original header was:

	Content-Disposition: attachment; filename=rmsame.bun
	Content-Type: text/plain; charset="UTF-8"
	Content-Transfer-Encoding: quoted-printable

[-- Attachment #2.2: rmsame.bun.suspect --]
[-- Type: application/octet-stream, Size: 30173 bytes --]

# To unbundle, run this file
mkdir rmsame
echo rmsame/Makefile
sed 's/^X//' >rmsame/Makefile <<'!'
OS=o8v
O=o
CFLAGS=-O -w -D_BSD_EXTENSION -D_POSIX_SOURCE
DESTDIR=$(HOME)/bin/$(objtype)
CC=cc
LD=cc

all: rmsame

rmsame: rmsame.$O cleanname.$O
X	$(CC) -o $@ $(CFLAGS) rmsame.$O cleanname.$O

install: rmsame
X	cp rmsame $(DESTDIR)
X	cp -x rmsame.man $(HOME)/man/1/rmsame

clean:
X	rm -f core make.log rmsame *.[$(OS)]
!
echo rmsame/README
sed 's/^X//' >rmsame/README <<'!'
cleanname.c is a Plan 9 source file, so cleanname.NOTICE
and cleanname.LICENSE apply to it.  The terms are fairly
liberal; you may redistribute it, modify it or sell it,
but read the terms to be certain.
!
echo rmsame/cleanname.LICENSE
sed 's/^X//' >rmsame/cleanname.LICENSE <<'!'
The Plan 9 software is provided under the terms of the
Lucent Public License, Version 1.02, reproduced below,
with the following exceptions:

1. No right is granted to create derivative works of or
X   to redistribute (other than with the Plan 9 Operating System)
X   the screen imprinter fonts identified in subdirectory
X   /lib/font/bit/lucida and printer fonts (Lucida Sans Unicode, Lucida
X   Sans Italic, Lucida Sans Demibold, Lucida Typewriter, Lucida Sans
X   Typewriter83), identified in subdirectory /sys/lib/postscript/font.
X   These directories contain material copyrights by B&H Inc. and Y&Y Inc.

2. The printer fonts identified in subdirectory /sys/lib/ghostscript/font
X   are subject to the GNU GPL, reproduced in the file /LICENSE.gpl.

3. The ghostscript program in the subdirectory /sys/src/cmd/gs is
X   covered by the Aladdin Free Public License, reproduced in the file
X   /LICENSE.afpl.

X===================================================================

Lucent Public License Version 1.02

THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS PUBLIC
LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE
PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.

1. DEFINITIONS

X"Contribution" means:

X  a. in the case of Lucent Technologies Inc. ("LUCENT"), the Original
X     Program, and
X  b. in the case of each Contributor,

X     i. changes to the Program, and
X    ii. additions to the Program;

X    where such changes and/or additions to the Program were added to the
X    Program by such Contributor itself or anyone acting on such
X    Contributor's behalf, and the Contributor explicitly consents, in
X    accordance with Section 3C, to characterization of the changes and/or
X    additions as Contributions.

X"Contributor" means LUCENT and any other entity that has Contributed a
Contribution to the Program.

X"Distributor" means a Recipient that distributes the Program,
modifications to the Program, or any part thereof.

X"Licensed Patents" mean patent claims licensable by a Contributor
which are necessarily infringed by the use or sale of its Contribution
alone or when combined with the Program.

X"Original Program" means the original version of the software
accompanying this Agreement as released by LUCENT, including source
code, object code and documentation, if any.

X"Program" means the Original Program and Contributions or any part
thereof

X"Recipient" means anyone who receives the Program under this
Agreement, including all Contributors.

2. GRANT OF RIGHTS

X a. Subject to the terms of this Agreement, each Contributor hereby
X    grants Recipient a non-exclusive, worldwide, royalty-free copyright
X    license to reproduce, prepare derivative works of, publicly display,
X    publicly perform, distribute and sublicense the Contribution of such
X    Contributor, if any, and such derivative works, in source code and
X    object code form.
X    
X b. Subject to the terms of this Agreement, each Contributor hereby
X    grants Recipient a non-exclusive, worldwide, royalty-free patent
X    license under Licensed Patents to make, use, sell, offer to sell,
X    import and otherwise transfer the Contribution of such Contributor, if
X    any, in source code and object code form. The patent license granted
X    by a Contributor shall also apply to the combination of the
X    Contribution of that Contributor and the Program if, at the time the
X    Contribution is added by the Contributor, such addition of the
X    Contribution causes such combination to be covered by the Licensed
X    Patents. The patent license granted by a Contributor shall not apply
X    to (i) any other combinations which include the Contribution, nor to
X    (ii) Contributions of other Contributors. No hardware per se is
X    licensed hereunder.
X    
X c. Recipient understands that although each Contributor grants the
X    licenses to its Contributions set forth herein, no assurances are
X    provided by any Contributor that the Program does not infringe the
X    patent or other intellectual property rights of any other entity. Each
X    Contributor disclaims any liability to Recipient for claims brought by
X    any other entity based on infringement of intellectual property rights
X    or otherwise. As a condition to exercising the rights and licenses
X    granted hereunder, each Recipient hereby assumes sole responsibility
X    to secure any other intellectual property rights needed, if any. For
X    example, if a third party patent license is required to allow
X    Recipient to distribute the Program, it is Recipient's responsibility
X    to acquire that license before distributing the Program.

X d. Each Contributor represents that to its knowledge it has sufficient
X    copyright rights in its Contribution, if any, to grant the copyright
X    license set forth in this Agreement.

3. REQUIREMENTS

A. Distributor may choose to distribute the Program in any form under
this Agreement or under its own license agreement, provided that:

X a. it complies with the terms and conditions of this Agreement;

X b. if the Program is distributed in source code or other tangible
X    form, a copy of this Agreement or Distributor's own license agreement
X    is included with each copy of the Program; and

X c. if distributed under Distributor's own license agreement, such
X    license agreement:

X      i. effectively disclaims on behalf of all Contributors all warranties
X         and conditions, express and implied, including warranties or
X         conditions of title and non-infringement, and implied warranties or
X         conditions of merchantability and fitness for a particular purpose;
X     ii. effectively excludes on behalf of all Contributors all liability
X         for damages, including direct, indirect, special, incidental and
X         consequential damages, such as lost profits; and
X    iii. states that any provisions which differ from this Agreement are
X         offered by that Contributor alone and not by any other party.

B. Each Distributor must include the following in a conspicuous
X   location in the Program:

X   Copyright (C) 2003, Lucent Technologies Inc. and others. All Rights
X   Reserved.

C. In addition, each Contributor must identify itself as the
originator of its Contribution in a manner that reasonably allows
subsequent Recipients to identify the originator of the Contribution.
Also, each Contributor must agree that the additions and/or changes
are intended to be a Contribution. Once a Contribution is contributed,
it may not thereafter be revoked.

4. COMMERCIAL DISTRIBUTION

Commercial distributors of software may accept certain
responsibilities with respect to end users, business partners and the
like. While this license is intended to facilitate the commercial use
of the Program, the Distributor who includes the Program in a
commercial product offering should do so in a manner which does not
create potential liability for Contributors. Therefore, if a
Distributor includes the Program in a commercial product offering,
such Distributor ("Commercial Distributor") hereby agrees to defend
and indemnify every Contributor ("Indemnified Contributor") against
any losses, damages and costs (collectively"Losses") arising from
claims, lawsuits and other legal actions brought by a third party
against the Indemnified Contributor to the extent caused by the acts
or omissions of such Commercial Distributor in connection with its
distribution of the Program in a commercial product offering. The
obligations in this section do not apply to any claims or Losses
relating to any actual or alleged intellectual property infringement.
In order to qualify, an Indemnified Contributor must: a) promptly
notify the Commercial Distributor in writing of such claim, and b)
allow the Commercial Distributor to control, and cooperate with the
Commercial Distributor in, the defense and any related settlement
negotiations. The Indemnified Contributor may participate in any such
claim at its own expense.

XFor example, a Distributor might include the Program in a commercial
product offering, Product X. That Distributor is then a Commercial
Distributor. If that Commercial Distributor then makes performance
claims, or offers warranties related to Product X, those performance
claims and warranties are such Commercial Distributor's responsibility
alone. Under this section, the Commercial Distributor would have to
defend claims against the Contributors related to those performance
claims and warranties, and if a court requires any Contributor to pay
any damages as a result, the Commercial Distributor must pay those
damages.

5. NO WARRANTY

EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS
PROVIDED ON AN"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY
OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
responsible for determining the appropriateness of using and
distributing the Program and assumes all risks associated with its
exercise of rights under this Agreement, including but not limited to
the risks and costs of program errors, compliance with applicable
laws, damage to or loss of data, programs or equipment, and
unavailability or interruption of operations.

6. DISCLAIMER OF LIABILITY

EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR
ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING
WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR
DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

7. EXPORT CONTROL

Recipient agrees that Recipient alone is responsible for compliance
with the United States export administration regulations (and the
export control laws and regulation of any other countries).

8. GENERAL

If any provision of this Agreement is invalid or unenforceable under
applicable law, it shall not affect the validity or enforceability of
the remainder of the terms of this Agreement, and without further
action by the parties hereto, such provision shall be reformed to the
minimum extent necessary to make such provision valid and enforceable.

If Recipient institutes patent litigation against a Contributor with
respect to a patent applicable to software (including a cross-claim or
counterclaim in a lawsuit), then any patent licenses granted by that
Contributor to such Recipient under this Agreement shall terminate as
of the date such litigation is filed. In addition, if Recipient
institutes patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Program
itself (excluding combinations of the Program with other software or
hardware) infringes such Recipient's patent(s), then such Recipient's
rights granted under Section 2(b) shall terminate as of the date such
litigation is filed.

All Recipient's rights under this Agreement shall terminate if it
fails to comply with any of the material terms or conditions of this
Agreement and does not cure such failure in a reasonable period of
time after becoming aware of such noncompliance. If all Recipient's
rights under this Agreement terminate, Recipient agrees to cease use
and distribution of the Program as soon as reasonably practicable.
However, Recipient's obligations under this Agreement and any licenses
granted by Recipient relating to the Program shall continue and
survive.

LUCENT may publish new versions (including revisions) of this
Agreement from time to time. Each new version of the Agreement will be
given a distinguishing version number. The Program (including
Contributions) may always be distributed subject to the version of the
Agreement under which it was received. In addition, after a new
version of the Agreement is published, Contributor may elect to
distribute the Program (including its Contributions) under the new
version. No one other than LUCENT has the right to modify this
Agreement. Except as expressly stated in Sections 2(a) and 2(b) above,
Recipient receives no rights or licenses to the intellectual property
of any Contributor under this Agreement, whether expressly, by
implication, estoppel or otherwise. All rights in the Program not
expressly granted under this Agreement are reserved.

This Agreement is governed by the laws of the State of New York and
the intellectual property laws of the United States of America. No
party to this Agreement will bring a legal action under this Agreement
more than one year after the cause of action arose. Each party waives
its rights to a jury trial in any resulting litigation.

!
echo rmsame/cleanname.NOTICE
sed 's/^X//' >rmsame/cleanname.NOTICE <<'!'
Copyright © 2002 Lucent Technologies Inc.
All Rights Reserved
!
echo rmsame/cleanname.c
sed 's/^X//' >rmsame/cleanname.c <<'!'
X/*
X * In place, rewrite name to compress multiple /, eliminate ., and process ..
X */
X#define SEP(x)	((x)=='/' || (x) == 0)
char*
cleanname(char *name)
X{
X	char *p, *q, *dotdot;
X	int rooted;

X	rooted = name[0] == '/';

X	/*
X	 * invariants:
X	 *	p points at beginning of path element we're considering.
X	 *	q points just past the last path element we wrote (no slash).
X	 *	dotdot points just past the point where .. cannot backtrack
X	 *		any further (no slash).
X	 */
X	p = q = dotdot = name+rooted;
X	while(*p) {
X		if(p[0] == '/')	/* null element */
X			p++;
X		else if(p[0] == '.' && SEP(p[1]))
X			p += 1;	/* don't count the separator in case it is nul */
X		else if(p[0] == '.' && p[1] == '.' && SEP(p[2])) {
X			p += 2;
X			if(q > dotdot) {	/* can backtrack */
X				while(--q > dotdot && *q != '/')
X					;
X			} else if(!rooted) {	/* /.. is / but ./../ is .. */
X				if(q != name)
X					*q++ = '/';
X				*q++ = '.';
X				*q++ = '.';
X				dotdot = q;
X			}
X		} else {	/* real path element */
X			if(q != name+rooted)
X				*q++ = '/';
X			while((*q = *p) != '/' && *q != 0)
X				p++, q++;
X		}
X	}
X	if(q == name)	/* empty string is really ``.'' */
X		*q++ = '.';
X	*q = '\0';
X	return name;
X}
!
echo rmsame/mkfile
sed 's/^X//' >rmsame/mkfile <<'!'
X</$objtype/mkfile

TARG=rmsame
OFILES=rmsame.$O cleanname.$O
HFILES=
BIN=$home/bin/$objtype
CFLAGS=-w -D_BSD_EXTENSION -D_POSIX_SOURCE
CC=pcc -c
LD=pcc

X</sys/src/cmd/mkone
!
echo rmsame/rmsame.c
sed 's/^X//' >rmsame/rmsame.c <<'!'
X/*
X * rmsame [-npsv] directory - remove files in . identical to those in directory.
X *
X * rmsame recursively descends the current directory subtree and
X * removes any files that are identical to files present in the
X * comparison directory.  rmsame refuses to "rmsame ." ("rm -rf ."  is
X * faster and has the same effect).  symbolic links to directories are
X * not followed.  In cases of doubt, the file is left alone.
X *
X * changed to read an entire directory's contents first, then process files,
X * instead of reading one directory entry and then processing it.
X *	by Geoff Collyer, April 1996
X * Copyright (C) 1986,1987	Ron Wessels
X * based on a shell script by Geoff Collyer
X *
X * Permission is hereby granted for general usage and re-distribution of
X * this program as long as:
X *	a) it is not sold for profit
X *	b) the author's name and this notice remain intact in the program
X */

X#include <stdio.h>
X#include <stdlib.h>
X#include <string.h>
X#include <dirent.h>
X#include <unistd.h>
X#include <errno.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <fcntl.h>

X#define STREQ(a, b)	(*(a) == *(b) && strcmp(a, b) == 0)
X#define SAMEFILE(stp1, stp2) ((stp1)->st_dev == (stp2)->st_dev && \
X			      (stp1)->st_ino == (stp2)->st_ino)

X#ifdef S_IFLNK
X#define STAT lstat
X#else
X#define STAT stat
X#endif			/* S_IFLNK */

X#ifndef MAXPATHLEN
X#define MAXPATHLEN 1024
X#endif

enum {
X	Differ = 0,
X	Same,
X	Missing,
X	Ignore,

X	/*
X	 * size of comparison buffers: too large means reading blocks
X	 * unnecessarily when files differ early on; too small means
X	 * many reads when files are identical.
X	 */
X	Bufsize = 4*1024,
X};

extern	char*	cleanname(char*);

char *argv0 = "rmsame";

typedef struct stat Stat;
typedef struct dirent Dirent;
typedef struct dirname Dirname;
struct dirname {
X	char	*name;
X	Dirname	*next;
X};

static char cmpfile[MAXPATHLEN+1];
X/*
X * holds full path of current directory at all times.
X * used for error messages, not traversal.
X */
static char fullcurrdir[MAXPATHLEN+1];
X/*
X * always contains current directory, but may be just the name of the last
X * component or may be the full path, depending upon the slow flag.
X */
static char currdir[MAXPATHLEN+1];
static Stat filestat, cmpstat;

X/*
X * Execution flags.
X */
static int verbose = 0;		/* print out progress */
X/*
X * don't use ".."; no longer needed on Plan 9 &
X * probably only rarely needed on Unix
X */
static int slow = 0;
static int prdiff, prsame, dontrm;

static void rmsame(void);
static int cmpplain(char *file1name, char *file2name);

static int
iscurrdir(char *dir, Stat *dotstp)
X{
X	Stat stbuf;
X	Stat *dstp = &stbuf;

X	return stat(dir, dstp) >= 0 && SAMEFILE(dotstp, dstp);
X}

static int
chgdir(char *dir)
X{
X	int ret = chdir(dir);

X	if (ret < 0) {
X		perror(dir);
X		fprintf(stderr, "%s: chdir(%s) in %s\n",
X			argv0, dir, fullcurrdir);
X	}
X	return ret;
X}

static void
setup(char *dirname)
X{
X	/*
X	 * Get an absolute path for the comparison directory,
X	 * and make sure it is not ".".
X	 */
X	if (stat(".", &filestat) < 0) {
X		perror(".");
X		fprintf(stderr, "%s: stat of . at start\n", argv0);
X		exit(2);
X	}
X	if (verbose)
X		fprintf(stderr, "getting current directory\n");
X	if (getcwd(currdir, sizeof currdir) == NULL) {
X		/* sometimes life is just too complex for getcwd */
X		char *pwd = getenv("PWD");

X		fprintf(stderr, "%s: getcwd failed\n", argv0, pwd, currdir);
X		if (pwd != NULL && iscurrdir(pwd, &filestat)) {
X			strncpy(currdir, pwd, sizeof currdir);
X			/* getcwd may have changed curr. dir. */
X			if (chgdir(pwd) < 0)
X				exit(1);
X		} else {
X			fprintf(stderr, "%s: can't get current dir.\n", argv0);
X			exit(1);
X		}
X	}
X	strcpy(fullcurrdir, currdir);

X	cmpfile[0] = '\0';
X	if (dirname[0] != '/') {
X		strcat(cmpfile, currdir);
X		strcat(cmpfile, "/");
X	}
X	strcat(cmpfile, dirname);
X	cleanname(cmpfile);
X	if (stat(cmpfile, &cmpstat) < 0) {
X		perror(cmpfile);
X		fprintf(stderr, "%s: stat(%s) in %s\n",
X			argv0, fullcurrdir, cmpfile, fullcurrdir);
X		exit(1);
X	}
X	if ((cmpstat.st_mode&S_IFMT) != S_IFDIR) {
X		fprintf(stderr, "%s: %s is not a directory\n", argv0, cmpfile);
X		exit(1);
X	}
X	if (SAMEFILE(&filestat, &cmpstat)) {
X		fprintf(stderr, "%s: directory is \".\"\n", argv0);
X		exit(1);
X	}
X}

main(int argc, char *argv[])
X{
X	int opt, errflag = 0;

X	if (argc > 0)
X		argv0 = argv[0];
X	while ((opt = getopt(argc, argv, "npsv")) != EOF) {
X		switch (opt) {
X		case 'n':
X			dontrm = prdiff = 1;
X			break;
X		case 'p':
X			dontrm = prsame = 1;
X			break;
X		case 's':
X			slow++;		/* but robust */
X			break;
X		case 'v':
X			verbose++;
X			break;
X		case '?':
X		default:
X			errflag++;
X			break;
X		}
X	}
X	if (errflag || optind != argc - 1) {
X		fprintf(stderr, "Usage: %s [-npsv] directory\n", argv0);
X		exit(1);
X	}
X	if (!dontrm)
X		setbuf(stdout, (char *)NULL);
X	setup(argv[optind]);

X	if (verbose)
X		fprintf(stderr, "beginning descent\n");
X	rmsame();
X	exit(0);
X	return 0;
X}

static int
dispose(char *compname, int same)
X{
X	int ret = 0;

X	if (dontrm) {
X		if (prdiff && (same == Differ || Same == Missing) ||
X		    prsame && same == Same) {
X			printf("%s\n", cmpfile);
X			fflush(stdout);
X		}
X	} else if (same == Same) {
X		ret = unlink(compname);
X		if (ret < 0) {
X			perror(compname);
X			fprintf(stderr, "%s: unlink(%s) in %s\n",
X				argv0, compname, fullcurrdir);
X		} else if (verbose)
X			printf("rm %s\n", compname);
X	}
X	return ret;
X}

X/*
X * Symbolic link data.
X */
X#ifdef S_IFLNK
static char filelink[MAXNAMLEN], cmplink[MAXNAMLEN];
static int filecount, cmpcount;
X#endif

typedef struct {
X	Dirname	*dirnm;
X	int	opened;
X	int	count;
X} Rddirres;

static Rddirres
readalldir(char *name)
X{
X	Rddirres res;
X	DIR *dir;
X	Dirent *dirp;
X	Dirname *newdir, *curdir = NULL;

X	errno = 0;
X	res.dirnm = NULL;
X	res.opened = res.count = 0;
X	dir = opendir(name);
X	if (dir == NULL)
X		return res;
X	res.opened++;

X	/* read the whole directory into memory */
X	while ((dirp = readdir(dir)) != NULL) {
X		newdir = malloc(sizeof *newdir);
X		if (newdir == NULL)
X			abort();
X		newdir->name = strdup(dirp->d_name);
X		newdir->next = NULL;
X		if (res.dirnm == NULL)
X			res.dirnm = newdir;
X		else
X			curdir->next = newdir;
X		curdir = newdir;
X		res.count++;
X	}
X	closedir(dir);
X	return res;
X}

static void
freealldir(Dirname *alldir)
X{
X	Dirname *next, *dp;

X	for (dp = alldir; dp != NULL; dp = next) {
X		next = dp->next;
X		dp->next = NULL;
X		free(dp->name);
X		dp->name = NULL;
X		free(dp);
X	}
X}

static int
samedir(char *compname, char *cdp)
X{
X	char *dirname;

X	/*
X	 * Recursively rmsame the sub-directory.
X	 */
X	*cdp = '/';
X	strcpy(cdp+1, compname);	/* maintain full path to . */
X	if (slow)
X		dirname = fullcurrdir;
X	else
X		dirname = compname;
X	strcpy(currdir, dirname);
X	if (verbose)
X		fprintf(stderr, "cd %s\n", dirname);
X	if (chgdir(dirname) < 0)	/* descend */
X		return Differ;		/* no perms, perhaps */

X	rmsame();

X	*cdp = '\0';			/* maintain full path to . */
X	if (!slow)
X		dirname = "..";
X	if (verbose)
X		fprintf(stderr, "cd %s\n", dirname);
X	if (chgdir(dirname) < 0)	/* climb back up */
X		exit(2);		/* something is ill */

X	/* Remove the directory entry if empty. */
X	if (!dontrm && rmdir(compname) == 0 && verbose)
X		fprintf(stderr, "rmdir %s\n", compname);
X	return Ignore;
X}

X#ifdef S_IFLNK
static int
samesymlnk(char *filename)
X{
X	int filecnt, cmpcnt, same = Differ;

X	/*
X	 * Remove if symbolic links point to the same place.
X	 * Arguably this is too conservative, but best to let
X	 * the user handle this one.
X	 */
X	filecnt = readlink(filename, filelink, sizeof filelink);
X	cmpcnt =  readlink(cmpfile,  cmplink,  sizeof cmplink);
X	if (filecnt < 0) {
X		perror(filename);
X		fprintf(stderr, "%s: %s in %s\n", argv0, filename, fullcurrdir);
X	} else if (cmpcnt < 0) {
X		perror(cmpfile);
X		fprintf(stderr, "%s: %s in %s\n", argv0, cmpfile,  fullcurrdir);
X	} else if (filecnt == cmpcnt &&
X	    strncmp(filelink, cmplink, filecnt) == 0)
X		same = Same;
X	return same;
X}
X#endif

static int
compare(char *compname, char *cmpname, char *cdp)
X{
X	/*
X	 * skip to next file if: ".", "..", either is non-existent,
X	 * differing file types, or matching device & i-number
X	 * (which means we got tricked by symbolic links or namespace
X	 * mapping) and link count is 1 (the last link).
X	 */
X	if (STREQ(compname, ".") || STREQ(compname, ".."))
X		return Ignore;
X	strcpy(cmpname, compname);
X	if (STAT(compname, &filestat) < 0) {	/* vanished since readdir? */
X		perror(compname);
X		fprintf(stderr, "%s: stat(%s) in %s\n",
X			argv0, compname, fullcurrdir);
X		return Missing;
X	}
X	if (STAT(cmpfile, &cmpstat) < 0)	/* not in other tree */
X		return Missing;
X	if ((filestat.st_mode&S_IFMT) != (cmpstat.st_mode&S_IFMT) ||
X		/* don't remove last link */
X	    SAMEFILE(&filestat, &cmpstat) && filestat.st_nlink <= 1) {
X		if (verbose)
X			printf("ignoring %s\n", compname);
X		return Differ;
X	}

X	switch (filestat.st_mode&S_IFMT) {
X	case S_IFDIR:
X		/* Recursively rmsame the sub-directory. */
X		return samedir(compname, cdp);
X	case S_IFREG:
X		return filestat.st_size == cmpstat.st_size &&
X		    cmpplain(compname, cmpfile) == Same;
X	case S_IFCHR:
X	case S_IFBLK:
X#ifdef notdef
X		/* Remove if major & minor device numbers are same. */
X		return filestat.st_rdev == cmpstat.st_rdev;
X#endif
X#ifdef S_IFLNK
X	case S_IFLNK:
X		return samesymlnk(compname);
X#endif
X#ifdef S_IFSOCK
X	case S_IFSOCK:
X		return Same;		/* Nuke the gay unborn sockets! */
X#endif
X	}
X}

static void
examine(char *compname, char *cmpname, char *cdp)
X{
X	if (verbose)
X		fprintf(stderr, "name: %s\n", compname);
X	dispose(compname, compare(compname, cmpname, cdp));
X}

static void
rmsame(void)
X{
X	char *cmpname, *cdp;
X	Dirname *dp;
X	Rddirres dirres;

X	cmpname = &cmpfile[strlen(cmpfile)];
X	*cmpname++ = '/';
X	cdp = fullcurrdir + strlen(fullcurrdir);

X	dirres = readalldir(".");
X	if (!dirres.opened) {
X		if (errno == EMFILE) {
X			fprintf(stderr, "%s: directory structure too deep.\n",
X				argv0);
X			exit(1);
X		}
X		perror(".");
X		fprintf(stderr, "%s: opendir(.) in %s\n", argv0, fullcurrdir);
X		/*
X		 * this is probably a permission problem, so give up on this
X		 * directory but keep going.
X		 */
X	} else {
X		for (dp = dirres.dirnm; dp != NULL; dp = dp->next)
X			examine(dp->name, cmpname, cdp);
X		freealldir(dirres.dirnm);
X	}
X	*cmpname = '\0';
X}

X/* read with warning if error */
static int
wread(int fd, void *buf, long len, char *name)
X{
X	int bytes = read(fd, buf, len);

X	if (bytes < 0) {
X		perror(name);
X		fprintf(stderr, "%s: read(%s) in %s\n", argv0, name,
X			fullcurrdir);
X	}
X	return bytes;
X}

X/* open with warning if error */
static int
wopen(char *name, int mode)
X{
X	int fd = open(name, mode);

X	if (fd < 0) {
X		perror(name);
X		fprintf(stderr, "%s: open(%s) in %s\n", argv0, name,
X			fullcurrdir);
X	}
X	return fd;
X}

static int
cmpfds(char *name1, char *name2, int fd1, int fd2)
X{
X	int cnt1, cnt2;
X	char buf1[Bufsize], buf2[Bufsize];

X	if (fd1 < 0 || fd2 < 0)
X		return Differ;
X	do {
X		cnt1 = wread(fd1, buf1, sizeof buf1, name1);
X		cnt2 = wread(fd2, buf2, sizeof buf2, name2);
X		if (cnt1 < 0 || cnt2 < 0)
X			return Differ;
X		if (cnt1 != cnt2) {		/* can't happen */
X			fprintf(stderr,
X				"%s: read differing amounts from %s and %s\n",
X				argv0, name1, name2);
X			return Differ;
X		}
X		if (cnt1 == 0)			/* both at EOF? */
X			return Same;
X	} while (memcmp(buf1, buf2, cnt1) == 0);
X	return Differ;
X}

static int
cmpplain(char *name1, char *name2)
X{
X	int fd1, fd2, result = Differ;

X	fd1 = wopen(name1, O_RDONLY);
X	fd2 = wopen(name2, O_RDONLY);
X	if (fd1 >= 0 && fd2 >= 0)
X		result = cmpfds(name1, name2, fd1, fd2);
X	if (fd1 >= 0)
X		close(fd1);
X	if (fd2 >= 0)
X		close(fd2);
X	return result;
X}
!
echo rmsame/rmsame.man
sed 's/^X//' >rmsame/rmsame.man <<'!'
X.TH RMSAME 1
X.SH NAME
rmsame \- remove identical files
X.SH SYNOPSIS
X.B rmsame
X[
X.B \-npsv
X]
X.I directory
X.SH DESCRIPTION
X.B rmsame
will recursively compare files from the current directory
X(and below) with corresponding files from the
X.I directory
argument.
When files are identical, the local copy is deleted.
After a subdirectory has been processed, it is removed if it is empty.
X.PP
This program is useful when maintaining a system that is constantly
receiving new software releases.
Instead of installing local revisions repeatedly into the new releases,
one could load a new release into a scratch disk and run rmsame to
leave only those files that have changed.
These can then be examined and processed manually.
X.SH OPTIONS
X.PD 0
X.TP 5
X.B \-n
don't remove any files, just print the names of those which differ from those
under
X.IR directory .
X.TP 5
X.B \-p
don't remove any files, just print the names of files identical to those under
X.IR directory .
X.TP 5
X.B \-s
traverse directory trees slowly but reliably.
X.TP 5
X.B \-v
show the processing as it is taking place
X(normally processing is silent except for error messages).
X.PD
X.SH "SEE ALSO"
X.IR cmp (1),
X.IR rm (1),
X.IR rmdir (1)
X.SH DIAGNOSTICS
X.TP 5
X\fIname\fP is "."
The directory given as the comparison directory is also the current directory.
The command "rm\ \-r\ ." has the same effect, and is much faster.
X.SH BUGS
If the directory structure is too deep, the program runs out of
file descriptors and exits.
X.PP
A symbolic link is considered to be only identical to another
symbolic link pointing to the same name.
If the names are different, no check is made to see if the
paths are really the same.
X.SH AUTHORS
The original
X.B rmsame
was a shell script written by Geoff\ Collyer.
It was later re-written as a C program by Ron\ Wessels.
!

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [9fans] inferrno install, macos x, fails ...
  2004-04-05  2:17           ` Geoff Collyer
@ 2004-04-05  2:46             ` ron minnich
  2004-04-05  2:50               ` Geoff Collyer
  0 siblings, 1 reply; 10+ messages in thread
From: ron minnich @ 2004-04-05  2:46 UTC (permalink / raw)
  To: 9fans

I'm probably missing something but did not see source lying around on the 
web page, unless it is in the tarballs? I assumed the ISO had everything 
but see no source.

ron



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [9fans] inferrno install, macos x, fails ...
  2004-04-05  2:46             ` ron minnich
@ 2004-04-05  2:50               ` Geoff Collyer
  2004-04-05  3:15                 ` Russ Cox
  0 siblings, 1 reply; 10+ messages in thread
From: Geoff Collyer @ 2004-04-05  2:50 UTC (permalink / raw)
  To: 9fans

I haven't kept up with Vitanuova's evolving licensing plans, but I've
been a subscriber and thus entitled to source.  I'm not sure if the
free downloads include it these days.



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [9fans] inferrno install, macos x, fails ...
  2004-04-05  2:50               ` Geoff Collyer
@ 2004-04-05  3:15                 ` Russ Cox
  0 siblings, 0 replies; 10+ messages in thread
From: Russ Cox @ 2004-04-05  3:15 UTC (permalink / raw)
  To: 9fans

Geoff Collyer wrote:
> I haven't kept up with Vitanuova's evolving licensing plans, but I've
> been a subscriber and thus entitled to source.  I'm not sure if the
> free downloads include it these days.

the free downloads include source.  the iso has .9gz files
that need further extraction (by the installer) iirc.

russ


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2004-04-05  3:15 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-04-04  1:58 [9fans] inferrno install, macos x, fails ron minnich
2004-04-04  3:03 ` Number Six
2004-04-04  6:56   ` Charles Forsyth
2004-04-04 10:08     ` Geoff Collyer
2004-04-04 14:34       ` Jeff Sickel
2004-04-04 23:00         ` Geoff Collyer
2004-04-05  2:17           ` Geoff Collyer
2004-04-05  2:46             ` ron minnich
2004-04-05  2:50               ` Geoff Collyer
2004-04-05  3:15                 ` Russ Cox

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).