Instalacion de Apache Tomcat 7 en Windows

Mini tutorial (con imágenes) sobre la instalación de Apache tomcat 7 en Windows. Dado que he decido volver a retomar la programación en Java quiero dejar constancia con estas breves notas sobre la instalación de Apache Tomcat. Sobre la terminología y conceptos no daré muchos detalles específicos sino solo a grandes rasgos, daré por hecho que si tu también quieres instalarlo es porque ya tienes nociones de programación en Java o al menos sabes algo sobre el tema.

Como dijo Jack El Destripador, vayamos por partes…

¿Que es Apache Tomcat?

Es un Software de código abierto para la implementación (vaya, programación) de Servlets y tecnologías JavaServer Pages (JSP) los cuales derivan de Java. En sí Apache Tomcat actúa como un contenedor web para ejecutar Servlets/JSP.

Descargar el instalador de Tomcat

Para descargar tomcat hay que visitar la dirección http://tomcat.apache.org/ y en el panel derecho (sección Download) elegir una versión de Apache Tomcat:

A la fecha de hoy la versión más reciente de Tomcat es la version 7.0.37, pero ¿Cual versión que debes bajarte? Si observas esa misma pregunta está en la página de tomcat (en esta página) en la sección de descargas. Como ellos mismos explican, la versión depende de la especificación de Servlets y JSP’s que vayas a usar a la hora de estar programando.

En mi caso como voy a usar Tomcat para pruebas y además quiero aprender lo más reciente sobre servlets y jsp entonces me bajare la versión más reciente de Apache Tomcat, es decir, la versión que mencione anteriormente, da click en la versión elegida y podrás ver una pantalla similar a la siguiente:

Aquí debes el servidor espejo y el formato en el que deseas descargar el instalador de Apache Tomcat (formato zip, tar, instalador .exe, etc). En mi caso me bajare la versión: 32-bit/64-bit Windows Service Installer. Esta versión es una versión para windows el cual permite instalar Tomcat con un asistente de instalación, además, permite ejecutar apache de forma automática al encender la pc con un servicio de Windows.

De preferencia descárgalo en el escritorio para fácil ubicación y borrado (después de instalarlo):

Ahora que ya lo tienes en el escritorio hay que darle doble click para ejecutarlo e iniciar el asistente de instalación:

Instalacion de Apache Tomcat

Ahora procederemos a instalar Apache Tomcat. Al dar doble click sobre el icono del escritorio, se abre el asistente de instalación.

Paso 1: Bienvenida

En este paso se te da la bienvenida al asistente y se te indica que cierres todos los programas aplicativos antes de iniciar dicha instalación:

En realidad eso de cerrar las aplicaciones no es tan necesario (aplicaba para versiones anteriores de Windows) pues hoy en día yo desde que tenía windows Xp he instalado muchos programas en Windows que también indican que cierres y se instalan y funcionan sin problemas. Pero por si las dudas si gustas tú puedes cerrarlas. Da click en el botón Next (siguiente) para pasar al siguiente paso de instalación.

Paso 2: Aceptar el acuerdo de licencia

Esta pantalla del asistente te muestra el acuerdo de licencia, léelo; en resumen te indica los términos y condiciones a los que te sometes si usas el programa. Apache Tomcat es un Software libre de código abierto que se distribuye bajo la licencia de Apache. Así que no creo que tengas mucho de qué preocuparte al usar este Software. No digo que no lo hagas, si es tu deseo, hazlo:

Si estas de acuerdo, da click en el botón I Agree (Si Acepto) para aceptar el acuerdo de licencia y pasar al siguiente paso.

Paso 3: Elegir los componentes a instalar

Este paso te permite indicar los componentes de Apache Tomcat que deseas instalar, algunos son opcionales, te recomiendo que dejes los que están marcados por defecto pues creo que si tienen utilidad, por ejemplo la opción ‘Start Menu Items’ te crea unos accesos directos en el Menú inicio para que desde ahí puedes abrir Tomcat en caso de que no los programes con ejecución automática (cada vez que se enciende la computadora).

La opción Documentation. Te copia la documentación de Tomcat en la carpeta de instalación (mas adelante indicaremos donde se instalara). Por cierto, la documentación te recomiendo que la instales y que la leas pues es muuy buena. Muchas veces instalamos un programa y nos ponemos a buscar tutoriales y videos, etc. acerca del uso del programa sin revisar la documentación de los creadores del programa (la oficial), no hay nada mejor que la doc. oficial de un programa para aprender a usarlo. Así que deja de buscar por otros lados tutoriales, manuales y primero que nada revisa esta documentación que aunque esta en inglés es muy útil.
La opción Manager: Instala una aplicacion Web para administrar Tomcat.
La opción Examples: Instala ejemplos de Servlets y JSPs.

Selecciona los componentes que desees y da click al botón Next para ir al siguiente paso del asistente.

Paso 4: Nombre del servicio y login del administrador


En este paso puedes configurar varias cosas, te recomiendo dejarlas como están, te explico algunas opciones:
Windows Service Name. El instalador automáticamente te crea un servicio para que al encender la PC te arranque Apache tomcat. Esta opción te permite especificar el nombre de dicho servicio de Windows. En la imagen se observa que a este servicio le asigne el nombre contenedor_tomcat7. Más adelante explicare como configurar este servicio para que no arranque Tomcat de forma automática.

En la sección Tomcat Administrator Login (optional):
User name: Aquí puedes especificar el nombre de usuario del administrador de tomcat y en la caja de texto password especificas la contraseña de dicho usuario.
Roles: Te permite especificar el rol del usuario, te recomiendo dejar el que esta por defecto (manager-gui) ya que ese te permite accesar a la aplicación web para administrar Tomcat. Da click en el boton Next para avanzar al siguiente paso.

Paso 5: Eleccion del Java Runtime Environment (JRE)


Como decía al inicio, Tomcat te permite la ejecución de tecnologías Servlets y JSPs, por lo tanto necesita de una Máquina Virtual de Java (JVM), en este paso debes elegir la ruta de instalación de una JVM. El instalador de Apache Tomcat por defecto ya trae un JRE que usa para ejecutar el servicio de Windows, pero el también usa el registro de Windows para determinar la ruta base de Java o JRE que pudiéramos tener preinstalados.

A menos que sepas donde esta una versión mas reciente, te recomiendo que dejes la ruta tal y como esta des click en el botón Next para ir al siguiente paso.

Paso 6: Ruta de instalacion de Apache Tomcat


En este paso debemos elegir una carpeta donde se instalara Apache Tomcat. Cabe mencionar que constantemente en tutoriales, manuales, libros, etc. encuentres muchas referencias la palabra $CATALINA_HOME. Ésta representa la carpeta de instalación de tomcat, independientemente si es Linux o Windows.

A menos que tengas poco espacio en disco o quieras instalarlo en otro lugar especifico, te recomiendo que dejes la ruta predeterminada y des click al botón install para iniciar la copia de los archivos del instalador al disco duro.

Copia de los archivos de Apache Tomcat

Despues de dar click al boton install veras una pantalla similar a la siguiente; en la cual se observa el progreso de la copia de archivos, creacion del servicio, etc.

Una vez que el instalador ha terminado de copiar los archivos te muestra la siguiente pantalla en la cual se te indica que ha sido completado el asistente de instalación de Apache Tomcat:

Además, te da la opción de arrancar Apache Tomcat (inicia el servicio de windows) y/o leer el archivo léame que contiene información sobre la versión instalada. Si eliges iniciar Tomcat te mostrara una barra de progreso

y si no hay ningún problema mostrara un nuevo icono en la bandeja del sistema de Windows (en mi caso Windows 7):

Desde este icono podrás configurar el inicio del servicio de Windows (Opción Configure…, ficha General, Opción Statup type).

Una vez que ya tenemos instalado e iniciado el servicio, podemos abrir el navegador y escribir la dirección http://localhost:8080/ para verificar la instalación:

Si al hacerlo, te muestra la pantalla anterior; la instalación fue exitosa y ya puedes empezar a escribir tus WebApps (Aplicaciones web), sino, que es muy poco probable vuelve realizar los pasos o déjame un comentario con una descripción del problema y en cuanto vea tu mensaje y tenga tiempo te contesto.

Desinstalacion de Apache Tomcat (Windows)

Si por alguna razon extraña ya no deseas tener instalado Apache Tomcat en tu computadora, para desinstalarlo;

  • En el Panel de control->Programas y características buscas Apache Tomcat y los desinstalas.
  • Asegúrate de que no tengas iniciado el servicio de Apache Tomcat (con el boton de la bandeja del sistema) y borra la carpeta de instalación de Tomcat (paso 6).
  • Listo, quedo desinstalado.

Despedida

Eso es todo sobre la instalación de Apache Tomcat, mas adelante explicare como crear tu primera aplicación web y ejecutarla en Apache Tomcat. Espero que te haya gustado y sobre todo que te sirva. Te invito a que me dejes un comentario si te gusto el tutorial.

Hasta pronto, saludos

Programa CGI en C que accesa una BD usando la libreria LPQ de Postgres

Ahora quiero mostrar como se usa la libreria LPQ para acceder a una base de datos de postgress. Yo le llamo la libreria LPQ a la libreria que nos permite establecer una conexion a una BD de Postgres desde un programa escrito en lenguaje C/C++.

los datos de conexion y la tabla a usar en el ejemplo son:
usuario: postgres
password: 12345
base de datos: prueba
tabla: alumnos

En la siguiente imagen se muestran los campos de la tabla alumnos:

El ejemplo que quiero mostrar esta compuesto de los archivos index.html, formularioAltas.html, formularioBajas.html, altaAlumnos.cgi, bajaAlumnos.cgi, mostrarAlumnos.cgi y a continuacion se muestra en la siguiente imagen como se relacionan entre si:

A continuacion se va a mostrar su codigo, se da una breve descripcion y se muestra una imagen de cada uno:

index.html
Este archivo es el principal y es una pagina web que esta localizada en la carpeta /usr/local/servidor_web/htdocs/lpq/index.html y se encarga de mostrar un menu con tres botones, uno para dar de alta un nuevo Alumno, el segundo para dar de baja un alumno y el tercero para consultar y mostrar el contenido de la tabla alumnos. Para no dar tantos detalles mejor muestro el codigo fuente de este archivo:

<!--		Instituto Tecnologico de Zacatepec
    Descripcion:   Indice de opciones del ejemplo que usa la libreria LPQ
    Author:     Gonzalo Silverio  gonzasilve@gmail.com
    Archivo:    index.html
-->
<HTML>
<HEAD>
   <TITLE> Ejemplo que usa la libreria LPQ </TITLE>
</HEAD>
<BODY bgcolor="#C9FF5C">
	<br>
    <h2 align="center">USO DE LA LIBRERIA LPQ DE POSTGRES</h2> <br>
    <TABLE width="80%" border="0" cellpadding="0" cellspacing="0" align="center">
    <TR>
        <TD align="center"><input type="button" name="alta" value="Dar de alta" onclick="location='formularioAltas.html'" > </TD>
        <TD align="center"><input type="button" name="baja" value="Baja de un alumno" onclick="location='http://localhost/lpq/formularioBajas.html'" ></TD>
        <TD align="center"><input type="button" name="ver" value="Ver tabla" onclick="location='http://localhost/cgi-bin/lpq/mostrarAlumnos.cgi'" ></TD>
    </TR>
    </TABLE>
</BODY>
</HTML>

Aca una imagen que muestra esta pagina en el navegador :

formularioAltas.html
Si el usuario elije el boton Dar de alta en la pagina principal, entonces se abrira este archivo que es una pagina web con un formulario. Esta pagina tiene como objetivo que el usuario rellene el formulario con datos de un nuevo alumno y mande estos datos a un programa CGI (altaAlumnos.cgi) al dar click en el boton Dar de alta!. Este archivo esta almacenado en /usr/local/servidor_web/htdocs/lpq. Bueno el contenido de este archivo es el siguiente:

<!--
		Instituto Tecnologico de Zacatepec
    Descripcion:
    Esta pagina web contiene un Formulario que se usara para enviar datos a un programa CGI
	 el cual los guardara en una tabla llamada alumnos de Postgres.
    Author:     Gonzalo Silverio   gonzasilve@gmail.com
    Archivo:    formularioAltas.html
-->
<html>
<head>
<title>Alta de un alumno</title>
</head>
<body bgcolor="#C9FF5C">
    <form name="form_altas" action="http://localhost/cgi-bin/lpq/altaAlumnos.cgi" method="GET">
        <table width="90%" border="1" align="center" bgcolor="#FFFFFF" >
            <tr>
                <td>
                    <table border="0" cellspacing="0" align="center" width="100%">
                <tr>
                    <td colspan="2" bgcolor="#6D6DFF"><h3 align="center">
                            <font color="white"><br><img src="logo_web.gif" alt="gonzasilve">
                                Alta de un nuevo alumno
                            </font></h3>
                    </td>
                </tr>
                <tr>
                    <td bgcolor="#ff9019"><b>N.C:</b> </td><td><input type="text" name="nc" size="20" maxlength="10"> </td>
                </tr>
                <tr>
                    <td bgcolor="#ff9019"><b>Nombre:</b> </td><td><input type="text" name="nombre" size="40" maxlength="255"> </td>
                </tr>
                <tr>
                    <td bgcolor="#ff9019"><b>Apellidos:</b> </td><td><input type="text" name="apellidos" size="40" maxlength="255"> </td>
                </tr>
                <tr>
                    <td bgcolor="#ff9019"><b>Direccion:</b> </td><td><textarea COLS="50" rows="3"  name="direccion" ></textarea></td>
                </tr>
                <tr>
                    <td bgcolor="#ff9019">
                        <b>Estatura:</b> </td><td><input type="text" name="estatura" size="10" maxlength="10">
                        <font color="#a4a2a1">mts.</font>
                    </td>
                </tr>
                <tr>
                    <td bgcolor="#ff9019">
                        <b>Peso:</b> </td><td><input type="text" name="peso" size="10" maxlength="10">
                        <font color="#a4a2a1">kgs.</font>
                    </td>
                </tr>
                <tr>
                    <td bgcolor="#ff9019"><b>Fecha de ingreso:</b> </td><td>Dia
                        <select name="dia" size="1">
                            <option value="1">1</option>
                            <option value="2">2</option>
                            <option value="3">3</option>
                            <option value="4">4</option>
                            <option value="5">5</option>
                            <option value="6">6</option>
                            <option value="7">7</option>
                            <option value="8">8</option>
                            <option value="9">9</option>
                            <option value="10">10</option>
                            <option value="11">11</option>
                            <option value="12">12</option>
                            <option value="13">13</option>
                            <option value="14">14</option>
                            <option value="15">15</option>
                            <option value="16">16</option>
                            <option value="17">17</option>
                            <option value="18">18</option>
                            <option value="19">19</option>
                            <option value="20">20</option>
                            <option value="21">21</option>
                            <option value="22">22</option>
                            <option value="23">23</option>
                            <option value="24">24</option>
                            <option value="25">25</option>
                            <option value="26">26</option>
                            <option value="27">27</option>
                            <option value="28">28</option>
                            <option value="29">29</option>
                            <option value="30">30</option>
                            <option value="31">31</option>
                        </select>
                        <b>Mes</b>
                        <select name="mes" size="1">
                            <option value="01">Enero</option>
                            <option value="02">Febrero</option>
                            <option value="03">Marzo</option>
                            <option value="04">Abril</option>
                            <option value="05">Mayo</option>
                            <option value="06">Junio</option>
                            <option value="07">Julio</option>
                            <option value="08">Agosto</option>
                            <option value="09">Septiembre</option>
                            <option value="10">Octubre</option>
                            <option value="11">Noviembre</option>
                            <option value="12">Diciembre</option>
                        </select>
                        <b>a&ntilde;o</b>
                        <input type="text" size="4" maxlength="4" name="anio" value="">
                    </td>
                </tr>
                <tr>
                    <td bgcolor="#ff9019"><b>Carrera:</b></td>
                    <td>
                        <select name="carrera" size="4">
                            <option value="ingSistemas">Ingenieria en Sistemas computacionales</option>
                            <option value="ingBioquimica">Ingenieria en Bioquimica</option>
                            <option value="ingCivil">Ingenieria Civil</option>
                            <option value="ingElectro">Ingenieria Electromecanica</option>
                            <option value="ingIndustrial">Ingenieria Industrial</option>
                            <option value="ingQuimica">Ingenieria en Quimica</option>
                            <option value="ingGestionEmp">Ingenieria en Gestion Empresarial</option>
                            <option value="maesQuimica">Maestr&iacute;a en Ciencias en Ingenier&iacute;a Qu&iacute;mica</option>
                            <option value="docPolimeroa">Doctorado en Ciencias en Polimeros</option>
                        </select>
                    </td>
                </tr>
                <tr>
                    <td bgcolor="#ff9019"><b>Sexo:</b> </td><td>
                        <input type="radio" name="sexo" value="hombre">Masculino &nbsp;&nbsp;
                        <input type="radio" name="sexo" value="mujer">Femenino<br><br>
                    </td>
                </tr>
            </table>
            </td>
        </tr>
      </table>
      <br>
      <table border="0" width="80%" align="center">
            <tr>
                <td align="center">
                    <input type="submit" name="guardar" value="Dar de alta!">&nbsp;&nbsp;&nbsp;
                </td>
                <td align="center">
                    <input type="reset" name="limpiar" value="Limpiar">&nbsp;&nbsp;&nbsp;
                </td>
                <td align="center">
                    <input type="Button" name="cancelar" value="Cancelar alta" onClick="location='http://localhost/lpq/index.html'">
                </td>
            </tr>
       </table>
    </form>
