📄 limond.cpp
字号:
/* LiMon-Server| Copyright (C) 2006 Marcelo Busico|| Author: Marcelo Busico marcelobusico@gmail.com|| This program is free software which I release under the GNU General Public| License. You may redistribute and/or modify this program under the terms| of that license as published by the Free Software Foundation; either| version 2 of the License, or (at your option) any later version.|| This program is distributed in the hope that it will be useful,| but WITHOUT ANY WARRANTY; without even the implied warranty of| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the| GNU General Public License for more details. Version 2 is in the| LICENSE.txt file in the top level directory of this distribution.| | To get a copy of the GNU General Puplic License, write to the Free Software| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/#include <sys/socket.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/un.h>#include <netinet/in.h>#include <arpa/inet.h>#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <syslog.h>#include <signal.h>#include <errno.h>#include <fcntl.h>#include "monitor.h"#include "pass.h"// Funcion Mainint main(int argc, char *argv[]){ int continuar=1; int debug=0; //Marca para entrar en modo DEBUG pid_t pid, sid; sigset_t conjunto_sig, conjunto_pendientes; struct sigaction accion; int sockfd; struct sockaddr_in srv; socklen_t socklen; char password[64]; char archivo_password[256]; int i = 1; // Espera el numero de puerto en la linea de comandos if(argc != 3 && argc !=4) { puts("USO: limond <numero de puerto> <archivo_password> [debug]"); exit(EXIT_FAILURE); } // Se fija que se pidio el modo debug if(argc==4) { if(strcmp(argv[3],"debug")==0) debug=1; else { puts("USO: limond <numero de puerto> <archivo_password> [debug]"); exit(EXIT_FAILURE); } } //Carga la contraseña y verifica que no sea nula strcpy(archivo_password,argv[2]); if(leePassword(archivo_password,password)==0) { puts("El archivo de password pasado no es valido."); puts("Debe contener una cadena no nula de longitud menor a 64 caracteres."); exit(EXIT_FAILURE); } else puts("Archivo de password leido correctamente");//Abre el registro del sistema y hace del proceso un demonio si//no esta en modo debugif(!debug){ puts("Iniciando Servidor LiMonD en segundo plano..."); // Abrir el registro del sistema openlog("LiMonD", LOG_PID, LOG_DAEMON); syslog(LOG_INFO, "%s\n", "Inicio de la actividad de LiMonD"); // Transforma al proceso en un demonio pid = fork(); if(pid < 0) { syslog(LOG_ERR, "%s\n", "Error fork"); syslog(LOG_ERR,"%s\n", "Programa Terminado"); puts("Error fork. Programa Terminado."); exit(EXIT_FAILURE); } if(pid > 0) // Salir del proceso padre exit(EXIT_SUCCESS); // Dar comienzo a una nueva sesión if((sid = setsid()) < 0) { syslog(LOG_ERR, "%s\n", "Error setsid"); syslog(LOG_ERR,"%s\n", "Programa Terminado"); puts("Error setsid. Programa Terminado."); exit(EXIT_FAILURE); } // Directorio de trabajo: Directorio Raiz "/" if((chdir("/")) < 0) { syslog(LOG_ERR, "%s\n", "Error chdir"); syslog(LOG_ERR,"%s\n", "Programa Terminado"); puts("Error chdir. Programa Terminado."); exit(EXIT_FAILURE); } // Reinicialización del modo de archivo umask(0); puts("Demonio Iniciado Correctamente."); // Cerrar stdin, stdout y stderr close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO);} //Fin no debug // Manipulacion de sigterm sigaddset(&conjunto_sig, SIGTERM); sigprocmask(SIG_BLOCK, &conjunto_sig, NULL); // Crea el socket if((sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0) { if(!debug) { syslog(LOG_ERR, "%s\n", "Error en Creación de Socket"); syslog(LOG_ERR,"%s\n", "Programa Terminado"); } else { printf("%s\n", "Error en Creación de Socket"); printf("%s\n", "Programa Terminado"); } exit(EXIT_FAILURE); } // Opcion para reusar la direccion local setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i)); // Inicializa y setea la estructura server memset(&srv, 0, sizeof(srv)); srv.sin_family = AF_INET; // El numero de puerto es pasado por parametro srv.sin_port = htons(atoi(argv[1])); // No olvidar que es en el orden de la red // Ligar el socket a la dirección socklen = sizeof(srv); if((bind(sockfd, (struct sockaddr *)&srv, socklen)) < 0) { if(!debug) { syslog(LOG_ERR, "%s\n", "Error Socket Bind"); syslog(LOG_ERR,"%s\n", "Programa Terminado"); } else { printf("%s\n", "Error Socket Bind"); printf("%s\n", "Programa Terminado"); } exit(EXIT_FAILURE); } // Espera por conexiones entrantes if((listen(sockfd, 5)) < 0) { if(!debug) { syslog(LOG_ERR, "%s\n", "Error Socket Listen"); syslog(LOG_ERR,"%s\n", "Programa Terminado"); } else { printf("%s\n", "Error Socket Listen"); printf("%s\n", "Programa Terminado"); } exit(EXIT_FAILURE); } if(!debug) { syslog(LOG_INFO, "%s\n", "TCP/IP Socket Disponible"); syslog(LOG_INFO, " Puerto %d\n", ntohs(srv.sin_port)); syslog(LOG_INFO, " Dirección %s\n", inet_ntoa(srv.sin_addr)); } else { printf("%s\n", "TCP/IP Socket Disponible"); printf("\tPuerto %d\n", ntohs(srv.sin_port)); printf("\tDirección %s\n", inet_ntoa(srv.sin_addr)); } // Bucle de repeticion del programa while(continuar) { int clientefd=0; // Acepta una nueva conexion clientefd=accept(sockfd, (struct sockaddr *)&srv, &socklen); if(!debug) { syslog(LOG_INFO, "%s\n", "Nueva Conexión Aceptada"); } else { printf("%s\n", "Nueva Conexión Aceptada"); } // Verificar si hay sigterm y terminar el programa si es cierto sigpending(&conjunto_pendientes); if(sigismember(&conjunto_pendientes, SIGTERM)) { sigemptyset(&accion.sa_mask); accion.sa_handler = SIG_IGN; sigaction(SIGTERM, &accion, NULL); continuar=0; } // Se trabaja con la conexion establecida MonitorServidor ms1(clientefd, password); ms1.monitorear(debug); } // Fin de la actividad de LiMonD if(!debug) { syslog(LOG_INFO, "%s\n", "Fin de la actividad de LiMonD"); closelog(); } else { printf("%s\n", "Fin de la actividad de LiMonD"); } sigprocmask(SIG_UNBLOCK, &conjunto_sig, NULL); exit(EXIT_SUCCESS);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -