root/trunk/serw2.c

Revision 389, 20.2 kB (checked in by heitor.barbieri, 3 weeks ago)

essage first commit

Line 
1/* ------------------------------ serw.c ---------------------------------- */
2
3
4/* Copyright (c) 1990 - 1994 Adalberto Otranto Tardelli. All rights reserved.
5 * Written by A.O.Tardelli 7/90
6 * Redistribution and use in source and binary forms are freely permitted
7 * provided that the above copyright notice and attribution and date of work
8 * and this paragraph are duplicated in all such forms.
9 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
10 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
11 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
12 * This program performs a MicroISIS master file dump, formatted display,
13 * search and record limits, pattern changes, data base join, field update,
14 * master file update and ISO-2709 processing. Input can also be a plain file.
15 * A description of this program is available in CISIS Interface Application -
16 * MX Program. Sao Paulo, BIREME - Latin American and Caribbean Center on
17 * Health Sciences Information/PAHO-WHO, April 1991. 12p. See also:
18 * - http://www.bireme.br (IsisFamily/CisisUtilities)
19 * - ftp://ftp.bireme.br/cisis
20 * Currently works with CISIS Interface 4.01 and BorlandC 5.02 or
21 * MSVC 6.0 for win32/console application, and for Linux/gcc, HPUX/CC and
22 * Sun/CC, among other platforms.  AOT, 21/02/2001.
23*/
24
25/*
26..Server program that makes a connection for a byte stream socket in the Internet namespace.
27*/
28/*
29*/
30
31#define P000          1                               //1
32
33#ifndef CISIS_H
34#define GEN_SERW      1
35#define GEN_MAIN      1
36#define GEN_MAINLOAD  00                              //00
37#endif
38
39#include <stdio.h>
40#include <string.h>
41#include <ctype.h>
42#include "cisis.h"      /* CISIS Interface header file */
43#include "cirun.h"      /* CISIS Interface runtime */
44
45#if GEN_MAIN
46//     #include <errno.h>
47//     #include <stdlib.h>
48#if P000 && PGCC
49     #include <unistd.h>
50#endif /* P000 */
51     #include <sys/types.h>
52#endif /*  GEN_MAIN */
53
54#if GEN_MAIN
55     #define PORT          1417
56     #define BUFFERSIZE   51200
57#endif /*  GEN_MAIN */
58
59     #define REPLYSIZE    51200
60
61
62#if P000
63     int mainserver_make_socket (int cmd, uint16_t port);
64     int mainserver_read_from_client (int cmd, uint16_t port, int filedes, char *buffer, int buffersize);
65     int mainserver_write_to_client (int cmd, uint16_t port, int filedes, char *message, int messagesize);
66     int mainserver (int cmd, WTFUN_ARRAY *awtfp, uint16_t port, char *buffer, int buffersize, int maxconnqueued);
67
68/*
69*/
70     int
71     mainserver_make_socket (int cmd, uint16_t port)
72     {
73       int sock;
74#if PGCC
75       struct sockaddr_in name;
76
77       /* Create the socket. */
78       sock = socket (PF_INET, SOCK_STREAM, 0);
79       if (sock < 0)
80         {
81           /*perror ("socket"); exit (EXIT_FAILURE);*/
82           return -1;
83         }
84
85       /* Give the socket a name. */
86       name.sin_family = AF_INET;
87       name.sin_port = htons (port);
88       name.sin_addr.s_addr = htonl (INADDR_ANY);
89       if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0)
90         {
91           /*perror ("bind"); exit (EXIT_FAILURE);*/
92           return -2;
93         }
94       return sock;
95#else
96       sock=1; return sock;
97#endif
98     }
99
100
101     int
102     mainserver_write_to_client (int cmd, uint16_t port, int filedes, char *message, int messagesize)
103     {
104       int nbytes;
105                              /* yyyymmdd hh:mm:ss WDAY YDAY */
106       char timestamp[80];    /* 123456789012345678901234 7  8 901 */
107       time_t secs_now;
108       struct tm *tp;
109       time(&secs_now); tp=localtime(&secs_now);
110       sprintf(timestamp,"%04d%02d%02d %02d%02d%02d %1d %3d", 1900+tp->tm_year,tp->tm_mon+1,tp->tm_mday, tp->tm_hour,tp->tm_min,tp->tm_sec, tp->tm_wday,tp->tm_yday);
111
112#if GEN_LOGS
113       if (cmd == 4) sprintf (logbuff, "Server [%d] [%d] [%s]: reply message (%d bytes): '%s' \n", port, filedes, timestamp, messagesize, message);
114#endif
115       if (cmd == 3) fprintf (stderr, "Server [%d] [%d] [%s]: reply message (%d bytes): '%s' \n", port, filedes, timestamp, messagesize, message);
116       if (cmd == 2) fprintf (stderr, "Server [%d] [%d] [%s]: reply message (%d bytes) \n", port, filedes, timestamp, messagesize);
117
118#if PGCC
119       nbytes = send (filedes, message, messagesize, 0);// send (int socket, void *buffer, size_t size, int flags)
120       if (nbytes < messagesize)
121         {
122           /* Write error */
123           /*perror ("write");*/
124           return -1;
125         }
126       else
127         return nbytes;
128#else
129       nbytes=1; return(nbytes);
130#endif
131     }
132
133
134     int
135     mainserver_read_from_client (int cmd, uint16_t port, int filedes, char *buffer, int buffersize)
136     {
137       int nbytes;
138
139#if PGCC
140       buffer[0]='\0';
141       nbytes = recv (filedes, buffer, buffersize-1, 0); // recv (int socket, void *buffer, size_t size, int flags)
142       if (nbytes < 0)
143         {
144           /* Read error. */
145           /*perror ("read"); exit (EXIT_FAILURE);*/
146           return -2;
147         }
148       else
149         {
150#if TRACER
151           char *p=buffer;
152           int loop=nbytes;
153           fprintf (stderr, "read(%d): ",nbytes);
154           for (; loop--; p++) fprintf (stderr, "%c=%02x ",*p,(int)*p);
155           fprintf (stderr, "\n");
156#endif
157           /* EOF (nbytes=0) or Data read. */
158           buffer[nbytes]='\0';
159           return nbytes;
160         }
161#else
162       buffer[0]='x'; buffer[1]='\0';
163       nbytes=1; return(nbytes);
164#endif
165     }
166
167
168/*
169     mainserver
170*/
171     int
172     mainserver (int cmd, WTFUN_ARRAY *awtfp, uint16_t port, char *buffer, int buffersize, int maxconnqueued)
173     {
174       int sock;
175#if PGCC
176       fd_set active_fd_set, read_fd_set;
177       struct sockaddr_in clientname;
178#endif
179       int i;
180       size_t size;
181       int shutdown=0; /* run */
182                              /* yyyymmdd hh:mm:ss WDAY YDAY */
183       char timestamp[80];    /* 123456789012345678901234 7  8 901 */
184       time_t secs_in;
185       time_t secs_now;
186       struct tm *tp;
187
188#if GEN_SERW
189       char wreply[REPLYSIZE];
190       int coll;
191#endif
192
193#if GEN_LOGS
194        RECSTRU *recp;
195        LONGX logcrec;
196        LONGX logirec;
197        char logsdb[CIMPL];
198       
199        /* log processing
200        */
201        strcpy(logsdb,"serw.log");
202               
203        if (!ndbxs) dbxinit();  /* init vdbxp/vrecp/vtrmp if not yet init - AOT, 28/10/2005 */
204               
205        /* alloc///logsdb ctl */
206        for (logcrec=maxnrec; logcrec--; ) { if (!vrecp[logcrec]) /* ja' decrementado */ break; }
207        if (logcrec<0L) fatal("wtrig2/logcrec");
208        recallok(logcrec,sizeof(M0STRU)); 
209       
210        /* alloc///logsdb */
211        for (logirec=maxnrec; logirec--; ) { if (!vrecp[logirec]) /* ja' decrementado */ break; }
212        if (logirec<0L) fatal("wtrig2/logirec");
213        recallok(logirec,MAXMFRL);  // RECsetup in w2setrt.c / w2logx.c + w2log1.c
214   
215        RECORD(logcrec,logsdb,0);
216        RECORD(logirec,logsdb,MF0nxtmfn); 
217        RECrc=RCNORMAL; MFRstatus=ACTIVE;
218#endif
219   
220       /* Create the socket and set it up to accept connections. */
221       sock = mainserver_make_socket (cmd, port);
222
223       time(&secs_now); tp=localtime(&secs_now); secs_in=secs_now;
224       sprintf(timestamp,"%04d%02d%02d %02d%02d%02d %1d %3d", 1900+tp->tm_year,tp->tm_mon+1,tp->tm_mday, tp->tm_hour,tp->tm_min,tp->tm_sec, tp->tm_wday,tp->tm_yday);
225
226#if GEN_LOGS
227       if (cmd) { sprintf (logbuff, "<101 0>Server [%d] [%d] [%s]: got socket</1>", port, sock, timestamp); if (fldupdat(logirec,logbuff)) fatal("wtrig2/fldupdat/1"); }
228#endif
229       if (cmd == 3) fprintf (stderr, "Server [%d] [%d] [%s]: got socket \n", port, sock, timestamp);
230
231#if PGCC
232       if (sock < 0)   /* <== */
233         {
234           /*perror ("sock"); exit (EXIT_FAILURE);*/
235           return -1;
236         }
237       if (listen (sock, maxconnqueued) < 0)   /* <== at most 1 connection queued */
238         {
239           /*perror ("listen"); exit (EXIT_FAILURE);*/
240           return -1;
241         }
242
243       /* Initialize the set of active sockets. */
244       FD_ZERO (&active_fd_set);
245       FD_SET (sock, &active_fd_set);
246#else
247       i=sock;
248#endif
249
250       awtfp->globalport=(int)port;       /* validade collection in w2.c */       
251       awtfp->globalsock=sock;            /* sock/fd */
252
253       while (!shutdown)
254         {
255#if PGCC
256           /* Block until input arrives on one or more active sockets. */
257           read_fd_set = active_fd_set;
258           if (select (FD_SETSIZE, &read_fd_set, NULL, NULL, NULL) < 0)
259             {
260               /*perror ("select"); exit (EXIT_FAILURE);*/
261               return -2;
262             }
263           /* Service all the sockets with input pending. */
264           for (i = 0; i < FD_SETSIZE; ++i) {
265             if (FD_ISSET (i, &read_fd_set))
266               {
267                 if (i == sock)
268                   {
269                     /* Connection request on original socket. */
270                     int new;
271                     size = sizeof (clientname);
272                     new = accept (sock,
273                                   (struct sockaddr *) &clientname,
274                                   &size);
275                     if (new < 0)
276                       {
277                         /*perror ("accept"); exit (EXIT_FAILURE);*/
278                         return -3;
279                       }
280#if GEN_LOGS
281                     if (cmd) sprintf (logbuff, "<102 0>Server [%d] [%d] [%s]: connect from host %s, port %hd</1>", port, sock, timestamp, inet_ntoa (clientname.sin_addr), ntohs (clientname.sin_port)); if (fldupdat(logirec,logbuff)) fatal("wtrig2/fldupdat/2"); }
282#endif
283                     if (cmd == 3) fprintf (stderr, "Server [%d] [%d] [%s]: connect from host %s, port %hd \n", port, sock, timestamp, inet_ntoa (clientname.sin_addr), ntohs (clientname.sin_port));
284                     FD_SET (new, &active_fd_set);
285                   }
286                 else
287                   {
288#endif
289                     /* Data arriving on an already-connected socket. */
290                     int nread = mainserver_read_from_client (cmd, port, i, buffer, buffersize);
291                     int code;
292                     char replybuf[REPLYSIZE];
293                     char *reply=replybuf;
294                     replybuf[0]='\0';
295
296                     time(&secs_now); tp=localtime(&secs_now);
297                     sprintf(timestamp,"%04d%02d%02d %02d%02d%02d %1d %3d", 1900+tp->tm_year,tp->tm_mon+1,tp->tm_mday, tp->tm_hour,tp->tm_min,tp->tm_sec, tp->tm_wday,tp->tm_yday);
298
299#if GEN_LOGS
300                     if (cmd) sprintf (logbuff, "<103 0>Server [%d] [%d] [%s]: got message (%d bytes)^v%s</1>", port, sock, timestamp, nread, buffer); if (fldupdat(logirec,logbuff)) fatal("wtrig2/fldupdat/3"); }
301#endif
302                     if (cmd == 3) fprintf (stderr, "Server [%d] [%d] [%s]: got message (%d bytes): '%s' \n", port, sock, timestamp, nread, buffer);
303
304                     if (strlen(buffer) == 0)              {         reply="serw 100 eof msg\n"; /* never */          code=100; }
305#if GEN_SERW
306                     if (strncmp(buffer,"wtrig2 ",7) == 0) {
307                                                             coll = loadcoll(cmd, awtfp, buffer, wreply);
308                                                             if (coll < 0) code=400; else code=200;
309                                                             //sprintf(replybuf,"serw %d coll#%d [%s]\n",code,coll,wreply);
310                                                             sprintf(replybuf,"%s\n",wreply);
311                     }
312                     else
313#endif /* GEN_SERW */
314                     if (strcmp(buffer,"\n") == 0)         {         reply="serw 101 null msg\n";                     code=101; }
315                     else
316                     if (strncmp(buffer,"shutdown",8) == 0)   {         reply="serw 200 thanks\n";                       code=0;   shutdown=1; }
317                     else
318                     if (strncmp(buffer,"hello",5) == 0)      {         reply="serw 200 hi\n";                           code=200; }
319                     else
320                     if (strncmp(buffer,"echo ",5) == 0)   { sprintf(replybuf,"serw 200 %s\n",buffer+5);  code=200; }
321#define GEN_HTTP 1
322#if GEN_HTTP
323                     else
324                     if (strncmp(buffer,"GET /wtrig2+",12) == 0)      { 
325                         int http=0;
326                         int lumlen;
327                         char *p;
328                         char *lfp=strchr(buffer,'\r');
329                         if (!lfp) lfp=strchr(buffer,'\n');
330                         if (lfp) {
331                             char k = *lfp;
332                             *lfp='\0';
333                             lumlen=strlen(buffer);  // 123456789012
334                             if (lumlen>=12) {       // X / HTTP/1.x
335                                 p=lfp-9;
336                                 if (strcmp(p," HTTP/1.0") == 0) http=10; else
337                                 if (strcmp(p," HTTP/1.1") == 0) http=11;
338                             }
339                             //*lfp = k;
340                         }
341#if 0
342if (http)
343sprintf(replybuf,"000 OK\nDate: Sun, 09 Feb 2003 08:08:53 GMT\nServer: Acme HTTP Server 0.01 alpha\nContent-Length: 92\nContent-Type: text/xml\nLast-Modified: Thu, 08 Nov 2001 22:12:35 GMT\n\n<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><greeting>hello world and Pr�iabetes</greeting>");
344else
345#endif
346                         if (http) {
347                             *p='\0';
348                             for (p=buffer+5; *p; p++) {
349                                 if (*p == '+') *p=' '; else
350                                 if (*p == '&') *p=' ';
351                             }
352                                                             coll = loadcoll(cmd, awtfp, buffer+5, wreply);
353                                                             if (coll < 0) code=400; else code=200;
354                                                             //sprintf(replybuf,"serw %d coll#%d [%s]\n",code,coll,wreply);
355//                                                             sprintf(replybuf,
356//"HTTP/1.0 %d OK\nDate: Fri, 16 Aug 1996 11:48:52 GMT\nServer: Apache/1.1.1 UKWeb/1.0\nLast-modified: Fri, 09 Aug 1996 14:21:40 GMT\nContent-length: %6d\nContent-type: text/xml; charset=\"ISO-8859-1\"\n\n<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n<yourrequest>%s</yourrequest>\n" ,code,strlen(wreply)+134+22,wreply);
357                                                             sprintf(replybuf,
358"HTTP/1.0 %d OK\nDate: Fri, 16 Aug 1996 11:48:52 GMT\nServer: Apache/1.1.1 UKWeb/1.0\nLast-modified: Fri, 09 Aug 1996 14:21:40 GMT\nContent-length: %6d\nContent-type: text/xml\n\n<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n<yourrequest>%s</yourrequest>\n" ,code,strlen(wreply),wreply);
359                         } 
360                         else
361                                                           {         reply="serw 404 invalid msg\n";                  code=400; }
362                     }
363#else/* GEN_HTTP */
364                     else
365                     if (strcmp(buffer+nread-1,"\n") != 0) {         reply="serw 505 bad msg\n";                      code=500; }
366                     else
367                                                           {         reply="serw 404 invalid msg\n";                  code=400; }
368#endif /* GEN_HTTP */
369
370                     /* Response */
371#if PGCC
372                     if (strlen(reply) > 0) {
373                       int nbytes=strlen(reply);
374                       nbytes = mainserver_write_to_client (cmd, port, i, reply, nbytes);
375                       if (nbytes < 0)
376                         {
377                           /*perror ("write (client)");*/
378                           close (i);
379                           FD_CLR (i, &active_fd_set);
380                           /* return -4; */
381                         }
382#if GEN_LOGS
383                     time(&secs_now); tp=localtime(&secs_now);
384                     sprintf(timestamp,"%04d%02d%02d %02d%02d%02d %1d %3d", 1900+tp->tm_year,tp->tm_mon+1,tp->tm_mday, tp->tm_hour,tp->tm_min,tp->tm_sec, tp->tm_wday,tp->tm_yday);
385                                                             if (cmd) sprintf (logbuff, "<104 0>Server reply [%d] [%d] [%s] code=%d coll#%d (%d bytes)^v%s</1>", port, sock, timestamp, code, coll, strlen(reply), reply); if (fldupdat(logirec,logbuff)) fatal("wtrig2/fldupdat/4"); }
386                                                             
387#endif
388                     }
389
390                     close (i);
391                     FD_CLR (i, &active_fd_set);
392
393                   } /* end data read */
394
395               } /* end if FD_ISSET */
396#endif
397
398               if (shutdown) break;
399
400 #if PGCC
401           } /* end for FD_SETSIZE */
402 #endif
403         } /* end while */
404
405         /* Release the socket. */
406 #if PGCC
407         close (sock);
408 #endif
409
410         time(&secs_now); tp=localtime(&secs_now);
411         sprintf(timestamp,"%04d%02d%02d %02d%02d%02d %1d %3d", 1900+tp->tm_year,tp->tm_mon+1,tp->tm_mday, tp->tm_hour,tp->tm_min,tp->tm_sec, tp->tm_wday,tp->tm_yday);
412
413#if GEN_LOGS
414         if (cmd) sprintf (logbuff, "<105 0>Server [%d] [%d] [%s]: close socket (%"_LD_" seconds)</1>", port, sock, timestamp,(LONGX)secs_now-secs_in); if (fldupdat(logirec,logbuff)) fatal("wtrig2/fldupdat/5"); }
415#endif
416         if (cmd == 3) fprintf (stderr, "Server [%d] [%d] [%s]: close socket (%"_LD_" seconds) \n", port, sock, timestamp,(LONGX)secs_now-secs_in);
417
418         return 0;
419
420     } /* end of mainserver */
421
422
423#endif /* P000 */
424
425
426
427
428/* Main
429
430./serw 3
431./serw 3 2>>xlog &
432
433*/
434
435#if GEN_MAIN
436     int
437     main(int argc, char *argv[])
438     {
439       /* calling parameters */
440       int cmd=0;
441       int rc;
442       int i;
443
444       uint16_t port=PORT;
445       char *cipfile="serw.cip";
446
447       int buffsize=MAXMFRL*2;
448       char *buffer;
449
450       WTFUN_ARRAY *awtfp=NULL;
451
452       if (argc == 1) {
453           printf("%s",cicopyr("Utility SERW"));
454           printf("\n");
455           //printf("serw [tell/debug] [cipar=<file>] [port=1417|<port>] \"msg[|]\" \"msg[|]\".. \n");
456           printf("serw [tell/debug] [cipar=<file>] [port=1417|<port>]");
457#if GEN_MAINLOAD
458           printf(" \"msg[|]\" \"msg[|]\"..");
459#endif
460           printf(" \n");
461           printf("\n");
462           exit (EXIT_FAILURE);
463       }
464
465       /* working area */
466       buffer=(char *)loadfile(NULL,'@',"",NULL, buffsize, '\0');
467       if (!buffer) {
468            fprintf(stderr, "serw: exit_failure buffer=%d bytes\n", buffsize);
469            exit (EXIT_FAILURE);
470       }
471
472       /* setup or loadcoll()
473       */
474       for (i=1; i < argc; i++) {
475            char *p=argv[i];
476            if (strcmp(p,"tell") == 0) {
477                cmd=1;
478                continue;
479            }
480            if (strcmp(p,"debug") == 0) {
481                cmd=3;
482                continue;
483            }
484            if (strncmp(p,"cipar=",6) == 0) {
485                cipfile=p+6;
486                continue;
487            }
488            if (strncmp(p,"port=",5) == 0) {
489                LONGX xval;
490                if (sscanf(p+5,"%"_LD_,&xval) != 1) fatal(p);
491                port=(uint16_t)xval;
492                continue;
493            }
494#if GEN_MAINLOAD
495            if (p) {
496                char *p;
497
498                if (!ciawtfp) if (dbxciset(cipfile)) {
499                    fprintf(stderr, "loadcoll failure: cipar=%s \n",cipfile);
500                    exit (EXIT_FAILURE);
501                }
502
503                for (p=argv[i]; *p; p++) if (*p=='|') *p='\n'; // test text=..|..
504
505                rc = loadcoll(cmd, ciawtfp, argv[i], buffer);
506                if (rc < 0) { 
507                    if (cmd >= 3) fprintf(stderr, "loadcoll failure %d \n", rc);
508                    exit (EXIT_FAILURE);
509                }
510                else printf("%s",buffer);
511           }
512#else /*  GEN_MAINLOAD */
513           fatal(p);
514#endif /*  GEN_MAINLOAD */
515       }
516   
517#if PGCC
518       if (!ciawtfp) if (dbxciset(cipfile)) {
519           fprintf(stderr, "serw/loadcoll failure: cipar \n");
520           exit (EXIT_FAILURE);
521       }
522       awtfp=ciawtfp;
523
524       // server
525       rc=(-1);
526       if (awtfp) {
527           if (cmd >= 3) fprintf(stderr, "serw: %d \n",port);
528           rc = mainserver(cmd, awtfp, port, buffer, buffsize, 1);
529           //free awtfp
530       }
531#endif //PGCC
532       
533       //free buffer
534
535       if (rc < 0) {
536           if (cmd >= 3) fprintf(stderr, "serw: exit_failure %d \n", rc);
537           exit (EXIT_FAILURE);
538       }
539
540       if (cmd >= 3) fprintf(stderr, "serw: exit_success \n");
541       exit (EXIT_SUCCESS);
542
543       return 1;
544     }
545#endif /*  GEN_MAIN */
546
547//#undef P000
548//#undef GEN_MAINLOAD
549//#undef GEN_MAIN
Note: See TracBrowser for help on using the browser.