# -*- coding: iso-8859-15 -*-
#!/usr/bin/python
"""
Sistema de procedimientos remotos del CdC Funciones comunes.
Funciones de uso comun en el metaservidor y en los distintos servicios.
"""

import os, signal
import time
import sys
import SocketServer
from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler, SimpleXMLRPCDispatcher
import subprocess       #para manejo de subprocesos, Python >02.5
import BaseHTTPServer
#para parsear comandos a la shell
#import shlex
import base64

#para cifrar la clave
import crypt, getpass, pwd
#para gestionar direcciones en formato cidr
import cidr
#Anade al path el direcotorio donde estan las funciones comunes
sys.path.insert(0, '/cac/cdcrpc')
#funciones comunes que se usan en varias partes

CAPTURA = 0


def log(string_log, salida, prioridad, logfile):
    """
    log(stringlog, salida, prioridad, logfile)
    Funcion que imprime por pantalla y escribe en un fichero de log
    los acontecimientos que se den en la ejecucion del script 
    escribe tambiï¿½n en la salida de logs estandar del sistema (unix)
    Parametros:
    string_log-> cadena que se imprimira
    salida-> bandera que hace abandonar el programa ante error critico (TRUE o FALSE)
    prioridad debe ser uno de los siguientes valores (string):
    LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_ERR, LOG_WARNING, LOG_NOTICE, LOG_INFO, LOG_DEBUG
    la facility debe ser uno de los siguientes valores (string):
    LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON, LOG_AUTH, LOG_LPR, LOG_NEWS, LOG_UUCP, LOG_CRON and LOG_LOCAL0 to LOG_LOCAL7.
    """
    #diferenciamos plataforma, si es windows no se usa syslog
    if os.name =='nt':
        file_log=open(logfile,"a")
        file_log.write(string_log)
        file_log.close()
    # imprimimos la cadena en fichero de log
    else:
        #importamos modulo exclusivo unix
        import syslog
        #procesamos prioridad
        if prioridad == 'LOG_EMERG':
            priority = syslog.LOG_EMERG
        if prioridad == 'LOG_ALERT':
            priority = syslog.LOG_ALERT
        if prioridad == 'LOG_CRIT':
            priority = syslog.LOG_CRIT
        if prioridad == 'LOG_ERR':
            priority = syslog.LOG_ERR
        if prioridad == 'LOG_WARNING':
            priority = syslog.LOG_WARNING
        if prioridad == 'LOG_NOTICE':
            priority = syslog.LOG_NOTICE
        if prioridad == 'LOG_INFO':
            priority = syslog.LOG_INFO
        if prioridad == 'LOG_DEBUG':
            priority = syslog.LOG_DEBUG
        
        
        #escribimos en el fichero de logs
        file_log=open(logfile,"a")
        file_log.write(string_log+'\n')
        file_log.close()
        #Escribimos es syslog, tag,0, facility
        syslog.openlog('CdCrpc: '+logfile,0,syslog.LOG_LOCAL3)
        syslog.syslog(priority,string_log)
        syslog.closelog()
    
    
    # salida del script
    if salida == True:
        sys.exit(-1)
# --------------------------------------------------------------------

def ahora():
    """
    ahora() nos de la hora de conexion
    funcion que nos da la hora local, en formato estandar (no español)
    """
    return time.ctime(time.time())



class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
    """
    Sobreescribimos algunos métodos del manejador: __init__ y log_request    
    __init__(self, request, client_address, server, logfile=None, ips=[]) 
    igual al manejador de SocketServer pero añadiendo lofile para la dirección
    del archvio de los y ips para la lista de las ips permitidas como parámetros opciones,
    con valor None por defecto.
    comprobamos si la ip del cliente está en la lista de ips permitidas, si es así instanciamos
    el manejador global, si no es así generamos log de alerta e ignoramos peticion
    
    log_request(self, code = '-', size = '-')
    sobreescribimos el perteneciente a BaseHTTPSeverRequestHandler para
    integrar nuestra función de log, enviar logs a syslog y diferenciar los archivos de logs
    según se trate de un servicio u otro, esto lo logramos con el prámetro logfile
    
    """
    
    def __init__(self, request, client_address, server, logfile=None, ips=[]):
        #copiamos las variables de instancia a locales
        self.logfile = logfile
        self.allowips = ips
       
       #comprobamos si la ip esta autorizada, si ok -> flag = true
        flag = False
        for ip in server.ips:
            if ip == client_address[0]:
                flag = True
        
        if flag:
            #ip autorizada, lanzamos el manejador, el logueara
            BaseHTTPServer.BaseHTTPRequestHandler.__init__(self, request, client_address, server)
        else:
            #la ip no esta autorizada, no permitimos acceso y logamos
            stringlog = 'Intento de acceso no autorizado desde ' + client_address[0] + ' a las  ' + ahora()
            log(stringlog, False, 'LOG_ALERT', server.logfile)

        
    def log_request(self, code='-', size='-'):
        """
        Aqui es donde loguea el manejador
        """
        
        filelog = (self.server.logfile)
        cadena = self.address_string()
        host, port = self.client_address[:2]
        stringlog = 'Peticion desde ' + cadena + '(' + host + ') ' + ' a las ' + ahora()
        log(stringlog, False, 'LOG_INFO', filelog)
       
    

