P8000/WEGA/src/cmd/standalone/sa.install.c

972 lines
24 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/******************************************************************************
*******************************************************************************
W E G A - Quelle (C) ZFT/KEAW Abt. Basissoftware - 1986
KOMMANDO install.c
Bearbeiter: N. Taege
Datum: 6.1.88
Version: 3.0
*******************************************************************************
******************************************************************************/
/* notwendig: -rw-r--r-- 1 bin system 2188 Mar 5 13:53 /lib/libb.a */
#include "sys/param.h"
#include "sys/ino.h"
#include "sys/inode.h"
#include "sys/filsys.h"
#include "sys/fblk.h"
#include "sys/dir.h"
/*--------------------------------------------- Konstanten ------------------*/
#define LCONT 15 /* max. Laenge der CONTENTS */
/*--------------------------------------------- Variable ------------------*/
int fsi, fdi, fdo; /* fopen-Werte von Source und Destination */
char *contp, CONT[LCONT*BSIZE]; /* CONTENTS - Puffer */
char CON[] = "CONTENTS";
char conline[50]; /* CONTENTS-Zeile */
char fddname[40] = "ud(0,0)"; /* floppy-disk-driver- & udos-file-name */
char hddname[20] = "md(0,0)"; /* hard-disk-driver-name (/usr) */
char estring[10]; /* Eingabe-Zeichenkette */
union {
struct fblk fb;
char pad1[BSIZE];
} fbuf;
union {
struct filsys fs;
char pad2[BSIZE];
} filsys;
struct dinode pin; /* inode der parent-Directory */
struct dinode iin; /* inode des zu installierenden Files */
long time; /* Zeit in Sekunden ab 1970 */
static int dmsize[12] = /* Tage/Monat (kumulierend) */
{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
long zdb[12]; /* Blocknummern im inode */
long adb[128]; /* einfach indirekt Adressblock */
long iadb[128]; /* zweifach indirekt Adressblock */
daddr_t aadb, aiadb; /* Blocknummern der Adressbloecke */
int padb, piadb, pzdb; /* Pointer in den Adressbloecken */
ino_t parinumb, inumb, oldinumb;
daddr_t apardir;
char pardir[BSIZE], parinob[BSIZE], inob[BSIZE];
int ppnidb;
int abfr; /* 0 = abfragen, 1 = a, 2 = A, 3 = q, 4 = Q */
char *aeintr; /* Adr(Dir.-Eintrag) */
daddr_t alloc();
long getnum();
ino_t sun(), alloci();
unsigned int get2b();
unsigned long get3b();
/*--------------------------------------------- Funktion ------------------*/
/*
* Das Standalone Modul sa.install dient der Installation der File-Systeme
* auf der Hard-Disk des P8000
*/
/*---------------------------------------------------------------------------*/
main()
{
register i;
indate(); /* Datum eingeben */
rmopen(0); /* remote open mit Abfrage */
for (i=1; i<5; i++) {
printf("\noutput file system : ");
gets(hddname, sizeof hddname);
if (hddname[0] == '\0') {
hddname[0] = 'm';
printf("%s\n", hddname); }
fdo = open(hddname, 1);
fdi = open(hddname, 0);
if (fdo<0 || fdi<0)
printf("cannot open %s\n", hddname);
else break; }
if (i == 5) exit(0);
for (i=0; i<128; pardir[i++]=0); /* parent-Directory loeschen */
rdfs((long)1, (char *)&filsys); /* read Superblock */
rddisk:
abfr = 0;
while (*contp != '\0') {
switch (*contp) {
case '/':
/*
* Directory - Definitions - Zeile
*/
if (abfr == 4) {
getstr(); /* bei eingegebenem 'Q' : Zeile ueberspringen */
break; }
if (abfr == 1 || abfr == 3) abfr = 0; /* 'a'- und 'q'-Mode beenden */
wpar(); /* write parent-Directory-Block u. inode */
parinumb = 2;
rindi(); /* read root-inode-Block u. 1.root-Directory-Block */
printf("%s\n", contp);
contp++;
rdloop:
if (*contp == '\0') {
contp++;
break; }
holdn(); /* Dir.-Namen aus CONT-Zeilenstueck in conline holen */
parinumb = sun(0); /* Directory-Namen in pardir suchen */
if (parinumb == 0) {
printf("\ndirectory %s not found\n", conline);
insend(); }
rindi(); /* Lese inode-Block u. 1.Directory-Block */
goto rdloop;
case 'l':
/*
* nlink - Zeile
*/
if (testab() == 0) break;
getstr();
getstr();
if (sun(1)) {
printf("\nlink-file: %s already exist; cannot overwrite !\n", conline);
break; }
iin.di_nlink++;
cfilend();
break;
case 'd':
case 'b':
case 'c':
case '-':
case 'n':
/*
* create - file - Zeile
*/
if (testab() == 0) break;
cfile();
break;
default:
printf("syntax error in CONTENTS\n");
printf("last instruction: %s\n",conline);
printf("next characters (hexadecimal): %x ", *contp++ & 0xFF);
printf("%x %x ", *contp++ & 0xFF, *contp++ & 0xFF);
printf("%x %x etc.\n", *contp++ & 0xFF, *contp++ & 0xFF);
insend();
}
}
loopnd:
printf("\n\007next input disk ? (y/n) : ");
gets(estring, sizeof estring);
switch (estring[0]) {
case 'Y':
case 'y':
rmopen(1); /* remote open ohne Eingabe */
goto rddisk;
case 'N':
case 'n':
insend();
default:
goto loopnd; }
}
/*---------------------------------------------------------------------------*/
/*
* Aussprung aus sa.install
*/
/*---------------------------------------------------------------------------*/
insend()
{
wpar(); /* write Parent-Dir. */
filsys.s_time = time; /* setze Superblock-Zeit */
wtfs((long)1, (char *)&filsys); /* write Superblock */
exit(0);
}
/*---------------------------------------------------------------------------*/
/*
* Lese Block (bno) von der Hard-Disk in den Puffer (bf)
*/
/*---------------------------------------------------------------------------*/
rdfs(bno, bf)
daddr_t bno;
char *bf;
{
register n;
lseek(fdi, bno*BSIZE, 0);
n = read(fdi, bf, BSIZE);
if (n != BSIZE) {
printf("read error: %ld\n", bno);
insend(); }
}
/*---------------------------------------------------------------------------*/
/*
* Schreibe Puffer (bf) in den Block (bno) der Hard-Disk
*/
/*---------------------------------------------------------------------------*/
wtfs(bno, bf)
daddr_t bno;
char *bf;
{
register n;
lseek(fdo, bno*BSIZE, 0);
n = write(fdo, bf, BSIZE);
if (n != BSIZE) {
printf("write error: %ld\n", bno);
insend(); }
}
/*---------------------------------------------------------------------------*/
/*
* Stelle einen freien Block (= Return-Wert) zu Verfuegung
*/
/*---------------------------------------------------------------------------*/
daddr_t
alloc()
{
register i;
register daddr_t bno;
filsys.s_tfree--;
bno = filsys.s_free[--filsys.s_nfree];
if (bno == 0) {
printf("\nout of free space\n");
insend(); }
if (filsys.s_nfree == 0) {
rdfs(bno, (char *)&fbuf);
filsys.s_nfree = fbuf.df_nfree;
for (i=0; i < NICFREE; i++)
filsys.s_free[i] = fbuf.df_free[i];
}
return(bno);
}
/*---------------------------------------------------------------------------*/
/*
* Speichere einen freigewordenen Block zurueck in die Freiblock-Liste
*/
/*---------------------------------------------------------------------------*/
bfree(bno)
register daddr_t bno;
{
register i;
filsys.s_tfree++;
if (filsys.s_nfree == NICFREE) {
clear(&fbuf, BSIZE);
fbuf.df_nfree = filsys.s_nfree;
for (i=0; i < NICFREE; i++)
fbuf.df_free[i] = filsys.s_free[i];
wtfs(bno, (char *)&fbuf);
filsys.s_nfree = 0; }
filsys.s_free[filsys.s_nfree++] = bno;
}
/*---------------------------------------------------------------------------*/
/*
* open remote
*/
/*---------------------------------------------------------------------------*/
rmopen(out)
register out;
{
register size, c, i;
for (i=1; i<5; i++) {
if (out == 0) {
printf("\ninput file system : ");
gets(fddname, sizeof fddname); }
if (fddname[0] == '\0') {
fddname[0] = 'u';
printf("%s\n", fddname); }
adname(CON);
fsi = open(fddname, 0);
if (fsi<0) {
printf("cannot open %s\n", fddname);
out = 0; }
else break; }
if (i == 5) insend();
size = 0;
for (i=1; i <= LCONT; i++) {
c = read(fsi, &CONT[size], BSIZE);
if (c < 0) insend();
size += c;
if (c < BSIZE) break; }
if (i > LCONT) {
printf("\nCONTENTS to long\n");
insend(); }
close(fsi);
for (i=0; i <= size; i++)
if (CONT[i] == '\r' || CONT[i] == '\n') CONT[i] = '\0';
for (--i; i < LCONT*BSIZE; i++) CONT[i] = '\0';
contp = CONT;
}
/*---------------------------------------------------------------------------*/
/*
* Eingabe des Datums
* Gueltig: 1.1.70 - 18.1.2038
*/
/*---------------------------------------------------------------------------*/
indate()
{
int year, month, day, hour;
loop:
printf("Enter Date (MM/DD/YY) : ");
gets(estring, sizeof estring);
month = getdat(1);
day = getdat(2);
year = getdat(3);
hour = 6; /* -1h fuer localtime und timezone */
if (month<1 || month>12 || day<1 || day>31)
goto loop;
time = 0;
if (year%4 == 0 && month > 2) ++dmsize[month-1];
if (year < 70) year += 100;
time = (year-69)/4;
time += 365*(year-70)+dmsize[month-1];
time += day - 1;
if (time > 24854) {
printf("can only create date from 1/1/(19)70 to 1/18/(20)38\n");
goto loop; }
time = 24*time + hour;
time = 60*60*time;
}
getdat(k)
int k;
{
register i, c, n;
n = 0;
for (i=0; c=estring[i]; i++) {
if (k-1 == 0) {
if (c == '/') return(n);
if (c < '0' || c > '9') return(-1);
n = n*10 + (c-'0'); }
else if (c == '/') k--; }
return(n);
}
/*---------------------------------------------------------------------------*/
/*
* Haenge UDOS-Dateinamen (*pt) an Drivernamen (fddname) an
*/
/*---------------------------------------------------------------------------*/
adname(pt)
char *pt;
{
register i;
for (i=0; (fddname[i] != ')') && (i < 20); i++);
do { i++;
fddname[i] = *pt;
pt++;
} while (*pt != '\0' && *pt != ' ');
fddname[++i] = '\0';
}
/*---------------------------------------------------------------------------*/
/*
* Lese Inode und zugehoerigen 1.Directory-Block
*/
/*---------------------------------------------------------------------------*/
rindi()
{
rdfs((long)((parinumb-1)>>3)+2, parinob);
copy(&pin, parinob+(parinumb-1)%8*64);
ppnidb = 1;
apardir = get3b(pin.di_addr);
rdfs(apardir, pardir);
}
/*---------------------------------------------------------------------------*/
/*
* Hole Dir.-Namen aus der Dir.-Definition-Zeile (CONT) in Puffer (conline)
*/
/*---------------------------------------------------------------------------*/
holdn()
{
register i;
for (i=0; i < 50; i++) {
conline[i] = *(contp++);
if (*contp == '/' || *contp == '\0') {
conline[i+1] = '\0';
if (*contp == '/') contp++;
break; }
}
}
/*---------------------------------------------------------------------------*/
/*
* Suche Namen (conline) in den 10 dir. Bloecken der Directory (pardir)
*/
/*---------------------------------------------------------------------------*/
ino_t
sun(c)
register c;
{
register i, j, k;
register ino_t inonb;
long z;
loop:
k=1;
for (i=0; i<32; i++) {
if ((inonb = get2b(aeintr = &pardir[i*16])) == 0) return(0);
k=0;
for (j=0; j<15; j++) {
if (pardir[i*16+2+j] != conline[j]) {
k++;
break; }
if (conline[j] == '\0') break; }
if (k == 0) return(inonb); }
if (ppnidb <= 10) {
if ((z = get3b(&pin.di_addr[3*ppnidb])) == 0) {
if (c==0) return(0); /* nur suchen */
wtfs(apardir, pardir); /* creiere neuen Block*/
z=alloc();
rdfs(z,pardir);
for (j=0; j<BSIZE; j++) pardir[j]=0;
ltol3(&pin.di_addr[3*ppnidb], &z, 1); }
else rdfs(z, pardir);
ppnidb++;
apardir = z;
goto loop; }
else {
/* Directory hat mehr als 10 Bloecke (= 318 Files) */
printf("\ndirectory too long !\n");
insend(); }
return(0);
}
/*---------------------------------------------------------------------------*/
/*
* Schreibe parent-Directory-Block und parent-Inode
*/
/*---------------------------------------------------------------------------*/
wpar()
{
if (parinumb && oldinumb) {
if (pardir[0] || pardir[1]) { /* beim 1.Mal ist pardir 0 */
wtfs(apardir, pardir);
if (((parinumb-1)>>3) != ((oldinumb-1)>>3)) {
wtfs((long)((oldinumb-1)>>3)+2, inob);
rdfs((long)((parinumb-1)>>3)+2, parinob);
copy(parinob+(parinumb-1)%8*64, &pin);
wtfs((long)((parinumb-1)>>3)+2, parinob); }
else {
copy(inob+(parinumb-1)%8*64, &pin);
wtfs((long)((oldinumb-1)>>3)+2, inob); }
} }
}
/*---------------------------------------------------------------------------*/
/*
* Test der Zelle abfr und Reaktion darauf
*/
/*---------------------------------------------------------------------------*/
testab()
{
if (abfr > 2) {
while (*contp != '\0') ++contp;
contp++;
return(0); }
printf("%s", contp);
if (abfr) printf("\n");
else {
loop:
printf(" (n/y/a/A/q/Q) ? : ");
gets(estring, sizeof estring);
switch (estring[0]) {
case 'a':
abfr = 1;
goto caseY;
case 'A':
abfr = 2;
case 'y':
case 'Y':
caseY:
return(1);
case 'q':
abfr = 3;
goto caseN;
case 'Q':
abfr = 4;
case 'n':
case 'N':
caseN:
while (*contp != '\0') ++contp;
contp++;
return(0);
default:
goto loop;
}
}
return(1); /* fuer 'a' und 'A' */
}
/*---------------------------------------------------------------------------*/
/*
* Directories und special-Files creieren und regular-Files laden
*/
/*---------------------------------------------------------------------------*/
cfile()
{
char db[BSIZE];
register i, c, nullfile;
ino_t dupinumb;
struct dinode dupin;
nullfile = 0;
for (i=0; i<BSIZE; db[i++]=0); /* loesche Datenpuffer 'db' */
clear(&iin, 64); /* loesche Strucktur 'iin' */
iin.di_atime = iin.di_mtime = iin.di_ctime = time;
padb = piadb = pzdb = 0;
for (i=0; i<12; zdb[i++]=0);
getstr();
if (conline[0] == 'n') {
conline[0] = '-';
nullfile++; }
iin.di_mode = gmode(conline[0], "-bcd", IFREG, IFBLK, IFCHR, IFDIR);
iin.di_mode |= gmode(conline[1], "-u" , 0, ISUID, 0, 0);
iin.di_mode |= gmode(conline[2], "-g" , 0, ISGID, 0, 0);
iin.di_mode |= gmode(conline[3], "-t" , 0, ISVTX, 0, 0);
for (i=4; i<7; i++) {
c = conline[i];
if (c < '0' || c > '7') {
printf("\nbad octal digit %x in %s\n", c, conline);
insend(); }
iin.di_mode |= (c-'0')<<(18-3*i); }
iin.di_uid = getnum();
iin.di_gid = getnum();
iin.di_nlink = 1;
inumb = alloci();
switch (iin.di_mode & IFMT) {
case IFREG:
getstr(); /* UDOS-Filename */
adname(conline);
if (*--contp) getstr(); /* wega-Filename */
else contp++;
if (dupinumb = sun(1)) {
rdfs((long)((dupinumb-1)>>3)+2, db);
copy(&dupin, db+(dupinumb-1)%8*64);
if (dupin.di_nlink) {
printf("file: %s already exist\n", conline);
loop:
printf("overwrite (y/n/q) ? : ");
gets(estring, sizeof estring);
switch (estring[0]) {
case 'y':
pin.di_size -= 0x10;
if (dupin.di_nlink != 1)
iin.di_nlink = dupin.di_nlink;
bfinfree(dupin.di_addr);
if (((dupinumb-1)>>3) != ((oldinumb-1)>>3)) {
db[(dupinumb-1)%8*64] = 0;
db[(dupinumb-1)%8*64+1] = 0;
wtfs((long)((dupinumb-1)>>3)+2, db); }
else {
inob[(dupinumb-1)%8*64] = 0;
inob[(dupinumb-1)%8*64+1] = 0; }
ifree(inumb); /* set inumber free */
inumb = dupinumb;
break;
case 'q':
abfr = 3; /* Abbruch fuer akt. Dir. */
case 'n':
ifree(inumb);
return;
default:
goto loop;
} } }
if (nullfile) break;
loopopen:
fsi = open(fddname, 0);
/* Achtung: ab 'open' bis 'close' ist kein E/A-Verkehr ueber tty moeglich !!! */
if (fsi<0) {
loopno:
printf("repeat (y/n/q) ? : ");
gets(estring, sizeof estring);
switch (estring[0]) {
case 'y':
goto loopopen;
case 'q':
abfr = 3; /* Abbruch fuer akt. Dir. */
case 'n':
ifree(inumb);
return;
default:
goto loopno; } }
while ((i=read(fsi, db, BSIZE)) > 0) {
iin.di_size += i;
newblk(db); }
close(fsi);
if (i < 0) {
if (piadb) wtfs(aiadb, iadb);
if (padb) wtfs(aadb, adb);
if (pzdb) ltol3(iin.di_addr, zdb, pzdb);
bfinfree(iin.di_addr);
loopre:
printf("repeat (y/n/q) ? : ");
gets(estring, sizeof estring);
switch (estring[0]) {
case 'y':
iin.di_size = 0;
padb = piadb = pzdb = 0;
for (i=0; i<12; zdb[i++]=0);
goto loopopen;
case 'q':
abfr = 3; /* Abbruch fuer akt. Dir. */
case 'n':
ifree(inumb);
return;
default:
goto loopre; } }
ltol3(iin.di_addr, zdb, pzdb);
if (padb) wtfs(aadb, adb);
if (piadb) wtfs(aiadb, iadb);
break;
case IFBLK:
case IFCHR:
i = getnum() & 0xFF; /* majory number */
c = getnum() & 0xFF; /* minory number */
iin.di_addr[1] = i;
iin.di_addr[2] = c;
getstr();
if(sun(1)) {
printf("\nspecial-file: %s already exist; cannot overwrite !\n", conline);
ifree(inumb);
return; }
break;
case IFDIR:
getstr();
if (sun(1)) {
printf("\ndirectory: %s already exist; cannot overwrite !\n", conline);
ifree(inumb);
return; }
entry(&inumb, ".", db);
entry(&parinumb, "..", &db[16]);
newblk(db);
ltol3(iin.di_addr, zdb, pzdb);
iin.di_nlink++;
iin.di_size = 0x20;
++pin.di_nlink;
break;
default:
printf("\ndi_mode - Fehler\n");
insend(); }
cfilend();
}
/*---------------------------------------------------------------------------*/
/*
* cfile-Ende-Behandlung
*/
/*---------------------------------------------------------------------------*/
cfilend()
{
if (oldinumb && (((inumb-1)>>3) != (oldinumb-1)>>3))
wtfs((long)((oldinumb-1)>>3)+2, inob);
if (((inumb-1)>>3) != ((oldinumb-1)>>3))
rdfs((long)((inumb-1)>>3)+2, inob);
copy(inob+(inumb-1)%8*64, &iin);
oldinumb = inumb;
pin.di_size += 0x10;
entry(&inumb, conline, aeintr);
}
/*---------------------------------------------------------------------------*/
/*
* Uebertrage akt. Teil einer Anweisung von CONT nach conline[]
*/
/*---------------------------------------------------------------------------*/
getstr()
{
register i;
register char c;
loop:
switch (c = *contp++) {
case ' ':
goto loop; }
i = 0;
do { conline[i++] = c ; c = *contp++; }
while (c != ' ' && c != '\0');
conline[i] = '\0';
}
/*---------------------------------------------------------------------------*/
/*
* Eintragen des Parameters m0,...,m3 in den Return-Wert
*/
/*---------------------------------------------------------------------------*/
gmode(c, s, m0, m1, m2, m3)
char c;
register char *s;
{
if (c == s[0])
return(m0);
if (c == s[1])
return(m1);
if (c == s[2])
return(m2);
if (c == s[3])
return(m3);
printf("\nbad charakter %x in %s\n", c, conline);
insend();
return(0);
}
/*---------------------------------------------------------------------------*/
/*
* Dezimale Eingabekonvertierung aus conline
*/
/*---------------------------------------------------------------------------*/
long
getnum()
{
register i, c;
register long n;
getstr();
n = 0;
for (i=0; c=conline[i]; i++) {
if (c < '0' || c > '9') {
printf("\nbad decimal digit %x in %s\n", c, conline);
insend(); }
n = n*10 + (c-'0'); }
return(n);
}
/*---------------------------------------------------------------------------*/
/*
* Loesche strukturierten Puffer *pt der Laenge l
*/
/*---------------------------------------------------------------------------*/
clear(pt, l)
register l;
register char *pt;
{
register i;
for (i=0; i<l; *pt++ = '\0', i++);
}
/*---------------------------------------------------------------------------*/
/*
* Copiere Inode (str1) := (str2)
*/
/*---------------------------------------------------------------------------*/
copy(str1, str2)
register char *str1, *str2;
{
register i;
for (i=0; i<64; *str1++ = *str2++, i++);
}
/*---------------------------------------------------------------------------*/
/*
* Gebe im Return-Wert freie inode-Nr. zurueck
*/
/*---------------------------------------------------------------------------*/
ino_t
alloci()
{
register i, j, k;
register ino_t inr;
char bf[BSIZE];
filsys.s_tinode--;
if (filsys.s_ninode == 0) { /* inode Liste fuellen */
for (i=0; i<filsys.s_isize; i++) {
if (i == (oldinumb-1)>>3)
for (j=0; j<BSIZE; j++) bf[j] = inob[j];
else rdfs((long)i+2, bf);
for (j=0; j<8; j++) {
if (get2b(&bf[64*j]) == 0) {
filsys.s_ninode++;
k = 100-filsys.s_ninode;
filsys.s_inode[k] = j+1+i*8;
if (filsys.s_ninode == 100)
goto holinr; } } }
printf("\nout of free inodes\n");
insend(); }
holinr: /* hole inode-Nr. */
inr = filsys.s_inode[--filsys.s_ninode];
return(inr);
}
/*---------------------------------------------------------------------------*/
/*
* Gebe eine freigewordene inode zurueck in die Frei-inode-Liste
*/
/*---------------------------------------------------------------------------*/
ifree(inb)
register ino_t inb;
{
filsys.s_tinode++;
if (filsys.s_ninode == NICINOD) return;
filsys.s_inode[filsys.s_ninode++] = inb;
}
/*---------------------------------------------------------------------------*/
/*
* Gebe Bloecke aus inode wieder frei
*/
/*---------------------------------------------------------------------------*/
bfinfree(pnt)
register pnt;
{
daddr_t bn;
register i, j;
long addrb[12], bf[128], ibf[128];
l3tol(addrb, pnt, 12);
for (i=0; i<10; i++) {
if (bn = addrb[i]) bfree(bn);
else return; }
if (bn = addrb[10]) {
rdfs(bn, bf);
bfree(bn);
for (i=0; i<128; i++) {
if (bn = bf[i]) bfree(bn);
else return; } }
else return;
if (bn = addrb[11]) {
rdfs(bn, ibf);
bfree(bn);
for (i=0; i<128; i++) {
if (bn = ibf[i]) {
rdfs(bn, bf);
bfree(bn);
for (j=0; j<128; j++) {
if (bn = bf[j]) bfree(bn);
else return; } }
else return; } }
}
/*---------------------------------------------------------------------------*/
/*
* Speicher Block (db) auf Hard-Disk und notiere es im inode (ib)
*/
/*---------------------------------------------------------------------------*/
newblk(db)
char *db;
{
register i;
register daddr_t bno;
bno = alloc();
wtfs(bno, db);
for (i=0; i<BSIZE; db[i++]=0);
if (pzdb < 10) { /* direkte Bloecke */
zdb[pzdb++] = bno;
return; }
/* dreifach indirekt wird nicht realisiert */
if (piadb == 0 && padb == 0 && pzdb == 12) {
printf("\nfile to long\n");
insend(); }
/* Start: zweifach indirekt */
if (piadb == 0 && padb == 0 && pzdb == 11) {
aiadb = alloc();
for (i=0; i<128; iadb[i++]=0);
zdb[pzdb++] = aiadb; }
/* Start: einfach indirekt */
if (padb == 0) {
aadb = alloc();
for (i=0; i<128; adb[i++]=0);
if (pzdb == 12) iadb[piadb++] = aadb; /* auch bei zweifach indirekt */
else zdb[pzdb++] = aadb; }
adb[padb++] = bno;
if (piadb == 128) {
wtfs(aiadb, iadb);
piadb = 0; }
if (padb == 128) {
wtfs(aadb, adb);
padb = 0; }
}
/*---------------------------------------------------------------------------*/
/*
* Eintragen des Filenamen (incl. inode-Nummer) in die Directory
*/
/*---------------------------------------------------------------------------*/
entry(inum, str, direa)
register char *inum, *str, *direa;
{
register i, j;
j = 0;
*direa++ = *inum++;
*direa++ = *inum;
for (i=0; i<14; i++) {
if (*str == '\0' || j == 1)
{ *direa++ = '\0'; j = 1; }
else *direa++ = *str++; }
}
/*---------------------------------------------------------------------------*/
/*
* Hole aus einem char-Buffer 2 oder 3 Byte
*/
/*---------------------------------------------------------------------------*/
unsigned
get2b(e)
char *e;
{
register unsigned i;
i = (*e << 8) | (*(e+1) & 0xFF);
return(i);
}
unsigned long
get3b(e)
char *e;
{
register unsigned long i;
i = ((unsigned long)*e << 16) & 0xFF0000;
i |= ((unsigned long)*(e+1) << 8) & 0xFF00;
i |= (unsigned long)*(e+2) & 0xFF;
return(i);
}