/****************************************************************
*
* Program fortuned
- * Fortune server - Using Messag queues
+ * Fortune server - Using Message Queues
*
* Author: Simone Piccardi
* Aug. 2002
*
* Usage: fortuned -h give all info
*
- * $Id: MQFortuneServer.c,v 1.1 2002/08/26 21:11:49 piccardi Exp $
- *
****************************************************************/
/*
* Include needed headers
*/
-#include <sys/types.h> /* predefined types */
-#include <sys/stat.h> /* */
-#include <unistd.h> /* include unix standard library */
-#include <stdio.h> /* include standard I/O library */
-#include <stdlib.h> /* standard library */
-#include <string.h> /* ANSI C standard string */
-#include <errno.h> /* errorstring */
-#include <signal.h> /* signals */
-#include <fcntl.h> /* */
+#include <sys/types.h> /* primitive system data types */
+#include <sys/stat.h> /* file characteristics constants and functions */
+#include <unistd.h> /* unix standard library */
+#include <stdio.h> /* standard I/O library */
+#include <stdlib.h> /* C standard library */
+#include <string.h> /* C strings library */
+#include <errno.h> /* error definitions and routines */
+#include <signal.h> /* signal constants, types and functions */
+#include <sys/ipc.h> /* SysV IPC functions */
+#include <sys/msg.h> /* SysV message queues */
#include "macros.h"
-#include "wrappers.h"
+#include "Gapil.h"
+
+/* Maximum message size */
+#define MSGMAX 8192
/* Subroutines declaration */
void usage(void);
void HandSIGTERM(int signo);
int FortuneParse(char *file, char **fortune, int n);
-/* name of well known fifo */
+int msgid; /* Message queue identifier */
int main(int argc, char *argv[])
{
/* Variables definition */
int i, n = 0;
- char **fortune;
- struct msgbuf_read {
- long mtype; /* message type, must be > 0 */
- int pid; /* message data */
+ char **fortune; /* array of fortune message string */
+ char *fortunefilename = "/usr/share/games/fortunes/linux"; /* file name */
+ struct msgbuf_read { /* message struct to read request from clients */
+ long mtype; /* message type, must be 1 */
+ long pid; /* message data, must be the pid of the client */
} msg_read;
- struct msgbuf_write {
- long mtype; /* message type, must be > 0 */
- char mtext[MSGMAX]; /* message data */
+ struct msgbuf_write { /* message struct to write result to clients */
+ long mtype; /* message type, will be the pid of the client*/
+ char mtext[MSGMAX]; /* message data, will be the fortune */
} msg_write;
- int msgid;
- key_t key;
- int size;
+ key_t key; /* Message queue key */
+ int size; /* message size */
/*
* Input section: decode parameters passed in the calling
* Use getopt function
/*
* Handling options
*/
- case 'h':
- printf("Wrong -h option use\n");
+ case 'h': /* print usage infos */
usage();
return(0);
break;
- case 'f':
+ case 'f': /* set fortune file name */
fortunefilename = optarg;
break;
- case 'n':
+ case 'n': /* set number of fortune string to use */
n = strtol(optarg, NULL, 10);
fortune = (char **) calloc(sizeof(*fortune), n);
break;
case '?': /* unrecognized options */
- printf("Unrecognized options -%c\n",optopt);
+ printf("Unrecognized options -%c\n", optopt);
usage();
default: /* should not reached */
usage();
* Comunication section
*/
key = ftok("./MQFortuneServer.c", 1);
- msgid = msgget(key, IPC_CREAT|666);
-
+ msgid = msgget(key, IPC_CREAT|0666);
+ if (msgid < 0) {
+ perror("Cannot create message queue");
+ exit(1);
+ }
+
/* Main body: loop over requests */
+ daemon(0, 0);
while (1) {
- msgrcv(msgid, &msg_read, 1, sizeof(int), MSG_NOERROR);
+ msgrcv(msgid, &msg_read, sizeof(int), 1, MSG_NOERROR);
+ debug("received request from %d\n", msg_read.pid);
n = random() % i; /* select random value */
- strncpy(msgbuf_write.mtext, fortune[n], MSGMAX);
+ strncpy(msg_write.mtext, fortune[n], MSGMAX);
size = min(strlen(fortune[n])+1, MSGMAX);
- msgsnd(msgid, &msg_write, size, 0);
+ msg_write.mtype=msg_read.pid; /* use request pid as type */
+ msgsnd(msgid, &msg_write, size, 0);
}
debug("Exiting for unknown reasons\n");
}
printf(" fortuned [-h] [-f] -n XXX \n");
printf(" -h print this help\n");
printf(" -f filename set file for fortunes\n");
- printf(" -n XXX set pool depth\n");
+ printf(" -n NNN set pool depth\n");
exit(1);
}
/*
*/
void HandSIGTERM(int signo) {
debug("Terminated by %s\n", strsignal(signo));
- unlink(fifoname);
+ msgctl(msgid, IPC_RMID, NULL); /* remove message queue */
exit(0);
}