</body>
</html>

Y aca se muestra una imagen con esta pagina en el navegador:

altaAlumnos.cgi
Este archivo es el que recibe los datos del formulario formularioAltas.html y a continuacion establece una conexion a la BD y ejecuta una operacion INSERT sobre la tabla alumnos. Este archivo esta almacenado en /usr/local/servidor_web/cgi-bin/lpq. A continuacion se muestra el codigo fuente en C de este programa CGI:


/*
		Instituto Tecnologico de Zacatepec
  Descripcion:	Programa que hacer un INSERT para dar de Alta a un nuevo 
					alumno en una tabla de alumnos de postgres
  Author:	Gonzalo Silverio  gonzasilve@gmail.com
  Archivo:	altasAlumnos.c
  Compilar con: 
		cc -c -I/usr/local/pgsql/include altaAlumnos.c
  Enlazar CGI con libreria LPQ con:
  		cc -o altaAlumnos.cgi altaAlumnos.o -L/usr/local/pgsql/lib -lpq
*/

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include "libpq-fe.h"

// Maximo 100 registros de alumnos
#define MAX 100

// Estrutura de datos que guarda los nombres de las variables CGI y sus valores de los formularios
struct 
{
  char nombre[128];
  char valor[128];
} elementos[MAX];

/* Estructura para guardar los datos del alumno */
struct datos
{
  char nc[128];
  char nombre[128];
  char apellidos[128];
  char direccion[128];
  double estatura;
  double peso;
  char fecha_ingreso[128];
  char carrera[128];
  char sexo[128];
} lista_alumnos;


void  guardar(void);

/* declaraciones de las funciones que se van a utilizar en el programa */
void splitword(char *out, char *in, char stop);
char x2c(char *x);
void unescape_url(char *url);
static void salir_bien(PGconn *conn);

/* Almacenamiento temporal de la variable de ambiente */
char *cp;
char *empty = "<vacio>";


	char *qs;	/* qs servira para guardar la cadena de consulta */

	int i,j;
	const char *conninfo;
	PGconn	   *conn;
	PGresult   *res;
	char cadSQL[8000];
	
/* Macro para desplegar las variables de ambiente */
#define safenv(a) ( (cp = getenv(a)) ? cp : empty)

int main(int argc, char **argv)
{
	/* Enviar primero el encabezado MIME */
	printf("Content-type: text/html\n\n");
	
	/* Iniciar una conexion a Postgres con los datos especificados */
	conn = PQsetdbLogin("localhost", NULL, NULL,NULL, "prueba","postgres", "12345");

	/* Comprobar si la conexion fue creada correctamente */
	if (PQstatus(conn) != CONNECTION_OK)
	{
		fprintf(stderr, "La conexion a la BD ha fallado: %s",	PQerrorMessage(conn) );
		salir_bien(conn);
	}

	/* Asignar la cadena de consulta a qs, abortar si esta vacia */
	if((qs = getenv("QUERY_STRING")) == NULL )
	{
		printf("No hay cadena de consulta a decodificar!<br> ");
		exit(1);
	}

	/* Dividir cada uno de los parametros de la cadena de consulta */
	for(i=0; qs[0] != '\0'; i++)
	{
	 /* Primero dividir por '&' cada parametro */
	 splitword(elementos[i].valor,qs,'&');
	 /* Convertir la cadena para caracteres exadecimales y signos mas */
	 unescape_url(elementos[i].valor);
	 /* separar ahora name y value */
	 splitword(elementos[i].nombre,elementos[i].valor,'=');    
	 
	}

	//Titulo de la pagina web
	printf("<HTML><HEAD><TITLE>Alta de un nuevo alumno</TITLE></HEAD>\n");
	//Cuerpo de la pagina web
	printf("<BODY bgcolor='#C9FF5C'>");

	printf("<br>Guardando... ");
  	guardar();		//Realizar el insert

	printf("<font color=\"blue\">Los siguientes datos fueron guardados (excepto el boton):</font><br>");
	for(i=0; elementos[i].nombre[0]; i++)
	 printf("<b>%s</b>=%s<br>",elementos[i].nombre,elementos[i].valor);
  	
	PQclear(res);
	
	//Cerrar la conexion a la BD y limpiar
	PQfinish(conn);
	
	printf("<br><form name=\"volver_indice\" action=\"http://localhost/lpq/index.html\" method=\"POST\">");
	printf("<input type=\"submit\" name=\"volver\" value=\"Volver al menu principal\">");
	printf("</form>");
	printf("</BODY>");

	return 0;
}

/* funcion del Libro */
void splitword(char *out, char *in, char stop)
{
  int i,j;

  for(i=0; in[i] && ( in[i] != stop ); i++)  
    out[i] = in[i];
  
  out[i] = '\0'; 	/* Terminar */
  if( in[i] )
    i++;

  for( j=0; in[j]; )
    in[j++] = in[i++];
}

/* funcion del Libro */
char x2c(char *x)
{
  register char c;
  /* NOTA: (x & oxdf) cambia a mayusculas a x */
  c = ( x[0] >= 'A' ? ( (x[0] & 0xdf) - 'A') +10 : ( x[0] -'0' ));
  c *= 16;
  c += (x[1] >= 'A' ? ( (x[1] & 0xdf) - 'A') +10 : ( x[1] -'0' ));
  return(c);
}

/* funcion del Libro */
void unescape_url(char *url)
{
  register int i,j;

  for(i=0, j=0; url[j]; ++i,++j)
  {
    if( (url[i] = url[j]) =='%' )
    {
      url[i] = x2c(&url[j+1]);
      j += 2;      
    }
    else if(url[i] == '+')
	  url[i] = ' ';
  }
  
  url[i] = '\0';	/* Terminar en la nueva longitud */
}

