186 lines
3.8 KiB
C
186 lines
3.8 KiB
C
/*
|
|
* Un faux daemon.
|
|
*
|
|
* Copyright (c) 1999 Association CRANS.
|
|
*
|
|
* Auteur: Olivier Saut <Olivier.Saut@crans.ens-cachan.fr>
|
|
*
|
|
*
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/wait.h>
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
#include <sys/socket.h>
|
|
#include <netinet/in.h>
|
|
#include <arpa/inet.h>
|
|
#include <unistd.h>
|
|
#include <signal.h>
|
|
|
|
#include <syslog.h>
|
|
#include <varargs.h>
|
|
#include <netdb.h>
|
|
|
|
#ifndef LINUX
|
|
#include <libutil.h>
|
|
#endif
|
|
|
|
|
|
#define kZamok_Tourne 1
|
|
#define kPORT 514 /* Port de rshd */
|
|
#define kMaxDaemonChildren 10
|
|
|
|
int nbrFils;
|
|
|
|
|
|
int daemon_init(void) {
|
|
pid_t pid;
|
|
|
|
if((pid = fork())<0)
|
|
return (-1);
|
|
else if (pid !=0) {
|
|
(void)fprintf(stdout,"beastie launched : %d\n",pid);
|
|
exit(0);
|
|
}
|
|
setsid();
|
|
chdir("/");
|
|
umask(0);
|
|
return(0);
|
|
}
|
|
|
|
/* Attention subtil (waitpid plutot que wait) :-) */
|
|
void zombie(int signo) {
|
|
pid_t pid;
|
|
int stat;
|
|
|
|
while ((pid = waitpid(-1, &stat, WNOHANG)) > 0)
|
|
nbrFils--;
|
|
|
|
return;
|
|
}
|
|
|
|
void sigterm(int signo) {
|
|
syslog(LOG_NOTICE,"beastie killed by SIGTERM.");
|
|
closelog();
|
|
exit(EXIT_SUCCESS);
|
|
}
|
|
|
|
|
|
int main(int argc, char *argv[]){
|
|
int serv_sock, client_sock, cli_len;
|
|
struct sockaddr_in serv_addr, cli_addr;
|
|
struct hostent *cli_ent;
|
|
char *clientname,*message;
|
|
int PORT;
|
|
pid_t pid;
|
|
sig_t previous_handler;
|
|
char buffer[1024];
|
|
|
|
if(argc>1)
|
|
PORT=atoi(argv[1]);
|
|
else
|
|
PORT=kPORT;
|
|
|
|
if(setuid(getuid())) {
|
|
perror("Setuid.");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* On se daemonize */
|
|
if(daemon_init()) {
|
|
perror("Initialize as daemon.");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* Pour éviter les zombies (vade retro...) */
|
|
previous_handler = signal(SIGCHLD,(sig_t)zombie);
|
|
if(previous_handler==SIG_ERR) {
|
|
perror("Installing SIGCHLD handler");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* Pour détecter le SIGTERM */
|
|
previous_handler = signal(SIGTERM,(sig_t)sigterm);
|
|
if(previous_handler==SIG_ERR) {
|
|
perror("Installing SIGTERM handler");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
nbrFils=0;
|
|
|
|
#ifndef LINUX
|
|
setproctitle("ecoute le port %d",PORT);
|
|
#endif
|
|
|
|
openlog("beastie", LOG_PID|LOG_CONS,LOG_LOCAL2);
|
|
|
|
serv_sock = socket(AF_INET, SOCK_STREAM, 0);
|
|
if (serv_sock < 0)
|
|
{
|
|
perror("Creating server socket.");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* On remplit la structure */
|
|
bzero((char *) &serv_addr, sizeof (serv_addr));
|
|
serv_addr.sin_family = AF_INET;
|
|
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
serv_addr.sin_port = htons(PORT);
|
|
|
|
/* Et on lie la socket au port */
|
|
if (bind(serv_sock, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) < 0)
|
|
{
|
|
perror("Binding server socket.");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
listen(serv_sock,5);
|
|
|
|
while(kZamok_Tourne) {
|
|
|
|
cli_len = sizeof (cli_addr);
|
|
bzero((char *) &cli_addr, sizeof (cli_addr));
|
|
|
|
client_sock = accept(serv_sock, (struct sockaddr *) &cli_addr, &cli_len);
|
|
if (client_sock < 0)
|
|
{
|
|
perror("Accepting connection on server socket.");
|
|
break;
|
|
}
|
|
|
|
/* On forke, on traite la requete dans le fils */
|
|
/* Evaluation paresseuse */
|
|
if((nbrFils++ < kMaxDaemonChildren) && ((pid=fork())==0) ) {
|
|
close(serv_sock);
|
|
clientname=inet_ntoa(cli_addr.sin_addr); /* On recupere le nom */
|
|
/* Hehe t'es loggue mon pote */
|
|
if(strcmp(clientname, "127.0.0.1")) {
|
|
if (!((cli_ent= gethostbyaddr((char *)&cli_addr.sin_addr.s_addr,
|
|
sizeof (u_long), AF_INET)) == (struct hostent *)0)) {
|
|
snprintf(buffer,1023, "Tentative de connexion de %s au port %d.",cli_ent->h_name,PORT);
|
|
syslog(LOG_NOTICE,buffer );
|
|
}
|
|
else {
|
|
snprintf(buffer,1023, "Tentative de connexion de %s au port %d.",clientname,PORT);
|
|
syslog(LOG_NOTICE,buffer);
|
|
}
|
|
}
|
|
close(client_sock);
|
|
exit(0);
|
|
}
|
|
/* Fin du fork */
|
|
|
|
close(client_sock);
|
|
|
|
}
|
|
|
|
closelog();
|
|
close(serv_sock);
|
|
exit( 0);
|
|
}
|