add first WEGA commands
This commit is contained in:
parent
2adeef252b
commit
47af93dcbc
|
|
@ -0,0 +1,46 @@
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
|
||||||
|
W E G A - Quelle (C) ZFT/KEAW Abt. Basissoftware - 1985
|
||||||
|
Standalone: sa.cat.c
|
||||||
|
|
||||||
|
|
||||||
|
Bearbeiter : P. Hoge
|
||||||
|
Datum : 04/01/87 11:15:40
|
||||||
|
Version : 1.1
|
||||||
|
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* standalone cat */
|
||||||
|
|
||||||
|
char buf[0x200];
|
||||||
|
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
register c, i, t;
|
||||||
|
|
||||||
|
do {
|
||||||
|
printf("File: ");
|
||||||
|
gets(buf, 100);
|
||||||
|
if (buf[0] == 0)
|
||||||
|
exit(1);
|
||||||
|
i = open(buf, 0);
|
||||||
|
} while (i <= 0);
|
||||||
|
|
||||||
|
for (t=0; (c=getc(i)) != -1;) {
|
||||||
|
if (c == 0x0a || (c >= 0x20 && c < 0x7f)) {
|
||||||
|
putchar(c);
|
||||||
|
t = ++t & 0x0007;
|
||||||
|
}
|
||||||
|
if (c == 0x09) {
|
||||||
|
do {
|
||||||
|
putchar(0x20);
|
||||||
|
t = ++t & 0x0007;
|
||||||
|
}while (t != 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,971 @@
|
||||||
|
/******************************************************************************
|
||||||
|
*******************************************************************************
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,747 @@
|
||||||
|
/***************************************************************************
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
W E G A - Quelle (C) ZFT/KEAW Abt. Basissoftware - 1985
|
||||||
|
Standalone: sa.mkfs.c
|
||||||
|
|
||||||
|
|
||||||
|
Bearbeiter: P. Bala / P.Hoge
|
||||||
|
Datum: 04/01/87 11:16:06
|
||||||
|
Version: 1.1
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
Hinweise:
|
||||||
|
mkfs kann sowohl als Standalone- als auch als Kommandoversion
|
||||||
|
generiert werden (Konstante STANDALONE =1 bzw. 0).
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Aufbau eines Filesystems-Prototyps
|
||||||
|
* Aufruf im Kommando: mkfs filsys proto/size [ m n ]
|
||||||
|
* Bei Standalone-Version erfolgt Parameter-Angabe ueber Konsole
|
||||||
|
*
|
||||||
|
*--------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
/*------------------------------------------------- Konstanten -------------*/
|
||||||
|
#define STANDALONE 1
|
||||||
|
#define NIPB (BSIZE/sizeof(struct dinode))
|
||||||
|
#define NDIRECT (BSIZE/sizeof(struct direct))
|
||||||
|
#define LADDR 10 /* Anzahl der Direktadressen im Inode */
|
||||||
|
#define MAXFN 72 /* Anzahl Blocks per Disk-Zyinder */
|
||||||
|
#define VERSATZ 1 /* kein Blockversatz */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef STANDALONE
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <s.out.h>
|
||||||
|
#endif
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/ino.h>
|
||||||
|
#include <sys/inode.h>
|
||||||
|
#include <sys/filsys.h>
|
||||||
|
#include <sys/fblk.h>
|
||||||
|
#include <sys/dir.h>
|
||||||
|
|
||||||
|
/*------------------------------------------------------- Variable --------*/
|
||||||
|
time_t utime;
|
||||||
|
#ifndef STANDALONE
|
||||||
|
FILE *fin;
|
||||||
|
#else
|
||||||
|
int fin;
|
||||||
|
#endif
|
||||||
|
int fsi;
|
||||||
|
int fso;
|
||||||
|
char *charp;
|
||||||
|
char buf[BSIZE];
|
||||||
|
union {
|
||||||
|
struct fblk fb;
|
||||||
|
char pad1[BSIZE];
|
||||||
|
} fbuf;
|
||||||
|
#ifndef STANDALONE
|
||||||
|
struct s_exec head;
|
||||||
|
#endif
|
||||||
|
char string[50];
|
||||||
|
union {
|
||||||
|
struct filsys fs;
|
||||||
|
char pad2[BSIZE];
|
||||||
|
} filsys;
|
||||||
|
char *fsys;
|
||||||
|
char *proto;
|
||||||
|
int f_n = MAXFN;
|
||||||
|
int f_m = VERSATZ; /* Standard-Blockversatz */
|
||||||
|
int error;
|
||||||
|
ino_t ino;
|
||||||
|
long getnum();
|
||||||
|
daddr_t alloc();
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Haupt - Programm
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
main(argc, argv)
|
||||||
|
char *argv[];
|
||||||
|
{
|
||||||
|
register int f, c;
|
||||||
|
register long n;
|
||||||
|
|
||||||
|
#ifndef STANDALONE
|
||||||
|
time(&utime);
|
||||||
|
if(argc < 3) {
|
||||||
|
printf("usage: mkfs filsys proto/size [ m n ]\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
fsys = argv[1];
|
||||||
|
proto = argv[2];
|
||||||
|
#else
|
||||||
|
/* Definiere Filesystem-Groesse ueber Konsole */
|
||||||
|
{
|
||||||
|
static char protos[60];
|
||||||
|
|
||||||
|
printf("file system size: ");
|
||||||
|
gets(protos, sizeof protos);
|
||||||
|
proto = protos;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef STANDALONE
|
||||||
|
{
|
||||||
|
char fsbuf[100];
|
||||||
|
|
||||||
|
/* Definiere Name und Nr. des 1. Blocks des Filesystems ueber Konsole */
|
||||||
|
do {
|
||||||
|
printf("file system: ");
|
||||||
|
gets(fsbuf, sizeof fsbuf);
|
||||||
|
fso = open(fsbuf, 1);
|
||||||
|
fsi = open(fsbuf, 0);
|
||||||
|
} while (fso < 0 || fsi < 0);
|
||||||
|
}
|
||||||
|
fin = 0;
|
||||||
|
argc = 0;
|
||||||
|
#else
|
||||||
|
fso = creat(fsys, 0666);
|
||||||
|
if(fso < 0) {
|
||||||
|
printf("%s: cannot create\n", fsys);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
fsi = open(fsys, 0);
|
||||||
|
if(fsi < 0) {
|
||||||
|
printf("%s: cannot open\n", fsys);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
fin = fopen(proto, "r");
|
||||||
|
#endif
|
||||||
|
/* Festlegen der Anzahl der inode-Bloecke des Filesystems */
|
||||||
|
if(fin == 0) {
|
||||||
|
n = 0;
|
||||||
|
for(f=0; c=proto[f]; f++) {
|
||||||
|
if(c<'0' || c>'9') {
|
||||||
|
printf("%s: cannot open\n", proto);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
n = n*10 + (c-'0');
|
||||||
|
}
|
||||||
|
filsys.s_fsize = n;
|
||||||
|
n = n/25;
|
||||||
|
if(n <= 0)
|
||||||
|
n = 1;
|
||||||
|
if(n > 65500/NIPB)
|
||||||
|
n = 65500/NIPB;
|
||||||
|
filsys.s_isize = n + 2;
|
||||||
|
printf("isize = %d\n", filsys.s_isize*NIPB);
|
||||||
|
/*
|
||||||
|
* Kommando-String zur Generierung einer leeren Directory
|
||||||
|
*/
|
||||||
|
charp = "d--777 0 0 $ ";
|
||||||
|
goto f3;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef STANDALONE
|
||||||
|
|
||||||
|
getstr();
|
||||||
|
f = open(string, 0);
|
||||||
|
if(f < 0) {
|
||||||
|
printf("%s: cannot open init\n", string);
|
||||||
|
goto f2;
|
||||||
|
}
|
||||||
|
read(f, (char *)&head, sizeof head);
|
||||||
|
if(head.s_magic != N_MAGIC1) {
|
||||||
|
printf("%s: bad format\n", string);
|
||||||
|
goto f1;
|
||||||
|
}
|
||||||
|
c = head.s_imsize;
|
||||||
|
if(c > BSIZE) {
|
||||||
|
printf("%s: too big\n", string);
|
||||||
|
goto f1;
|
||||||
|
}
|
||||||
|
read(f, buf, c);
|
||||||
|
wtfs((long)0, buf);
|
||||||
|
|
||||||
|
f1:
|
||||||
|
close(f);
|
||||||
|
|
||||||
|
|
||||||
|
f2:
|
||||||
|
filsys.s_fsize = getnum();
|
||||||
|
n = getnum();
|
||||||
|
n /= NIPB;
|
||||||
|
filsys.s_isize = n + 3;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
f3:
|
||||||
|
if(argc >= 5) {
|
||||||
|
f_m = atoi(argv[3]);
|
||||||
|
f_n = atoi(argv[4]);
|
||||||
|
if(f_n <= 0 || f_n >= 1000)
|
||||||
|
f_n = 1000;
|
||||||
|
if(f_m <= 0 || f_m > f_n)
|
||||||
|
f_m = 3;
|
||||||
|
}
|
||||||
|
filsys.s_m = f_m;
|
||||||
|
filsys.s_n = f_n;
|
||||||
|
printf("m/n = %d %d\n", f_m, f_n);
|
||||||
|
if(filsys.s_isize >= filsys.s_fsize) {
|
||||||
|
printf("%ld/%ld: bad ratio\n", filsys.s_fsize, filsys.s_isize-2);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
filsys.s_tfree = 0;
|
||||||
|
filsys.s_tinode = 0;
|
||||||
|
for(c=0; c<BSIZE; c++)
|
||||||
|
buf[c] = 0;
|
||||||
|
for(n=2; n!=filsys.s_isize; n++) {
|
||||||
|
wtfs(n, buf);
|
||||||
|
filsys.s_tinode += NIPB;
|
||||||
|
}
|
||||||
|
ino = 0;
|
||||||
|
|
||||||
|
/* Anlegen der Freiblock-Liste des Filesystems */
|
||||||
|
bflist();
|
||||||
|
|
||||||
|
/* Generierung der Root-Directory entspr. der Kommando-String */
|
||||||
|
cfile((struct inode *)0);
|
||||||
|
|
||||||
|
filsys.s_time = utime;
|
||||||
|
filsys.s_mach = 0;
|
||||||
|
/* Schreibe Superblock (Blocknr. 1 des Filesystems) auf Disk */
|
||||||
|
wtfs((long)1, (char *)&filsys);
|
||||||
|
exit(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------
|
||||||
|
* Generiere einen File unter wega-Verwaltung anhand einer
|
||||||
|
* Kommando-String
|
||||||
|
*-----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
cfile(par)
|
||||||
|
register struct inode *par;
|
||||||
|
{
|
||||||
|
struct inode in;
|
||||||
|
int dbc, ibc;
|
||||||
|
char db[BSIZE];
|
||||||
|
daddr_t ib[NINDIR];
|
||||||
|
register int i, f, c;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Eingabe mode, uid und gid
|
||||||
|
*/
|
||||||
|
|
||||||
|
getstr();
|
||||||
|
in.i_mode = gmode(string[0], "-bcd", IFREG, IFBLK, IFCHR, IFDIR);
|
||||||
|
in.i_mode |= gmode(string[1], "-u", 0, ISUID, 0, 0);
|
||||||
|
in.i_mode |= gmode(string[2], "-g", 0, ISGID, 0, 0);
|
||||||
|
for(i=3; i<6; i++) {
|
||||||
|
c = string[i];
|
||||||
|
if(c<'0' || c>'7') {
|
||||||
|
printf("%c/%s: bad octal mode digit\n", c, string);
|
||||||
|
error = 1;
|
||||||
|
c = 0;
|
||||||
|
}
|
||||||
|
in.i_mode |= (c-'0')<<(15-3*i);
|
||||||
|
}
|
||||||
|
in.i_uid = getnum();
|
||||||
|
in.i_gid = getnum();
|
||||||
|
|
||||||
|
|
||||||
|
/* Loesche zugewiesenes inode */
|
||||||
|
ino++;
|
||||||
|
in.i_number = ino;
|
||||||
|
for(i=0; i<BSIZE; i++)
|
||||||
|
db[i] = 0;
|
||||||
|
for(i=0; i<NINDIR; i++)
|
||||||
|
ib[i] = (daddr_t)0;
|
||||||
|
in.i_nlink = 1;
|
||||||
|
in.i_size = 0;
|
||||||
|
for(i=0; i<NADDR; i++)
|
||||||
|
in.i_addr[i] = (daddr_t)0;
|
||||||
|
if(par == (struct inode *)0) {
|
||||||
|
par = ∈
|
||||||
|
in.i_nlink--;
|
||||||
|
}
|
||||||
|
dbc = 0;
|
||||||
|
ibc = 0;
|
||||||
|
switch(in.i_mode&IFMT) {
|
||||||
|
/* regular file
|
||||||
|
* die in der Kommando-String angegebene Datei wird in das
|
||||||
|
* Filesystem uebertragen
|
||||||
|
*/
|
||||||
|
|
||||||
|
case IFREG:
|
||||||
|
/*
|
||||||
|
* Regular File
|
||||||
|
* Inhalt ist ein File-Name
|
||||||
|
*/
|
||||||
|
|
||||||
|
getstr();
|
||||||
|
f = open(string, 0);
|
||||||
|
if(f < 0) {
|
||||||
|
printf("%s: cannot open\n", string);
|
||||||
|
error = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
while((i=read(f, db, BSIZE)) > 0) {
|
||||||
|
in.i_size += i;
|
||||||
|
newblk(&dbc, db, &ibc, ib);
|
||||||
|
}
|
||||||
|
close(f);
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* special file
|
||||||
|
* die in der Kommando-String notierte Devicenr. wird in das
|
||||||
|
* inode uebernommen
|
||||||
|
*/
|
||||||
|
case IFBLK:
|
||||||
|
case IFCHR:
|
||||||
|
/*
|
||||||
|
* Special File
|
||||||
|
* Inhalt ist eine major/minor - Devicenummer
|
||||||
|
*/
|
||||||
|
|
||||||
|
i = getnum() & 0377;
|
||||||
|
f = getnum() & 0377;
|
||||||
|
in.i_addr[0] = (i<<8) | f;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IFDIR:
|
||||||
|
/* directory
|
||||||
|
* Anlegen eines File-Verzeichnisses bei rekursiver Definition
|
||||||
|
* der in der akt. Directory notierten Files entsprechend der
|
||||||
|
* Kommando-String.
|
||||||
|
* Ende der Eintragungen in die akt. Directory, wenn der File-
|
||||||
|
* Name "$" gefunden wurde
|
||||||
|
*/
|
||||||
|
|
||||||
|
par->i_nlink++;
|
||||||
|
in.i_nlink++;
|
||||||
|
entry(in.i_number, ".", &dbc, db, &ibc, ib);
|
||||||
|
entry(par->i_number, "..", &dbc, db, &ibc, ib);
|
||||||
|
in.i_size = 2*sizeof(struct direct);
|
||||||
|
for(;;) {
|
||||||
|
getstr();
|
||||||
|
if(string[0]=='$' && string[1]=='\0')
|
||||||
|
break;
|
||||||
|
entry(ino+1, string, &dbc, db, &ibc, ib);
|
||||||
|
in.i_size += sizeof(struct direct);
|
||||||
|
cfile(&in);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* Schreibe inode auf Disk */
|
||||||
|
if(dbc != 0)
|
||||||
|
newblk(&dbc, db, &ibc, ib);
|
||||||
|
iput(&in, &ibc, ib);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
* Eintragen einer der drei Parameter m0 .. m3 entsprechend
|
||||||
|
* dem Kommando-Steuerzeichen in c anhand der vorgegebenen
|
||||||
|
* Moeglichkeiten s[0] .. s[3]
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
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("%c/%s: bad mode\n", c, string);
|
||||||
|
error = 1;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------
|
||||||
|
* Eingabe-Konvertierung dezimal aus Kommando-String
|
||||||
|
*----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
long
|
||||||
|
getnum()
|
||||||
|
{
|
||||||
|
register int i, c;
|
||||||
|
register long n;
|
||||||
|
|
||||||
|
getstr();
|
||||||
|
n = 0;
|
||||||
|
for(i=0; c=string[i]; i++) {
|
||||||
|
if(c<'0' || c>'9') {
|
||||||
|
printf("%s: bad number\n", string);
|
||||||
|
error = 1;
|
||||||
|
return((long)0);
|
||||||
|
}
|
||||||
|
n = n*10 + (c-'0');
|
||||||
|
}
|
||||||
|
return(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------
|
||||||
|
* Uebertrage akt. Term aus Kommando-String nach string[]
|
||||||
|
*----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
getstr()
|
||||||
|
{
|
||||||
|
register int i, c;
|
||||||
|
|
||||||
|
loop:
|
||||||
|
switch(c=getch()) {
|
||||||
|
|
||||||
|
case ' ':
|
||||||
|
case '\t':
|
||||||
|
case '\n':
|
||||||
|
goto loop;
|
||||||
|
|
||||||
|
case '\0':
|
||||||
|
printf("EOF\n");
|
||||||
|
exit(1);
|
||||||
|
|
||||||
|
case ':':
|
||||||
|
while(getch() != '\n');
|
||||||
|
goto loop;
|
||||||
|
|
||||||
|
}
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
string[i++] = c;
|
||||||
|
c = getch();
|
||||||
|
} while(c!=' '&&c!='\t'&&c!='\n'&&c!='\0');
|
||||||
|
string[i] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------
|
||||||
|
* Read Block von Disk
|
||||||
|
*--------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
rdfs(bno, bf)
|
||||||
|
daddr_t bno;
|
||||||
|
char *bf;
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
|
||||||
|
lseek(fsi, bno*BSIZE, 0);
|
||||||
|
n = read(fsi, bf, BSIZE);
|
||||||
|
if(n != BSIZE) {
|
||||||
|
printf("read error: %ld\n", bno);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------
|
||||||
|
* Write Block auf Disk
|
||||||
|
*----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
wtfs(bno, bf)
|
||||||
|
daddr_t bno;
|
||||||
|
char *bf;
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
|
||||||
|
lseek(fso, bno*BSIZE, 0);
|
||||||
|
n = write(fso, bf, BSIZE);
|
||||||
|
if(n != BSIZE) {
|
||||||
|
printf("write error: %D\n", bno);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------
|
||||||
|
* Der Return-Wert von alloc ist die Nummer des naechsten Blocks
|
||||||
|
* aus der Freiblockliste des Superblocks. Ist diese leer, wird
|
||||||
|
* der naechste Ankerblock in den Superblock gelesen und die Nr.
|
||||||
|
* des Ankerblocks selbst zurueckgegeben. Ist kein solcher Anker-
|
||||||
|
* Block mehr vorhanden, wird mkfs beendet
|
||||||
|
*------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
daddr_t
|
||||||
|
alloc()
|
||||||
|
{
|
||||||
|
register int i;
|
||||||
|
register daddr_t bno;
|
||||||
|
|
||||||
|
filsys.s_tfree--;
|
||||||
|
bno = filsys.s_free[--filsys.s_nfree];
|
||||||
|
if(bno == 0) {
|
||||||
|
printf("out of free space\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------
|
||||||
|
* Eintragen der Blocknr. bno in die Freiblockliste des Superblocks
|
||||||
|
* Ist dieses Teil voll, so wird der akt. freizugebende Block als
|
||||||
|
* Ankerblock benutzt, um die volle Freiblockliste des Superblocks
|
||||||
|
* auf die Disk auszulagern
|
||||||
|
*-----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
bfree(bno)
|
||||||
|
register daddr_t bno;
|
||||||
|
{
|
||||||
|
register int i;
|
||||||
|
|
||||||
|
filsys.s_tfree++;
|
||||||
|
if(filsys.s_nfree >= NICFREE) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------
|
||||||
|
* Eintragen Filename incl. inode-Nummer in akt. Directory
|
||||||
|
*---------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
entry(inum, str, adbc, db, aibc, ib)
|
||||||
|
ino_t inum;
|
||||||
|
char *str;
|
||||||
|
register int *adbc, *aibc;
|
||||||
|
char *db;
|
||||||
|
daddr_t *ib;
|
||||||
|
{
|
||||||
|
register struct direct *dp;
|
||||||
|
register int i;
|
||||||
|
|
||||||
|
dp = (struct direct *)db;
|
||||||
|
dp += *adbc;
|
||||||
|
(*adbc)++;
|
||||||
|
dp->d_ino = inum;
|
||||||
|
for(i=0; i<DIRSIZ; i++)
|
||||||
|
dp->d_name[i] = 0;
|
||||||
|
for(i=0; i<DIRSIZ; i++)
|
||||||
|
if((dp->d_name[i] = str[i]) == 0)
|
||||||
|
break;
|
||||||
|
if(*adbc >= NDIRECT)
|
||||||
|
newblk(adbc, db, aibc, ib);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------
|
||||||
|
* Schreibe gefuellten internen Datenblock auf Disk und loesche
|
||||||
|
* den internen Datenblock
|
||||||
|
*----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
newblk(adbc, db, aibc, ib)
|
||||||
|
register int *adbc, *aibc;
|
||||||
|
char *db;
|
||||||
|
daddr_t *ib;
|
||||||
|
{
|
||||||
|
register int i;
|
||||||
|
daddr_t bno;
|
||||||
|
|
||||||
|
bno = alloc();
|
||||||
|
wtfs(bno, db);
|
||||||
|
for(i=0; i<BSIZE; i++)
|
||||||
|
db[i] = 0;
|
||||||
|
*adbc = 0;
|
||||||
|
ib[*aibc] = bno;
|
||||||
|
(*aibc)++;
|
||||||
|
if(*aibc >= NINDIR) {
|
||||||
|
printf("indirect block full\n");
|
||||||
|
error = 1;
|
||||||
|
*aibc = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------
|
||||||
|
* Lies akt. Zeichen von Kommando-String
|
||||||
|
*-----------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
getch()
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifndef STANDALONE
|
||||||
|
if(charp)
|
||||||
|
#endif
|
||||||
|
return(*charp++);
|
||||||
|
#ifndef STANDALONE
|
||||||
|
return(getc(fin));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------
|
||||||
|
* Aufbau der Freiblock-Liste des akt. Filesystems
|
||||||
|
*---------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
bflist()
|
||||||
|
{
|
||||||
|
struct inode in;
|
||||||
|
daddr_t ib[NINDIR];
|
||||||
|
int ibc;
|
||||||
|
char flg[MAXFN];
|
||||||
|
int adr[MAXFN];
|
||||||
|
register int i, j;
|
||||||
|
register daddr_t f, d;
|
||||||
|
|
||||||
|
/* Aufbau der Musterverteilung der freien Bloecke auf
|
||||||
|
* einem Disk-Zylinder entsprechend des vorgegebenen
|
||||||
|
* Blockversatzes
|
||||||
|
*/
|
||||||
|
for(i=0; i<f_n; i++)
|
||||||
|
flg[i] = 0;
|
||||||
|
i = 0;
|
||||||
|
for(j=0; j<f_n; j++) {
|
||||||
|
while(flg[i])
|
||||||
|
i = (i+1)%f_n;
|
||||||
|
adr[j] = i+1;
|
||||||
|
flg[i]++;
|
||||||
|
i = (i+f_m)%f_n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Anlegen des inodes 1 (bad blocks)
|
||||||
|
*/
|
||||||
|
ino++;
|
||||||
|
in.i_number = ino;
|
||||||
|
in.i_mode = IFREG;
|
||||||
|
in.i_uid = 0;
|
||||||
|
in.i_gid = 0;
|
||||||
|
in.i_nlink = 0;
|
||||||
|
in.i_size = 0;
|
||||||
|
for(i=0; i<NADDR; i++)
|
||||||
|
in.i_addr[i] = (daddr_t)0;
|
||||||
|
|
||||||
|
for(i=0; i<NINDIR; i++)
|
||||||
|
ib[i] = (daddr_t)0;
|
||||||
|
ibc = 0;
|
||||||
|
/* Markiere Ende der Freiblockliste
|
||||||
|
* (Adr. Ankerblock = 0)
|
||||||
|
*/
|
||||||
|
bfree((daddr_t)0);
|
||||||
|
/* Generiere Freiblockliste anhand der Musterverteilung
|
||||||
|
* wobei die definierten inode-Bloecke nicht einbezogen
|
||||||
|
* werden.
|
||||||
|
*/
|
||||||
|
d = filsys.s_fsize-1;
|
||||||
|
while(d%f_n)
|
||||||
|
d++;
|
||||||
|
for(; d > 0; d -= f_n)
|
||||||
|
for(i=0; i<f_n; i++) {
|
||||||
|
f = d - adr[i];
|
||||||
|
if(f < filsys.s_fsize && f >= filsys.s_isize)
|
||||||
|
if(badblk(f)) {
|
||||||
|
if(ibc >= NINDIR) {
|
||||||
|
printf("too many bad blocks\n");
|
||||||
|
error = 1;
|
||||||
|
ibc = 0;
|
||||||
|
}
|
||||||
|
ib[ibc] = f;
|
||||||
|
ibc++;
|
||||||
|
} else
|
||||||
|
bfree(f);
|
||||||
|
}
|
||||||
|
/* Schreibe "bad-blocks"-inode auf Disk
|
||||||
|
*/
|
||||||
|
iput(&in, &ibc, ib);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------
|
||||||
|
* Wandle interne Form des inodes ip in Diskform und Eintragen
|
||||||
|
* dieser in den zugeordeten inode-Block
|
||||||
|
*---------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
iput(ip, aibc, ib)
|
||||||
|
register struct inode *ip;
|
||||||
|
register int *aibc;
|
||||||
|
daddr_t *ib;
|
||||||
|
{
|
||||||
|
register struct dinode *dp;
|
||||||
|
daddr_t d;
|
||||||
|
register int i;
|
||||||
|
|
||||||
|
filsys.s_tinode--;
|
||||||
|
d = itod(ip->i_number);
|
||||||
|
if(d >= filsys.s_isize) {
|
||||||
|
if(error == 0)
|
||||||
|
printf("ilist too small\n");
|
||||||
|
error = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
rdfs(d, buf);
|
||||||
|
dp = (struct dinode *)buf;
|
||||||
|
dp += itoo(ip->i_number);
|
||||||
|
|
||||||
|
dp->di_mode = ip->i_mode;
|
||||||
|
dp->di_nlink = ip->i_nlink;
|
||||||
|
dp->di_uid = ip->i_uid;
|
||||||
|
dp->di_gid = ip->i_gid;
|
||||||
|
dp->di_size = ip->i_size;
|
||||||
|
dp->di_atime = utime;
|
||||||
|
dp->di_mtime = utime;
|
||||||
|
dp->di_ctime = utime;
|
||||||
|
|
||||||
|
switch(ip->i_mode&IFMT) {
|
||||||
|
|
||||||
|
/* Fuer regular files und directorys werden die max. 128
|
||||||
|
* Blocknummern entspr. der unix-Konvention ( 10 direkte
|
||||||
|
* Adressen, Rest in einem einfach indexierten Ankerblock
|
||||||
|
* im inode) in eine 3-Byte-Form gewandelt
|
||||||
|
*/
|
||||||
|
case IFDIR:
|
||||||
|
case IFREG:
|
||||||
|
for(i=0; i<*aibc; i++) {
|
||||||
|
if(i >= LADDR)
|
||||||
|
break;
|
||||||
|
ip->i_addr[i] = ib[i];
|
||||||
|
}
|
||||||
|
if(*aibc >= LADDR) {
|
||||||
|
ip->i_addr[LADDR] = alloc();
|
||||||
|
for(i=0; i<NINDIR-LADDR; i++) {
|
||||||
|
ib[i] = ib[i+LADDR];
|
||||||
|
ib[i+LADDR] = (daddr_t)0;
|
||||||
|
}
|
||||||
|
wtfs(ip->i_addr[LADDR], (char *)ib);
|
||||||
|
}
|
||||||
|
|
||||||
|
case IFBLK:
|
||||||
|
case IFCHR:
|
||||||
|
ltol3(dp->di_addr, ip->i_addr, NADDR);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
printf("bad mode %o\n", ip->i_mode);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
wtfs(d, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
badblk(bno)
|
||||||
|
daddr_t bno;
|
||||||
|
{
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue