Mostrando entradas con la etiqueta C. Mostrar todas las entradas
Mostrando entradas con la etiqueta C. Mostrar todas las entradas

sábado, 1 de marzo de 2014

miniServidor Web en Windows

Mirando un poco cómo hacer una pequeña aplicación en lenguaje C para probar Sockets y comunicar programas a través de TCP/IP, encontré que el compilador LCC-Win trae una biblioteca llamada netutils.h dejando el asunto fácil y muy interesante.

Adaptando un poco el ejemplo de la aplicación servidor que trae la documentación, decidí dar un repaso al protocolo HTTP y crear un pequeño servidor Web.

El funcionamiento de este miniServidor Web sería muy sencillo y no cumpliría mucho con el estándar, pero para ver cómo funciona por dentro está bien. Lo que hace es lo siguiente:

  • Leer un archivo HTML dado como parámetro.
  • Iniciar una sesión de conexión a un Socket en la IP 127.0.01 en el puerto 10000.
  • Esperar una conexión de un navegador web.
  • Cuando reciba una conexión, visualiza la información recibida (las cabeceras HTTP del navegador).
  • Preparar las cabeceras HTTP de respuesta.
  • Leer el archivo HTML dado y agregarlo a las cabeceras anteriores.
  • Enviar la respuesta al navegador (cabeceras HTTP y el HTML).
  • Visualizar los datos enviados.

El código fuente sería el siguiente (servidor.c):

#include <stdio .h>
#include "netutils.h"

int main(int argc,char *argv[])
{
  while (1)
  {
    FILE* pf;
    if ((pf = fopen(argv[1],"rt")) == NULL)
    {
      puts("Error abriendo html.");
      return 1;
    }
    
    Session session; 
    char buf[8192];
    memset(&session,0,sizeof(session));
    session.port = 10000;
    session.Host = "127.0.0.1";
    
    if (ServerConnect(&session)){ return 0; }

    printf("Conectado...\n");
    memset(buf,0,sizeof(buf));
    
    if (Receive(&session,sizeof(buf)-1,buf)){ return 0; }
    
    printf("Datos recibidos:\n\n %s\n",buf);

    char texto[1000000] = "HTTP/1.1 200 OK\nContent-Type: text/html\n\n";

    int c, i = strlen(texto);

    while ( (c=getc(pf) ) != EOF){ texto[i] = c; i++; }
    texto[i] = '\0';

    fclose(pf);    
    
    if (Send(&session,strlen(texto),texto)){ return 0; }

    printf("Datos enviados:\n\n %s\n", texto);

    CloseSession(&session);

    printf("\nConexion cerrada.\n");
  }
}

Una vez creado servidor.c, en la misma carpeta creamos el archivo HTML que queremos publicar en nuestro miniServidorWeb (holamundo.html), cuyo código sería el siguiente:

<html>
<head>
  <title>Titulo>/title>
</head>
<body>
  <p><h1>Hola Mundo</h1></p>
</body>
</html>

Asumiendo que  LCC-Win está instalado en c:\lcc y que tenemos la ruta de los binarios del compilador (c:\lcc\bin) incluida en la variable PATH del sistema, ya podemos compilar y enlazar:

    lcc servidor.c
    lcclnk servidor.obj c:\lcc\lib\netutils.lib

Con esto tendremos el ejecutable servidor.exe creado, que es nuestro miniServidor Web. Lo ejecutamos dándole como parámetro el nombre del archivo HTML a publicar:

    servidor.exe holamundo.html

Y el miniServidor Web quedará a la escucha en el puerto 10000 de la IP 127.0.0.1, datos proporcionados en el código fuente. Ahora le toca al cliente, vamos al navegador Web y tecleamos la URL:

    http://127.0.0.1:10000

Con esto el navegador Web conecta con la IP indicada en el puerto 10000 y recupera nuestro HTML.

Mientras, en la ventana donde ejecutamos el miniServidor Web aparecerán los datos recibidos y los enviados en cada sesión HTTP.

Y ahí lo tienes, el servidor Web más pequeño del mundo.

martes, 11 de diciembre de 2012

Información de un sistema Windows con WMI y C