/*
	Guardar la lista de contactos que esta en la estructura de arrays en un archivo de disco.
*/
void guardar(void)
{
	/* Salvar los datos del StringQuery en la Estructura de datos */
	strcat(lista_alumnos.nc,elementos[0].valor);
	strcat(lista_alumnos.nombre, elementos[1].valor);
  	strcat(lista_alumnos.apellidos, elementos[2].valor);
  	strcat(lista_alumnos.direccion, elementos[3].valor);
  	
	lista_alumnos.estatura = atof(elementos[4].valor); 
	lista_alumnos.peso = atof(elementos[5].valor);
  	
  	strcat(lista_alumnos.fecha_ingreso, elementos[6].valor);
  	strcat(lista_alumnos.fecha_ingreso, "-");  
  	strcat(lista_alumnos.fecha_ingreso, elementos[7].valor); 
  	strcat(lista_alumnos.fecha_ingreso, "-");
  	strcat(lista_alumnos.fecha_ingreso, elementos[8].valor); 
  	
  	strcat(lista_alumnos.carrera, elementos[9].valor);
  	strcat(lista_alumnos.sexo, elementos[10].valor);
	
	/* Unir en una sola cadena los datos a insertar (formar la operacion insert de SQL) */
	strcat(cadSQL, "INSERT INTO alumnos VALUES(");
	strcat(cadSQL, "\'");	strcat(cadSQL, lista_alumnos.nc);					strcat(cadSQL, "\',");
	strcat(cadSQL, "\'");	strcat(cadSQL, lista_alumnos.nombre);				strcat(cadSQL, "\',");
	strcat(cadSQL, "\'");	strcat(cadSQL, lista_alumnos.apellidos);			strcat(cadSQL, "\',");
	strcat(cadSQL, "\'");	strcat(cadSQL, lista_alumnos.direccion);			strcat(cadSQL, "\',");
	strcat(cadSQL, elementos[4].valor);			strcat(cadSQL, ",");
	strcat(cadSQL, elementos[5].valor);			strcat(cadSQL, ",");	
	strcat(cadSQL, "\'");	strcat(cadSQL, lista_alumnos.fecha_ingreso);		strcat(cadSQL, "\',");
	strcat(cadSQL, "\'");	strcat(cadSQL, lista_alumnos.carrera);				strcat(cadSQL, "\',");
	strcat(cadSQL, "\'");	strcat(cadSQL, lista_alumnos.sexo);					strcat(cadSQL, "\'");
	strcat(cadSQL, ")");

	/*Ejecutar la operacion SQL en el servidor */
	res = PQexec(conn, cadSQL);
	
	/* Si la operacion salio bien, mostrar un MSG, sino tbn (jejeje) */
	if ( PQresultStatus(res) == PGRES_COMMAND_OK )
	{
	printf(" ok");
		printf("<br>Estado de comando INSERT: %s<br><br>", PQresStatus(PQresultStatus(res)));
	}
	else
	{
		printf("Estado de la operacion SQL (insert): %s<br>", PQresStatus(PQresultStatus(res)));
	}
}

static void salir_bien(PGconn *conn)
{
	PQfinish(conn);
	exit(1);
}

Y aca se muestra una imagen con la pagina que muestra este programa en el navegador, despues de haber realizado la operacion INSERT en la tabla:


Como es de suponerse el usuario debe dar click en el boton para volver a la pagina principal.

formularioBajas.html
Por otra parte si en el menu de la pagina principal (index.html) el usuario da click en el boton Dar de baja entonces se abrira la pagina web de este achivo. Esta pagina tiene como objetivo capturar el Numero de control (n.c.) de un alumno al cual se desea dar de baja. Al dar click en el boton Dar de baja se enviara este numero de control a un programa CGI llamado bajaAlumnos.cgi que sera el que borrara al alumno con ese n.c. Este archivo esta almacenado en /usr/local/servidor_web/htdocs/lpq. Bueno a continuacion muestro el contenido de este este archivo:

<!--		Instituto Tecnologico de Zacatepec
    Descripcion:
    Formulario de datos que se usara para leer el NC del alumno que se dara de baja	 y enviarlo a un programa CGI
    Author:     Gonzalo Silverio  gonzasilve@gmail.com
    Archivo:    formularioBajas.html
-->
<html>
<head>
<title>Baja de un alumno</title>
</head>
<body bgcolor="#C9FF5C">
    <br>
    <form name="form_bajas" action="http://localhost/cgi-bin/lpq/bajaAlumnos.cgi" method="GET">
        <br>
        <table width="90%" border="1" align="center" bgcolor="#FFFFFF" >
            <tr>
                <td>
                    <table border="0" cellspacing="0" align="center" width="100%">
                        <tr>
                            <td colspan="2" bgcolor="#6D6DFF"><h2 align="center">
                                <font color="white"><br><img src="logo_web.gif" alt="gonzasilve">
                                    Baja de un alumno
                                </font></h2>
                            </td>
                        </tr>
                        <tr>
                            <td align="center"><br><br>
                                <b>Escriba el N.C del alumno<br> que desea dar de baja:</b><br>
                                <input type="text" name="nc" size="30" maxlength="10"><br><br>
                            </td>
                        </tr>
                    </table>
                </td>
            </tr>
        </table>
      <br><br>
      <table border="0" width="80%" align="center">
            <tr>
                <td colspan="2" align="center">
                    <input type="submit" name="baja" value="Dar de baja">&nbsp;&nbsp;&nbsp;
                </td>
                <td colspan="2" align="center">
                    <input type="reset" name="limpiar" value="Limpiar">&nbsp;&nbsp;&nbsp;
                </td>
                <td colspan="2" align="center">
                    <input type="Button" name="cancelar" value="Cancelar baja" onClick="location='http://localhost/lpq/index.html'">
                </td>
            </tr>
       </table>
    </form>
</body>
</html>

Y ahora la siguiente imagen muestra esta pagina en el navegador:

bajaAlumnos.cgi
Este archivo es un programa CGI y recibe a travez del formulario del archivo formularioBajas.html el n.c. de un alumno que se desea dar de baja. Despues de que recibe el n.c. establece una conexion con la BD y ejecuta una operacion DELETE sobre la tabla alumnos.Este archivo esta almacenado en /usr/local/servidor_web/cgi-bin/lpq. A continuacion A continuacion se muestra el codigo fuente en C de este programa CGI:


/*
	Instituto Tecnologico de Zacatepec
  Descripcion:	Programa que hace un DELETE para dar de baja a un alumno en una tabla de postgres
  Author:	Gonzalo Silverio  gonzasilve@gmail.com
  Archivo:	bajaAlumnos.c
  Compilar con: 
		cc -c -I/usr/local/pgsql/include bajaAlumnos.c
  Enlazar CGI con libreria LPQ con:
  		cc -o bajaAlumnos.cgi bajaAlumnos.o -L/usr/local/pgsql/lib -lpq
*/

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include "libpq-fe.h"

// Maximo 100 registros de alumnos
#define MAX 100

// Estrutura de datos que guarda los nombres de las variables CGI y sus valores de los formularios
struct 
{
  char nombre[128];
  char valor[128];
} elementos[MAX];


void  baja(void);

// declaraciones de las funciones que se van a utilizar en el programa
void splitword(char *out, char *in, char stop);
char x2c(char *x);
void unescape_url(char *url);
static void salir_bien(PGconn *conn);

// Almacenamiento temporal de la variable de ambiente
char *cp;
char *empty = "<vacio>";


	char *qs;	/* qs servira para guardar la cadena de consulta */

	int i,j;
	PGconn	   *conn;
	PGresult   *res;
	char cadSQL[8000];

