Download | Plain Text | No Line Numbers
- /*
- * Name: gluefile (server(
- * Author: Manuel Mausz, 0728348
- * Description: Server writes data read from client via IPC message queue to
- * file. If filesize is reached server quits automatically. Client
- * sends data read from file via IPC message queue to server
- * Offset specifies file offset to start writing for server.
- * Created: 12.03.2009
- * Exercise: 1h B
- */
-
- #include <unistd.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <errno.h>
- #include <limits.h>
- #include "global.h"
-
- /*
- * NAME: sighandler
- * PURPOSE:
- * signal handler sets global error flag to 1
- *
- * PARAMETERS:
- * int signum ... signal number
- *
- * RETURN VALUE:
- * void
- *
- * GLOBAL VARS:
- * error
- */
- static void sighandler(int signum)
- {
- #ifdef DEBUG
- #endif
- error = 1;
- }
-
- /*
- * NAME: usage
- * PURPOSE:
- * prints program usage to stderr and terminates with EXIT_FAILURE
- *
- * PARAMETERS:
- * void
- *
- * RETURN VALUE:
- * void
- *
- * GLOBAL VARS:
- * me
- */
- static void usage(void)
- {
- }
-
- /*
- * NAME: recv_write
- * PURPOSE:
- * writes data read from client via IPC msg queue to stream pointed to by fp.
- * maxsize specifies maximum filesize (data to write). function returns after
- * maxsize is reached or on error.
- *
- * PARAMETERS:
- * int msgqid ... msg queue id to read from
- * FILE *fp ... pointer to stream to write to
- * long maxsize ... maximum file size
- *
- * RETURN VALUE:
- * void
- *
- * GLOBAL VARS:
- * error
- */
- static void recv_write(int msgqid, FILE *fp, long maxsize)
- {
- long pos = 0, maxpos = 0;
- msg_t msg;
-
- while(!error)
- {
- /* receive message */
- msg.mtype = (maxpos + 1) * -1;
- #ifdef DEBUG
- #endif
- if (!error && msgrcv(msgqid, &msg, MSGSIZE, msg.mtype, 0) == -1)
- {
- (void) printferr("Couldn't receive message");
- break;
- }
-
- #ifdef DEBUG
- #endif
- msg.mtype--;
-
- /* ignore messages to big */
- if (!error && msg.mtype + msg.len > maxsize)
- {
- #ifdef DEBUG
- #endif
- continue;
- }
-
- /* seek to requested position */
- if (!error && pos != msg.mtype)
- {
- #ifdef DEBUG
- #endif
- {
- (void) printferr("Unable to seek to requested position");
- break;
- }
- pos = msg.mtype;
- }
-
- /* write to file */
- {
- (void) printferr("Unable to write data to file");
- break;
- }
-
- /* update file current position */
- pos += msg.len;
- if (pos > maxpos)
- maxpos = pos;
-
- /* filesize reached */
- if (!error && pos == maxsize)
- break;
- }
- }
-
- /*
- * NAME: main
- * PURPOSE:
- * install signal handler, parse commandline options,
- * create msg queue and call recv_write
- *
- * PARAMETERS:
- * standard parameters of main
- *
- * RETURN VALUE:
- * int ... 0 on success, 1 on error
- *
- * GLOBAL VARS:
- * me, error
- */
- int main(int argc, char *argv[])
- {
- int opt, msgqid = -1;
- long size = 0;
- char *endptr;
- char *filename = NULL;
- FILE *fp = NULL;
- struct sigaction new_action, old_action;
-
- /* save me */
- me = argv[0];
-
- /* install signal handler */
- new_action.sa_handler = sighandler;
- sigemptyset(&new_action.sa_mask);
- new_action.sa_flags = 0; /* to avoid restart of blocking syscalls */
- INSTALL_SIGNAL(SIGINT, new_action, old_action)
- INSTALL_SIGNAL(SIGQUIT, new_action, old_action)
- INSTALL_SIGNAL(SIGTERM, new_action, old_action)
-
- /* parse cmdline options */
- while ((opt = getopt(argc, argv, "s:")) != -1)
- {
- switch(opt)
- {
- case 's':
-
- if ((errno == ERANGE && (size == LONG_MAX || size == LONG_MIN))
- || (errno != 0 && size == 0))
- (void) bailout("Invalid size value");
-
- if (*endptr != '\0' || size <= 0)
- (void) bailout("Invalid size value. Only positive numbers allowed.");
-
- break;
- default:
- (void) usage();
- break;
- }
- }
- argv += optind;
-
- /* parse next commandline option */
- if (argv)
- filename = *argv;
-
- /* check required option value */
- if (size <= 0 || filename == NULL)
- (void) usage();
-
- #ifdef DEBUG
- #endif
-
- /* open file to write to */
- (void) bailout("%s", filename);
-
- /* get message queue id */
- if (!error && (msgqid = msgget(IPC_KEY, IPC_PERMS|IPC_CREAT)) == -1)
- (void) printferr("Couldn't create message queue");
- #ifdef DEBUG
- if (msgqid != -1)
- #endif
-
- /* receive and write data */
- if (!error)
- (void) recv_write(msgqid, fp, size);
-
- /* cleanup stuff */
- #ifdef DEBUG
- #endif
-
- /* remove message queue */
- if (msgqid != -1 && msgctl(msgqid, IPC_RMID, NULL) == -1)
- (void) printferr("Unable to remove message queue");
-
- /* close open fds */
- if (fp != NULL)
-
- return (error) ? 1 : 0;
- }
-
- /* vim: set et sw=2 ts=2: */
-