class AsyncXMLRPCServer(SocketServer.ThreadingMixIn,SimpleXMLRPCServer):
    """
    definimos la clase para el servidor xml
    si tenemos problemas con los hilos probar con ForkinMix en lugar del Threading
    abre un nuevo hilo para cada peticion al heredar de la clase indicada
    """
    pass


def inicia(host, Port, cerrojo, codificacion, ExportClass, filelog, allowips):
    """
    inicia(host, Port, cerrojo, codificacion, ExportClass, filelog, allowips)
    funcion a la que llama cada servicio para iniciar su servidor xmlrpc
    recibe como parametros: host (ip o nombre de la interfaz local del sistema)
    Port: puerto en el que escuchará el servicio
    cerrojo: varible candado para evitar condiciones de carrera al iniciar los servicios,
    se libera cuando el servicio se ha iniciado correctamente o ha dado algún error
    codificiacion: codificacion que se usara en la transmision xmlrpc
    ExportClass: clase que se exporta, debe contener los metodos remotos
    filelog: fichero de log que usara el servicio
    allowips: lista de ips permitidas para cierto servicio
    """
    try:
        print "DENTRO DE INICIA"
        #Arrancamos el objeto servidor
        if sys.version_info[1] < 5:
            #para versiones antiguas de python
            server = AsyncXMLRPCServer((host, Port), MySimpleXMLRPCRequestHandler, logRequests=True)
        else:
            server = AsyncXMLRPCServer((host, Port), MySimpleXMLRPCRequestHandler , allow_none=True, logRequests=True, encoding=codificacion)
        #lo primero le pasamos al servidor las ips autorizadas y el fichero de logs
        print "DEBUG NUMERO UNO"
        server.ips = allowips
        server.logfile = filelog
        #registramos la instancia de la clase a exportar
        server.register_instance(ExportClass())
 
        #logamos
        stringlog = 'Servicio iniciado correctamente en el puerto ' + str(Port) + ' a las ' + ahora()
        log(stringlog, False, 'LOG_INFO', filelog )
        print stringlog
       #ya ha terminado de usar variables compartidas, libera cerrojo 
        cerrojo.release()

        #lo ponemos a la escucha
        server.serve_forever()
        #petada()
    except Exception, why:
        cerrojo.release()
        print "Error iniciando un servidor xml"
        log('Error inciando un servidor xml: %s' % why, True, 'LOG_ERR', filelog)
        
        

def leeconf(line, param, variable, lugar):
    """
    leeconf(line, param, variable, lugar)
    funcion que lee el fichero de configuracion en texto plano y nos devuelve el valor
    de la variable buscada en cada momento
    line: se la pasa la linea que se esta procesando
    param: parametro de comienzo de la linea del fichero de configuracion que identifica
    cada parametro distinto
    variable: el valor que tomara el parametro en esa linea en concreto
    lugar: el lugar en el que se buscara el valor del parameto en la linea
    entiende direcciones en formato cidr
    """

    if len(line.split()) >= 3 and line.split()[0] == param:
        try:
            #hack para manejar direcciones ip en formato cidr
            if param == 'ALLOWIP':
                try:
                    #prueba si esta en formato CIDR
                    ip=line.split()[lugar]
                    #si no es cidr saltara al except
                    ip.split('/')[1]
                    variable = cidr.convertcidr(str(ip))
                    #aqui es donde enlazo con cidr.py que me devolvera una lista que almacena en variable
                except:
                    variable.append(line.split()[lugar])            
            else:
                variable.append(line.split()[lugar])
        except:
            variable = line.split()[lugar]
    return variable


def invoca(comando):
    """
    invoca(comando)
    comando: orden del shell unix (no funciona en windows) seguida de sus parametros,
    debe escribirse tal cual la escribiriamos en la consola.
    esta funcion nos devuelve dos listas, una con la salida estandar del comando ejecutado
    y otra con la salida de error, cada uno de los elementos de la lista es una linea
    de su respectiva salida, la funcion que llame a esta debe imprimir cada elemento como
    si fuera una linea para obtener una salida fidedigna
    """
    salida = []
    salidaerr = []
    print comando 
    if sys.version_info[1] < 5:
        try:
            import popen2
            print "Ejecutando comando en versiones antiguas de python"
            stin, stout, sterr = os.popen3(comando)
            #o, inn, e = popen2.popen3(comando)
            log("Comando en versiones antiguas ejecutado correctamente", False, 'LOG_INFO', '/dev/null')
            if stout:
                print "aqui llega"
                #print x[0]
                #stout = o.readlines()
                #print stout
                #le quitamos los fines de linea a la salida, cada linea es un elemento
                #distinto dentro de su lista, el cliente debera formatearlo como
                #considerere
                for line in stout:
                    log('dentro del bucle', False, 'LOG_INFO', '/dev/null')
                    print line
                    line = line.split('\n')[0]
                    print line
                    try:
                        salida.append(line)
                        print "Ha hecho el append"
                    except:
                        log("Error en append", False, 'LOG_ERR', '/dev/null')
            else:
                #si esta vacio ponemos esta marca
                #salida.append('NONE')
                pass
            #idem para la salida de error
            print "Todavia no ha petao"
            if sterr:
                print "dentro del tema del error"
                for line in sterr:
                    #pass
                    print 'error ' + line
                    line = line.split('\n')[0]
                    salidaerr.append(line)
            else:
                salidaerr.append('NONE')
            #hack para que funcione
            #salidaerr.append('NONE')
            print salida
            print salidaerr
        except Exception, why:
            salidaerr = [str(Exception), str(why)]        
            log('Fallo al ejecutar la orden', False, 'LOG_ERR', '/dev/null')
    else:
        try:
            #para manejo de subprocesos, Python >02.5
            #ejecutamos el comando y capturamos las salidas, shlex nos permite que la
            #shell entienda el comando perfectamente
            #resp = subprocess.Popen(shlex.split(comando), stdout=sp.PIPE, stderr=sp.PIPE)
            
	    sp = subprocess
            
            resp = subprocess.Popen(comando, stdout=sp.PIPE, stderr=sp.PIPE, shell=True)

            if resp.stdout:
                #le quitamos los fines de linea a la salida, cada linea es un elemento
                #distinto dentro de su lista, el cliente debera formatearlo como
                #considerere
                for line in resp.stdout:
                    line = line.split('\n')[0]
                    salida.append(line)
            else:
                #si esta vacio ponemos esta marca
                salida.append('NONE')
            #idem para la salida de error
            if resp.stderr:
                for line in resp.stderr:
                    line = line.split('\n')[0]
                    salidaerr.append(line)
            else:
                salidaerr.append('NONE')
        except Exception, why:
            salidaerr = [str(Exception), str(why)]
    print salida
    print "Final del todo"
    #print salidaerr
    return salida, salidaerr

def captura(comando):
    
    global CAPTURA

    salida = []
    salidaerr = []
    
    print comando 

    try:
	#para manejo de subprocesos, Python >02.5
	#ejecutamos el comando y capturamos las salidas, shlex nos permite que la
	#shell entienda el comando perfectamente
	#resp = subprocess.Popen(shlex.split(comando), stdout=sp.PIPE, stderr=sp.PIPE)
	if CAPTURA == 0:
		sp = subprocess
			    
		CAPTURA = subprocess.Popen(comando, stderr=sp.PIPE, shell=True)

		resultado = str('Captura Iniciada')
	else:
		resultado = str('Hay una captura iniciada')
	
	salida.append(resultado)
	
		    
    except Exception, why:
            salidaerr = [str(Exception), str(why)]
    print salida
    print "Final del todo"
    #print salidaerr
    return salida, salidaerr