int main(int argc, char **argv)
{
	// Enviar primero el encabezado MIME
	printf("Content-type: text/html\n\n");
	
	// Iniciar una conexion a Postgres con los datos especificados 
	conn = PQsetdbLogin("localhost", NULL, NULL,NULL, "prueba","postgres", "12345");

	// Comprobar si la conexion fue creada correctamente 
	if (PQstatus(conn) != CONNECTION_OK)
	{
		fprintf(stderr, "La conexion a la BD ha fallado: %s",	PQerrorMessage(conn) );
		salir_bien(conn);
	}

	// Asignar la cadena de consulta a qs, abortar si esta vacia
	if((qs = getenv("QUERY_STRING")) == NULL )
	{
		printf("No hay cadena de consulta a decodificar!<br> ");
		exit(1);
	}

	// Dividir cada uno de los parametros de la cadena de consulta
	for(i=0; qs[0] != '\0'; i++)
	{
	 // Primero dividir por '&' cada parametro
	 splitword(elementos[i].valor,qs,'&');
	 // Convertir la cadena para caracteres exadecimales y signos mas
	 unescape_url(elementos[i].valor);
	 // separar ahora name y value 
	 splitword(elementos[i].nombre,elementos[i].valor,'=');    
	 
	}

	//Titulo de la pagina web
	printf("<HTML><HEAD><TITLE>baja de un alumno</TITLE></HEAD>\n");
	//Cuerpo de la pagina web
	printf("<BODY bgcolor='#C9FF5C'><br>");

  	baja();
  	
	PQclear(res);
	
	// cerrar la conexion a la BD y limpiar
	PQfinish(conn);
	
	printf("<br><form name=\"volver_indice\" action=\"http://localhost/lpq/index.html\" method=\"POST\">");
	printf("<input type=\"submit\" name=\"volver\" value=\"Volver al menu principal\">");
	printf("</form>");
	printf("</BODY>");

	return 0;
}

/// funcion del Libro 
void splitword(char *out, char *in, char stop)
{
  int i,j;

  for(i=0; in[i] && ( in[i] != stop ); i++)  
    out[i] = in[i];
  
  out[i] = '\0'; 	// Terminar
  if( in[i] )
    i++;

  for( j=0; in[j]; )
    in[j++] = in[i++];
}

// funcion del Libro 
char x2c(char *x)
{
  register char c;
  // NOTA: (x & oxdf) cambia a mayusculas a x
  c = ( x[0] >= 'A' ? ( (x[0] & 0xdf) - 'A') +10 : ( x[0] -'0' ));
  c *= 16;
  c += (x[1] >= 'A' ? ( (x[1] & 0xdf) - 'A') +10 : ( x[1] -'0' ));
  return(c);
}

// funcion del Libro 
void unescape_url(char *url)
{
  register int i,j;

  for(i=0, j=0; url[j]; ++i,++j)
  {
    if( (url[i] = url[j]) =='%' )
    {
      url[i] = x2c(&url[j+1]);
      j += 2;      
    }
    else if(url[i] == '+')
	  url[i] = ' ';
  }
  
  url[i] = '\0';	// Terminar en la nueva longitud 
}

//	Ejecutar Operacion DELETE en el DBMS Postgres
void baja(void)
{	
	// Formar la cadena de la operacion SQL que se quiere mandar al server
	strcat(cadSQL, "DELETE FROM alumnos WHERE nc=\'");
	strcat(cadSQL, elementos[0].valor);
	strcat(cadSQL, "\'");
	
	// Ejecutar la operacion SQL en el servidor 
	res = PQexec(conn, cadSQL);
	
	// Si la operacion salio bien, mostrar un MSG, sino tbn (jejeje)
	if ( PQresultStatus(res) == PGRES_COMMAND_OK )
	{
		printf("<br>baja realizada con exito: %s<br>", PQresStatus(PQresultStatus(res)));
	}
	else
	{
		printf("Estado de la operacion SQL (delete): %s<br>", PQresStatus(PQresultStatus(res)));
	}	
}

static void salir_bien(PGconn *conn)
{
	PQfinish(conn);
	exit(1);
}

Una vez que se a ejecutado la operacion DELETE exitosamente el programa bajaAlumnos.cgi muestra una pagina web, la cual es la siguiente:


y pues nuevamente, el usuario debe dar click en el boton para volver a la pagina principal.

mostrarAlumnos.cgi
Si en la pagina principal el usuario da click en el boton Ver tabla entonces se ejecuta este programa CGI, el cual tiene la funcion de conectarse a la Base de datos y hacer una operacion SELECT para mostrar una pagina web en una tabla los datos de la tabla alumnos. Este archivo esta almacenado en /usr/local/servidor_web/cgi-bin/lpq. A continuacion el codigo fuente en C del programa CGI:

/*
	Instituto Tecnologico de Zacatepec
  Descripcion:	Programa CGI que hace un SELECT para mostrar el contenido de la tabla alumnos de postgres
  Author:	Gonzalo Silverio  gonzasilve@gmail.com
  Archivo:	mostrarAlumnos.c
  Compilar con: 
		cc -c -I/usr/local/pgsql/include mostrarAlumnos.c
  Enlazar CGI con libreria LPQ con:
  		cc -o mostrarAlumnos.cgi mostrarAlumnos.o -L/usr/local/pgsql/lib -lpq
*/

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include "libpq-fe.h"

void  mostrar(void);
static void salir_bien(PGconn *conn);

int i,j;
PGconn	   *conn;
PGresult   *res;
char cadSQL[8000];

int main(int argc, char **argv)
{
	// Enviar primero el encabezado MIME
	printf("Content-type: text/html\n\n");

	//titulo de la pagina web
	printf("<HTML><HEAD><TITLE>Uso de la libreria LPQ de Postgres</TITLE></HEAD><BODY bgcolor=\'#C9FF5C\'>");
		
	// Iniciar una conexion a Postgres con los datos especificados
	conn = PQsetdbLogin("localhost", NULL, NULL,NULL, "prueba","postgres", "12345");

	// Comprobar si la conexion fue creada correctamente
	if (PQstatus(conn) != CONNECTION_OK)
	{
		fprintf(stderr, "La conexion a la BD ha fallado: %s",	PQerrorMessage(conn) );
		salir_bien(conn);
	}

	printf("<br><h1 align='center'>CGI que usa la libreria LPQ de Postgres</h1>");
	printf("Consultando tabla alumnos......<br><br>");
  	mostrar();
  	
	PQclear(res);
	
	///Cerrar la conexion a la BD y limpiar
	PQfinish(conn);
	
	printf("<br><form name=\"volver_indice\" action=\"http://localhost/lpq/index.html\" method=\"POST\">");
	printf("<center><input type=\"submit\" name=\"volver\" value=\"Volver al menu principal\"></center>");
	printf("</form>");
	printf("</BODY></HTML>");

	return 0;
}


//	Muestra el contenido de la tabla Alumnos.
void mostrar(void)
{
	// Ejecutar la operacion Select SQL en el servidor Postgres
	res = PQexec(conn, "SELECT * FROM alumnos");
	
	// Si la operacion salio bien, mostrar la tabla HTML
	if ( PQresultStatus(res) == PGRES_TUPLES_OK )
	{
		int ntup, nf;
		ntup=PQntuples(res);		
		nf=PQnfields(res);	
		printf("<TABLE width=\'90%%\' BORDER=\'1\' align=\'center\' bgcolor=\'#FFFFFF\'> <TR> <TD align=\'center\'>");
		printf("<TABLE width=\'100%%\' BORDER=\'0\'>");
		printf("<TR bgcolor=\'#c9dfef\'>");
		printf("<TD align=\'center\'><b>N.C</b></TD><TD align=\'center\'><b>Nombre</b></TD><TD align=\'center\'><b>Apellidos</b></TD><TD align=\'center\'><b>Direccion</b></TD><TD align=\'center\'><b>Estatura</b></TD><TD align=\'center\'><b>Peso</b></TD><TD align=\'center\'><b>Fecha ingreso</b></TD><TD align=\'center\'><b>Carrera</b></TD><TD align=\'center\'><b>sexo</b></TD>");
		printf("</TR>");

		for (i=0; i<ntup; i++)
		{
			printf("<TR>");
		   for (j=0; j<nf; j++)
		   {
		   	printf("<TD align=\'center\'> %s </TD>", PQgetvalue(res, i, j));
		   }
			printf("</TR>");
		}
		printf("</TABLE>");
		printf("</TD> </TR></TABLE>");
	}
	else
	{
		printf("ERROR!, Estado de la consulta: %s<br>", PQresStatus(PQresultStatus(res)));
	}
	
}

