Messi gli esempi nel testo e usata daemon dove serve nei server
[gapil.git] / sources / FortuneServer.c
index c00b3fedf5a80ca33d6de56dbb3652bd97b8132c..8ba3a2fc65b158cd48a58d3130e37b9086cb7f02 100644 (file)
@@ -26,7 +26,7 @@
  *
  * Usage: fortuned -h give all info
  *
- * $Id: FortuneServer.c,v 1.1 2002/08/18 10:34:10 piccardi Exp $
+ * $Id: FortuneServer.c,v 1.6 2003/01/12 00:24:28 piccardi Exp $
  *
  ****************************************************************/
 /* 
 #include <stdlib.h>     /* standard library */
 #include <string.h>     /* ANSI C standard string */
 #include <errno.h>      /* errorstring */
+#include <signal.h>     /* signals */
 #include <fcntl.h>      /*  */
 
 #include "macros.h"
+#include "Gapil.h"
 
 /* Subroutines declaration */
 void usage(void);
+void HandSIGTERM(int signo);
 int FortuneParse(char *file, char **fortune, int n);
 
+/* name of well known fifo */
+char *fifoname = "/tmp/fortune.fifo";
 int main(int argc, char *argv[])
 {
 /* Variables definition */
-    int n = 0;
-    FILE *fortunefile;
-    char *fortunefilename = "/usr/share/misc/fortune/fortune.it";
-    char *fifoname = "/tmp/fortune.fifo";
+    int i, n = 0;
+    char *fortunefilename = "/usr/share/games/fortunes/linux";
     char **fortune;
     char line[80];
     int fifo_server, fifo_client;
@@ -62,8 +65,7 @@ int main(int argc, char *argv[])
      * Input section: decode parameters passed in the calling 
      * Use getopt function
      */
-    int i;
-    opterr = 0;         /* don't want writing to stderr */
+    opterr = 0;                                     /* don't want writing to stderr */
     while ( (i = getopt(argc, argv, "hn:f:")) != -1) {
        switch (i) {
        /* 
@@ -81,10 +83,10 @@ int main(int argc, char *argv[])
            n = strtol(optarg, NULL, 10);
            fortune = (char **) calloc(sizeof(*fortune), n);
            break;
-       case '?':   /* unrecognized options */
+       case '?':                                    /* unrecognized options */
            printf("Unrecognized options -%c\n",optopt);
            usage();
-       default:    /* should not reached */
+       default:                                       /* should not reached */
            usage();
        }
     }
@@ -95,36 +97,54 @@ int main(int argc, char *argv[])
      *               Main code beginning
      * 
      * ***********************************************************/
-    if (n==0) {                                   /* if no pool depth exit */
-       usage();                                       /* print usage info */
-    }
-    i = FortuneParse(fortunefilename, fortune, n);
-    for (n=0; n<i; n++) debug("%s", fortune[n]);
+    if (n==0) usage();          /* if no pool depth exit printing usage info */
+    Signal(SIGTERM, HandSIGTERM);            /* set handlers for termination */
+    Signal(SIGINT, HandSIGTERM);
+    Signal(SIGQUIT, HandSIGTERM);
+    i = FortuneParse(fortunefilename, fortune, n);          /* parse phrases */
+    for (n=0; n<i; n++) debug("%s%%\n", fortune[n]);
     /* 
      * Comunication section 
      */
-    if (mkfifo(fifoname, 0622)) {
+    if (mkfifo(fifoname, 0622)) {  /* create well known fifo if does't exist */
        if (errno!=EEXIST) {
            perror("Cannot create well known fifo");
-           exit(-1);
+           exit(1);
        }
     }
+    daemon(0, 0);
+    /* open fifo two times to avoid EOF */
+    fifo_server = open(fifoname, O_RDONLY);
+    if (fifo_server < 0) {
+       perror("Cannot open read only well known fifo");
+       exit(1);
+    }
+    if (open(fifoname, O_WRONLY) < 0) {
+       perror("Cannot open write only well known fifo");
+       exit(1);
+    }
+    /* Main body: loop over requests */
     while (1) {
-       fifo_server = open(fifoname, O_RDONLY);
-       if (fifo_server < 0) {
-           perror("Cannot open well known fifo");
-           exit(-1);
+       nread = read(fifo_server, line, 79);                 /* read request */
+       if (nread < 0) {
+           perror("Read Error");
+           exit(1);
        }
-       nread = read(fifo_server, line, 79);
-       line[nread] = 0;
+       line[nread] = 0;                       /* terminate fifo name string */
        debug("%s %d\n", line,nread);
-       n = random() % i;
+       n = random() % i;                             /* select random value */
        debug("fortune[%d]=%s\n", n, fortune[n]);
-       fifo_client = open(line, O_WRONLY);
-       nread = write(fifo_client, fortune[n], strlen(fortune[n])+1);
-       close(fifo_client);
-       close(fifo_server);
+       fifo_client = open(line, O_WRONLY);              /* open client fifo */
+       if (fifo_client < 0) {
+           debug("Client fifo is %s\n", line);
+           perror("Cannot open");
+           exit(1);
+       }
+       nread = write(fifo_client,                           /* write phrase */
+                     fortune[n], strlen(fortune[n])+1);
+       close(fifo_client);                             /* close client fifo */
     }
+    debug("Exiting for unknown reasons\n");
 }
 /*
  * routine to print usage info and exit
@@ -138,3 +158,11 @@ void usage(void) {
     printf("  -n XXX        set pool depth\n");
     exit(1);
 }
+/*
+ * Signal Handler to manage termination
+ */
+void HandSIGTERM(int signo) {
+    debug("Terminated by %s\n", strsignal(signo));
+    unlink(fifoname);
+    exit(0);
+}