#include "mhshmkern.h" #include "mhshmnetwork.h" long id; char *servhost; int servport; unsigned char *shared_page; int running; int lport; void newmod (void); void sighandler (int sig) { switch (sig) { case SIGHUP: /* le noyau nous informe de quelquechose */ fprintf (stderr, " SIGHUP \n"); newmod (); break; case SIGINT: case SIGTERM: running = 0; break; default: fprintf (stderr, "Recu signal %d\n", sig); } } void newmod (void) { unsigned long i, j; struct mhshm_net_packet packet; struct mhshm_net_mod *modnet = &packet.data.moddata; struct mhshm_kern_mod modker; packet.type = SENDMOD; packet.port = lport; modnet->nb_mod = 0; mhshm_getmod (id, &modker); /* if (!modker.nb_users) { running = 0; return; } */ i = 0; j = 0; while (1) { if (j >= MHSHM_NBMODS_KERN) { j = 0; mhshm_getmod (id, &modker); } if (j >= modker.nb_mod) { if (modnet->nb_mod) send_packet (servhost, servport, &packet); break; } if (i > MHSHM_NBMODS_NET) { i = 0; send_packet (servhost, servport, &packet); } modnet->nb_mod = i + 1; modnet->mod[i].offset = modker.offset[j]; modnet->mod[i].data = shared_page[modker.offset[j]]; i++; j++; } } void daemon_noserv (void) { fprintf (stderr, "\nLe serveur est mort !!!!\n\n"); running = 0; } void daemon_newpage (unsigned char *page) { static int initialized = 0; if (initialized) fprintf (stderr, "Erreur: reinitialisation de la page\n"); initialized = 1; memcpy (shared_page, page, 4096); } void daemon_newmod (struct mhshm_net_mod *mod) { unsigned i; for (i=0 ; inb_mod ; i++) { shared_page[mod->mod[i].offset] = mod->mod[i].data; } } void server (int listened_socket) { struct mhshm_net_packet packet; struct sockaddr_in sa; int salen; int sock_in; packet.type = NEWDAEMON; packet.port = lport; if (send_packet (servhost, servport, &packet)) return; running = 1; for (;;) { /* on attend une connection entrante */ /* evite d'utiliser le processeur a 100% */ usleep (10000); salen = sizeof (sa); sock_in = accept (listened_socket, (struct sockaddr *)&sa, &salen); if ((sock_in == -1) && (errno == EAGAIN) && running) continue; printf ("\n"); if (!running) break; if (sock_in == -1) { fprintf (stderr, "Error: accept: %s\n", strerror (errno)); usleep (100000); continue; } if (strcmp (inet_ntoa (sa.sin_addr), servhost)) { fprintf (stderr, "Error: recu paquet de %s qui n'est pas le serveur %s\n", inet_ntoa (sa.sin_addr), servhost); continue; } printf ("Connection de %s\n", servhost); if (read_packet (sock_in, &packet)) { fprintf (stderr, "Erreur a la réception du paquet - paquet ignoré\n"); continue; } switch (packet.type) { case DISPMOD: daemon_newmod (&packet.data.moddata); break; case INITPAGE: daemon_newpage (packet.data.page); break; case SERVQUIT: daemon_noserv (); break; case ERROR: fprintf (stderr, "Erreur du serveur\n"); break; default: fprintf (stderr, "Error: recu paquet de type %d (%s)\n", (int)packet.type, pkt2str(packet.type)); } } packet.type = DIEDAEMON; packet.port = lport; send_packet (servhost, servport, &packet); } char *inithost (char *hostname) { struct hostent *phe; char *ret; struct in_addr ia; if (!(phe = gethostbyname (hostname))) { fprintf (stderr, "Error: gethostbyname: %s\n", hstrerror (h_errno)); exit (1); } memcpy (&ia, phe->h_addr_list[0], sizeof (ia)); ret = strdup (inet_ntoa (ia)); if (!ret) { fprintf (stderr, "Error: malloc: %s\n", strerror (errno)); exit (1); } return ret; } int main (int argc, char **argv) { int listened_sock; if (argc < 5) { fprintf (stderr, "Usage : %s \n", argv[0]); exit (1); } id = atol (argv[1]); lport = atol (argv[2]); servhost = inithost (argv[3]); /* nom->ip */ servport = atoi (argv[4]); if (mhshm_create (id, &shared_page) == -1) { fprintf (stderr, "Erreur: mhshm_create: %s\n", strerror (errno)); exit (1); } listened_sock = listen_socket (lport); signal (SIGINT, sighandler); signal (SIGTERM, sighandler); signal (SIGHUP, sighandler); fprintf (stderr, "Daemon for page %lu up on port %d, server is %s:%d\n", id, lport, servhost, servport); server (listened_sock); shutdown (listened_sock, SHUT_RDWR); close (listened_sock); mhshm_detach (shared_page); return 0; }