static void salir_bien(PGconn *conn)
{
	PQfinish(conn);
	exit(1);
}

y aka la imagen con la la pagina web que genera el programa anterior, como se observa previamente e insertado 3 registros para que hubiera algo que mostrar.


Ufff, hasta que al fin acabe con este ejemplo (jejejej algo largo). Como se puede apreciar no pongo mucha explicacion sobre el codigo de los programas CGI, por que el objetivo es tener un apunte a la mano por si lo ocupo despues. Ademas no esta muy complicado de entender si sabes algo de lenguaje C .

Bueno, hasta pronto y espero comentarios o dudas acerca de este ejemplo, o si quieres los fuentes…. deja tu e-mail.

Decodificacion de la variable de ambiente Query_String

Bueno continuo sacando algunos programas CGI de mis apuntes, en este Post quiero mostrar como se puede decodificar la variable de ambiente Query_String recordemos que esta variable es la que contiene los nombres y sus valores de las variables que llegan de un formulario a un programa CGI. El fuente HTML del formulario que se va a enviar al programa CGI es el siguiente:

<!--
	Instituto Tecnologico de Zacatepec
    Descripcion:
    Formulario de datos que se usara en conjunto con el programa decodifica_QueryString.cgi para
    leer los valores que son enviados de este formulario.
    Author:     Gonzalo Silverio  gonzasilve@gmail.com
    Archivo:    formulario.html
-->

<html>
<head>
<title>Decodificar Query String</title>
</head>
<body>
    <br><br><br>
    <form name="formulario1" action="http://localhost/cgi-bin/pruebas/decodifica_QueryString.cgi" method="GET">
        <table width="90%" border="0" align="center" cellspacing="0">
        <tr>
            <td colspan="2" bgcolor="#6D6DFF"><h2 align="center">
                    <font color="white"><br>
                        Decodificar la variable Query String
                    </font></h2>
            </td>
        </tr>
        <tr>
            <td bgcolor="#ff9019"><b>N.C:</b> </td><td><input type="text" name="nc" size="30" maxlength="10"> </td>
        </tr>
        <tr>
            <td bgcolor="#ff9019"><b>Nombre:</b> </td><td><input type="text" name="nombre" size="67" maxlength="255"> </td>
        </tr>
        <tr>
            <td bgcolor="#ff9019"><b>Apellidos:</b> </td><td><input type="text" name="apellidos" size="67" maxlength="255"> </td>
        </tr>
        <tr>
            <td bgcolor="#ff9019"><b>Domicilio:</b> </td><td><textarea COLS="60" rows="3"  name="domicilio" ></textarea></td>
        </tr>
        <tr>
            <td bgcolor="#ff9019">
                <b>Edad:</b> </td><td><input type="text" name="edad" size="10" maxlength="10">
                <font color="#a4a2a1">a&ntilde;os</font>
            </td>
        </tr>
        <tr>
            <td bgcolor="#ff9019">
                <b>Estatura:</b> </td><td><input type="text" name="estatura" size="10" maxlength="10">
                <font color="#a4a2a1">mts.</font>
            </td>
        </tr>
        <tr>
            <td bgcolor="#ff9019">
                <b>Peso:</b> </td><td><input type="text" name="peso" size="10" maxlength="10">
                <font color="#a4a2a1">kgs.</font>
            </td>
        </tr>
        <tr>
            <td bgcolor="#ff9019"><b>Fecha de ingreso:</b> </td><td>Dia
                <select name="dia" size="1">
                    <option value="1">1</option>
                    <option value="2">2</option>
                    <option value="3">3</option>
                    <option value="4">4</option>
                    <option value="5">5</option>
                    <option value="6">6</option>
                    <option value="7">7</option>
                    <option value="8">8</option>
                    <option value="9">9</option>
                    <option value="10">10</option>
                    <option value="11">11</option>
                    <option value="12">12</option>
                    <option value="13">13</option>
                    <option value="14">14</option>
                    <option value="15">15</option>
                    <option value="16">16</option>
                    <option value="17">17</option>
                    <option value="18">18</option>
                    <option value="19">19</option>
                    <option value="20">20</option>
                    <option value="21">21</option>
                    <option value="22">22</option>
                    <option value="23">23</option>
                    <option value="24">24</option>
                    <option value="25">25</option>
                    <option value="26">26</option>
                    <option value="27">27</option>
                    <option value="28">28</option>
                    <option value="29">29</option>
                    <option value="30">30</option>
                    <option value="31">31</option>
                </select>
                <b>Mes</b>
                <select name="mes" size="1">
                    <option value="1">Enero</option>
                    <option value="2">Febrero</option>
                    <option value="3">Marzo</option>
                    <option value="4">Abril</option>
                    <option value="5">Mayo</option>
                    <option value="6">Junio</option>
                    <option value="7">Julio</option>
                    <option value="8">Agosto</option>
                    <option value="9">Septiembre</option>
                    <option value="10">Octubre</option>
                    <option value="11">Noviembre</option>
                    <option value="12">Diciembre</option>
                </select>
                <b>a&ntilde;o</b>
                <input type="text" size="4" maxlength="4" name="anio" value="">
            </td>
        </tr>
        <tr>
            <td bgcolor="#ff9019"><b>Sexo:</b> </td><td>
                <input type="radio" name="sexo" value="hombre">Masculino &nbsp;&nbsp;
                <input type="radio" name="sexo" value="mujer">Femenino
            </td>
        </tr>
        <tr>
            <td colspan="2" align="center"><br><br>
                <input type="submit" name="enviar" value="Enviar datos a CGI">&nbsp;&nbsp;&nbsp;
                <input type="reset" name="limpiar" value="Limpiar">
            </td>
        </tr>
    </table>
    </form>
</body>
</html>

Y su aspecto en el navegador es mas o menos similar a esto:


El usuario una vez que ha llenado los campos da click en el boton Enviar datos a CGI, dicho boton manda a llamar al programa decodifica_QueryString.cgi y este programa es el que recibe los datos del formulario. A continuacion muestro el programa fuente en C del CGI que recibira los datos del formulario anterior y ‘ despedazara’ la variable de ambiente Query_String para obtener los valores de los campos de dicho formulario:

/*
	Instituto Tecnologico de Zacatepec
  Descripcion:	Programa que decodifica la variable de ambiente Query_String obtiendo los
		valores de las variables que se reciben de un formulario.
  Author:	Gonzalo Silverio     gonzasilve@gmail.com
  Archivo: 	decodifica_QueryString.c
*/

#include<stdio.h>
#include<stdlib.h>

/* Estrutura de datos que guarda los nombres de las variables CGI y sus valores de los formularios */
struct 
{
  char nombre[128];
  char valor[128];
} elementos[16];

/* declaraciones de las funciones que se van a utilizar en el programa */
void splitword(char *out, char *in, char stop);
char x2c(char *x);
void unescape_url(char *url);

/* Almacenamiento temporal de la variable de ambiente */
char *cp;
char *empty = "<vacio>";

/* Macro para desplegar las variables de ambiente */
#define safenv(a) ( (cp = getenv(a)) ? cp : empty)

