]> git.somenet.org - pub/jan/sysprog.git/blob - gluefile/gluefile.c
all the old sysprog files
[pub/jan/sysprog.git] / gluefile / gluefile.c
1 /**************
2 * Name:         gluefile.c
3 * Author:       Jan Vales (e0726236@student.tuwien.ac.at)
4 * Date:         9.11.2009
5 * Purpose:      Server. Merges received file-stubs\r
6 * Usage:        gluefile -s <size> <filename>\r
7 * Output:       debuginfo only\r
8 **************/\r
9
10 #define _SVID_SOURCE\r
11 #define _XOPEN_SOURCE 600
12 \r
13 #include <stdio.h>\r
14 #include <errno.h>\r
15 #include <stdlib.h>\r
16 #include <signal.h>\r
17 #include <assert.h>\r
18 #include <getopt.h>\r
19 \r
20 #include <sys/types.h>\r
21 #include <sys/ipc.h>\r
22 #include <sys/msg.h>\r
23 \r
24 \r
25 #include "aufgb.h" \r
26 \r
27 const char *szCommand = "<not yet set>";        /* cmd name */
28 volatile static int nQueueID = -1;              /* message queue ID */
29 \r
30 /* prints a usage message to stderr */\r
31 void usage( void )  {\r
32   (void) fprintf(stderr, "USAGE: %s -s <filesize> <filename>\n", szCommand);\r
33 }
34
35 /* forward declaration */\r
36 void errorHalt(char *msg);\r
37 \r
38 /* close queue if open */\r
39 void cleanup(){
40   (void)fprintf(stderr, "CLEANUP\n");\r
41   if(nQueueID == -1)return;\r
42   if(msgctl(nQueueID, IPC_RMID, (void*) 0) == -1){\r
43     nQueueID = -1;\r
44     errorHalt("Cannot remove message queue!");\r
45   }\r
46   nQueueID = -1;\r
47 }\r
48
49
50 /* prints error messages if an error has occoured */\r
51 void errorHalt(char* msg){
52   if(errno != 0)(void)fprintf(stderr, "%s: %s = %s\n", szCommand, msg, strerror(errno));\r
53   else (void)fprintf(stderr, "%s: %s\n", szCommand, msg);\r
54   cleanup();\r
55   exit(EXIT_FAILURE);\r
56\r
57
58 /* handles signals */\r
59 void Handler( int nSignal )  {\r
60   cleanup();\r
61   exit(EXIT_SUCCESS);\r
62 }
63 \r
64 /* main program; sends messages via msg-queue to the "server" */\r
65 int main( int argc, char **argv )  {
66   FILE *fp;
67   message_t msg;
68   int filesize;
69   char *filename;
70   char c;
71   int len;
72   szCommand = argv[0];
73
74
75   while((c = getopt(argc, argv, "s:")) != EOF){\r
76     switch(c){\r
77       case 's':filesize = strtol(optarg, 0, 0); 
78         if(filesize < 1)errorHalt("Could not determine filesize or filesize 0 or negative!");
79         break;\r
80       case '?': usage(); return 0;
81       default:assert(0); break;\r
82     }
83   }
84   filename = argv[optind];
85   if(!filename)errorHalt("Filename not given!");
86
87   (void) signal(SIGINT, Handler);\r
88   (void) signal(SIGTERM, Handler);\r
89   (void) signal(SIGQUIT, Handler);
90
91   if((nQueueID = msgget( KEY, PERM | IPC_CREAT )) == -1 )errorHalt("Cannot create/access message queue!");
92   if((fp = fopen(filename,"w")) == NULL)errorHalt("ERROR while opening file");
93
94   char fdata[filesize];
95   int offset = 0;  
96   /* receive file-stubs and merge them*/
97   for(; offset < filesize;){
98     (void)fprintf( stderr, "\nwaiting: fsize:%d curr.written:%d\n", filesize, offset);
99     if(msgrcv(nQueueID, &msg, (sizeof(msg)-sizeof(long)), -(offset+1), 0) == -1)errorHalt("Cannot read from message queue!");
100
101     /* get valid datalength */
102     len = 0;
103     for(;len < sizeof(msg.mData)+1;len++){
104       if(msg.mData[len] == 0)break;
105     }
106     (void)fprintf(stderr, "got msg: datalength:%d offset:%ld\n",  len, msg.mType-1);
107
108     /* store new data */
109     if((msg.mType-1 + len) > filesize){fprintf(stderr, "**filesize exceeded -> discard**\n"); continue;}
110     (void)memcpy(fdata+(msg.mType-1), msg.mData, len);
111     if((msg.mType-1 + len) > offset)offset = (msg.mType-1 + len);
112   }
113
114   offset = 0;
115   /* write data to file*/
116   for(; offset < filesize;){
117     if(!fputc(fdata[offset++],fp))fprintf( stderr, "Cannot write to file!\n");
118   }
119   if(fclose(fp))errorHalt("Cannot close file!");
120   cleanup();
121   return 0;\r
122 }
123