Plan 9 from Bell Labs’s /usr/web/sources/contrib/sascharetzki/devevilfs.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


/* Dispositivo para el sistema de ficheros malvado 
*  creado por Eduardo Orive
*  para la asignatura de DSO
*  se declina cualquier responsabilidad
*  --------------------------------
*  Utilizare la letra V porque esta libre y porque
*  es una de las letras de malVado, como el mismo.
*/

#include	"u.h"
#include	"../port/lib.h"
#include	"mem.h"
#include	"dat.h"
#include	"fns.h"
#include	"../port/error.h"

enum{
	Qtop = 0,
	Qdir = 0,
	Qctl = 1,
	Qfirst = 2,	Qdisp=2, 	// a partir de aqui van los Qid de los descriptores
	r0,				// Raid0 (mirroring)
	r1,				// Raid1 (Striping)
	r3,				// Raid5 (interleaving)
	dv,				// disco virtual particionable
	// numero de FSes especiales, yo los llamare principales
	N = 8,
	// numero de posiciones posibles en la matriz de punteros a nodos.
	NNod = 9,
	bloque = 8 * 1024,
	Qdata=1,
};
Dirtab evilfstab[N+2]={
	".",		{Qdir, 0, QTDIR},	0,	0555,
	"evilfs",	{Qctl, 0},		0,	0660,
	// Las posiciones restantes se emplearan para los dispositivos
};
int NDisp=0 ;
static Qid dispid = { Qdisp , 0  } ; 
#define	NKBFILE	sizeof(evilfstab)/sizeof(evilfstab[0])

#define	KBLINELEN	(3*NUMSIZE+1)	/* t code val\n */
typedef struct principal principal;
typedef struct nodo nodo;

struct principal {
	int tipo;
	char *nombre;
	long ini;
	long t;
	int n_nodos;
	nodo *nodos[NNod];		//dedicado a aquellos que no quieren ptr en kernel
	nodo *sig;			// para la rotacion del rd3
};

typedef nodo nodo;
struct nodo {
	char *n;
	Chan *c;
	long t;
	nodo *sig;			// para el interleaving
};
static principal *dispositivos[N] = nil;
int libre(int inicio)
{
	int i;

	for (i = inicio; i < N; i++) {
		if (dispositivos[i] == nil)
			return (i);
	};
	return -1;
};
void  alta_disp(char *nombre) {
	Dirtab nuevo ;
//	char *n;
//	n = malloc (strlen(nombre) ) ;
	Qid 	   qid = {Qfirst+NDisp,0} ;
	strcpy (nuevo.name, nombre);
	nuevo.qid= qid ;
	nuevo.length = 0 ;
	nuevo.perm= 0660; 
	evilfstab[Qfirst+NDisp] = nuevo ; NDisp++ ;
}  
static int config_linea(char *cadena)
{
	int i;
	int tipo;
	int ifich;
	int ffich;
	int npos;
	char *tokens[10] = nil;
	int args=0;
	long a1;
	long a2;
	principal *nuevo;
	nodo *anterior = nil;
	char *nombre;


	print("%s \n", cadena) ;
	args = getfields(cadena, tokens, 8, 1, " ");
	print("se han  recibido %i parametros\n",args);
	if (args < 4) { 
		print("no hay parametros para hacer nada \n");
		return -1;
	}
	if (strcmp(tokens[0], "r0") == 0) {
		tipo = r0;
	} else if (strcmp(tokens[0], "r1") == 0) {
		tipo = r1;
	} else if (strcmp(tokens[0], "r3") == 0) {
		tipo = r3;
	} else if (strcmp(tokens[0], "dv") == 0) {
		tipo = dv;
	} else {
		error ("el tipo de dispostivo no esta reconocido");
		return -1;
	};
	 
/*	for (i = 0; i < 9; i++) {
		if (tokens[i] == nil)
			break;		// ya no quedan tokens
		if (tokens[i][0] == 0)
			continue;		// eran 2 espacios seguidos
		args++;
		//      printf("%s:%i\n",tokens[i],atol(tokens[i])); 
	};*/
//	error(tokens[1]);
	switch (tipo) {
	case dv:
		if (args < 4) {
		error("se requieren 4 parametros para un disco virtual: nombre fichero inicio y fina\n");
			return -1;
		}
		a1 = strtol(tokens[3],nil,0);
		a2 = strtol(tokens[4],nil,0);
		if (!strcmp(tokens[3], "0") && (a1 == 0)) {
		error("inicio y final deben ser variables numericas\n");
			return -1;
		};
		if (a1 >= a2) {
		error	("la posicion de inicio debe ser menor que la de final y ambas deben ser numericas\n");
			return -1;
		};
		ifich = 2;
		ffich = 2;
		break;
	default:
		print("default\n");
		ifich = 2;
		ffich = args - 1;
		print("%i nodos a instanciar.\n", ffich - ifich);

	};
	// esta es la parte donde se acometen los cambios
	// abrimos los ficheros 
	print("aqui va el malloc de principal\n"); 
	nuevo = malloc(sizeof(principal));
	print("aqui va el malloc de nombre\n");
	nuevo->nombre = malloc(strlen(tokens[1])) ;
	//print(tokens[1]) ;
	strcpy(nuevo->nombre, tokens[1]) ;
	//print( nuevo->nombre ) ;
	print("buscamos una posicion libre para el dispositivo\n"); 
	npos = libre(0);
	if (npos == -1) { 
		error("no quedan posiciones libres en el array de dispositivos");
		return -1; }
	print("iniciamos a apertura de  ficheros:");
	print(" %i a %i\n" , ifich, ffich) ;
	for (i = 0; ifich + i <= ffich; i++) {
	
		print("abriendo %s, %i de %i\n", tokens[i + ifich], i + 1,ffich - ifich + 1);

		nuevo->nodos[i] = malloc(sizeof(nodo));
		if (i == 0) {
			nuevo->sig = nuevo->nodos[0];
			nuevo->nodos[0]->sig = nuevo->nodos[0];
		} else {
			anterior->sig = nuevo->nodos[i];
			nuevo->nodos[i]->sig = nuevo->sig;
		};
		nuevo->nodos[i]->n = tokens[i + ifich];
		anterior = nuevo->nodos[i];
		print("fin commit para %s\n", nuevo->nodos[i]->n);
		nuevo->n_nodos = args + 1;
	};
	//calc_size(nuevo); 
	npos = Qfirst + NDisp;
	dispositivos[npos] = nuevo; 
	print(" alta dispositivos ") ;
	alta_disp(tokens[1]); 
	
	if (i + ifich < ffich) {
	//	printf("instanciacion  abortada\n");
		// tocaria deshacer pero no es prioritario 
		return -1;
	} else print("fin commit para el dispositivo: %s\n", tokens[1]);
	return 0;
};