def captura2():
   
    global CAPTURA
    salida = []
    salidaerr = [] 
    

    try:
	if CAPTURA != 0: # Hay captura iniciada
		comando = 'pidof tcpdump'
		sp = subprocess
           	resp = subprocess.Popen(comando, stdout=sp.PIPE, stderr=sp.PIPE, shell=True)
		# Obtenemos el numero de proceso tcpdump
		if resp.stdout:
                	for line in resp.stdout:
                    		line = line.split('\n')[0]
                    		proceso=int(line)
				comando = 'kill %d' %(proceso)
				salida, salidaerr = invoca(comando)
				CAPTURA = 0
				resultado = str('Captura Finalizada')
            	else:
                	#si esta vacio ponemos esta marca
                	proceso.append('NONE')
			resultado = str('No se ha podido parar la captura')
		if resp.stderr:
                	for line in resp.stderr:
                    		line = line.split('\n')[0]
                    		salidaerr.append(line)
            	else:
                	salidaerr.append('NONE')
	else:
		resultado = str('No hay captura iniciada')

	salida.append(resultado)
	
		    
    except Exception, why:
            salidaerr = [str(Exception), str(why)]
    return salida, salidaerr

def captura3(usuario):
    global CAPTURA
    salida = []
    salidaerr = [] 
    ficheroxml = []
    try:
	if CAPTURA == 0:
		nombre = str(usuario)
		fichero = '/home/labredes/capturas/%s.pcap' %(nombre)
		if os.path.isfile(fichero):
			fich = open(fichero,'r')
			ficheroxml.append(base64.b64encode(fich.read()))
			fich.close()
			os.remove(fichero)
			resultado = str('Captura almacenada en el servidor')
		else:
			resultado = str('No hay captura iniciada')
	else:
		resultado = str('La captura no ha finalizado')
	salida.append(resultado)
    except Exception, why:
            salidaerr = [str(Exception), str(why)]
    
    return salida, salidaerr, ficheroxml


# Para crear fichero usando base64_decode
def crea_fichero(ficheroxml , fichero):
    salida = []
    salidaerr = []
    try:
    	fich=open(fichero,'w')
    	fich.write(base64.b64decode(ficheroxml))
    	fich.close()
	resultado = str('Fichero subido')
    	salida.append(resultado)	
    except Exception, why:
            salidaerr = [str(Exception), str(why)]
    return salida, salidaerr

