head     56.3;
access   paws bayes jws quist brad dew jwh;
symbols  ;
locks    ; strict;
comment  @# @;


56.3
date     93.01.27.13.17.39;  author jwh;  state Exp;
branches ;
next     56.2;

56.2
date     93.01.27.11.58.58;  author jwh;  state Exp;
branches ;
next     56.1;

56.1
date     91.11.05.09.54.49;  author jwh;  state Exp;
branches ;
next     55.1;

55.1
date     91.08.25.10.30.16;  author jwh;  state Exp;
branches ;
next     54.3;

54.3
date     91.08.21.10.35.24;  author jwh;  state Exp;
branches ;
next     54.2;

54.2
date     91.08.21.09.39.47;  author jwh;  state Exp;
branches ;
next     54.1;

54.1
date     91.03.18.15.32.05;  author jwh;  state Exp;
branches ;
next     53.1;

53.1
date     91.03.11.19.31.58;  author jwh;  state Exp;
branches ;
next     52.1;

52.1
date     91.02.19.09.16.48;  author jwh;  state Exp;
branches ;
next     51.1;

51.1
date     91.01.30.16.16.20;  author jwh;  state Exp;
branches ;
next     50.1;

50.1
date     90.10.29.16.30.40;  author jwh;  state Exp;
branches ;
next     49.1;

49.1
date     90.08.14.14.14.26;  author jwh;  state Exp;
branches ;
next     48.1;

48.1
date     90.07.26.11.20.47;  author jwh;  state Exp;
branches ;
next     47.1;

47.1
date     90.05.14.11.05.27;  author dew;  state Exp;
branches ;
next     46.1;

46.1
date     90.05.07.08.52.24;  author jwh;  state Exp;
branches ;
next     45.1;

45.1
date     90.04.19.16.00.22;  author jwh;  state Exp;
branches ;
next     44.1;

44.1
date     90.04.01.22.17.31;  author jwh;  state Exp;
branches ;
next     43.1;

43.1
date     90.03.20.14.10.01;  author jwh;  state Exp;
branches ;
next     42.1;

42.1
date     90.01.23.17.54.27;  author jwh;  state Exp;
branches ;
next     41.1;

41.1
date     89.12.22.11.36.40;  author jwh;  state Exp;
branches ;
next     40.1;

40.1
date     89.09.29.11.57.44;  author jwh;  state Exp;
branches ;
next     39.1;

39.1
date     89.09.26.16.42.29;  author dew;  state Exp;
branches ;
next     38.1;

38.1
date     89.08.29.11.34.26;  author jwh;  state Exp;
branches ;
next     37.1;

37.1
date     89.05.12.11.48.10;  author dew;  state Exp;
branches ;
next     36.1;

36.1
date     89.02.06.10.25.50;  author dew;  state Exp;
branches ;
next     35.1;

35.1
date     89.02.02.13.41.17;  author dew;  state Exp;
branches ;
next     34.1;

34.1
date     89.01.23.16.16.31;  author jwh;  state Exp;
branches ;
next     33.1;

33.1
date     89.01.16.11.47.59;  author dew;  state Exp;
branches ;
next     32.1;

32.1
date     89.01.10.11.57.10;  author bayes;  state Exp;
branches ;
next     31.1;

31.1
date     88.12.14.18.18.07;  author bayes;  state Exp;
branches ;
next     30.1;

30.1
date     88.12.09.13.55.06;  author dew;  state Exp;
branches ;
next     29.1;

29.1
date     88.10.31.15.39.45;  author bayes;  state Exp;
branches ;
next     28.1;

28.1
date     88.10.06.11.06.05;  author dew;  state Exp;
branches ;
next     27.1;

27.1
date     88.09.29.11.48.46;  author bayes;  state Exp;
branches ;
next     26.1;

26.1
date     88.09.28.13.34.31;  author bayes;  state Exp;
branches ;
next     25.1;

25.1
date     88.03.02.09.42.27;  author bayes;  state Exp;
branches ;
next     24.1;

24.1
date     87.08.31.10.12.01;  author jws;  state Exp;
branches ;
next     23.1;

23.1
date     87.08.26.10.55.13;  author bayes;  state Exp;
branches ;
next     22.1;

22.1
date     87.08.17.11.36.45;  author bayes;  state Exp;
branches ;
next     21.1;

21.1
date     87.08.12.14.20.57;  author bayes;  state Exp;
branches ;
next     20.1;

20.1
date     87.07.30.11.32.25;  author bayes;  state Exp;
branches ;
next     19.1;

19.1
date     87.06.01.08.44.46;  author jws;  state Exp;
branches ;
next     18.1;

18.1
date     87.05.20.15.51.43;  author bayes;  state Exp;
branches ;
next     17.1;

17.1
date     87.04.30.10.56.18;  author jws;  state Exp;
branches ;
next     16.1;

16.1
date     87.04.26.16.06.46;  author jws;  state Exp;
branches ;
next     15.1;

15.1
date     87.04.13.09.46.34;  author jws;  state Exp;
branches ;
next     14.1;

14.1
date     87.04.01.15.55.20;  author jws;  state Exp;
branches ;
next     13.1;

13.1
date     87.02.28.18.50.15;  author jws;  state Exp;
branches ;
next     12.1;

12.1
date     87.02.02.13.43.06;  author jws;  state Exp;
branches ;
next     11.1;

11.1
date     87.01.19.10.09.35;  author jws;  state Exp;
branches ;
next     10.1;

10.1
date     86.12.24.11.24.23;  author jws;  state Exp;
branches ;
next     9.1;

9.1
date     86.12.12.15.07.24;  author bayes;  state Exp;
branches ;
next     8.1;

8.1
date     86.11.27.12.18.12;  author jws;  state Exp;
branches ;
next     7.1;

7.1
date     86.11.20.14.27.35;  author hal;  state Exp;
branches ;
next     6.2;

6.2
date     86.11.19.17.24.28;  author bayes;  state Exp;
branches ;
next     6.1;

6.1
date     86.11.04.18.23.28;  author paws;  state Exp;
branches ;
next     5.1;

5.1
date     86.10.28.17.10.55;  author hal;  state Exp;
branches ;
next     4.1;

4.1
date     86.09.30.20.06.57;  author hal;  state Exp;
branches ;
next     3.1;

3.1
date     86.09.01.12.17.22;  author hal;  state Exp;
branches ;
next     1.7;

1.7
date     86.08.18.10.05.34;  author hal;  state Exp;
branches ;
next     1.6;

1.6
date     86.08.14.11.42.57;  author hal;  state Exp;
branches ;
next     1.5;

1.5
date     86.08.14.10.20.51;  author hal;  state Exp;
branches ;
next     1.4;

1.4
date     86.08.13.12.35.22;  author hal;  state Exp;
branches ;
next     1.3;

1.3
date     86.08.13.10.21.00;  author hal;  state Exp;
branches ;
next     1.2;

1.2
date     86.08.12.11.25.37;  author hal;  state Exp;
branches ;
next     1.1;

1.1
date     86.08.01.16.43.01;  author hal;  state tmp;
branches ;
next     ;


desc
@Base file for PWS 3.2 release.

@