static int evilconfig(char *cadena, long n)
{
	char *cadenas[2]=nil;
	char *sig_cadena=nil;
	long i = n ;
	while (sig_cadena != cadena) {
		getfields(cadena, cadenas, 2, 1, "\n");
		cadena = cadenas[0];
		sig_cadena = cadenas[1];
		if (cadena == nil) {
			break		;				};
		print("recibido; %s\n", cadena);
	//	i -= strlen(cadena) ;
		print("siguientes: %s %p\n",sig_cadena, sig_cadena);
		print("punteros: %p %p \n",cadenas[0], cadenas[1]);
		if (config_linea(cadena) == -1) {
			error("error creando el dispositivo");break;};
		if (strlen(sig_cadena) == 0 )
			break;
		cadena = sig_cadena;
	};
	return 0;
};
static Chan *
evilfsattach(char *spec)
{
//	alta_disp("uno") ; alta_disp("dos");
	return devattach(L'V', spec);
}

static Walkqid*
evilfswalk(Chan *c, Chan *nc, char **name, int nname)
{	
	return devwalk(c, nc, name, nname, evilfstab, Qfirst+NDisp, devgen); 
}

static int
evilfsstat(Chan *c, uchar *dp, int n)
{
	return devstat(c, dp, n, evilfstab, Qfirst+NDisp, devgen);
}

static Chan*
evilfsopen(Chan *c, int omode)
{
	if(!iseve())
		error(Eperm);
	return devopen(c, omode, evilfstab, Qfirst+NDisp, devgen);
}

static void
evilfsclose(Chan *c)
{
	if(c->aux){
		free(c->aux);
		c->aux = nil;
	}
}

static long
evilfsread(Chan *c, void *a, long n, vlong offset)
{
	char *bp;
	char tmp[KBLINELEN+1];
	int t, sc;
	Rune r;

	if(c->qid.type == QTDIR)
		return devdirread(c, a, n, evilfstab, Qfirst+NDisp, devgen);

	switch((int)(c->qid.path)){
	case Qctl:
		if(kbdgetmap(offset/KBLINELEN, &t, &sc, &r)) {
			bp = tmp;
			bp += readnum(0, bp, NUMSIZE, t, NUMSIZE);
			bp += readnum(0, bp, NUMSIZE, sc, NUMSIZE);
			bp += readnum(0, bp, NUMSIZE, r, NUMSIZE);
			*bp++ = '\n';
			*bp = 0;
			n = readstr(offset%KBLINELEN, a, n, tmp);
		} else
			n = 0;
		break;
	default:
		n=0;
		break;
	}
	return n;
}

static long
evilfswrite(Chan *c, void *a, long n, vlong)
{
	char line[100], *lp, *b;
	int key, m, l;
	Rune r;

	if(c->qid.type == QTDIR)
		error(Eperm);

	switch((int)(c->qid.path)){
	case Qctl:
		evilconfig(a,n);
	}
	return n;
}

Dev evilfsdevtab = {
	L'V',
	"evilfs",

	devreset,
	devinit,
	devshutdown,
	evilfsattach,
	evilfswalk,
	evilfsstat,
	evilfsopen,
	devcreate,
	evilfsclose,
	evilfsread,
	devbread,
	evilfswrite,
	devbwrite,
	devremove,
	devwstat,
};

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to [email protected].