main(int argc, char **argv)
{
  char *qs;	/* qs servira para guardar la cadena de consulta */
  int i;

  /* Enviar primero el encabezado MIME */
  printf("Content-type: text/html\n\n");
  
	//Titulo de la pagina web
	printf("<HTML><HEAD><TITLE>Decodificacion de Query_String</TITLE></HEAD>\n");
	//Cuerpo de la pagina web
	printf("<BODY><br>");

  printf("<b>Contenido de la variable sin decodificar: <br>QUERY_STRING =</b> %s <br>",safenv("QUERY_STRING"));
  

  /* Asignar la cadena de consulta a qs, abortar si esta vacia */
  if((qs = getenv("QUERY_STRING")) == NULL )
  {
    printf("No hay cadena de consulta a decodificar!<br> ");
    exit(1);
  }

  /* Dividir cada uno de los parametros de la cadena de consulta */
  for(i=0; qs[0] != '\0'; i++)
  {
    /* Primero dividir por '&' cada parametro */
    splitword(elementos[i].valor,qs,'&');
    /* Convertir la cadena para caracteres exadecimales y signos mas */
    unescape_url(elementos[i].valor);
    /* separar ahora name y value */
    splitword(elementos[i].nombre,elementos[i].valor,'=');    
    
  }

  /* Imprimir todos los valores de formulario */
  printf("<br></b>LAS VARIABLES Y SUS VALORES SON: </b><br><br>");
  for(i=0; elementos[i].nombre[0]; i++)
    printf("%s=%s  <br>",elementos[i].nombre,elementos[i].valor);

	printf("</BODY>");
}

void splitword(char *out, char *in, char stop)
{
  int i,j;

  for(i=0; in[i] && ( in[i] != stop ); i++)  
    out[i] = in[i];
  
  out[i] = '\0'; 	/* Terminar */
  if( in[i] )
    i++;

  for( j=0; in[j]; )
    in[j++] = in[i++];
}

char x2c(char *x)
{
  register char c;
  /* NOTA: (x & oxdf) cambia a mayusculas a x */
  c = ( x[0] >= 'A' ? ( (x[0] & 0xdf) - 'A') +10 : ( x[0] -'0' ));
  c *= 16;
  c += (x[1] >= 'A' ? ( (x[1] & 0xdf) - 'A') +10 : ( x[1] -'0' ));
  return(c);
}

void unescape_url(char *url)
{
  register int i,j;

  for(i=0, j=0; url[j]; ++i,++j)
  {
    if( (url[i] = url[j]) =='%' )
    {
      url[i] = x2c(&url[j+1]);
      j += 2;      
    }
    else if(url[i] == '+')
	  url[i] = ' ';
  }
  
  url[i] = '\0';	/* Terminar en la nueva longitud */
}

…cabe mencionar que parte del codigo que muestro no es de mi propia cosecha pues lo saque de un libro que me pidieron que consultara y cuyo titulo y autor ahora no recuerdo su nombre, pero en cuanto recuerde lo pongo para que lo consulten, esta muy bueno el libro, bueno aca la compilacion del programa anterior:

y por ultimo muestro lo que arroja el programa CGI decodifica_QueryString.cgi una vez que a decodificado la variable de ambiente Query_String:

buen, espero comentarios o dudas o si les interesan los fuentes, adelante basta dejar su correo. Hasta pronto y gracias x pasar por aqui.

Programa CGI: Lectura de variables de ambiente

En esta ocasion muestro como se pueden leer las variables de ambiente. Recordemos que las variables de ambiente son variables que existen dentro de cada cliente y nos permiten recuperar ciertas caracteristicas acerca de dicho cliente y del servidor donde se ejecuta el programa CGI. Bueno aca el programa fuente:

/*
	Instituto Tecnologico de Zacatepec
 Descripcion:		Lectura de las variables de ambiente con C
 Author: 	Gonzalo Silverio	gonzasilve@gmail.com
 Archivo:	leerVariablesCGI.c
*/

#include<stdio.h>
#include<stdlib.h>

// almacenamiento temporal de la variable de ambiente
char * cp;
char * empty = "<empty>";

main(int argc, char ** argv)
{
  // enviar el encabezado de tipo mime
  printf("Content-type: text/html\n\n");

  // Macro para desplegar la variables de ambiente
  #define safenv(a) ((cp = getenv(a)) ? cp : empty)

//Titulo de la pagina web
 printf("<HTML><HEAD><TITLE>Leer Variables de ambiente</TITLE></HEAD>\n");
//Cuerpo de la pagina web
 printf("<BODY><br><b>Las Variables de ambiente son:</b><br><br>");

  // A continuacion vamos a desplegar todas las variables estandar de CGI
  printf("GATEWAY_INTERFACE = %s <br>",safenv("GATEWAY_INTERFACE"));
  printf("REQUEST_METHOD = %s <br>",safenv("REQUEST_METHOD"));
  printf("SCRIPT_NAME = %s <br>",safenv("SCRIPT_NAME"));
  printf("QUERY_STRING = %s <br>",safenv("QUERY_STRING"));
  printf("SERVER_SOFTWARE = %s <br>",safenv("SERVER_SOFTWARE"));
  printf("SERVER_NAME = %s <br>",safenv("SERVER_NAME"));
  printf("SERVER_PROTOCOL = %s <br>",safenv("SERVER_PROTOCOL"));
  printf("SERVER_PORT = %s <br>",safenv("SERVER_PORT"));
  printf("HTTP_USER_AGENT = %s <br>",safenv("HTTP_USER_AGENT"));
  printf("HTTP_ACCEPT = %s <br>",safenv("HTTP_ACCEPT"));
  printf("PATH_INFO = %s <br>",safenv("PATH_INFO"));
  printf("PATH_TRANSLATED = %s <br>",safenv("PATH_TRANSLATED"));
  printf("REMOTE_HOST = %s <br>",safenv("REMOTE_HOST"));
  printf("REMOTE_ADDR = %s <br>",safenv("REMOTE_ADDR"));
  printf("REMOTE_USER = %s <br>",safenv("REMOTE_USER"));
  printf("REMOTE_IDENT = %s <br>",safenv("REMOTE_IDENT"));
  printf("AUTH_TYPE = %s <br>",safenv("AUTH_TYPE"));
  printf("CONTENT_TYPE = %s <br>",safenv("CONTENT_TYPE"));
  printf("CONTENT_LENGTH = %s <br>",safenv("CONTENT_LENGTH"));
  printf("</BODY>");
}

aka la compilacion:

Compilacion lectura de variables de ambiente

…y ahora la ejecucion en el navegador, como se ve algunas variables no tienen valor, lo que quiere decir que tienen un valor 0 ho que simplemente no tienen nada.

Ejecucion de prog. CGI que lee variables de ambiente.

bueno eso es todo y espero comentarios o dudas.

CGI del Clasico Hola mundo en C

Ando un poco aburridon y ps para recapitular un poco sobre lo aprendido en mi materia de programacion web, pues en esta ocasion nada mas dejo el CGI del clasico Hola Mundo, escrito en lenguaje C.

/*
		Instituto Tecnologico de Zacatepec
	Descripcion: Version CGI del clasico programa Hola Mundo
	Author: Gonzalo Silverio  gonzasilve@gmail.com
	Archivo: HolaMundo.c
*/

#include<stdio.h>
main( int argc, char **argv)
{
	//Enviar el encabezado de tipo mime
	printf("Content-type: text/html\n\n");

	//Titulo de la pagina web
	printf("<HTML><HEAD><TITLE>Practica con CGI</TITLE></HEAD>\n");
	//Cuerpo de la pagina web
	printf("<BODY><br><H1 align='center'>Hola Mundo de CGI's</H1>");
	printf("<BR><B></BODY></HTML>\n");
}

Aka el pantallazo de la compilacion para que vean que si furula:

Compilacion de clasico CGI Hola Mundo en C

y ahora la ejecucion en el navegador:

Ejecucion de clasico CGI Hola Mundo en C

como se ve es algo muy basico pero me sirve para tener algun apunte y tbn espero dudas y comentarios.

Como hacer un INSERT y un SELECT en una BD de MySQL usando PHP

Desde hace ya tiempo tenia ganas de exponer algo sobre PHP pero hasta hoy me di a la tarea de invertir algo de tiempo en hacerlo. Y es que muchos dicen que ya PHP esta cayendo en desuso y otros que esta todavia muy fuerte, que esto y que el otro, la verdad es que no e investigado estadisticas para dar mi propia opinion. Pero creo que es un buen lenguaje web y cualquier estudiante de sistemas deberia tener a la mano algun apunte aunque sea algo basico, por eso me decidi a exponer algo.

