Programaci贸n Procedural M.C. Juan Carlos Olivares Rojas jolivares@uvaq.edu.mx http://antares.itmorelia.edu.mx/~jcolivar Agosto, 2009
Agenda 2.1 CaracterĂsticas principales de los lenguajes procedurales  2.2 Lenguajes representativos: C y AJAX.
Introducción
• Este tipo de programación se basa en la modularidad de los programas. Esto quiere decir que los programas se dividen en módulos más pequeños, y cada uno realiza una tarea específica. Así, la complejidad de un problema determinado también se ve reducida al dividir las tareas, que, en su conjunto, permiten la resolución de éste.
Introducción
• En el pasado la programación no estaba estructurada por lo que se tenía el código GO TO que hacía al código verse como espagueti. • La programación modular permite reutilizar código y hacer los programas más fáciles de elaborar.
Pasos para resolver un problema: 1. Definición del problema 2. Diseño del algoritmo para resolverlo 3. Transformación del algoritmo en programa 4. Ejecución y validación del programa
Problema
Diseño del algoritmo
Programa de computadora
un
Ejecución y validación
¿Que es un algoritmo? • Un algoritmo es la secuencia ordenada de pasos que conducen a la solución de un problema dado, y puede ser expresado en lenguaje natural, por ejemplo el castellano
Características de un algoritmo • Preciso. Indicar el orden de realización de cada paso • Definido. Si se sigue un algoritmo dos veces, se debe obtener el mismo resultado cada vez. • Finito. Debe terminar el algún momento
Inicio
Algoritmo para hacer una taza de tĂŠ
Tomar la tetera Llenarla de agua Encender el fuego Mientras no hierva el agua Esperar
Introducir una bolsa de tĂŠ en la tetera Vaciar el tĂŠ en la taza
fin
Ejemplo
• Construya un algoritmo para preparar “Pechugas de pollo en salsa de elote y chile poblano”: – Ingredientes (para 6 personas) – 3 Pechugas deshuesadas, sin piel y partidas a la mitad. – 1 diente de ajo – 4 gramos de pimienta negra. Sal. – 6 cucharadas de aceite – 5 chiles poblanos asados y limpios. – ½ Taza de leche. – ¼ Taza de crema ligera. – 1 lata de crema de elote.
Ejemplo
• Algoritmo (Preparación):
– Muela el ajo, la pimienta y un poco de sal y únteselo a las pechugas. – Caliente el aceite y dore las pechugas. – Licue los chiles con la leche y la crema, y mézclelos con la crema de elote. – En una fuente coloque las pechugas y báñelas con la mezcla anterior. – Cubra el platón con papel aluminio y hornee a 200 °C, durante 15 minutos.
Otros ejemplos de algoritmos • Las instrucciones o serie de pasos que sigues para grabar un número telefónico en tu celular. • Las instrucciones que te dan para resolver un examen.
• Los pasos que sigues para prender el carbón para una carne asada • El procedimiento que sigues para inscribirte
• EL procedimiento para obtener tu pasaporte
• La receta que sigues para preparar un pastel • Los pasos para invitar a alguien al cine
Introducción • Existen varias formas de representar soluciones a problemas, como son algoritmos, lenguaje estructurado, seudocódigo, diagramas de flujo, etc. • Estas herramientas no son lenguajes de programación y por lo tanto una computadora no tiene capacidad para procesarlos, su propósito es proporcionar una manera de documentar sus ideas para el diseño de programas.
Introducción • Es un sistema de notación para algoritmos que se han descrito como una mezcla de lenguaje común y su lenguaje de programación favorito. • El pseudocódigo está menos formalizado que el lenguaje estructurado de modo que la estructura y la redacción dependen del usuario.
Introducción • Cuando se escribe pseudocódigo, se permite incorporar palabras de comandos y sintaxis del lenguaje computacional que se pretende usar para el programa actual. • Otras formas de representación son los diagramas de flujo, los cuales muestran de manera gráfica como resolver problemas.
SĂmbolos del diagrama de Flujo
SĂmbolos del diagrama de Flujo
SĂmbolos del diagrama de Flujo
SĂmbolos del diagrama de Flujo
SĂmbolos del diagrama de Flujo
SĂmbolos del diagrama de Flujo
Diagramas Nassi-Scneiderman • Conocidos como Diagramas N-S o Diagramas de Chapin. Las acciones se escriben dentro de cajas sucesivas.
Ejercicio
• Realizar el siguiente algoritmo REGISTRO DE VENDEDORES. • Una tienda emplea un cierto número de vendedores. La mayoría de estos empleados obtienen sus ingresos de comisiones sobre los artículos que venden, pero existen algunos empleados que obtienen su salario fijo, sin importar el tipo o cantidad de artículos que venden, más una comisión por sobre ciertos artículos. • La tienda ofrece distintos tipos de mercancías, algunas de las cuales se clasifican como artículos estándar por que son de uso común y no requieren de técnicas creativas de venta; además, hay artículos que son altamente remunerados pero difíciles de vender.
Ejercicio • Los compradores tambiĂŠn se clasifican. Algunos se conocen como compradores regulares, pues hacen transacciones tan a menudo que no se requiere de hacerles venta creativa. Sin embargo, la mayorĂa de los clientes hacen pocas transacciones dentro de la tienda, y es probable que entren, compren algo y no vuelvan a ser vistos.
Ejercicio • Si un empleado vende cualquier tipo de artículo a un cliente regular, no se da comisión alguna. • Si un empleado asalariado vende un artículo extra, recibe una comisión del 10% a menos que el artículo tenga un precio mayor de $10,000, en cuyo caso recibe una comisión del 15%.
Ejercicio • Si un empleado no asalariado vende un artículo extra a alguien que no sea un comprador regular, recibe un 15% de comisión a menos que el artículo tenga un precio mayor a $10,000 en cuyo caso recibe una comisión del 20%. Si un empleado asalariado vende un artículo estándar recibe un 3% de comisión, en caso de ser un empleado no asalariado recibe un 7%.
Ejercicio
• Realizar este problema en lenguaje C o en algún otro lenguaje procedimental. • La E de datos se da desde línea de comandos, la salida se mostrará en pantalla. • El entorno deberá de ser de preferencia un sistema *X.
Programación en C en UNIX • Por default el sistema operativo Unix y variantes está hecho en C. • Los programas se compilan con la opción gcc archivo.c –o nombre. • Se deberá asegurar que se tengan permisos de ejecución. Sino aplicar chmod +a nombre
Programación en C en UNIX • Aplica exactamente el mismo lenguaje ANSI C por lo que la portabilidad está garantizada a otras plataformas. • Los tipos de datos varían de acuerdo a la arquitectura de computadoras utilizada. Se puede conocer a través del comando sizeof(). • Se utiliza mucho la línea de argumentos para pasar valores.
Pseudoc贸digo
Diagrama de Flujo “Cálculo de comisión”
30
Ejercicio resuelto
Características
• Los primeros programas modulares y que contribuyeron al desarrollo del paradigma procedimental fueron los macroensambladores que permitieron reutilizar código fuente • A continuación se muestran las principales características que presentan los lenguajes con paradigma procedimental. Se dará un repaso de cómo se implementan estas en Lenguaje C.
SENTENCIAS DE CONTROL
Estructura Selectiva Diagrama de Flujo
Diagrama N-S
Pseudoc贸digo si <condici贸n> entonces acci贸n 1 fin_si
Estructura Selectiva Doble Diagrama de Flujo
Diagrama N-S
Pseudoc贸digo si <condici贸n> entonces acci贸n 1 si_no acci贸n 2 fin_si
Estructura Selectiva MĂşltiple Diagrama de Flujo
Diagrama N-S
Estructura Selectiva Múltiple Estructura Selectiva Múltiple Pseudocódigo según_sea <expresión> hacer <lista 1> : acción 1 <lista 2> : acción 2 ... [si_no acción n] fin_según
Estructura Repetitiva Diagrama de Flujo
Diagrama N-S
Pseudoc贸digo mientras <expresi贸n l贸gica> hacer acci贸n fin_mientras
Estructura Repetitiva Diagrama de Flujo
Diagrama N-S
Pseudoc贸digo repetir acci贸n hasta_que <expresi贸n l贸gica>
Estructura Anidada Pseudocรณdigo si <condiciรณn1> entonces <acciรณnes1> si_no si <condiciรณn2> entonces <acciones2> si_no si <condiciรณn3> entonces <acciones3> si_no <accionesX> fin_si fin_si fin_si
โ ข Tanto las estructuras selectivas como las repetitivas pueden ser anidadas, e introducidas unas en el interior de las otras.
C
• Actividad: Desarrollar un programa para calcular el área de un triángulo conociendo solamente la longitud de sus tres lados. • ¿Qué se necesita? Entender el problema. La fórmula es: • S = (A + B + C)/2
C • Donde A, B y C son los lados del triangulo. Después se aplica la fórmula:
Área = S ( S − A)( S − B )( S − C )
• Se debe utilizar la función sqrt dentro de la biblioteca math.h
C
• Realizar un programa que permita jugar “Craps”. Dicho juego consiste en lanzar dos dados (simulación realizada a través de una función que se invoque dos veces) y sumar la puntuación. Si la suma de los dados da 2,3 o 12 el usuario pierde inmediatamente. • El programa deberá manejar funciones
C
• Si la suma da 7 u 11 el usuario gana. Si da cualquier otra combinación 4,5,6,8,9 o 10, el usuario tiene otra segunda oportunidad. • El programa debe de pedir al usuario la cantidad de dinero con la que cuenta el usuario. Por cada juego se debe pedir la apuesta. Se debe sumar o restar dependiendo de si ganó o perdió el juego. El juego termina hasta tener 0 pesos o bien que el usuario decida salir.
C • Actividad: realizar un programa que permita simular una partida de póker. El usuario deberá tener 5 cartas. La simulación consiste en repartir aleatoriamente cartas. Del 1 al 10 las cartas de corazones (donde el 1 representa el as), del 11 al 20 los diamantes (por ejemplo el 13) indica que se sacó el tres de diamantes, del 21 al 30 el trebol, y del 31 al 40 las picas. Los jotos están representados del 41 al 44, donde el 41 representa el joto de corazones y así
C • Las reinas están representadas del 51 al 54 (por ejemplo el 52 representa la reina de diamantes), y los reyes están del 61 al 64 (donde el 64 es el rey de picas). • No se deberán repartir cartas. Se debe indicar si se hizo alguna jugada válida del póker (par, dos pares, tercia, full (tercia, par), póker (4 figuras igual), flor y flor imperial).
C â&#x20AC;˘ Actividad: realizar un programa que permita calcular la exponencial de un nĂşmero dado.
2
n
x x x e = 1 + + + ... + 1! 2! n! x
C • Actividad: Resolver un sistema de ecuaciones de tamaño n con n incógnitas por la Regla de Cramer y el Método Gauss-Jordan. • Determinantes.
C
• Actividad: Realizar otro programa que permita determinar la multiplicación y la división de un número entero por dos. Se debe de hacer con operadores de bits. • Actividad: realizar un programa que permita determinar si un número tiene paridad par o impar, considerar todos los bits menos el más significativo, el cual deberá contener un 0 si es paridad par o un 1 si es paridad impar.
Programación Distribuida
• La programación distribuida o programación en red implica todo un cambio de paradigmas en la forma de pensar los programas. • La arquitectura más conocida es la cliente/servidor por lo que la lógica de la aplicación se ve dividida en dos grandes bloques: la lógica de la aplicación o modelo y los datos en el lado del servidor y la presentación en el lado del cliente.
Programación Distribuida
• La comunicación entre las distintas entidades se hace a través de paso de mensajes. • El modelo más implementado de pasos de mensajes es el mecanismo de sockets. • Se les denomina conectores por que unen procesos cliente y servidor, de manera semejante a como se unir un enchufe de un dispositivo eléctrico con un zócalo.
Programación Distribuida
• El mecanismo de sockets más conocido es el referente a la API de Berkeley. • Está API está implementado en prácticamente todos los sistemas Unix, por lo que se maneja C, pero también está portado a otras arquitecturas como Windows (WinSock) y a otros lenguajes como Java.
Programación Distribuida
• Para la comunicación de procesos remotos se necesita conocer la dirección de la máquina destino y el puerto donde se va a escuchar. • Los sockets no están casados con ningún tipo de red, por lo que se pueden implementar en diversos protocolos de red como IPX/SPX, NetBEUI, TCP/IP, siendo este último el más importante.
ProgramaciĂłn Distribuida
â&#x20AC;˘ Las primitivas de sockets vienen defindas en <sys/socket.h> â&#x20AC;˘ Para utilizar sockets TCP/IP se debe emplear la familia o protocolo Internet, la cual define sus direcciones en <netinet/in.h> y son:
Programaciรณn Distribuida
struct sockaddr_in {
};
short sin_familiy; /*AF_INET*/ u_short sin_port; /*16 bits*/ struct in_addr sin_addr; /*32 bits*/ char sin_zero[8]; /*8 bytes no usados*/
โ ข Existen dos tipos de sockets: orientados a la conexiรณn (stream/TCP) y no orientados a la conexiรณn (datagram/UDP).
Programaciรณn Distribuida
โ ข Las primitivas para comunicaciรณn orientada a conexiรณn (Stream) en el lado del servidor son: socket(); bind(); listen(); accept(); read(); write();
Programaciรณn Distribuida
โ ข Las primitivas de sockets pueden ser bloqueantes y no bloqueantes. Las primitivas stream en el lado cliente son: socket(); connect(); write(); read(); close();
Programaci贸n Distribuida
Programaciรณn Distribuida
โ ข Las primitivas para comunicaciรณn entre procesos no orientada a conexiรณn (Datagramas) en el lado del servidor son: socket(); bind(); recvfrom(); sendto();
Programaciรณn Distribuida
โ ข Las primitivas de comunicaciรณn datagramas en elclinente son:
con
socket(); bind();* sendto(); recvfrom(); shutdown(); *Opcional sรณlo si se requiere de respuesta del lado del cliente.
Programación Distribuida
• A continuación implementación de comunicación en red:
se muestran las funciones
Socket(int af, int type, int protocol) • Tipos: SOCK_STREAM, SOCK_DGRAM bind(int sfd, const void *addr, int addrlen); listen(int sfd, int backlog);
la de
Programaciรณn Distribuida
connect(int sfd, void *addr, int addrlen);
Ns =accept(int sfd, void *addr, int *addrlen); Todas las funciones regresan -1 para error โ ข Para leer datos de un socket se pueden utilizar las siguientes primitivas: read, readv, recv(sfd, buf, len, flags), recvfrom y recvmsg.
Programación Distribuida
• Para escribir datos en un socket se utilizan las siguientes primitivas: write, writev, send, sendto y sendmsg, siendo las más utilizadas write y send(sfd, buf, len, flags). • Se necesitan funciones de conversión para poder homogenizar las diferencias existentes entre las diversas arquitecturas de cómputo.
Programación Distribuida
• En <arpa/inet.h> se encuentra definida la función inet_addr(char *) convierte una dirección IP en formato de cadena a su representación en bytes. • char *inet_ntoa(struct in_addr) convierte una dirección IP a cadena. unsigned long htonl(unsigned long hostlong); unsigned short htons(unsigned short hshort); unsigned long ntohl(unsigned long netlong);
Programaciรณn Distribuida
unsgined long ntohs(unsigned short netsho); โ ข h:host n:network l:long s:short /*Ejemplo de Servidor*/ int sfd, nsfd, pid; struct sockaddr_in ser, cli; int tam_clie; if((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) /*Error al crear el socket*/
Programación Distribuida
/*Dirección del servidor*/ ser.sin_family = AF_INET; ser.sin_addr.s_addr inet_addr( “148.208.209.25”); ser.sin_port = htons(24400);
if(bind(sfd, &ser, sizeof(ser)) == -1) /*Error al publicar dirección*/
listen(sfd, 5);
=
Programaci贸n Distribuida
for(;;){ /*Un servidor siempre est谩 activo*/
tam_clie = sizeof(clie); if((nsfd = accept(sfd, &clie, &tam_clie)) == -1) /*Error al aceptar peticiones*/
}
if((pid = fork()) ==-1) /*Error al subproceso*/ else if(pid ==0) /*Hijo atiende peticiones*/ /*C贸digo padre*/ close(sfd);
crear
Programación Distribuida
• /*Ejemplo de cliente stream*/ ser.sin_addr.s_addr inet_addr( “148.208.209.25”); ser.sin_port = htons(24400);
=
if(connect(sfd, &ser, sizeof(ser)) ==-1) /*Error al conectar*/ send(); read(); …. close(sfd);
Programaciรณn Distribuida
โ ข /*Servidor de Datagramas*/ int sfd; struct sockaddr_in ser, clie;
if((sfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) /*Error al crear socket datagrama*/ /*Direcciรณn del servidor*/ ser.sin_family = AF_INET; ser.sin_port = htons(21100);
Programación Distribuida
ser.sin_addr.s_addr inet_addr( “142.208.209.25”);
=
if(bind(sfd, &ser, sizeof(ser)) ==-1) /*Error al ligar el socket*/ recvfrom(); sendto(); close(sfd);
Programaciรณn Distribuida
โ ข /*Cliente datagrama*/ int sfd; struct sockaddr_in ser, clie;
if((sfd = socket(AF_INET, SOCK_DGRAM, 0)) ==-1) /*Error al crear el socket*/ /*Direcciรณn del servidor*/ ser.sin_family = AF_INET; ser.sin_port = htons(21100);
Programación Distribuida
ser.sin_addr.s_addr inet_addr( “148.208.209.25”); /*Dirección del cliente*/ cli.sin_family = AF_INET cli.sin_addr.s_addr inet_addr(INADDR_ANY); cli.sin_port = htons(0);
=
=
if(bind(sfd, &cli, & sizeof(cli)) ==-1) /*Error*/
Programación Distribuida
sento(); recvfrom(); … close(sfd);
• Se puede utilizar resolución de nombres si se utiliza la biblioteca <netdb.h> de la siguiente forma: struct hostent *host; if((host = gethostbyname(argv[1])) ==-1)
Programación Distribuida
• ser.sin_addr.s_addr h_addr_list;
=
*(long
*)
host->
• Se pueden utilizar mecanismos más simplificados llamados middlewares que nos permiten enmascarar la complejidad de la comunicación en red. Los principales middlewares son: RPC, RMI, CORBA y los servicios Web
Programación de CGIs
• El CGI (Common Gateway Interface) es una interfaz común que permite el pasar parámetros y realizar programación en el lado del servidor. • Generalmente se programa en Perl y en C aunque pueden ser en otros lenguajes. La mayoría de los servidores Web definen una carpeta especial para poderse ejecutar. Se deben de revisar los permisos de la carpeta y configuración del servidor.
Programación de CGIs
• En el caso del servidor Web apache, los CGIs se invocan desde la URL: http://mi.sitio.com/cgi-bin/miarchivo.cgi • Las extensiones deben de ser .cgi o .exe para el caso de Windows. Estos archivos se guardan dentro de la carpeta CGI-EXEC (Mac OS X).
Programación de CGIs
• Se debe tener activado el módulo cgi_module y la directiva ExecCGI sobre el DocumentRoot dentro del archivo de configuración httpd.conf • La programación de CGIs se hace como cualquier programa en C, de manera automática la entrada y la salida estándar están redireccionadas al servidor Web.
Programación de CGIs
• /*Ejemplo de CGI*/ • #include <stdio.h>
• int main(){ • printf("Content-Type: text/html\n\n"); printf("<html>"); printf("<head><title>Ejemplo de CGI</title></head>"); • printf("<body><p>Hola Mundo</p>"); printf("<br /><h1>Ejemplo de programaci√n</h1></body>");
Programación de CGIs
• printf("</html>"); • return 0; • }
• Nótese que se debe de indicar el encabezado de HTTP Content-Type para indicarle al navegador Web que la salida generada por el servidor la interprete como HTML.
Programación de CGI
• /*Ejemplo de paso de parámetros*/#include <stdio.h> • #include <stdlib.h> • int main(){ • printf("Content-Type: text/html\n\n"); printf("Documento antecesor: %s\n", getenv("HTTP_REFERER")); printf("Navegador: %s\n", getenv("HTTP_USER_AGENT")); printf("Sistema Operativo: %s", getenv("HTTP_USER_OS"));
Programación de CGIs
• printf("Host remote: getenv("REMOTE_HOST")); printf("Dirección Remota: getenv("REMOTE_ADDR")); • return 0; • }
%s", %s",
• Las variables de entorno se obtienen con la función getenv().
Programación de CGIs
• /*Ejemplo de paso de parámetros*/#include <stdio.h> • #include <stdlib.h> • #include <string.h> • int main(){ • char variable[100]; • printf("Content-Type: text/html\n\n"); • strcpy(variable, getenv("QUERY_STRING")); printf("Variables recibidas por el método GET= %s", variable);
Programación de CGIs
• return 0; • }
• La variable de entorno QUERY_STRING tiene todas las variables pasadas por u formulario por el método get. En dicho método las variables forman parte de la URL: http://sitio.com/cgi-bin/variables.cgi? var1=valor&var2=xy
Programación de CGIs
• Realizar una descomposición de la cadena anterior para tener en variables distintas el valor de cada una de ellas. • EXTRA: realizar un programa que permite convertir cualquier recurso en una URL válida. Por ejemplo en las URL no hay espacios en blanco, ni acentos ni signos de puntuación especiales.
Programación de CGIs
#include <stdio.h> #include <stdlib.h> #define MAX 80 int main(void){ char *longcad; char entrada[MAX+1]; long longitud; printf("ContentType:text/html;charset=iso-8859-1\n\n"); • printf("<TITLE>Respuesta</TITLE>\n"); • • • • • • • •
Programación de CGIs
• longcad = getenv("CONTENT_LENGTH"); • if(longcad == NULL || sscanf(longcad,"%ld",&longitud)!=1 || len > MAXLEN) • printf("<P>Error en invocacion probablemente del formulario."); • else { • fgets(entrada, longitud+1, stdin); • printf("<P>Los datos por post son: <BR>%s", entrada); • } return 0;}
Programación de CGIs
• Las variables por el método POST se pasan dentro del encabezado HTTP de la petición. • Al igual que con el método get, se necesita separar el contenido de cada variable.
Programación de CGIs
• REALIZAR un programa que descomponga las variables enviadas por POST, las almacene en un archivo y verifique si ya estaban dados de alta anteriormente. • Para no quedarnos con la duda se verá un ejemplo de un CGI en Perl (lenguaje interpretado)
• • • • • • • • •
Programación de CGIs
#!/bin/sh # disable filename globbing set -f echo "Content-type: text/plain; charset=iso8859-1" echo echo CGI/1.0 test script report: echo echo argc is $#. argv is "$*". echo
Programación de CGIs
• echo SERVER_SOFTWARE $SERVER_SOFTWARE • echo SERVER_NAME = $SERVER_NAME • echo GATEWAY_INTERFACE $GATEWAY_INTERFACE • echo SERVER_PROTOCOL $SERVER_PROTOCOL • echo SERVER_PORT = $SERVER_PORT • echo REQUEST_METHOD $REQUEST_METHOD
= = = =
GTK
• GTK es una librería para el desarrollo de aplicaciones con entornos gráficos disponible para varios sistemas *X. • GTK es el motor principal del proyecto gnome, el principal escritorio en los sistemas *X libres. • Se pueden utilizar herramientas como Glade que permitan la construcción rápida de entornos gráficos.
GTK
• La implementación de los eventos se realiza aparte. • Se deben de indicar las librerías al momento de compilar. • gcc -Wall -g helloworld.c -o hello_world `gtkconfig --cflags` \ `gtk-config --libs`
GTK
• Se ha portado a diversos lenguajes de programación no sólo C, sino también hay versiones disponibles para .NET, PHP, Python entre otros. • Las nuevas versiones de Glade requieren de la herramienta gtk-builder para poderse compilar de forma adecuada, ya que el archivo resultante de la interfaz se guarda en formato XML.
NCurses
â&#x20AC;˘ Para poder mostrar aplicaciones en modo texto de forma mejorada se utiliza la biblioteca ncurses definida en los sistemas *X. /*Bosquejo de curses*/ #include <curses.h> int main(void){ initscr(); endwin(); return 0;}
NCurses
• En general se hace referencia a curses.h por que ncurses no está definida en todos los sistemas *X. • Para compilar es necesario incluir la biblioteca curses: gcc archivos.c –o salida – lcurses • /*Programa que muestra las dimensiones de una ventana de texto */
Curses
#include <curses.h> int main(void){ int x, y; initscr(); getmaxyx(stdscr, y, x); printw("Cantidad de lineas=%d\n", y); printw("Cantidad de columnas=%d\n", x); refresh(); sleep(3); endwin(); return 0;}
Curses
/*Programa que crea una nueva terminal con Ncurses */ #include <stdlib.h> #include <curses.h> int main(void){ SCREEN *ventana; if((ventana=newterm(NULL, stdout, stdin)) == NULL){ perror("Error al crear nueva terminal"); exit(EXIT_FAILURE); }
Curses
if(set_term(ventana) == NULL{ endwin(); delscreen(ventana); perror("Error al inicializar ventana"); exit(EXIT_FAILURE); } printw("Esta ventana de ncurses ha sido creada con newterm\n"); refresh(); sleep(3);
• • • • • •
Curses
printw("Terminar ahora la ventana\n"); refresh(); sleep(3); endwin(); delscreen(ventana); exit(0);}
• Las ventanas de ncurses predetermina se desaparecen.
de
manera
Ncurses
/* Funciones de ncurses para la salida de caracteres */ #include <stdlib.h> #include <curses.h> #include <errno.h> int main(void){ SCREEN *ventana; if((ventana=newterm(NULL, stdout, stdin)) == NULL){ perror("Error al crear nueva terminal");
Ncurses
if(set_term(ventana) == NULL){ endwin(); delscreen(ventana); perror("Error al inicializar ventana"); exit(EXIT_FAILURE); } addch('X'); addch('Y' | A_REVERSE); mvaddch(2, 1, 'Z' | A_BOLD); refresh();
NCurses
sleep(3); clear(); waddch(stdscr, 'X'); waddch(stdscr, 'Y' | A_REVERSE); mvwaddch(stdscr, 2, 1, 'Z' | A_BOLD); refresh(); sleep(3); endwin(); delscreen(ventana); return 0;}
NCurses
/* Funciones de cadenas en Ncurses */ #include <stdlib.h> #include <curses.h> #include <errno.h> int main(void){ int xmax, ymax; WINDOW *ventana_temp; SCREEN *ventana; if((ventana=newterm(NULL, stdout, stdin)) == NULL){
NCurses
perror("Error al crear nueva terminal"); exit(EXIT_FAILURE); } if(set_term(ventana) == NULL){ endwin(); delscreen(ventana); perror("Error al inicializar ventana"); exit(EXIT_FAILURE); } getmaxyx(stdscr, ymax, xmax); addstr("Ejemplo de cadena agregada\n"); hline(ACS_HLINE, xmax);
NCurses
mvaddstr(3, 0, "Esta cadena aparecerรก completa\n"); mvaddnstr(5, 0, "Esta cadena aparecera truncada\n", 20); refresh(); sleep(3); if((ventana_temp = newwin(0, 0, 0, 0)) == NULL){ perror("Error al crear la subventana"); exit(1); }
NCurses
• mvwaddstr(ventana_temp, 1, 1, "Este mensaje aparece en una subventana"); • /*worded(ventana_temp, 0, 0, 0, 0, 0, 0, 0, 0);*/ • touchwin(ventana_temp); • wrefresh(ventana_temp); • sleep(3); • delwin(ventana_temp); • endwin(); • delscreen(ventana); return 0;}
NCurses
/*Ejemplo de trazado de lĂneas y cuadros */ #include <stdlib.h> #include <curses.h> #include <errno.h> int main(){ int ymax, xmax; SCREEN *ventana; if((ventana=newterm(NULL, stdout, stdin)) == NULL){
• • • • • • • • • •
NCurses
perror("Error al crear nueva terminal"); exit(EXIT_FAILURE); } if(set_term(ventana) == NULL){ endwin(); delscreen(ventana); perror("Error al inicializar ventana"); exit(EXIT_FAILURE); } getmaxyx(stdscr, ymax, xmax); mvaddch(0, 0, ACS_ULCORNER); hline(ACS_HLINE, xmax -2);
NCurses
mvaddch(ymax-1, 0, ACS_LLCORNER); hline(ACS_HLINE, xmax-2); mvaddch(0, xmax-1, ACS_URCORNER); vline(ACS_VLINE, ymax -2); mvvline(1, xmax -1, ACS_VLINE, ymax-2); mvaddch(ymax-1, xmax-1, ACS_LRCORNER); mvprintw(ymax / 3 -1, (xmax -30) /2, "Borde manual"); refresh(); sleep(3);
NCurses
clear(); box(stdscr, ACS_VLINE, ACS_HLINE); mvprintw(ymax / 3 -1, (xmax -30) /2, "Borde con box"); refresh(); sleep(3); clear();
NCurses
wborder(stdscr, ACS_VLINE | A_BOLD, ACS_VLINE | A_BOLD, ACS_HLINE | A_BOLD, ACS_HLINE | A_BOLD, ACS_ULCORNER | A_BOLD, ACS_URCORNER | A_BOLD, ACS_LLCORNER | A_BOLD, ACS_LRCORNER | A_BOLD); mvprintw(ymax / 3 -1, (xmax - 25) /2, "Borde con wborder"); refresh(); sleep(3); endwin(); delscreen(ventana); return 0;}
NCurses
• wborder(stdscr, ACS_VLINE | A_BOLD, ACS_VLINE | A_BOLD, ACS_HLINE | A_BOLD, ACS_HLINE | A_BOLD, ACS_ULCORNER | A_BOLD, ACS_URCORNER | A_BOLD, ACS_LLCORNER | A_BOLD, ACS_LRCORNER | A_BOLD); mvprintw(ymax / 3 -1, (xmax - 25) /2, "Borde con wborder"); refresh(); sleep(3); endwin(); delscreen(ventana); return 0;}
NCurses
/* Ingreso de Caracteres en Ncurses */ #include <stdlib.h> #include <curses.h> #include <errno.h> int main(void){ int c, i = 0, xmax, ymax; char cadena[80]; WINDOW *puntero_ventana; SCREEN *ventana;
NCurses
if((ventana=newterm(NULL, stdout, stdin)) == NULL){ perror("Error al crear nueva terminal"); exit(EXIT_FAILURE); } if(set_term(ventana) == NULL){ endwin(); delscreen(ventana); perror("Error al inicializar ventana"); exit(EXIT_FAILURE); } crmode();
NCurses
getmaxyx(stdscr, ymax, xmax); if((puntero_ventana=subwin(stdscr, 3, 40, ymax / 3, (xmax -40) /2)) == NULL){ perror("Error al crear la subventana"); exit(-1); } box(puntero_ventana, ACS_VLINE, ACS_HLINE); mvwaddstr(puntero_ventana, 1, 1, "Contrase単a: "); noecho();
NCurses
cadena[i++]=c; waddch(puntero_ventana, '*'); wrefresh(puntero_ventana); } echo(); cadena[i]= '\0'; wrefresh(puntero_ventana); mvwprintw(puntero_ventana, 1, 1, "Se introdujo: %s\n", cadena); box(puntero_ventana, ACS_VLINE, ACS_HLINE);
NCurses
wrefresh(puntero_ventana); sleep(3); endwin(); delscreen(ventana); return 0;
NCurses
/* Funciones para el ingreso de cadenas en Ncurses */ #include <stdlib.h> #include <curses.h> #include <errno.h> #include <string.h> #define TAM 20 int main(int argc, char *argv[]){ int c, i=0; char cadena[TAM];
NCurses
SCREEN *ventana; if((ventana=newterm(NULL, stdout, stdin)) == NULL){ perror("Error al crear nueva terminal"); exit(EXIT_FAILURE); } if(set_term(ventana) == NULL){ endwin(); delscreen(ventana); perror("Error al inicializar ventana"); exit(EXIT_FAILURE); }
NCurses
crmode(); printw("Introduce tu nombre?"); refresh(); getnstr(cadena, TAM); printw("Tu nombre es: %s\n", cadena); refresh(); sleep(3); endwin(); delscreen(ventana); return 0;}
Lenguajes Interpretados • Un lenguaje interpretado es aquel que permite ejecutarse línea por línea. Generalmente se hace a través de un software que permita realizar múltiples acciones. • Ejemplos de lenguajes interpretados son HTML, Visual Basic ScriptHost, las macros de Office, los lenguajes de configuración, los archivos por lotes entre muchas
Programación del Shell en Unix • Este es un ejemplo de lenguaje interpretado, en el cual se pueden utilizar todos los comandos del sistema y llamar a una aplicación. • Se pueden meter más de un comando en la shell en la misma línea si se separan por medio de “;”. Por ejemplo: $ cls; ls • Borrará y listará el directorio actual.
Programación del Shell en Unix • Los programas del shell se escriben en editores de texto plano como vi y emacs. • Se ejecutan con el comando sh (bash o como se llame el shell utilizado), seguido del nombre del archivo del script. O bien, se pueden ejecutar firmándolos con la instrucción: • #!/bin/sh
Programación del Shell en Unix • Los comentarios inician con el carácter # • Los scripts de la shell se utilizan para arrancar demonios, inicializar servicios, administrar aplicaciones, etc. • Se utilizan algunas variables especiales en el sistema como: • $1 - $9 parámetros
Programación del Shell • $0 nombre del comando actual • $# número de parámetros $? status del último comando ejecutado dado como un string decimal. $$ el número de proceso de este shell $! el pid del último comando ejecutado en background.
Programación del Shell en Unix • $- las opciones actuales suministradas para esta invocación del shell. • • $* $@@ un string que contiene todos los argumentos del shell comenzando por el $1. • Para imprimir variables y mensajes se utiliza echo • El operador test [] sirve para evaluar expresiones lógicas, las cuales utilizan los caracteres: &&, ||, para la and y or respectivamente.
Programación del Shell en Linux • En la shell se utilizan algunos caracteres especiales como: – ‘’ Literal simple – `` Sustituir valor de la variable
– “” Sustituir por lo que haya en las comillas
• Se utilizan otras instrucciones como Shift para avanzar parámetros. • Para leer datos se utiliza la instrucción read.
Programación del Shell en Linux • El operador argumentos • • • • • • • •
test
tiene
los
-d directorio -e archivo sin importar el tipo -f archivo normal -r leer archivo -s tamaño mayor que 0 -w escribir archivo -x archivo ejecutable -eq iguales
siguientes
Programación del Shell en Linux • • • • • • • • •
-gt mayor -ge mayor o igual -lt menor -le menor o igual = cadenas idénticas != cadenas no son idénticas < menor > mayor -n longitud de la cadena de texto es distinta de cero
Programación del Shell en Linux • ! Negación • -a and • -o or • Se puede declarar funciones de la forma: • _nombre_funcion_ { _lista_de_ordenes_ }
()
Programación del Shell en Linux • La estructura de decisión tiene el siguiente formato: • • • • • •
if ....; then .... elif ....; then .... else .... fi
Programación del Shell en Linux • [ -f "/etc/shadow" ] && echo "Este ordenador usa shadow passwors" • Estas líneas de código revisan si existe el archivo /etc/shadow y si existe muestran un mensaje de confirmación. • Nótese que los paréntesis van separados por un espacio en blanco. El lenguaje es muy sensible a ciertos caracteres.
Programación del Shell en Linux • La estructuras de decisión múltiple pueden ser de la forma: case ... in ...) hacer algo aquí;; esac • Generalmente las variables tienen asociados el símbolo de $.
Programaciรณn del Shell en Linux โ ข Las estructuras de repeticiรณn tienen los siguientes formatos: while ...; do .... done for var in ....; do .... done
Programación del Shell en Linux • El operador ; se utiliza en algunas instrucciones para indicar que su uso aun continua en la siguiente línea. • A continuación se presentan algunos ejemplos de programas hechos en la shell.
Programación del Shell en Linux #!/bin/sh #Programa que verifica el tipo de shell if [ "$SHELL" = "/bin/bash” ]; then echo "tu shell es el bash (bourne again shell)“ else echo "tu shell no es bash sino $SHELL" fi
Programaci贸n del Shell en Linux #!/bin/sh test -x /home/www/bin/httpd || exit 0 case "$1" in #cu谩l fue el par谩metro de invocaci贸n start) echo -n "Iniciando servidor http" start-stop-daemon --start --quiet --pidfile /var/run/httpd.pid \ --exec /home/www/bin/httpd echo "." ;; stop) echo -n "Deteniendo servidor httpd" start-stop-daemon --stop --quiet --pidfile /var/run/httpd.pid echo "." ;;
Programaci贸n del Shell en Linux restart) /etc/init.d/httpd stop sleep 2 /etc/init.d/httpd start echo "." ;; *) echo "Uso: /etc/init.d/httpd {start|stop|restart}" exit 1 esac exit 0
Programaci贸n del Shell en Linux #!/bin/sh #Shell que crea un usuario pasando el nombre como par谩metro asi como su directorio public html if [ $# -eq 1 ] then #creamos el nuevo usuario useradd $1 mkdir /home/$1 cd /home/$1 mkdir public_html else echo "!Sintaxis incorrecta!. nombre_usuario" fi
Uso
correcto:
$0
Programaciรณn del Shell de Linux โ ข Realizar un script que permita determinar cuantos compiladores existen en el sistema e indicarle al usuario que tan geek es en computaciรณn. Por ejemplo se definen lenguajes como c, python, perl, pascal, ada y se buscan dichos archivos en el sistema. Se contabiliza el total, se saca una proporciรณn, si se tienen 5 de 7 elementos por ejemplo: indicar que se es buen programador, 1/7 novato, etc.
Programación del Shell en Linux • Uno de los ataques más comunes consiste en suplantar los comandos y programas más utilizados de la ruta de path de tal forma que se ejecuten antes de tiempo. Realizar un programa que permita buscar archivos replicados en el sistema operativo e indicar su ruta. • Si el usuario introduce algo como $buscar python debe encontrar todos los archivos que se llamen python en el sistema.
多Preguntas, dudas y comentarios?