<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv=Content-Type content="text/html; charset=utf8">
<title>/usr/web/sources/contrib/sascharetzki/devevilfs.c - Plan 9 from Bell Labs</title>
<!-- THIS FILE IS AUTOMATICALLY GENERATED. -->
<!-- EDIT sources.tr INSTEAD. -->
</meta>
</head>
<body>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: center;">
<span style="font-size: 10pt"><a href="/plan9/">Plan 9 from Bell Labs</a>&rsquo;s /usr/web/sources/contrib/sascharetzki/devevilfs.c</span></p>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<center><font size=-1>
Copyright © 2009 Alcatel-Lucent.<br />
Distributed under the
<a href="/plan9/license.html">Lucent Public License version 1.02</a>.
<br />
<a href="/plan9/download.html">Download the Plan 9 distribution.</a>
</font>
</center>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<table width="100%" cellspacing=0 border=0><tr><td align="center">
<table cellspacing=0 cellpadding=5 bgcolor="#eeeeff"><tr><td align="left">
<pre>
<!-- END HEADER -->
/* 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 &lt; 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 &lt; 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 &lt; 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 &lt; 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") &amp;&amp; (a1 == 0)) {
		error("inicio y final deben ser variables numericas\n");
			return -1;
		};
		if (a1 &gt;= 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-&gt;nombre = malloc(strlen(tokens[1])) ;
	//print(tokens[1]) ;
	strcpy(nuevo-&gt;nombre, tokens[1]) ;
	//print( nuevo-&gt;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 &lt;= ffich; i++) {
	
		print("abriendo %s, %i de %i\n", tokens[i + ifich], i + 1,ffich - ifich + 1);

		nuevo-&gt;nodos[i] = malloc(sizeof(nodo));
		if (i == 0) {
			nuevo-&gt;sig = nuevo-&gt;nodos[0];
			nuevo-&gt;nodos[0]-&gt;sig = nuevo-&gt;nodos[0];
		} else {
			anterior-&gt;sig = nuevo-&gt;nodos[i];
			nuevo-&gt;nodos[i]-&gt;sig = nuevo-&gt;sig;
		};
		nuevo-&gt;nodos[i]-&gt;n = tokens[i + ifich];
		anterior = nuevo-&gt;nodos[i];
		print("fin commit para %s\n", nuevo-&gt;nodos[i]-&gt;n);
		nuevo-&gt;n_nodos = args + 1;
	};
	//calc_size(nuevo); 
	npos = Qfirst + NDisp;
	dispositivos[npos] = nuevo; 
	print(" alta dispositivos ") ;
	alta_disp(tokens[1]); 
	
	if (i + ifich &lt; 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-&gt;aux){
		free(c-&gt;aux);
		c-&gt;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-&gt;qid.type == QTDIR)
		return devdirread(c, a, n, evilfstab, Qfirst+NDisp, devgen);

	switch((int)(c-&gt;qid.path)){
	case Qctl:
		if(kbdgetmap(offset/KBLINELEN, &amp;t, &amp;sc, &amp;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-&gt;qid.type == QTDIR)
		error(Eperm);

	switch((int)(c-&gt;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,
};
<!-- BEGIN TAIL -->
</pre>
</td></tr></table>
</td></tr></table>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: center;">
<span style="font-size: 10pt"></span></p>
<p style="margin-top: 0; margin-bottom: 0.50in"></p>
<p style="margin-top: 0; margin-bottom: 0.33in"></p>
<center><table border="0"><tr>
<td valign="middle"><a href="http://www.alcatel-lucent.com/"><img border="0" src="/plan9/img/logo_ft.gif" alt="Bell Labs" />
</a></td>
<td valign="middle"><a href="http://www.opensource.org"><img border="0" alt="OSI certified" src="/plan9/img/osi-certified-60x50.gif" />
</a></td>
<td><img style="padding-right: 45px;" alt="Powered by Plan 9" src="/plan9/img/power36.gif" />
</td>
</tr></table></center>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<center>
<span style="font-size: 10pt">(<a href="/plan9/">Return to Plan 9 Home Page</a>)</span>
</center>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<center><font size=-1>
<span style="font-size: 10pt"><a href="http://www.lucent.com/copyright.html">Copyright</a></span>
<span style="font-size: 10pt">© 2009 Alcatel-Lucent.</span>
<span style="font-size: 10pt">All Rights Reserved.</span>
<br />
<span style="font-size: 10pt">Comments to</span>
<span style="font-size: 10pt"><a href="mailto:webmaster@plan9.bell-labs.com">webmaster@plan9.bell-labs.com</a>.</span>
</font></center>
</body>
</html>