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