Ya sabemos que WMI es la forma más sencilla de extraer información útil de un sistema Windows, ya sea para realizar diagnósticos, para registrar equipos o para realizar informes.

Buscando la forma más sencilla para conseguir esta información en cualquier máquina Windows, existe un comando de consola que extrae el dato directamente: wmic

Por ejemplo, si queremos ver el número de serie de la máquina local, podemos hacerlo así:

    wmic csproduct get identifyingnumber

de igual forma, si queremos ver el nombre del microprocesador, utilizamos:

    wmic cpu get name

Si con antelación sabemos la información que nos interesa de un sistema, podemos incluir todas
las sentencias que queramos en un archivo por lotes (.bat) y utilizarlo, pero si además nos interesa disponer de un archivo ejecutable que realice lo mismo, podemos hacerlo con un pequeño programa en C, llamado por ejemplo regsys.c de la siguiente forma:

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

char *wmi();

int main()
{
// número de serie
char *nserie = "wmic csproduct get IdentifyingNumber";
char *pNserie = wmi( nserie );
printf("Numero de serie: %s", pNserie);

// fabricante
char *fabricante = "wmic computersystem get Manufacturer";
char *pFabricante = wmi( fabricante );
printf("Fabricante: %s", pFabricante);

// modelo placa
char *modeloPlaca = "wmic computersystem get model";
char *pModeloPlaca = wmi( modeloPlaca );
printf("Modelo placa: %s", pModeloPlaca);

// arquitectura
char *arq = "wmic computersystem get SystemType";
char *pArq = wmi( arq );
printf("Arquitectura: %s", pArq);

// procesador
char *cpu = "wmic cpu get name";
char *pCpu = wmi( cpu );
printf("Procesador: %s", pCpu);

return 0;
}

char *wmi( char *in )
{
FILE *fp;
char line[130];
char *line2;
line2 = malloc(130 * sizeof(char *));
 
fp = popen( in, "r" );

int x = 0;

while ( fgets( line, sizeof line, fp))
{
if ( x == 1 )
{
int z;

for ( z = 0 ; z < sizeof line ; z++ )
{
line2[z] = line[z];
}
}
x++;
}

pclose(fp);

return line2;
}

Podemos modificar el programa anterior e incluir todas las sentencias WMI que necesitemos mostrar. Además, con los conocimientos necesarios podemos ampliarlo para darle más funcionalidad como aceptar argumentos y escribir informes en un archivo HTML, por ejemplo.

El programa anterior se puede escribir en cualquier Windows, y compilarlo y enlazarlo con MinGW de la siguiente forma:

    cc regsys.c -o regsys.exe

y ya tendremos la herramienta regsys.exe lista para ejecutarlo.

jueves, 5 de enero de 2012

Averigua el tamaño de una carpeta con C


El objetivo de este post es ver cómo funciona un programa en C que averigua el tamaño de una carpeta de Windows dada (subcarpetas incluidas), ya sea en el sistema de archivos local o en red.

Por ejemplo, con esta herramienta (fsize.exe, una vez compilado y enlazado) y el siguiente script:

@echo off
fsize c:\windows
fsize "c:\Archivos de programa"
fsize \\server-1\datos\pepe

obtuve los siguientes resultados:

c:\windows:
6.48 GBytes - 28332 archivos - 2459 carpetas.

c:\Archivos de programa:
2.13 GBytes - 14883 archivos - 2834 carpetas.

\\server-1\datos\pepe:
1.48 GBytes - 3659 archivos - 91 carpetas.


El código fuente de fsize.c está disponible en:

http://sites.google.com/site/ramiroencinas/soft/fsize.c

e incluye comentarios explicando el funcionamiento.

El archivo fsize.exe junto con el código fuente también está disponible en:

http://sites.google.com/site/ramiroencinas/soft/fsize.zip

Notas:
  • El compilador de C que he utilizado es lcc-win32.
  • El compilado-linkado lo realizé con: lc fsize.c -o fsize.exe -s
  • El archivo generado ejecutable fsize.exe tiene un tamaño de 32KBytes (es lo bueno de programar directamente con la API de Windows).
  • Funciona a partir de Windows XP.