/* file: server.c * author: Robert S. Laramee * class: cs720/820 * date started: 25 Apr 98 * date "finished": 04 May 98 * project: assignment 5 * description: This process runs in the background. The server first * creates the server message Q (standard name that is * known to all clients). The server continually waits to read messages from * its server queue. Once the message is read, it is serviced and the request * is written to the specific client's message queue (name of this queue is * sent in the request). * * Compile the program using the -lrt option on Christa or Alberti * e.g. % gcc -lrt -o server server.c */ #include/* for printf(), scanf(), fopen(), perror() etc. */ #include /* for EXIT_FAILURE */ #include /* for strlen(), strncopy() */ #include /* for strerror(), errno */ #include /* for open(), lseek(), creat() */ #include /* for open(), creat() */ #include /* for open(), creat() */ #include /* for read(), write(), lseek() */ #include /* for mq_open(), mq_send(), mq_recieve etc. */ #include "message.h" /* the header file with some data strctures */ /* Process the client's request to create a file. If the creat call fails, * return suitable error message to the client. */ int server_create(REQUEST *request, RESPONSE *response) { mode_t create_mode=0; create_mode = (mode_t)request->mode_or_offset; /* The umask command sets the file mode creation mask of the current * shell execution environment to the value specified by the mask operand. * This mask affects the initial value of the file permission bits of * subsequently created files. */ umask(0); if ((creat(request->file_name, create_mode)) == -1) { perror("error creating file: "); return -1; } return 0; } /* Process the client's read request. If any system call fails, return * suitable error message to the client. */ int server_read(REQUEST *request, RESPONSE *response) { int from_fd; /* read bytes from disk */ if((from_fd = open(request->file_name, O_RDONLY)) == -1) { fprintf(stderr, "error cannot open %s: %s \n" , request->file_name, strerror(errno)); return -1;; } if (lseek(from_fd, request->mode_or_offset, SEEK_SET) != (request->mode_or_offset)) { fprintf(stderr, "error with offset in file %s: %s \n" , request->file_name, strerror(errno)); return -1; } if (read(from_fd, response->data, request->num_bytes) != request->num_bytes) { fprintf(stderr, "error reading file %s: %s \n" , request->file_name, strerror(errno)); return -1; } close(from_fd); return 0; } int main (void) { int i=0; int operation=0; /* operation MSG_CREATE = 1, MSG_READ = 2 */ int mode_or_offset=0; /* IF read THEN offset IF create THEN mode */ int priority=0; /* priority of message */ char serverQ_buffer[MAX_MSG]; /* server Q message buffer */ char clientQ_buffer[MAX_MSG]; /* client Q message buffer */ char *serverQ_name = "server_queue"; /* server Q name */ struct mq_attr attribute; /* message Q attributes */ REQUEST *request; /* pointer to client's request */ RESPONSE *response; /* pointer to server's response */ mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO; mqd_t server_descriptor; /* server message Q descripitor */ mqd_t client_descriptor; /* client message Q descripitor */ attribute.mq_maxmsg = 200; attribute.mq_msgsize = MAX_MSG; /* create server message queue */ server_descriptor = mq_open(serverQ_name, O_RDONLY|O_CREAT, mode, &attribute); if (server_descriptor == -1) { perror("Error opening server message queue: (errno) \n"); exit(EXIT_FAILURE); } /* allocate memory for a RESPONSE structure */ if ((response = (RESPONSE *)malloc(sizeof(RESPONSE))) == NULL) { perror("error allocating memory for response : (errno) \n"); } while(1) { /* receive client's message */ if(mq_receive(server_descriptor, serverQ_buffer, MAX_MSG, &priority) == 0) { perror("error receiving message from client: (errno) \n"); exit(EXIT_FAILURE); } else { /* check the request type */ request = (REQUEST *)serverQ_buffer; if (request->request_type == MSG_CREATE) { if (server_create(request, response) != 0) { response->status = UNSUCCESS; strncpy(response->data, "error creating file\n", MAX_NAME); } else { response->status = SUCCESS; strncpy(response->data, " ok \n", MAX_NAME); } /* end if(server_create()) */ } else if (request->request_type == MSG_READ) { if (server_read(request, response) != 0) { response->status = UNSUCCESS; strncpy(response->data, "no data from read()", MAX_NAME); } else { response->status = SUCCESS; } /* end if(server_read()) */ } else { fprintf(stderr, "unidentified client request type \n"); } } /* end if (mq_receive ...) */ /* open clients's message queue */ client_descriptor = mq_open(request->client_msgQ_name, O_RDWR, mode, &attribute); if (client_descriptor == -1) { perror("Error opening client message queue: (errno) \n"); exit(EXIT_FAILURE); } /* send the client the response */ if(mq_send(client_descriptor,(char*)response, MAX_MSG, priority) != 0){ perror("Error sending reply message to client: (errno) \n"); exit(EXIT_FAILURE); } free(response); /* avoid memory leaks in server */ } /* end while(1) */ }