home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The C Users' Group Library 1994 August
/
wc-cdrom-cusersgrouplibrary-1994-08.iso
/
listings
/
v_08_11
/
8n11059b
< prev
next >
Wrap
Text File
|
1990-09-26
|
5KB
|
214 lines
/* Program: usrsnd
*
* Filename: listing1.c
*
* Description: Demonstration program that uses a message
* queue to enable users to send one line messages
* to each other.
*
* Contents: main(), send_mssg(), recv_mssg(),
* get_msg_queue()
*
* Author/Programmer: W. J. Freda
* Automated Concepts Inc.
*/
#include <stdio.h>
#include <signal.h>
#include <pwd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define KEY 0x5642412
static struct mssg {
long mtype; /* Message type */
char mtext[BUFSIZ]; /* Message text */
} Msgbuf;
static int Msqid; /* Message queue identifier */
static int Firstime=1;
/* MAIN
*
* DESCRIPTION: Provides a simple menu that ties the
* send_msg() and recv_msg() functions
* together.
*
* INPUT: NONE
* OUTPUT: Program termination
*/
main()
{
char *mssg, *recv_mssg();
char selection[80];
while(1) {
printf("\n\n\t1) Send a message to a specific user\n");
printf("\t2) Receive messages\n");
printf("\t3) Exit\n");
printf("\n\t\tEnter selection: ");
gets(selection);
switch(*selection) {
case '1':
send_mssg();
break;
case '2':
if ((mssg=recv_mssg()) == NULL)
printf("\n\nNo messages on queue\n\n");
else
printf("\n\n%s\n\n",mssg);
break;
case '3':
exit(0);
default:
printf("\tInvalid selection.\n\n");
break;
}
}
}
/* SEND_MSSG FUNCTION
*
* DESCRIPTION: Prompts the user for a username and message
* and sends the message to that user via a message
* queue. The user can read the message using
* rcv_mssg().
*
* INPUT: NONE
* OUTPUT: 0 If successful
* -1 Otherwise
*/
send_mssg()
{
extern int Msqid; /* Message queue identifier */
extern struct mssg Msgbuf; /* Message structure */
extern int errno;
int msglen; /* Length of message */
char message[BUFSIZ]; /* Message text */
char username[20];
struct passwd *pass, *getpwnam();
if (Firstime) {
if ((Msqid=get_msg_queue()) == -1)
return(-1);
Firstime=0;
}
/* Prompt for user name */
printf("\n\nSend message to which user? ");
gets(username);
/* Validate username */
setpwent();
pass=getpwnam(username);
endpwent();
if (pass == NULL) {
printf("Invalid username.\n\n");
return(0);
}
/* Prompt user for a message to send */
printf("Enter message: ");
gets(Msgbuf.mtext);
if (*(Msgbuf.mtext) == NULL)
/* Nothing to send */
return(0);
/* Set the message length */
msglen=strlen(Msgbuf.mtext);
/* Set the message type equal to the userid
* we want to send the message to.
*/
Msgbuf.mtype = pass->pw_uid;
/* Send the message. The IPC_NOWAIT flag informs msgsnd()
* not to send the message if the message queue is full.
* Without the IPC_NOWAIT flag this process would be put
* to sleep by the kernel until the message can be sent.
*/
if (msgsnd(Msqid, &Msgbuf, msglen, IPC_NOWAIT) == -1) {
/* Error occurred */
return(-1);
}
return(0);
}
/* RECV_MSSG FUNCTION char *recv_mssg()
*
* DESCRIPTION: Attempts to retrieve a message from the
* message queue.
*
* INPUT: NONE
* OUTPUT: text Returns a pointer to the first
* character of the message text.
* NULL If there are no messages or an
* error occurred.
*/
char *recv_mssg()
{
extern int Msqid; /* Message queue identifier */
extern struct mssg Msgbuf; /* Message structure */
extern int Firstime;
int uid; /* User id */
int len;
if (Firstime) {
if ((Msqid=get_msg_queue()) == -1) {
return(NULL);
}
Firstime=0;
}
/* Get the user id */
uid=getuid();
/* Receive a message. The IPC_NOWAIT flag informs msgrcv()
* to return immediately if no message is on queue. Without
* the IPC_NOWAIT flag this process would be put to sleep by
* the kernel until a message of type uid is received.
*/
if ((len=msgrcv(Msqid, &Msgbuf, BUFSIZ, uid, IPC_NOWAIT)) == -1)
return(NULL);
/* Null terminate the message */
Msgbuf.mtext[len]=NULL;
return(Msgbuf.mtext);
}
/* GET_MSG_QUEUE FUNCTION
*
* DESCRIPTION: Gets and possibly creates a message
* queue identifier via the msgget(2)
* system call.
*
* INPUT: NONE
* OUTPUT: qid Message queue ID
* -1 Otherwise
*/
get_msg_queue()
{
int qid;
/* Acquire a message queue.
* The IPC_CREAT flag informs msgget() to create
* the message queue with the permission 0666.
* The IPC_CREAT flags inform msgget() to create
* the message queue if it doesn't already exist.
*/
if ((qid=msgget((key_t)KEY, 0666 | IPC_CREAT)) == -1) {
return(-1);
}
return(qid);
}