56.3
log
@
pws2rcs automatic delta on Wed Jan 27 13:14:25 MST 1993
@
text
@{
{ HFSBOOT
{ bootdam for HFS
{ has just enough HFS knowledge to read a file off the disc
{ $included by INITLOAD.
}
$partial_eval on$ { MUST be on }

module hfsboot;

import sysglobals, asm, loader;

export

procedure hfsread(sector, bytecount: integer;
		  anyvar buffer: window; media: boolean);

function hfsopen(anyvar fname: string255; var xaddr, length: integer;
		 var ftype: shortint): boolean;

implement


$include 'HFS:consts'$
$include 'HFS:cgroup'$
$include 'HFS:super'$
$include 'HFS:inode'$
$include 'HFS:dir'$

const
    { size of sectors used by boot ROM }
    BOOT_BSIZE =  256;

    { size of our cache block (we have 2) }
    { any power of 2 in [256..8K] }
    { We set this large, as space is only temporarily used }
    CSIZE  = 8*1024;

    { amount of superblock we really need, bytes }
    { WARNING -- breaks when sb format changes }
    SBNEEDED = 192;

    wshdr_size = 512;

type
    cache_buf = packed array[0..CSIZE-1] of char;
    indir_buf = packed array[0..(CSIZE div sizeof(integer))-1] of integer;
    super_buf = packed array[0..SBNEEDED-1] of char;
    cache_buf_ptr = ^cache_buf;

    {
    { Io block: includes an
    { inode, cells for the use of seek, etc,
    { and a buffer.
    }
    iob_type = {packed} record
	i_ino: inode_type;
	i_offset: integer;             { seek offset in file }
	i_bn: integer;                 { 1st block # of next read }
	i_ma: cache_buf_ptr;           { memory address of i/o buffer }
	i_cc: shortint;                { character count of transfer }
	i_buf: cache_buf;              { i/o buffer }
	i_fs: super_buf;               { superblock }
    end;

    indirb_type = packed record
	indirbuf: indir_buf;           { indirect block data }
	blkno: integer;                { frag # in indir buf }
	cblkno: integer;               { cache blk # in indir buf }
    end;

    vars_type = packed record
	{ indirect block cache }
	indirb: indirb_type;
	{ buffer for file i/o }
	iob: iob_type;
	fs: super_block_ptr_type;
    end;

    vars_ptr_type = ^vars_type;

var
    vars: vars_ptr_type;


procedure boot_mread(sector,bytecount: integer;
		     anyvar buffer:window; media:boolean); external;

{----------------------------------------------------------------}
function min(x, y: integer): integer;
begin
    if x < y then
	min := x
    else
	min := y;
end;

{-------------------------------------------------------------}
{
{ Low-level device reader.
{ Slightly altered (from bootlib) interface:
{      i_bn            fragment number from sbmap, or SBLOCK
{      i_offset        byte offset (absolute or in big blk)
{      i_cc            xfer count
{      i_ma            where it goes
{ i_ma always points to CSIZE (cache size) buffer
{ on return,
{      i_ma            where the requested data begins
{      i_cc            how much we got this time
{ return i_cc
{ if fs is nil, then this is a "raw" read, where i_bn is the
{ device block number, and i_offset the offset from there.
}
function devread: integer;
var
    sector, gap, xfer: integer;
begin
    with vars^.iob do begin
	{ 256-byte sector number }
	if vars^.fs <> nil then with vars^.fs^ do
	    sector := ((i_bn * fsize)
		       + (i_offset mod bsize)) div BOOT_BSIZE
	else
	    sector := ((i_bn * DEV_BSIZE) + i_offset) div BOOT_BSIZE;

	{ gap between start of sector and what user wants }
	gap := i_offset mod BOOT_BSIZE;

	xfer := min(CSIZE, i_cc + gap);

	{ boot_mread does an escape if error }
	boot_mread(sector, xfer, i_ma^, true);
	i_ma := addr(i_ma^, gap);
	i_cc := xfer - gap;
	devread := i_cc;
    end;
end;

{---------------------------------------------------------------}
{
{ sbmap
{ simplified read-only version of kernel bmap
{ given logical block number in file,
{ returns fragment number on disc
}
function sbmap(bn: integer): integer;
label
    999;
var
    ibyte, nb, cc, oldoffset, i, j, sh: integer;
    loopdone: boolean;
begin
    sbmap := 0;
    with vars^.fs^, vars^.iob.i_ino do begin

	{
	{ blocks 0..NDADDR-1 are direct blocks
	}
	if bn < NDADDR then begin
	    sbmap := db[bn];
	    goto 999;
	end;

	{
	{ addresses NIADDR have single and double indirect blocks.
	{ the first step is to determine how many levels of indirection.
	}
	sh := 1;
	bn := bn - NDADDR;
	j := NIADDR;
	loopdone := false;
	while (j > 0) and not loopdone do begin
	    sh := sh * nindir;
	    if bn < sh then
		loopdone := true
	    else begin
		bn := bn - sh;
		j := j - 1;
	    end;
	end;

	{
	{ fetch the first indirect block address from the inode
	}
	nb := ib[NIADDR - j];
	if nb = 0 then
	    goto 999;

	{
	{ fetch through the indirect blocks
	}
	while j <= NIADDR do with vars^.indirb do begin
	    sh := sh div nindir;
	    i := (bn div sh) mod nindir;
	    { want cache block with nb[i] }
	    ibyte := i * sizeof(integer);
	    if (blkno <> nb) or (cblkno <> ibyte div CSIZE) then
		with vars^.iob do begin
		    { block not in cache, so read it in }
		    i_bn := nb;
		    { read from beginning of CSIZE block }
		    oldoffset := i_offset;
		    i_offset := (ibyte div CSIZE) * CSIZE;
		    i_ma := addr(indirbuf);
		    i_cc := CSIZE;
		    cc := devread;
		    i_offset := oldoffset;
		    if cc <> CSIZE then
			goto 999;
		    blkno := nb;
		    cblkno := ibyte div CSIZE;
		end;
	    nb := indirbuf[i mod (CSIZE div sizeof(integer))];
	    if nb = 0 then
		goto 999;
	    j := j + 1;
	end;
    end;
    sbmap := nb;
999:
end;

{------------------------------------------------------------------}
procedure hfsread(sector, bytecount: integer;
		  anyvar buffer: window; media: boolean);
label
    999;
var
    lbn, xferred: integer;
    bufp: windowp;
begin
    with vars^.iob, vars^.fs^ do begin
	{ find byte offset in file }
	i_offset := (sector * BOOT_BSIZE) + wshdr_size;
	bufp := addr(buffer);
	xferred := 0;
	bytecount := min(bytecount, i_ino.size.ls - i_offset);
	while xferred < bytecount do begin
	    lbn := i_offset div bsize;
	    i_bn := sbmap(lbn);
	    if i_bn = 0 then
		goto 999;
	    i_ma := addr(i_buf);
	    i_cc := min(bytecount - xferred,
			bsize - (i_offset mod bsize));
	    if devread < 0 then
		goto 999;
	    moveleft(i_ma^, bufp^, i_cc);
	    i_offset := i_offset + i_cc;
	    xferred := xferred + i_cc;
	    bufp := addr(bufp^, i_cc);
	end;
    end;
999:
end;


{----------------------------------------------------------------------}
{
{ start of inode section, in frags
{ #define cgimin(fs, c)  (cgstart(fs, c) +(fs)->fs_iblkno)
}
function cgimin(c: integer): integer;
begin
    with vars^.fs^ do
	cgimin := (c * fpg) + (cgoffset * iand(c, -1-cgmask)) + iblkno;
end;

{------------------------------------------------------------}
{
{ inumber to frag containing it
{ #define itod(fs,x)      \
{     ((daddr_t)(cgimin(fs, itog(fs, x)) + \
{     (blkstofrags((fs),(((x) %(fs) -> fs_ipg) / INOPB(fs))))))
}
function itod(x: integer): integer;
begin
    with vars^.fs^ do
	itod := cgimin(x div ipg)
	   + ((x mod ipg) div inopb) * frag;
end;
{---------------------------------------------------------------------}
{
{ openi
{ open inode n by reading inode into buffer
{ returns boolean indicating success
}
function openi(n: integer): boolean;
label
    999;
var
    cc: integer;
begin
    with vars^.iob do begin
	i_bn := itod(n);
	i_offset := (n mod vars^.fs^.inopb) * sizeof(i_ino);
	i_cc := sizeof(i_ino);
	i_ma := addr(i_buf);
	if devread = sizeof(i_ino) then begin
	    moveleft(i_ma^, i_ino, sizeof(i_ino));
	    openi := true;
	end
	else
	    openi := false;
    end;
999:
end;


{------------------------------------------------------------------}
{
{ get next entry in a directory.
}
function readdir(var dirloc: integer): direntry_ptr_type;
label
    999;
var
    dp: direntry_ptr_type;
    off, lbn, d: integer;
begin

    readdir := nil;

    with vars^.iob do while dirloc < i_ino.size.ls do begin

	{ offset in cache block }
	off := dirloc mod CSIZE;

	if (dirloc = 0)
	or (dirloc div CSIZE <> i_offset div CSIZE) then begin
	    { read CSIZE more bytes }
	    lbn := dirloc div vars^.fs^.bsize;
	    d := sbmap(lbn);
	    if d = 0 then
		goto 999;
	    i_bn := d;
	    i_ma := addr(i_buf);
	    i_offset := dirloc;
	    i_cc := min(CSIZE, i_ino.size.ls - dirloc);
	    if devread < 0 then
		goto 999;
	end;

	dp := addr(i_buf, off);
	dirloc := dirloc + dp^.reclen;
	if dp^.ino <> 0 then begin
	    readdir := dp;
	    goto 999;
	end;
    end;
999:
end;

{----------------------------------------------------------------}
{
{ dlook
{ find inumber of given file in this directory
{ 0 -> not found
}
function dlook(s: string255ptr): integer;
label
    999;
const
    dirmode = 4;
    modediv = 4096;
var
    dp: direntry_ptr_type;
    dirloc: integer;
    i, len: integer;
    found: boolean;
begin
    dlook := 0;

    len := strlen(s^);
    if len = 0 then
	goto 999;
    if vars^.iob.i_ino.mode div modediv <> dirmode then
	goto 999;

    dirloc := 0;
    while true do begin
	dp := readdir(dirloc);
	if dp = nil then
	    goto 999;
	with dp^ do
	    if len = namlen then begin
		found := true;
		for i := 1 to len do
		    if name[i-1] <> s^[i] then
			found := false;
		if found then begin
		    dlook := ino;
		    goto 999;
		end;
	    end;
    end;
999:
end;

{----------------------------------------------------------------}
{
{ ifind
{ turn a pathname into an inumber
{ 0 -> failure
}
function ifind(path: string255): integer;
label
    999;
var
    n, i: integer;
    q: string255ptr;
    lenleft: integer;
begin
    ifind := 0;

    { always start at root }
    if not openi(root_inode) then
	goto 999;

    { q will march down string }
    q := addr(path);
    lenleft := strlen(path);

    while true do begin

	{ peel off initial slashes }
	while (lenleft > 0) and (q^[1] = '/') do begin
	    q := addr(q^, 1);
	    lenleft := lenleft - 1;
	    setstrlen(q^, lenleft);
	end;

	{ find end of next cmpnt }
	i := 1;
	while (i <= lenleft) and (q^[i] <> '/') do
	    i := i + 1;
	setstrlen(q^, i - 1);

	n := dlook(q);

	{ cmpnt not there? }
	if n = 0 then
	    goto 999;

	{ end of string? }
	if (i-1) = lenleft then begin
	    ifind := n;
	    goto 999;
	end;

	{ open this inode? }
	if not openi(n) then
	    goto 999;

	{ bump past this cmpnt }
	q := addr(q^, i-1);
	lenleft := lenleft - (i-1);
	setstrlen(q^, lenleft);
    end;

999:
end;

{------------------------------------------------------------------}
function hfsopen(anyvar fname: string255;
		 var xaddr, length: integer;
		 var ftype: shortint): boolean;
label
    999;
var
    togo, i: integer;
begin
    hfsopen := false;

    { borrow space from other end of globals area }
    vars := vars_ptr_type(a5 - 32766);

    { read superblock }
    with vars^.iob do begin
	togo := SBNEEDED;
	i_ma := addr(i_fs);
	vars^.fs := nil;
	i_offset := 0;
	i_bn := SBLOCK;
	while togo > 0 do begin
	    i_cc := togo;
	    if devread < 0 then
		goto 999;
	    togo := togo - i_cc;
	    i_ma := addr(i_ma^, i_cc);
	    i_offset := i_offset + i_cc;
	end;
	vars^.fs := addr(i_fs);

	{ get the inumber }
	i := ifind(fname);
	if i = 0 then
	    goto 999;

	{ and the inode }
	if not openi(i) then
	    goto 999;

    end;

    xaddr := 0;
    ftype := -5582;
    length := vars^.iob.i_ino.size.ls - wshdr_size;

    hfsopen := true;
999:
end;

end
@


56.2
log
@
pws2rcs automatic delta on Wed Jan 27 11:57:27 MST 1993
@
text
@d1 514
@


56.1
log
@Automatic bump of revision number for PWS version 3.25
@
text
@a0 514
{
{ HFSBOOT
{ bootdam for HFS
{ has just enough HFS knowledge to read a file off the disc
{ $included by INITLOAD.
}
$partial_eval on$ { MUST be on }

module hfsboot;

import sysglobals, asm, loader;

export

procedure hfsread(sector, bytecount: integer;
		  anyvar buffer: window; media: boolean);

function hfsopen(anyvar fname: string255; var xaddr, length: integer;
		 var ftype: shortint): boolean;

implement


$include 'HFS:consts'$
$include 'HFS:cgroup'$
$include 'HFS:super'$
$include 'HFS:inode'$
$include 'HFS:dir'$

const
    { size of sectors used by boot ROM }
    BOOT_BSIZE =  256;

    { size of our cache block (we have 2) }
    { any power of 2 in [256..8K] }
    { We set this large, as space is only temporarily used }
    CSIZE  = 8*1024;

    { amount of superblock we really need, bytes }
    { WARNING -- breaks when sb format changes }
    SBNEEDED = 192;

    wshdr_size = 512;

type
    cache_buf = packed array[0..CSIZE-1] of char;
    indir_buf = packed array[0..(CSIZE div sizeof(integer))-1] of integer;
    super_buf = packed array[0..SBNEEDED-1] of char;
    cache_buf_ptr = ^cache_buf;

    {
    { Io block: includes an
    { inode, cells for the use of seek, etc,
    { and a buffer.
    }
    iob_type = {packed} record
	i_ino: inode_type;
	i_offset: integer;             { seek offset in file }
	i_bn: integer;                 { 1st block # of next read }
	i_ma: cache_buf_ptr;           { memory address of i/o buffer }
	i_cc: shortint;                { character count of transfer }
	i_buf: cache_buf;              { i/o buffer }
	i_fs: super_buf;               { superblock }
    end;

    indirb_type = packed record
	indirbuf: indir_buf;           { indirect block data }
	blkno: integer;                { frag # in indir buf }
	cblkno: integer;               { cache blk # in indir buf }
    end;

    vars_type = packed record
	{ indirect block cache }
	indirb: indirb_type;
	{ buffer for file i/o }
	iob: iob_type;
	fs: super_block_ptr_type;
    end;

    vars_ptr_type = ^vars_type;

var
    vars: vars_ptr_type;


procedure boot_mread(sector,bytecount: integer;
		     anyvar buffer:window; media:boolean); external;

{----------------------------------------------------------------}
function min(x, y: integer): integer;
begin
    if x < y then
	min := x
    else
	min := y;
end;

{-------------------------------------------------------------}
{
{ Low-level device reader.
{ Slightly altered (from bootlib) interface:
{      i_bn            fragment number from sbmap, or SBLOCK
{      i_offset        byte offset (absolute or in big blk)
{      i_cc            xfer count
{      i_ma            where it goes
{ i_ma always points to CSIZE (cache size) buffer
{ on return,
{      i_ma            where the requested data begins
{      i_cc            how much we got this time
{ return i_cc
{ if fs is nil, then this is a "raw" read, where i_bn is the
{ device block number, and i_offset the offset from there.
}
function devread: integer;
var
    sector, gap, xfer: integer;
begin
    with vars^.iob do begin
	{ 256-byte sector number }
	if vars^.fs <> nil then with vars^.fs^ do
	    sector := ((i_bn * fsize)
		       + (i_offset mod bsize)) div BOOT_BSIZE
	else
	    sector := ((i_bn * DEV_BSIZE) + i_offset) div BOOT_BSIZE;

	{ gap between start of sector and what user wants }
	gap := i_offset mod BOOT_BSIZE;

	xfer := min(CSIZE, i_cc + gap);

	{ boot_mread does an escape if error }
	boot_mread(sector, xfer, i_ma^, true);
	i_ma := addr(i_ma^, gap);
	i_cc := xfer - gap;
	devread := i_cc;
    end;
end;

{---------------------------------------------------------------}
{
{ sbmap
{ simplified read-only version of kernel bmap
{ given logical block number in file,
{ returns fragment number on disc
}
function sbmap(bn: integer): integer;
label
    999;
var
    ibyte, nb, cc, oldoffset, i, j, sh: integer;
    loopdone: boolean;
begin
    sbmap := 0;
    with vars^.fs^, vars^.iob.i_ino do begin

	{
	{ blocks 0..NDADDR-1 are direct blocks
	}
	if bn < NDADDR then begin
	    sbmap := db[bn];
	    goto 999;
	end;

	{
	{ addresses NIADDR have single and double indirect blocks.
	{ the first step is to determine how many levels of indirection.
	}
	sh := 1;
	bn := bn - NDADDR;
	j := NIADDR;
	loopdone := false;
	while (j > 0) and not loopdone do begin
	    sh := sh * nindir;
	    if bn < sh then
		loopdone := true
	    else begin
		bn := bn - sh;
		j := j - 1;
	    end;
	end;

	{
	{ fetch the first indirect block address from the inode
	}
	nb := ib[NIADDR - j];
	if nb = 0 then
	    goto 999;

	{
	{ fetch through the indirect blocks
	}
	while j <= NIADDR do with vars^.indirb do begin
	    sh := sh div nindir;
	    i := (bn div sh) mod nindir;
	    { want cache block with nb[i] }
	    ibyte := i * sizeof(integer);
	    if (blkno <> nb) or (cblkno <> ibyte div CSIZE) then
		with vars^.iob do begin
		    { block not in cache, so read it in }
		    i_bn := nb;
		    { read from beginning of CSIZE block }
		    oldoffset := i_offset;
		    i_offset := (ibyte div CSIZE) * CSIZE;
		    i_ma := addr(indirbuf);
		    i_cc := CSIZE;
		    cc := devread;
		    i_offset := oldoffset;
		    if cc <> CSIZE then
			goto 999;
		    blkno := nb;
		    cblkno := ibyte div CSIZE;
		end;
	    nb := indirbuf[i mod (CSIZE div sizeof(integer))];
	    if nb = 0 then
		goto 999;
	    j := j + 1;
	end;
    end;
    sbmap := nb;
999:
end;

{------------------------------------------------------------------}
procedure hfsread(sector, bytecount: integer;
		  anyvar buffer: window; media: boolean);
label
    999;
var
    lbn, xferred: integer;
    bufp: windowp;
begin
    with vars^.iob, vars^.fs^ do begin
	{ find byte offset in file }
	i_offset := (sector * BOOT_BSIZE) + wshdr_size;
	bufp := addr(buffer);
	xferred := 0;
	bytecount := min(bytecount, i_ino.size.ls - i_offset);
	while xferred < bytecount do begin
	    lbn := i_offset div bsize;
	    i_bn := sbmap(lbn);
	    if i_bn = 0 then
		goto 999;
	    i_ma := addr(i_buf);
	    i_cc := min(bytecount - xferred,
			bsize - (i_offset mod bsize));
	    if devread < 0 then
		goto 999;
	    moveleft(i_ma^, bufp^, i_cc);
	    i_offset := i_offset + i_cc;
	    xferred := xferred + i_cc;
	    bufp := addr(bufp^, i_cc);
	end;
    end;
999:
end;


{----------------------------------------------------------------------}
{
{ start of inode section, in frags
{ #define cgimin(fs, c)  (cgstart(fs, c) +(fs)->fs_iblkno)
}
function cgimin(c: integer): integer;
begin
    with vars^.fs^ do
	cgimin := (c * fpg) + (cgoffset * iand(c, -1-cgmask)) + iblkno;
end;

{------------------------------------------------------------}
{
{ inumber to frag containing it
{ #define itod(fs,x)      \
{     ((daddr_t)(cgimin(fs, itog(fs, x)) + \
{     (blkstofrags((fs),(((x) %(fs) -> fs_ipg) / INOPB(fs))))))
}
function itod(x: integer): integer;
begin
    with vars^.fs^ do
	itod := cgimin(x div ipg)
	   + ((x mod ipg) div inopb) * frag;
end;
{---------------------------------------------------------------------}
{
{ openi
{ open inode n by reading inode into buffer
{ returns boolean indicating success
}
function openi(n: integer): boolean;
label
    999;
var
    cc: integer;
begin
    with vars^.iob do begin
	i_bn := itod(n);
	i_offset := (n mod vars^.fs^.inopb) * sizeof(i_ino);
	i_cc := sizeof(i_ino);
	i_ma := addr(i_buf);
	if devread = sizeof(i_ino) then begin
	    moveleft(i_ma^, i_ino, sizeof(i_ino));
	    openi := true;
	end
	else
	    openi := false;
    end;
999:
end;


{------------------------------------------------------------------}
{
{ get next entry in a directory.
}
function readdir(var dirloc: integer): direntry_ptr_type;
label
    999;
var
    dp: direntry_ptr_type;
    off, lbn, d: integer;
begin

    readdir := nil;

    with vars^.iob do while dirloc < i_ino.size.ls do begin

	{ offset in cache block }
	off := dirloc mod CSIZE;

	if (dirloc = 0)
	or (dirloc div CSIZE <> i_offset div CSIZE) then begin
	    { read CSIZE more bytes }
	    lbn := dirloc div vars^.fs^.bsize;
	    d := sbmap(lbn);
	    if d = 0 then
		goto 999;
	    i_bn := d;
	    i_ma := addr(i_buf);
	    i_offset := dirloc;
	    i_cc := min(CSIZE, i_ino.size.ls - dirloc);
	    if devread < 0 then
		goto 999;
	end;

	dp := addr(i_buf, off);
	dirloc := dirloc + dp^.reclen;
	if dp^.ino <> 0 then begin
	    readdir := dp;
	    goto 999;
	end;
    end;
999:
end;

{----------------------------------------------------------------}
{
{ dlook
{ find inumber of given file in this directory
{ 0 -> not found
}
function dlook(s: string255ptr): integer;
label
    999;
const
    dirmode = 4;
    modediv = 4096;
var
    dp: direntry_ptr_type;
    dirloc: integer;
    i, len: integer;
    found: boolean;
begin
    dlook := 0;

    len := strlen(s^);
    if len = 0 then
	goto 999;
    if vars^.iob.i_ino.mode div modediv <> dirmode then
	goto 999;

    dirloc := 0;
    while true do begin
	dp := readdir(dirloc);
	if dp = nil then
	    goto 999;
	with dp^ do
	    if len = namlen then begin
		found := true;
		for i := 1 to len do
		    if name[i-1] <> s^[i] then
			found := false;
		if found then begin
		    dlook := ino;
		    goto 999;
		end;
	    end;
    end;
999:
end;

{----------------------------------------------------------------}
{
{ ifind
{ turn a pathname into an inumber
{ 0 -> failure
}
function ifind(path: string255): integer;
label
    999;
var
    n, i: integer;
    q: string255ptr;
    lenleft: integer;
begin
    ifind := 0;

    { always start at root }
    if not openi(root_inode) then
	goto 999;

    { q will march down string }
    q := addr(path);
    lenleft := strlen(path);

    while true do begin

	{ peel off initial slashes }
	while (lenleft > 0) and (q^[1] = '/') do begin
	    q := addr(q^, 1);
	    lenleft := lenleft - 1;
	    setstrlen(q^, lenleft);
	end;

	{ find end of next cmpnt }
	i := 1;
	while (i <= lenleft) and (q^[i] <> '/') do
	    i := i + 1;
	setstrlen(q^, i - 1);

	n := dlook(q);

	{ cmpnt not there? }
	if n = 0 then
	    goto 999;

	{ end of string? }
	if (i-1) = lenleft then begin
	    ifind := n;
	    goto 999;
	end;

	{ open this inode? }
	if not openi(n) then
	    goto 999;

	{ bump past this cmpnt }
	q := addr(q^, i-1);
	lenleft := lenleft - (i-1);
	setstrlen(q^, lenleft);
    end;

999:
end;

{------------------------------------------------------------------}
function hfsopen(anyvar fname: string255;
		 var xaddr, length: integer;
		 var ftype: shortint): boolean;
label
    999;
var
    togo, i: integer;
begin
    hfsopen := false;

    { borrow space from other end of globals area }
    vars := vars_ptr_type(a5 - 32766);

    { read superblock }
    with vars^.iob do begin
	togo := SBNEEDED;
	i_ma := addr(i_fs);
	vars^.fs := nil;
	i_offset := 0;
	i_bn := SBLOCK;
	while togo > 0 do begin
	    i_cc := togo;
	    if devread < 0 then
		goto 999;
	    togo := togo - i_cc;
	    i_ma := addr(i_ma^, i_cc);
	    i_offset := i_offset + i_cc;
	end;
	vars^.fs := addr(i_fs);

	{ get the inumber }
	i := ifind(fname);
	if i = 0 then
	    goto 999;

	{ and the inode }
	if not openi(i) then
	    goto 999;

    end;

    xaddr := 0;
    ftype := -5582;
    length := vars^.iob.i_ino.size.ls - wshdr_size;

    hfsopen := true;
999:
end;

end
@


55.1
log
@Automatic bump of revision number for PWS version 3.25A
@
text
@@


54.3
log
@
pws2rcs automatic delta on Wed Aug 21 10:27:27 MDT 1991
@
text
@@


54.2
log
@
pws2rcs automatic delta on Wed Aug 21 09:35:48 MDT 1991
@
text
@d1 514
@


54.1
log
@Automatic bump of revision number for PWS version 3.24
@
text
@a0 514
{
{ HFSBOOT
{ bootdam for HFS
{ has just enough HFS knowledge to read a file off the disc
{ $included by INITLOAD.
}
$partial_eval on$ { MUST be on }

module hfsboot;

import sysglobals, asm, loader;

export

procedure hfsread(sector, bytecount: integer;
		  anyvar buffer: window; media: boolean);

function hfsopen(anyvar fname: string255; var xaddr, length: integer;
		 var ftype: shortint): boolean;

implement


$include 'HFS:consts'$
$include 'HFS:cgroup'$
$include 'HFS:super'$
$include 'HFS:inode'$
$include 'HFS:dir'$

const
    { size of sectors used by boot ROM }
    BOOT_BSIZE =  256;

    { size of our cache block (we have 2) }
    { any power of 2 in [256..8K] }
    { We set this large, as space is only temporarily used }
    CSIZE  = 8*1024;

    { amount of superblock we really need, bytes }
    { WARNING -- breaks when sb format changes }
    SBNEEDED = 192;

    wshdr_size = 512;

type
    cache_buf = packed array[0..CSIZE-1] of char;
    indir_buf = packed array[0..(CSIZE div sizeof(integer))-1] of integer;
    super_buf = packed array[0..SBNEEDED-1] of char;
    cache_buf_ptr = ^cache_buf;

    {
    { Io block: includes an
    { inode, cells for the use of seek, etc,
    { and a buffer.
    }
    iob_type = {packed} record
	i_ino: inode_type;
	i_offset: integer;             { seek offset in file }
	i_bn: integer;                 { 1st block # of next read }
	i_ma: cache_buf_ptr;           { memory address of i/o buffer }
	i_cc: shortint;                { character count of transfer }
	i_buf: cache_buf;              { i/o buffer }
	i_fs: super_buf;               { superblock }
    end;

    indirb_type = packed record
	indirbuf: indir_buf;           { indirect block data }
	blkno: integer;                { frag # in indir buf }
	cblkno: integer;               { cache blk # in indir buf }
    end;

    vars_type = packed record
	{ indirect block cache }
	indirb: indirb_type;
	{ buffer for file i/o }
	iob: iob_type;
	fs: super_block_ptr_type;
    end;

    vars_ptr_type = ^vars_type;

var
    vars: vars_ptr_type;


procedure boot_mread(sector,bytecount: integer;
		     anyvar buffer:window; media:boolean); external;

{----------------------------------------------------------------}
function min(x, y: integer): integer;
begin
    if x < y then
	min := x
    else
	min := y;
end;

{-------------------------------------------------------------}
{
{ Low-level device reader.
{ Slightly altered (from bootlib) interface:
{      i_bn            fragment number from sbmap, or SBLOCK
{      i_offset        byte offset (absolute or in big blk)
{      i_cc            xfer count
{      i_ma            where it goes
{ i_ma always points to CSIZE (cache size) buffer
{ on return,
{      i_ma            where the requested data begins
{      i_cc            how much we got this time
{ return i_cc
{ if fs is nil, then this is a "raw" read, where i_bn is the
{ device block number, and i_offset the offset from there.
}
function devread: integer;
var
    sector, gap, xfer: integer;
begin
    with vars^.iob do begin
	{ 256-byte sector number }
	if vars^.fs <> nil then with vars^.fs^ do
	    sector := ((i_bn * fsize)
		       + (i_offset mod bsize)) div BOOT_BSIZE
	else
	    sector := ((i_bn * DEV_BSIZE) + i_offset) div BOOT_BSIZE;

	{ gap between start of sector and what user wants }
	gap := i_offset mod BOOT_BSIZE;

	xfer := min(CSIZE, i_cc + gap);

	{ boot_mread does an escape if error }
	boot_mread(sector, xfer, i_ma^, true);
	i_ma := addr(i_ma^, gap);
	i_cc := xfer - gap;
	devread := i_cc;
    end;
end;

{---------------------------------------------------------------}
{
{ sbmap
{ simplified read-only version of kernel bmap
{ given logical block number in file,
{ returns fragment number on disc
}
function sbmap(bn: integer): integer;
label
    999;
var
    ibyte, nb, cc, oldoffset, i, j, sh: integer;
    loopdone: boolean;
begin
    sbmap := 0;
    with vars^.fs^, vars^.iob.i_ino do begin

	{
	{ blocks 0..NDADDR-1 are direct blocks
	}
	if bn < NDADDR then begin
	    sbmap := db[bn];
	    goto 999;
	end;

	{
	{ addresses NIADDR have single and double indirect blocks.
	{ the first step is to determine how many levels of indirection.
	}
	sh := 1;
	bn := bn - NDADDR;
	j := NIADDR;
	loopdone := false;
	while (j > 0) and not loopdone do begin
	    sh := sh * nindir;
	    if bn < sh then
		loopdone := true
	    else begin
		bn := bn - sh;
		j := j - 1;
	    end;
	end;

	{
	{ fetch the first indirect block address from the inode
	}
	nb := ib[NIADDR - j];
	if nb = 0 then
	    goto 999;

	{
	{ fetch through the indirect blocks
	}
	while j <= NIADDR do with vars^.indirb do begin
	    sh := sh div nindir;
	    i := (bn div sh) mod nindir;
	    { want cache block with nb[i] }
	    ibyte := i * sizeof(integer);
	    if (blkno <> nb) or (cblkno <> ibyte div CSIZE) then
		with vars^.iob do begin
		    { block not in cache, so read it in }
		    i_bn := nb;
		    { read from beginning of CSIZE block }
		    oldoffset := i_offset;
		    i_offset := (ibyte div CSIZE) * CSIZE;
		    i_ma := addr(indirbuf);
		    i_cc := CSIZE;
		    cc := devread;
		    i_offset := oldoffset;
		    if cc <> CSIZE then
			goto 999;
		    blkno := nb;
		    cblkno := ibyte div CSIZE;
		end;
	    nb := indirbuf[i mod (CSIZE div sizeof(integer))];
	    if nb = 0 then
		goto 999;
	    j := j + 1;
	end;
    end;
    sbmap := nb;
999:
end;

{------------------------------------------------------------------}
procedure hfsread(sector, bytecount: integer;
		  anyvar buffer: window; media: boolean);
label
    999;
var
    lbn, xferred: integer;
    bufp: windowp;
begin
    with vars^.iob, vars^.fs^ do begin
	{ find byte offset in file }
	i_offset := (sector * BOOT_BSIZE) + wshdr_size;
	bufp := addr(buffer);
	xferred := 0;
	bytecount := min(bytecount, i_ino.size.ls - i_offset);
	while xferred < bytecount do begin
	    lbn := i_offset div bsize;
	    i_bn := sbmap(lbn);
	    if i_bn = 0 then
		goto 999;
	    i_ma := addr(i_buf);
	    i_cc := min(bytecount - xferred,
			bsize - (i_offset mod bsize));
	    if devread < 0 then
		goto 999;
	    moveleft(i_ma^, bufp^, i_cc);
	    i_offset := i_offset + i_cc;
	    xferred := xferred + i_cc;
	    bufp := addr(bufp^, i_cc);
	end;
    end;
999:
end;


{----------------------------------------------------------------------}
{
{ start of inode section, in frags
{ #define cgimin(fs, c)  (cgstart(fs, c) +(fs)->fs_iblkno)
}
function cgimin(c: integer): integer;
begin
    with vars^.fs^ do
	cgimin := (c * fpg) + (cgoffset * iand(c, -1-cgmask)) + iblkno;
end;

{------------------------------------------------------------}
{
{ inumber to frag containing it
{ #define itod(fs,x)      \
{     ((daddr_t)(cgimin(fs, itog(fs, x)) + \
{     (blkstofrags((fs),(((x) %(fs) -> fs_ipg) / INOPB(fs))))))
}
function itod(x: integer): integer;
begin
    with vars^.fs^ do
	itod := cgimin(x div ipg)
	   + ((x mod ipg) div inopb) * frag;
end;
{---------------------------------------------------------------------}
{
{ openi
{ open inode n by reading inode into buffer
{ returns boolean indicating success
}
function openi(n: integer): boolean;
label
    999;
var
    cc: integer;
begin
    with vars^.iob do begin
	i_bn := itod(n);
	i_offset := (n mod vars^.fs^.inopb) * sizeof(i_ino);
	i_cc := sizeof(i_ino);
	i_ma := addr(i_buf);
	if devread = sizeof(i_ino) then begin
	    moveleft(i_ma^, i_ino, sizeof(i_ino));
	    openi := true;
	end
	else
	    openi := false;
    end;
999:
end;


{------------------------------------------------------------------}
{
{ get next entry in a directory.
}
function readdir(var dirloc: integer): direntry_ptr_type;
label
    999;
var
    dp: direntry_ptr_type;
    off, lbn, d: integer;
begin

    readdir := nil;

    with vars^.iob do while dirloc < i_ino.size.ls do begin

	{ offset in cache block }
	off := dirloc mod CSIZE;

	if (dirloc = 0)
	or (dirloc div CSIZE <> i_offset div CSIZE) then begin
	    { read CSIZE more bytes }
	    lbn := dirloc div vars^.fs^.bsize;
	    d := sbmap(lbn);
	    if d = 0 then
		goto 999;
	    i_bn := d;
	    i_ma := addr(i_buf);
	    i_offset := dirloc;
	    i_cc := min(CSIZE, i_ino.size.ls - dirloc);
	    if devread < 0 then
		goto 999;
	end;

	dp := addr(i_buf, off);
	dirloc := dirloc + dp^.reclen;
	if dp^.ino <> 0 then begin
	    readdir := dp;
	    goto 999;
	end;
    end;
999:
end;

{----------------------------------------------------------------}
{
{ dlook
{ find inumber of given file in this directory
{ 0 -> not found
}
function dlook(s: string255ptr): integer;
label
    999;
const
    dirmode = 4;
    modediv = 4096;
var
    dp: direntry_ptr_type;
    dirloc: integer;
    i, len: integer;
    found: boolean;
begin
    dlook := 0;

    len := strlen(s^);
    if len = 0 then
	goto 999;
    if vars^.iob.i_ino.mode div modediv <> dirmode then
	goto 999;

    dirloc := 0;
    while true do begin
	dp := readdir(dirloc);
	if dp = nil then
	    goto 999;
	with dp^ do
	    if len = namlen then begin
		found := true;
		for i := 1 to len do
		    if name[i-1] <> s^[i] then
			found := false;
		if found then begin
		    dlook := ino;
		    goto 999;
		end;
	    end;
    end;
999:
end;

{----------------------------------------------------------------}
{
{ ifind
{ turn a pathname into an inumber
{ 0 -> failure
}
function ifind(path: string255): integer;
label
    999;
var
    n, i: integer;
    q: string255ptr;
    lenleft: integer;
begin
    ifind := 0;

    { always start at root }
    if not openi(root_inode) then
	goto 999;

    { q will march down string }
    q := addr(path);
    lenleft := strlen(path);

    while true do begin

	{ peel off initial slashes }
	while (lenleft > 0) and (q^[1] = '/') do begin
	    q := addr(q^, 1);
	    lenleft := lenleft - 1;
	    setstrlen(q^, lenleft);
	end;

	{ find end of next cmpnt }
	i := 1;
	while (i <= lenleft) and (q^[i] <> '/') do
	    i := i + 1;
	setstrlen(q^, i - 1);

	n := dlook(q);

	{ cmpnt not there? }
	if n = 0 then
	    goto 999;

	{ end of string? }
	if (i-1) = lenleft then begin
	    ifind := n;
	    goto 999;
	end;

	{ open this inode? }
	if not openi(n) then
	    goto 999;

	{ bump past this cmpnt }
	q := addr(q^, i-1);
	lenleft := lenleft - (i-1);
	setstrlen(q^, lenleft);
    end;

999:
end;

{------------------------------------------------------------------}
function hfsopen(anyvar fname: string255;
		 var xaddr, length: integer;
		 var ftype: shortint): boolean;
label
    999;
var
    togo, i: integer;
begin
    hfsopen := false;

    { borrow space from other end of globals area }
    vars := vars_ptr_type(a5 - 32766);

    { read superblock }
    with vars^.iob do begin
	togo := SBNEEDED;
	i_ma := addr(i_fs);
	vars^.fs := nil;
	i_offset := 0;
	i_bn := SBLOCK;
	while togo > 0 do begin
	    i_cc := togo;
	    if devread < 0 then
		goto 999;
	    togo := togo - i_cc;
	    i_ma := addr(i_ma^, i_cc);
	    i_offset := i_offset + i_cc;
	end;
	vars^.fs := addr(i_fs);

	{ get the inumber }
	i := ifind(fname);
	if i = 0 then
	    goto 999;

	{ and the inode }
	if not openi(i) then
	    goto 999;

    end;

    xaddr := 0;
    ftype := -5582;
    length := vars^.iob.i_ino.size.ls - wshdr_size;

    hfsopen := true;
999:
end;

end
@


53.1
log
@Automatic bump of revision number for PWS version 3.24B
@
text
@@


52.1
log
@Automatic bump of revision number for PWS version 3.24A
@
text
@@


51.1
log
@Automatic bump of revision number for PWS version 3.24d
@
text
@@


50.1
log
@Automatic bump of revision number for PWS version 3.23c
@
text
@@


49.1
log
@Automatic bump of revision number for PWS version 3.24b
@
text
@@


48.1
log
@Automatic bump of revision number for PWS version 3.24a
@
text
@@


47.1
log
@Automatic bump of revision number for PWS version 3.23
@
text
@@


46.1
log
@Automatic bump of revision number for PWS version 3.23
@
text
@@


45.1
log
@Automatic bump of revision number for PWS version 3.23C
@
text
@@


44.1
log
@Automatic bump of revision number for PWS version 3.23B
@
text
@@


43.1
log
@Automatic bump of revision number for PWS version 3.23aA
@
text
@@


42.1
log
@Automatic bump of revision number for PWS version 3.23e
@
text
@@


41.1
log
@Automatic bump of revision number for PWS version 3.23d
@
text
@@


40.1
log
@Automatic bump of revision number for PWS version 3.23c
@
text
@@


39.1
log
@Automatic bump of revision number for PWS version 3.23b
@
text
@@


38.1
log
@Automatic bump of revision number for PWS version 3.23a
@
text
@@


37.1
log
@Automatic bump of revision number for PWS version 3.3a
@
text
@@


36.1
log
@Automatic bump of revision number for PWS version 3.22
@
text
@@


35.1
log
@Automatic bump of revision number for PWS version 3.22
@
text
@@


34.1
log
@Automatic bump of revision number for PWS version 3.22
@
text
@@


33.1
log
@Automatic bump of revision number for PWS version 3.22D
@
text
@@


32.1
log
@Automatic bump of revision number for PWS version 3.22C
@
text
@@


31.1
log
@Automatic bump of revision number for PWS version 3.22B
@
text
@@


30.1
log
@Automatic bump of revision number for PWS version 3.22A
@
text
@@


29.1
log
@Automatic bump of revision number for PWS version 3.22b
@
text
@@


28.1
log
@Automatic bump of revision number for PWS version 3.3b
@
text
@@


27.1
log
@Automatic bump of revision number for PWS version 3.3a
@
text
@@


26.1
log
@Automatic bump of revision number for PWS version 3.3 Synch
@
text
@@


25.1
log
@Automatic bump of revision number for PWS version 3.2Y
@
text
@@


24.1
log
@Automatic bump of revision number for PWS version 3.2
@
text
@@


23.1
log
@Automatic bump of revision number for PWS version 3.2P
@
text
@@


22.1
log
@Automatic bump of revision number for PWS version 3.2N
@
text
@@


21.1
log
@Automatic bump of revision number for PWS version 3.2M
@
text
@@


20.1
log
@Automatic bump of revision number for PWS version 3.2L
@
text
@@


19.1
log
@Automatic bump of revision number for PWS version 3.2K
@
text
@@


18.1
log
@Automatic bump of revision number for PWS version 3.2J
@
text
@@


17.1
log
@Automatic bump of revision number for PWS version 3.2I+
@
text
@@


16.1
log
@Automatic bump of revision number for PWS version 3.2I
@
text
@@


15.1
log
@Automatic bump of revision number for PWS version 3.2H
@
text
@@


14.1
log
@Automatic bump of revision number for PWS version 3.2G
@
text
@@


13.1
log
@Automatic bump of revision number for PWS version 3.2F
@
text
@@


12.1
log
@Automatic bump of revision number for PWS version 3.2E
@
text
@@


11.1
log
@Automatic bump of revision number for PWS version 3.2D
@
text
@@


10.1
log
@Automatic bump of revision number for PWS version 3.2C
@
text
@@


9.1
log
@Automatic bump of revision number for PWS version 3.2B
@
text
@@


8.1
log
@Automatic bump of revision number for PWS version 3.2A
@
text
@@


7.1
log
@Automatic bump of revision number for PWS version 3.2l
@
text
@@


6.2
log
@Pws2unix automatic delta on Wed Nov 19 15:16:12 MST 1986
@
text
@@


6.1
log
@Automatic bump of revision number for PWS version 3.2k
@
text
@d56 1
a56 1
    iob_type = packed record
@


5.1
log
@Automatic bump of revision number for PWS version 3.2j
@
text
@@


4.1
log
@Automatic bump of revision number for PWS version 3.2i
@
text
@@


3.1
log
@Automatic bump of revision number for PWS version 3.2h
@
text
@@


1.7
log
@Now included by INITLOAD, so remove $modcal$, etc.
Since data space only temporarily used, use 8K cache buffers.
@
text
@@


1.6
log
@Add some decls for last delta.
@
text
@d5 1
a6 8
$modcal$

$range off$
$ovflcheck off$
$debug off$
$stackcheck off$
$iocheck off$

a7 1
$search 'ASM', 'INITLOAD'$
d36 2
a37 1
    CSIZE  = 2048;
a60 1
	i_ioff: shortint;              { internal offset for LIFhdr files }
d514 1
a514 121
end.

{ WHAT FOLLOWS IS TEST CODE THAT I'M RELUCTANT TO THROW AWAY YET }

$if 1=0$

import hfsboot, hfsalloc, sysglobals, hfsupport, hfscache, hfscalc, hfstuff;
var
    x, y, i, j: integer;
    s: shortint;
    fname: string255;
    sbp: super_block_ptr_type;
    ip: inode_ptr_type;
    tbuf: packed array[1..256] of char;

function memdiff(p1, p2: charptr; size: integer): boolean;
label
    999;
begin
    memdiff := true;
    while size > 0 do begin
	if p1^ <> p2^ then
	    goto 999;
	p1 := addr(p1^, 1);
	p2 := addr(p2^, 1);
	size := size - 1;
    end;
    memdiff := false;
999:
end;

begin
   { test ifind }
   {while true do begin
       write('name to parse? ');
       readln(fname);
       i := ifind(fname);
   end;}

   { test devread, hfopen (sb read) }
   {fname := '/foo';
   writeln(hfsopen(fname, i, i, s));
   with vars^.fs^ do begin
      writeln('sblkno ', sblkno);
      writeln('cblkno ', cblkno);
      writeln('iblkno ', iblkno);
      writeln('nindir ', nindir);
      writeln('inopb ', inopb);
      writeln('ipg ', ipg);
   end;}

   { test itod }
   {fname := '/foo';
   writeln(hfsopen(fname, i, i, s));
   for i := 1 to 100000 do begin
     x := itod(addr(iob.i_fs), i);
     y := itod(i);
     if x <> y then writeln('i, real, me ', i, x, y);
     if i mod 1000 = 0 then writeln(i);
   end;}


   { test openi }
   {fname := '/foo';
   writeln(hfsopen(fname, i, i, s));
   sbp := get_superblock(11);
   for i := 1 to (sbp^.ncg * sbp^.ipg) - 2 do begin
      ip := get_inode(i);
      if not openi(i) then
	  writeln('OPENI FAILED');
      if memdiff(charptr(ip), charptr(addr(iob.i_ino)), sizeof(iob.i_ino)) then
	  writeln('INODES DIFFER, #', i:1);
      put_inode(ip, [release]);
      if i mod 100 = 0 then writeln(i);
   end;
   put_superblock(sbp, [release]);}

   { test sbmap }
   {fname := '/foo';
   writeln(hfsopen(fname, i, i, s));
   sbp := get_superblock(11);
   for i := 1 to (sbp^.ncg * sbp^.ipg) - 2 do begin
      if not openi(i) then
	  writeln('OPENI FAILED');
      if (iob.i_ino.mode <> 0) and (iob.i_ino.size.ls > 12*8*1024) then begin
	  ip := get_inode(i);
	  for j := 0 to (iob.i_ino.size.ls-1) div fs^.bsize do begin
	     x := sbmap(j);
	     y := get_dbnum(ip, j*fs^.bsize, B_READ, 0);
	     if x <> y then
		writeln('inode, block, real, me ', i, j, y, x)
	     else writeln('same');
	  end;
	  put_inode(ip, [release]);
      end;
      if i mod 100 = 0 then writeln(i);
   end;
   put_superblock(sbp, [release]);}

   { test readdir }
   {while true do begin
       write('name to look up? ');
       readln(fname);
       writeln(hfsopen(fname, i, i, s));
   end;}

   { test reading file }
   write('name to look up? ');
   readln(fname);
   writeln(hfsopen(fname, i, i, s));
   if iob.i_ino.size.ls > 0 then
     for i := 0 to (iob.i_ino.size.ls - 1) div BOOT_BSIZE do begin
	hfsread(i, min(BOOT_BSIZE, iob.i_ino.size.ls - i*BOOT_BSIZE),
		tbuf, false);
	write(tbuf);
     end;


end.

$end$
@


1.5
log
@Remove space from globals area; use other end of globals (borrowed)
instead.  Remove references to hfsbflg.
@
text
@d19 1
a19 1
import sysglobals, asm;
d88 2
d91 1
a91 1
    vars: ^vars_type;
@


1.4
log
@New() of previous version doesn't work.
We put the data space in globals until we can find a better place.
@
text
@a88 2

    varxxx: vars_type; {TEMP UNTIL FIGURE OUT WHERE TO PUT DATA SPACE}
a90 1
    hfsbflg['HFSBFLG']: shortint;
d481 2
a482 4
    if hfsbflg = 1 then begin
	hfsbflg := 2;
	vars := addr(varxxx);
    end;
@


1.3
log
@send TRUE to boot_mread (reads raw device).
@
text
@d90 1
d486 1
a486 1
	new(vars);
@


1.2
log
@Add $search$ directives.
Use only 4 bytes of globals (was about 4K).  These now
taken from heap (permanently), but could be stolen from,
say, system stack if needed.
@
text
@d140 1
a140 1
	boot_mread(sector, xfer, i_ma^, false);
@


1.1
log
@Initial revision
@
text
@d8 5
a12 4
{ these should be off when finished }
$range on$
$ovflcheck on$
$debug on$
d15 1
d80 7
a88 2
    { indirect block cache }
    indirb: indirb_type;
d90 1
a90 2
    { buffer for file i/o }
    iob: iob_type;
d92 1
a92 1
    fs: super_block_ptr_type;
a93 1

d126 1
a126 1
    with iob do begin
d128 1
a128 1
	if fs <> nil then with fs^ do
d162 1
a162 1
    with fs^, iob.i_ino do begin
d200 1
a200 1
	while j <= NIADDR do with indirb do begin
d206 1
a206 1
		with iob do begin
d240 1
a240 1
    with iob, fs^ do begin
d273 1
a273 1
    with fs^ do
d286 1
a286 1
    with fs^ do
d302 1
a302 1
    with iob do begin
d304 1
a304 1
	i_offset := (n mod fs^.inopb) * sizeof(i_ino);
d332 1
a332 1
    with iob do while dirloc < i_ino.size.ls do begin
d340 1
a340 1
	    lbn := dirloc div fs^.bsize;
d385 1
a385 1
    if iob.i_ino.mode div modediv <> dirmode then
d483 5
d489 1
a489 1
    with iob do begin
d492 1
a492 1
	fs := nil;
d503 1
a503 1
	fs := addr(i_fs);
d518 1
a518 1
    length := iob.i_ino.size.ls - wshdr_size;
d566 1
a566 1
   with fs^ do begin
@