En este ejemplo doy por hecho que ya tienes un servidor Apache correctamente instalado y configurado para cargar como modulo al PHP, sino sabes que es eso o todavia no lo tienes pues seria bueno irte ahora mismo a otro sitio y leer algo previo, por que sino no vas a entender mucho.

El ejemplo es muy sencillo; simplemente se realiza una insercion (INSERT) en una tabla que se llama usuarios, la tabla usuarios solamente tiene 3 campos y esta dentro de una Base de datos (BD) que lleva por nombre prueba.

Aca el comando SQL para crear la BD prueba y la tabla usuarios:

create database prueba;
create table usuarios(nick char(60) not null, pw char(40), correo char(255), primary key(nick));

Aca una imagen muestra en forma grafica el aspecto de la tabla ( creada con el workbench ):

Tabla usuarios

El ejemplo consta de tres archivos de codigo fuente; los cuales se describen a continuacion:

formularioAlta.html

Este archivo genera un formulario con tres campos de texto donde el usuario ingresara los datos que desea insertar en la tabla usuarios, una vez que el usuario a escrito los datos debe dar click en el boton Dar de alta! el cual es un boton submit que manda a llamar al archivo guardarAlta.php , dicho archivo es el que realmente guarda los datos en la tabla. Aca el codigo fuente:

<!--
                   Instituto Tecnologico de Zacatepec, Morelos
Descripcion:    Archivo fuente HTML que crea un formulario para capturar datos que seran
                enviados a un archivo .php para insertarlos en una BD de MySQL.
Author:         Gonzalo Silverio  gonzasilve@gmail.com
Fecha:          02/09/2010
Archivo:        formularioAlta.html
-->
<HTML>
   <HEAD>
        <TITLE>PHP y MySQL -Capturar datos alta</TITLE>
   </HEAD>

   <BODY>
      <FORM method="POST" action = "guardarAlta.php">
        Su nombre de usuario: <INPUT TYPE="text" name="nick" id="nick"><BR>
        Su Contraseña: <INPUT TYPE="password" name="password" id="password"><BR>
        Su correo electronico: <INPUT type="text" name="correo" id="correo"><BR><BR>
        <INPUT type="submit" NAME="enviar" VALUE="Dar de alta!" id="enviar">
      </FORM>
   </BODY>
</HTML>

guardarAlta.php
Este archivo abre una conexion con el servidor MySQL, captura los datos que llegan por el metodo POST, realiza dos comprobaciones para validar los datos a insertar, si los datos logran pasar satisfactoriamente las dos validaciones se hace la insercion y se avisa al usuario del exito de la operacion. A continuacion el codigo fuente, los comentarios indican donde se realiza cada cosa:

<!--
                   Instituto Tecnologico de Zacatepec, Morelos
Descripcion:    Archivo fuente de PHP que muestra como realizar una operacion INSERT
                en una BD de MySQL, con datos que llegan de un formulario HTML.
Author:         Gonzalo Silverio  gonzasilve@gmail.com
Fecha:          02/09/2010
Archivo:        guardarAlta.php
-->

<HTML>
<HEAD>
     <TITLE>PHP y MySQL -Resultados de alta</TITLE>
</HEAD>

<BODY>

<?php
   //Abrir una conexion con el servidor MySQL
   $conexio = mysql_connect("localhost","root","12345");
   mysql_select_db ("prueba", $conexio) OR die ("No se puede conectar");

   //Recoger datos que llegan
   $nik=$_POST['nick'];
   $pas=$_POST['password'];
   $cor=$_POST['correo'];

   //1.- Comprobar que no haya otro usuario con el mismo nick
   $sql="SELECT nick FROM usuarios WHERE nick='".$nik."'";
   $result=mysql_query($sql,$conexio);
   if($row=mysql_fetch_array($result))
   {
     echo "El nick <b>".$nik."</b> ya fue elegido por otro usuario.";
     exit();   /*cancelar la ejecucion del script y por tanto de la pagina web*/
   }
   //2.- Comprobar que no haya otro usuario registrado con el mismo correo
   $sql="SELECT correo FROM usuarios WHERE correo='".$cor."'";
   $result=mysql_query($sql,$conexio);
   if($row=mysql_fetch_array($result))
   {
     echo "El correo electronico <b>".$cor."</b> ya fue registrado por otro usuario.";
     exit();  /*cancelar la ejecucion del script y por tanto de la pagina web*/
   }
   //Si se ha logrado pasar las dos validaciones anteriores, entonces...
   //Realizar el INSERT en la tabla
   mysql_query("INSERT INTO usuarios(nick,pw,correo) VALUE ('$nik', '$pas', '$cor')",$conexio);
   echo "Registro Exitoso! <br><br> Usuario: <b>".$nik."</b> <br>Mail: <b>".$cor."</b>";

   //Cerrar la conexion
   mysql_close($conexio);
?>
 <BR><BR>
 <form method="POST" action="mostrarRegistros.php">
       <input type="submit" name="enviar" id="enviar" value="Ver registros de tabla">
 </form>
</BODY>
</HTML>

mostrarRegistros.php
Este archivo de codigo fuente abre una conexion con el servidor MySQL, realiza una seleccion (SELECT) de todos los registros de la tabla usuarios y los muestra en una tabla de tres columnas (3 campos tiene la tabla). A continuacion el codigo, otra vez los comentarios indican donde se realiza cada cosa:

<!--
                   Instituto Tecnologico de Zacatepec, Morelos
Descripcion:    Archivo fuente de PHP que muestra como realizar una operacion SELECT
                en una BD de MySQL.
Author:         Gonzalo Silverio  gonzasilve@gmail.com
Fecha:          02/09/2010
Archivo:        mostrarRegistros.php
-->
<HTML>
<HEAD>
     <TITLE>PHP y MySQL -Mostrar datos</TITLE>
</HEAD>

<BODY>

<?php
   //Abrir una conexion con el servidor MySQL
   $conexio = mysql_connect("localhost","root","12345");
   mysql_select_db ("prueba", $conexio) OR die ("No se puede conectar");

   //Seleccionar todos los registros
   $sql="SELECT * FROM usuarios";
   $result=mysql_query($sql,$conexio);

   //Mostrar los registros en una tabla en el navegador
   echo "<TABLE BORDER='1' width=50% align=center>";
   echo "<TR align=center><TD><b>Nick</b></TD><TD><b>Password</bd></TD><td><b>correo</b></td></TR>";
   while ($row=mysql_fetch_array($result))
   {
     echo "<TR><TD>".$row["nick"]."</TD><TD>".$row["pw"]."</TD><td>".$row["correo"]."</td></TR>";
   }
   echo "</TABLE>";

   //Cerrar la conexion
    mysql_close($conexio);

?>
<center>
   <br>
    <form method="POST" action="formularioAlta.html">
          <input type="submit" name="nuevo" id="enviar" value="Nuevo contacto">
    </form>
</center>
</BODY>
</HTML>

En resumen la logica del ejemplo es: El usuario abre el archivo formularioAltas.html en un navegador –> el usuario ingresa los datos y da clic en el boton submit –> Los datos son enviados al archivo guardarAlta.php –> Una vez que llegan los datos, se insertan en la BD (ho se muestra un msg de error de validacion) –> El usuario da clic en el boton Ver registros el cual es un boton submit y manda a llamar al archivo mostrarRegistros.php–> El archivo mostrarRegistros.php muestra los datos en el navegador.

A continuacion unos pantallazos de la ejecucion del ejemplo:

El usuario captura los datos y da clic en el boton Dar de alta!

formularioAltas.html

Se muestran al usuario resultados de la insercion, el usuario debe dar clic en el boton Ver registros de tabla

guardarAltas.php

Se muestran los datos en el navegador

mostrarRegistros.php Hasta pronto, comenta en caso de cualquier duda.