<?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:[email protected]">[email protected]</a>.</span>
</font></center>
</body>
</html>