# Realiza la descarga del archivo mediante tftp
def cliente_tftp(servidor, archivo):
    salida = []
    salidaerr = []
    
    try:
	comando = 'tftp -v ' + str(servidor)		    
	p = subprocess.Popen(comando, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
	comando = 'get ' + str(archivo)
	comando_stdout = p.communicate(input=comando)[0]
	
	if comando_stdout:
            	comando_stdout = comando_stdout.replace('tftp',' ')
		salida.append(comando_stdout)
	else:
             salida.append('NONE')
	
	while(os.path.exists('/%s' %(str(archivo)))==False):
			time.sleep(1)
	comando = 'mv /%s /home/labredes/downloads/tftp/%s' %(str(archivo), str(archivo))
	salida2, salidaerr = invoca(comando)
	while(os.path.exists('/home/labredes/downloads/tftp/%s' %(str(archivo)))==False):
			time.sleep(1)
	if comando_stdout.count("Error code 1"):
		comando = 'rm -r /home/labredes/downloads/tftp/%s' %(str(archivo))
		salida2, salidaerr = invoca(comando)
    except Exception, why:
            salidaerr = [str(Exception), str(why)]
    return salida, salidaerr
	
# Realiza la descarga del archivo mediante wget
def wget(comando, archivo):
    salida = []
    salidaerr = []
    
    try:		    
	p = subprocess.Popen(comando, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
	# La salida del wget es por stderr, pero la guardamos en la salida normal
	if p.stderr:
            for line in p.stderr:
                  line = line.split('\n')[0]
                  salida.append(line)
        else:
             salida.append('NONE')
    except Exception, why:
            salidaerr = [str(Exception), str(why)]
    return salida, salidaerr

#para pasar de iso a utf8!!!!
def utf8(str):
    """
    esta funcion transforma una cadena codificada en iso-8859-1 y la codifica en
    utf8, utilisima para interactuar con aplicaciones que usen distintas
    codificaciones
    """
    str = str.decode('iso-8859-1').encode('utf-8')
    return str#genera contraseña cifrada para unix

#genera contraseña cifrada para unix
import random, string

def getsalt(chars = string.letters + string.digits):
    """
    genera un salt aleatorio de dos caracteres para usar con la interfaz crypt()
    de unix
    """
    # generate a random 2-character 'salt'
    return random.choice(chars) + random.choice(chars)

def mandamail(cuenta, mensaje, asunto):
    """
    manda un correo que permite tildes y simbolos iso-8859-15
    """
    import smtplib
    from email.MIMEText import MIMEText
    from email.Header import Header
        
    print "dentro de mandamail"
    sender = "centrodecalculo@esi.us.es"
    receiver = cuenta
    
    body = unicode(mensaje, 'iso-8859-1')
 
    coding = 'iso-8859-1'
    msg = MIMEText(body.encode(coding), 'plain', coding)
    msg['From']    = sender
    msg['To']      = receiver
    if asunto == 1:
        stringlog = "Asunto con la fecha"
        print stringlog
        msg['Subject'] = Header(u'Aviso expiración cuenta en ESI', coding)  # la 'ñ' no se puede codificar en ASCII    if asunto==2:
    if asunto == 2:
        msg['Subject'] = Header(u'Bienvenido al servicio de correo ESI', coding)  # la 'ñ' no se puede codificar en ASCII    if asunto==2:

    try:
        server = smtplib.SMTP('esi.us.es')
        server.sendmail(sender, receiver, msg.as_string())
        server.quit()
    except Exception,why:
        print str(why)
    

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="es">
	<head>
            <title>e-REdING. Biblioteca de la Escuela Superior de Ingenieros de Sevilla.</title>

                <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name="description" content="Buscador de proyectos ETSI" />
<meta name="author" content="Daniel Callejo"/>
<meta name="author" content="Federico L&oacute;pez"/>
<meta name="author" content="Juli&aacute;n P&eacute;rez"/>
<meta name="author" content="Jos&eacute; Mar&iacute;a Vidal Vidal"/>
<base href="https://biblus.us.es/bibing/proyectos/" /><link rel="shortcut icon" href="./favicon.ico" />
<link rel="stylesheet" href="./publico/css/estructura.css" type="text/css" />
<link rel="stylesheet" href="./publico/css/bootstrap.css" type="text/css" media="screen"/>
<link rel="stylesheet" href="./publico/css/enlaces-capas.css" type="text/css"  />
<link rel="stylesheet" href="./publico/css/pestanas.css" type="text/css"  /> 
<link rel="stylesheet" href="./publico/css/formularios.css" type="text/css" />
<link rel="stylesheet" href="./publico/css/lightbox.css" type="text/css"  />
<link rel="stylesheet" href="./publico/css/autocompleter.css" type="text/css"  />
<link rel="stylesheet" href="./publico/css/resultados.css" type="text/css"  />
<link rel="stylesheet" href="./publico/css/milista.css" type="text/css"  />
<link rel="stylesheet" href="./publico/css/explorador.css" type="text/css"  />
<link rel="stylesheet" href="./publico/css/ultimos.css" type="text/css"  />
<link rel="stylesheet" href="./publico/css/contactar.css" type="text/css"  />
<!-- <link rel="stylesheet" href="./css/print.css" type="text/css" media="print" /> -->
<script src="./publico/javascript/jquery-1.9.1.min.js" type="text/javascript"></script>
<script src="./publico/javascript/bootstrap.js" type="text/javascript"></script>

<script src="./publico/javascript/mootools-1.2.4-core.js" type="text/javascript"></script>
<script src="./publico/javascript/mootools-1-1.2.4.2-more.js" type="text/javascript"></script>
<script src="./publico/javascript/targetbl.js" type="text/javascript"></script>
<script src="./publico/javascript/mensajes.js" type="text/javascript"></script>
<script src="./publico/javascript/form.js" type="text/javascript"></script>
<script src="./publico/javascript/autocompleter/Observer.js" type="text/javascript"></script>
<script src="./publico/javascript/autocompleter/Autocompleter.js" type="text/javascript"></script>
<script src="./publico/javascript/autocompleter/Autocompleter.Request.js" type="text/javascript"></script>
<script src="./publico/javascript/domready.js" type="text/javascript"></script>

<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-2HP38G406P"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'G-2HP38G406P');
</script>



<script type="text/javascript">
function seleccionar_todo(){
   for (i=0;i<document.formulario_marcados.elements.length;i++)
      if(document.formulario_marcados.elements[i].type == "checkbox")
         document.formulario_marcados.elements[i].checked=1
}
function deseleccionar_todo(){
   for (i=0;i<document.formulario_marcados.elements.length;i++)
      if(document.formulario_marcados.elements[i].type == "checkbox")
         document.formulario_marcados.elements[i].checked=0
} 
</script>
	</head>
    <body style="min-width: 960px; background-color: #e2e2e2; height: 100%">	
		<a name="arriba"></a>
<div>
<div id="header">
    <table id="Tabla_01" height="105" border="0" cellpadding="0" cellspacing="0">
    <tr>
        <td>
            <img src="./publico/imagenes/cabecera/banner_new2_01.jpg" width="3" height="105" alt="">
        </td>
        <td>
            <img src="./publico/imagenes/cabecera/banner_new2_02.jpg" width="100" height="105" alt="">
        </td>
        <td width="100%" align="right"  style="min-width: 613px; background-repeat: no-repeat; background-position: top right; font-size: medium; font-weight: bold; color: white;">
            <table width="100%" height="105" border="0">
                <tr>
                    <td style=" vertical-align: top; width: 547px">
                        <!-- <a style="text-decoration: none" href="./"><img src="./publico/imagenes/cabecera/banner_new2_03.jpg"alt=""></a> -->
                        <a style="text-decoration: none" href="https://biblus.us.es/bibing/proyectos/"><img src="./publico/imagenes/cabecera/banner_new2_03.jpg"alt=""></a>
                     </td>
                     <td  background="./publico/imagenes/cabecera/banner_new2_04.jpg" style="background-repeat: no-repeat; background-color: #c6d4e8;"><br><br><br>
                         &nbsp;
                        </td>
                    </tr>
             </table>
        </td>
    </tr>
    <tr style="border-top: 1px solid #ffffff;">
        <td colspan="3" id="menu_sup" style="font-size: small; text-align: right; background-color: #9c1f2f; vertical-align: bottom">
                                     

                                <a href="https://biblus.us.es/bibing/proyectos/" class="enlace " style=" color: #ffffff">Inicio&nbsp;&nbsp;|</a>
                                <a href="https://biblus.us.es/bibing/proyectos/acerca/" style=" color: #ffffff" class="enlace ">&nbsp;&nbsp;Acerca de&nbsp;&nbsp;|</a>
                                
                                <a href="https://biblus.us.es/bibing/proyectos/contactar/" style=" color: #ffffff" class="enlace ">&nbsp;&nbsp;Contactar&nbsp;&nbsp;</a>
                         <!--       <a href="https://biblus.us.es/bibing/proyectos/ayuda/" style=" color: #ffffff" class="enlace  ">&nbsp;&nbsp;Ayuda&nbsp;&nbsp;|</a> -->
                                <!-- <form id="idioma" class=""  method="post" action="">
                                <div class="inline" style="color: white">
                                <input type="submit" class="tipo_letra " style=" color: #ffffff"name="idioma" value="Castellanossss" />&nbsp;&nbsp;
                                </div>	
                                </form> -->

                                </td>

    </tr>
    </table>
</div>
<br><br>
<div class="colmask rightmenu">
<div class="panel panel-default" style="margin:20px">
            <div class="panel-heading"><h4>DESARROLLO DE UN ENTORNO DE PRÃ�CTICAS PARA REDES MULTISERVICIO</h4><h5 style="color:grey"><span class="glyphicon glyphicon-user""></span> : <b>MartÃ­n Redondo, Alberto JesÃºs</b><br><span class="glyphicon glyphicon-book""></span>  :<b> Ingenier&iacute;a TelecomunicaciÃ³n</b></h5></div><div class="panel-body"><div class="contenido_proyecto"><div class="titulo2_explorador">Contenido del proyecto:</div><div class="ruta"><a href="abreproy/12106">Directorio ra&iacute;z</a>&nbsp;&nbsp;>&nbsp;&nbsp;<a href="abreproy/12106/direccion/ARCHIVOS%252F">ARCHIVOS</a>&nbsp;&nbsp;>&nbsp;&nbsp;<a href="abreproy/12106/direccion/ARCHIVOS%252Fservidor_xmlrpc%252F">servidor_xmlrpc</a>&nbsp;&nbsp;>&nbsp;&nbsp;<a href="abreproy/12106/direccion/ARCHIVOS%252Fservidor_xmlrpc%252Fcommonfunc.py%252F">commonfunc.py</a></div><div class="listing"></div></div></div></div>
</div>
</div>

        
	</body>
 
 
<!-- Inicio Google Analytics -->
<!--
	<script type="text/javascript">
		var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
		document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
	</script>
	
	<script type="text/javascript">
		try {
		var pageTracker = _gat._getTracker("UA-7789620-1");
		pageTracker._trackPageview();
	} 
		catch(err) {}
	</script>
-->
<!-- Fin Google Analytics -->

</html>

