root/trunk/serw2a.c

Revision 389, 19.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                         int http=0;
325                         int lumlen;
326                         char *lfp=strchr(buffer,'\r');
327                         if (!lfp) lfp=strchr(buffer,'\n');
328                         if (lfp) {
329                             char k = *lfp;
330                             *lfp='\0';
331                             lumlen=strlen(buffer);  // 123456789012
332                             if (lumlen>=12) {       // X / HTTP/1.x
333                                 char *p=lfp-9;
334                                 if (strcmp(p," HTTP/1.0") == 0) http=10; else
335                                 if (strcmp(p," HTTP/1.1") == 0) http=11;
336                             }
337                             *lfp = k;
338                         }
339                         if (http) {
340#if 1
341                                                             sprintf(replybuf,
342"HTTP/1.0 200 OK\n"\
343"Date: Fri, 16 Aug 1996 11:48:52 GMT\n"\
344"Server: Apache/1.1.1 UKWeb/1.0\n"\
345"Last-modified: Fri, 09 Aug 1996 14:21:40 GMT\n"\
346"Content-length: %6d\n"\
347"Content-type: text/plain\n\n"\
348"<html><body><pre>%s</pre></body></html>\n"
349,strlen(buffer)+64+22,buffer);
350#else
351                                                             sprintf(replybuf,
352"HTTP/1.0 200 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=\"utf-8\"?>\n<yourrequest>%s</yourrequest>\n" ,strlen(buffer)+107+22,buffer);
353#endif
354                         } 
355                         else
356                                                           {         reply="serw 404 invalid msg\n";                  code=400; }
357                     }
358#else/* GEN_HTTP */
359                     else
360                     if (strcmp(buffer+nread-1,"\n") != 0) {         reply="serw 505 bad msg\n";                      code=500; }
361                     else
362                                                           {         reply="serw 404 invalid msg\n";                  code=400; }
363#endif /* GEN_HTTP */
364
365                     /* Response */
366#if PGCC
367                     if (strlen(reply) > 0) {
368                       int nbytes=strlen(reply);
369                       nbytes = mainserver_write_to_client (cmd, port, i, reply, nbytes);
370                       if (nbytes < 0)
371                         {
372                           /*perror ("write (client)");*/
373                           close (i);
374                           FD_CLR (i, &active_fd_set);
375                           /* return -4; */
376                         }
377#if GEN_LOGS
378                     time(&secs_now); tp=localtime(&secs_now);
379                     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);
380                                                             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"); }
381                                                             
382#endif
383                     }
384
385                     close (i);
386                     FD_CLR (i, &active_fd_set);
387
388                   } /* end data read */
389
390               } /* end if FD_ISSET */
391#endif
392
393               if (shutdown) break;
394
395 #if PGCC
396           } /* end for FD_SETSIZE */
397 #endif
398         } /* end while */
399
400         /* Release the socket. */
401 #if PGCC
402         close (sock);
403 #endif
404
405         time(&secs_now); tp=localtime(&secs_now);
406         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);
407
408#if GEN_LOGS
409         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"); }
410#endif
411         if (cmd == 3) fprintf (stderr, "Server [%d] [%d] [%s]: close socket (%"_LD_" seconds) \n", port, sock, timestamp,(LONGX)secs_now-secs_in);
412
413         return 0;
414
415     } /* end of mainserver */
416
417
418#endif /* P000 */
419
420
421
422
423/* Main
424
425./serw 3
426./serw 3 2>>xlog &
427
428*/
429
430#if GEN_MAIN
431     int
432     main(int argc, char *argv[])
433     {
434       /* calling parameters */
435       int cmd=0;
436       int rc;
437       int i;
438
439       uint16_t port=PORT;
440       char *cipfile="serw.cip";
441
442       int buffsize=MAXMFRL*2;
443       char *buffer;
444
445       WTFUN_ARRAY *awtfp=NULL;
446
447       if (argc == 1) {
448           printf("%s",cicopyr("Utility SERW"));
449           printf("\n");
450           //printf("serw [tell/debug] [cipar=<file>] [port=1417|<port>] \"msg[|]\" \"msg[|]\".. \n");
451           printf("serw [tell/debug] [cipar=<file>] [port=1417|<port>]");
452#if GEN_MAINLOAD
453           printf(" \"msg[|]\" \"msg[|]\"..");
454#endif
455           printf(" \n");
456           printf("\n");
457           exit (EXIT_FAILURE);
458       }
459
460       /* working area */
461       buffer=(char *)loadfile(NULL,'@',"",NULL, buffsize, '\0');
462       if (!buffer) {
463            fprintf(stderr, "serw: exit_failure buffer=%d bytes\n", buffsize);
464            exit (EXIT_FAILURE);
465       }
466
467       /* setup or loadcoll()
468       */
469       for (i=1; i < argc; i++) {
470            char *p=argv[i];
471            if (strcmp(p,"tell") == 0) {
472                cmd=1;
473                continue;
474            }
475            if (strcmp(p,"debug") == 0) {
476                cmd=3;
477                continue;
478            }
479            if (strncmp(p,"cipar=",6) == 0) {
480                cipfile=p+6;
481                continue;
482            }
483            if (strncmp(p,"port=",5) == 0) {
484                LONGX xval;
485                if (sscanf(p+5,"%"_LD_,&xval) != 1) fatal(p);
486                port=(uint16_t)xval;
487                continue;
488            }
489#if GEN_MAINLOAD
490            if (p) {
491                char *p;
492
493                if (!ciawtfp) if (dbxciset(cipfile)) {
494                    fprintf(stderr, "loadcoll failure: cipar=%s \n",cipfile);
495                    exit (EXIT_FAILURE);
496                }
497
498                for (p=argv[i]; *p; p++) if (*p=='|') *p='\n'; // test text=..|..
499
500                rc = loadcoll(cmd, ciawtfp, argv[i], buffer);
501                if (rc < 0) { 
502                    if (cmd >= 3) fprintf(stderr, "loadcoll failure %d \n", rc);
503                    exit (EXIT_FAILURE);
504                }
505                else printf("%s",buffer);
506           }
507#else /*  GEN_MAINLOAD */
508           fatal(p);
509#endif /*  GEN_MAINLOAD */
510       }
511   
512#if PGCC
513       if (!ciawtfp) if (dbxciset(cipfile)) {
514           fprintf(stderr, "serw/loadcoll failure: cipar \n");
515           exit (EXIT_FAILURE);
516       }
517       awtfp=ciawtfp;
518
519       // server
520       rc=(-1);
521       if (awtfp) {
522           if (cmd >= 3) fprintf(stderr, "serw: %d \n",port);
523           rc = mainserver(cmd, awtfp, port, buffer, buffsize, 1);
524           //free awtfp
525       }
526#endif //PGCC
527       
528       //free buffer
529
530       if (rc < 0) {
531           if (cmd >= 3) fprintf(stderr, "serw: exit_failure %d \n", rc);
532           exit (EXIT_FAILURE);
533       }
534
535       if (cmd >= 3) fprintf(stderr, "serw: exit_success \n");
536       exit (EXIT_SUCCESS);
537
538       return 1;
539     }
540#endif /*  GEN_MAIN */
541
542//#undef P000
543//#undef GEN_MAINLOAD
544//#undef GEN_MAIN
Note: See TracBrowser for help on using the browser.