From 47af93dcbcafcadd89c81f4cba925417d29b9910 Mon Sep 17 00:00:00 2001 From: Oliver Lehmann Date: Fri, 3 Feb 1989 07:49:07 +0000 Subject: [PATCH] add first WEGA commands --- WEGA/src/cmd/standalone/sa.cat.c | 46 ++ WEGA/src/cmd/standalone/sa.install.c | 971 +++++++++++++++++++++++++++ WEGA/src/cmd/standalone/sa.mkfs.c | 747 +++++++++++++++++++++ 3 files changed, 1764 insertions(+) create mode 100644 WEGA/src/cmd/standalone/sa.cat.c create mode 100644 WEGA/src/cmd/standalone/sa.install.c create mode 100644 WEGA/src/cmd/standalone/sa.mkfs.c diff --git a/WEGA/src/cmd/standalone/sa.cat.c b/WEGA/src/cmd/standalone/sa.cat.c new file mode 100644 index 0000000..4bca53c --- /dev/null +++ b/WEGA/src/cmd/standalone/sa.cat.c @@ -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); +} diff --git a/WEGA/src/cmd/standalone/sa.install.c b/WEGA/src/cmd/standalone/sa.install.c new file mode 100644 index 0000000..beba696 --- /dev/null +++ b/WEGA/src/cmd/standalone/sa.install.c @@ -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>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 '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>3) + for (j=0; j +#include +#endif +#include +#include +#include +#include +#include +#include + +/*------------------------------------------------------- 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'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 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) { + fbuf.df_nfree = filsys.s_nfree; + for(i=0; id_ino = inum; + for(i=0; id_name[i] = 0; + for(i=0; id_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= 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 0; d -= f_n) + for(i=0; i= 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; ii_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); +}