root/trunk/serwofi.c

Revision 389, 18.0 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 <math.h>
43#include <time.h>
44#include "cisis.h"      /* CISIS Interface header file */
45#if GCC
46#define PGCC  1
47#else
48#define uint16_t unsigned short
49#endif
50#include "cirun.h"      /* CISIS Interface runtime */
51
52#include "wt.h"         /* //MAXNREC; typedef VECTEL; typedef LISTA */
53#include "wtfun.h"      /* typedef WTFUN_XWT */
54
55#if GEN_SERW
56#include "cihsh.h"      /* CISIS Interface hashing & binary table search */
57#include "wtrun.h"      /* define ((WTFUN_XWT *)xwtp)-> */
58#include "wtrun.c"      /* wtnew();  wtexit(); loadcoll() source code */
59#endif /* GEN_SERW */
60
61#if GEN_MAIN
62     #include <errno.h>
63     #include <stdlib.h>
64#if P000 && PGCC
65     #include <unistd.h>
66#endif /* P000 */
67     #include <sys/types.h>
68#endif /*  GEN_MAIN */
69
70#if P000
71#if PGCC
72     #include <sys/socket.h>
73     #include <netinet/in.h>
74     #include <netdb.h>
75     #include <time.h>
76#else
77//     #include <wsksock.h>
78#endif
79#endif /* P000 */
80
81#if GEN_MAIN
82     #define PORT          1417
83     #define BUFFERSIZE   51200
84#endif /*  GEN_MAIN */
85
86     #define REPLYSIZE    51200
87
88
89#if P000
90     int mainserver_make_socket (int cmd, uint16_t port);
91     int mainserver_read_from_client (int cmd, uint16_t port, int filedes, char *buffer, int buffersize);
92     int mainserver_write_to_client (int cmd, uint16_t port, int filedes, char *message, int messagesize);
93     int mainserver (int cmd, WTFUN_ARRAY *awtfp, uint16_t port, char *buffer, int buffersize, int maxconnqueued);
94
95/*
96*/
97     int
98     mainserver_make_socket (int cmd, uint16_t port)
99     {
100       int sock;
101#if PGCC
102       struct sockaddr_in name;
103
104       /* Create the socket. */
105       sock = socket (PF_INET, SOCK_STREAM, 0);
106       if (sock < 0)
107         {
108           /*perror ("socket"); exit (EXIT_FAILURE);*/
109           return -1;
110         }
111
112       /* Give the socket a name. */
113       name.sin_family = AF_INET;
114       name.sin_port = htons (port);
115       name.sin_addr.s_addr = htonl (INADDR_ANY);
116       if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0)
117         {
118           /*perror ("bind"); exit (EXIT_FAILURE);*/
119           return -2;
120         }
121       return sock;
122#else
123       sock=1; return sock;
124#endif
125     }
126
127
128     int
129     mainserver_write_to_client (int cmd, uint16_t port, int filedes, char *message, int messagesize)
130     {
131       int nbytes;
132                              /* yyyymmdd hh:mm:ss WDAY YDAY */
133       char timestamp[80];    /* 123456789012345678901234 7  8 901 */
134       time_t secs_now;
135       struct tm *tp;
136       time(&secs_now); tp=localtime(&secs_now);
137       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);
138
139#if GEN_LOGS
140       if (cmd == 4) sprintf (logbuff, "Server [%d] [%d] [%s]: reply message (%d bytes): '%s' \n", port, filedes, timestamp, messagesize, message);
141#endif
142       if (cmd == 3) fprintf (stderr, "Server [%d] [%d] [%s]: reply message (%d bytes): '%s' \n", port, filedes, timestamp, messagesize, message);
143       if (cmd == 2) fprintf (stderr, "Server [%d] [%d] [%s]: reply message (%d bytes) \n", port, filedes, timestamp, messagesize);
144
145#if PGCC
146       nbytes = send (filedes, message, messagesize, 0);// send (int socket, void *buffer, size_t size, int flags)
147       if (nbytes < messagesize)
148         {
149           /* Write error */
150           /*perror ("write");*/
151           return -1;
152         }
153       else
154         return nbytes;
155#else
156       nbytes=1; return(nbytes);
157#endif
158     }
159
160
161     int
162     mainserver_read_from_client (int cmd, uint16_t port, int filedes, char *buffer, int buffersize)
163     {
164       int nbytes;
165
166#if PGCC
167       buffer[0]='\0';
168       nbytes = recv (filedes, buffer, buffersize-1, 0); // recv (int socket, void *buffer, size_t size, int flags)
169       if (nbytes < 0)
170         {
171           /* Read error. */
172           /*perror ("read"); exit (EXIT_FAILURE);*/
173           return -2;
174         }
175       else
176         {
177#if TRACER
178           char *p=buffer;
179           int loop=nbytes;
180           fprintf (stderr, "read(%d): ",nbytes);
181           for (; loop--; p++) fprintf (stderr, "%c=%02x ",*p,(int)*p);
182           fprintf (stderr, "\n");
183#endif
184           /* EOF (nbytes=0) or Data read. */
185           buffer[nbytes]='\0';
186           return nbytes;
187         }
188#else
189       buffer[0]='x'; buffer[1]='\0';
190       nbytes=1; return(nbytes);
191#endif
192     }
193
194
195/*
196     mainserver
197*/
198     int
199     mainserver (int cmd, WTFUN_ARRAY *awtfp, uint16_t port, char *buffer, int buffersize, int maxconnqueued)
200     {
201       int sock;
202#if PGCC
203       fd_set active_fd_set, read_fd_set;
204       struct sockaddr_in clientname;
205#endif
206       int i;
207       size_t size;
208       int shutdown=0; /* run */
209                              /* yyyymmdd hh:mm:ss WDAY YDAY */
210       char timestamp[80];    /* 123456789012345678901234 7  8 901 */
211       time_t secs_in;
212       time_t secs_now;
213       struct tm *tp;
214
215#if GEN_SERW
216       char wreply[REPLYSIZE];
217       int coll;
218#endif
219
220#if GEN_LOGS
221        RECSTRU *recp;
222        LONGX logcrec;
223        LONGX logirec;
224        char logsdb[CIMPL];
225       
226        /* log processing
227        */
228        strcpy(logsdb,"serw.log");
229               
230        if (!ndbxs) dbxinit();  /* init vdbxp/vrecp/vtrmp if not yet init - AOT, 28/10/2005 */
231               
232        /* alloc///logsdb ctl */
233        for (logcrec=maxnrec; logcrec--; ) { if (!vrecp[logcrec]) /* ja' decrementado */ break; }
234        if (logcrec<0L) fatal("wtrig2/logcrec");
235        recallok(logcrec,sizeof(M0STRU)); 
236       
237        /* alloc///logsdb */
238        for (logirec=maxnrec; logirec--; ) { if (!vrecp[logirec]) /* ja' decrementado */ break; }
239        if (logirec<0L) fatal("wtrig2/logirec");
240        recallok(logirec,MAXMFRL);  // RECsetup in w2setrt.c / w2logx.c + w2log1.c
241   
242        RECORD(logcrec,logsdb,0);
243        RECORD(logirec,logsdb,MF0nxtmfn); 
244        RECrc=RCNORMAL; MFRstatus=ACTIVE;
245#endif
246   
247       /* Create the socket and set it up to accept connections. */
248       sock = mainserver_make_socket (cmd, port);
249
250       time(&secs_now); tp=localtime(&secs_now); secs_in=secs_now;
251       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);
252
253#if GEN_LOGS
254       if (cmd) { sprintf (logbuff, "<101 0>Server [%d] [%d] [%s]: got socket</1>", port, sock, timestamp); if (fldupdat(logirec,logbuff)) fatal("wtrig2/fldupdat/1"); }
255#endif
256       if (cmd == 3) fprintf (stderr, "Server [%d] [%d] [%s]: got socket \n", port, sock, timestamp);
257
258#if PGCC
259       if (sock < 0)   /* <== */
260                 {
261                             /*perror ("sock"); exit (EXIT_FAILURE);*/
262                           return -1;
263                           }
264       if (listen (sock, maxconnqueued) < 0)   /* <== at most 1 connection queued */
265         {
266           /*perror ("listen"); exit (EXIT_FAILURE);*/
267           return -1;
268         }
269
270       /* Initialize the set of active sockets. */
271       FD_ZERO (&active_fd_set);
272       FD_SET (sock, &active_fd_set);
273#else
274       i=sock;
275#endif
276
277       while (!shutdown)
278         {
279#if PGCC
280           /* Block until input arrives on one or more active sockets. */
281           read_fd_set = active_fd_set;
282           if (select (FD_SETSIZE, &read_fd_set, NULL, NULL, NULL) < 0)
283             {
284               /*perror ("select"); exit (EXIT_FAILURE);*/
285               return -2;
286             }
287           /* Service all the sockets with input pending. */
288           for (i = 0; i < FD_SETSIZE; ++i) {
289             if (FD_ISSET (i, &read_fd_set))
290               {
291                 if (i == sock)
292                   {
293                     /* Connection request on original socket. */
294                     int new;
295                     size = sizeof (clientname);
296                     new = accept (sock,
297                                   (struct sockaddr *) &clientname,
298                                   &size);
299                     if (new < 0)
300                       {
301                         /*perror ("accept"); exit (EXIT_FAILURE);*/
302                         return -3;
303                       }
304#if GEN_LOGS
305                     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"); }
306#endif
307                     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));
308                     FD_SET (new, &active_fd_set);
309                   }
310                 else
311                   {
312#endif
313                     /* Data arriving on an already-connected socket. */
314                     int nread = mainserver_read_from_client (cmd, port, i, buffer, buffersize);
315                     int code;
316                     char replybuf[REPLYSIZE];
317                     char *reply=replybuf;
318                     replybuf[0]='\0';
319
320                     time(&secs_now); tp=localtime(&secs_now);
321                     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);
322
323#if GEN_LOGS
324                     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"); }
325#endif
326                     if (cmd == 3) fprintf (stderr, "Server [%d] [%d] [%s]: got message (%d bytes): '%s' \n", port, sock, timestamp, nread, buffer);
327
328                     if (strlen(buffer) == 0)              {         reply="serw 100 eof msg\n"; /* never */          code=100; }
329                     else
330#if GEN_SERW
331                     if (strncmp(buffer,"wtrig2 ",7) == 0) {
332                                                             coll = loadcoll(cmd, awtfp, buffer, wreply);
333                                                             if (coll < 0) code=400; else code=200;
334                                                             //sprintf(replybuf,"serw %d coll#%d [%s]\n",code,coll,wreply);
335                                                             sprintf(replybuf,"%s\n",wreply);
336                     }
337                     else
338#endif /* GEN_SERW */
339                     if (strcmp(buffer,"\n") == 0)         {         reply="serw 101 null msg\n";                     code=101; }
340                     else
341                     if (strncmp(buffer,"shutdown",8) == 0)   {         reply="serw 200 thanks\n";                       code=0;   shutdown=1; }
342                     else
343                             if (strncmp(buffer,"hello",5) == 0)      {         reply="serw 200 hi\n";                           code=200; }
344                     else
345                     if (strncmp(buffer,"echo ",5) == 0)   { sprintf(replybuf,"serw 200 %s\n",buffer+5);  code=200; }
346                     else
347                     if (strcmp(buffer+nread-1,"\n") != 0) {         reply="serw 505 bad msg\n";                      code=500; }
348                     else
349                                                           {         reply="serw 404 invalid msg\n";                  code=400; }
350
351                     /* Response */
352#if PGCC
353                     if (strlen(reply) > 0) {
354                       int nbytes=strlen(reply);
355                       nbytes = mainserver_write_to_client (cmd, port, i, reply, nbytes);
356                       if (nbytes < 0)
357                         {
358                           /*perror ("write (client)");*/
359                           close (i);
360                           FD_CLR (i, &active_fd_set);
361                           /* return -4; */
362                         }
363#if GEN_LOGS
364                     time(&secs_now); tp=localtime(&secs_now);
365                     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);
366                                                             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"); }
367                                                             
368#endif
369                     }
370
371                     close (i);
372                     FD_CLR (i, &active_fd_set);
373
374                   } /* end data read */
375
376               } /* end if FD_ISSET */
377#endif
378
379               if (shutdown) break;
380
381 #if PGCC
382           } /* end for FD_SETSIZE */
383 #endif
384         } /* end while */
385
386         /* Release the socket. */
387 #if PGCC
388         close (sock);
389 #endif
390
391         time(&secs_now); tp=localtime(&secs_now);
392         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);
393
394#if GEN_LOGS
395         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"); }
396#endif
397         if (cmd == 3) fprintf (stderr, "Server [%d] [%d] [%s]: close socket (%"_LD_" seconds) \n", port, sock, timestamp,(LONGX)secs_now-secs_in);
398
399         return 0;
400
401     } /* end of mainserver */
402
403
404#endif /* P000 */
405
406
407
408
409/* Main
410
411./serw 3
412./serw 3 2>>xlog &
413
414*/
415
416#if GEN_MAIN
417     int
418     main(int argc, char *argv[])
419     {
420       /* calling parameters */
421       int cmd=0;
422       int rc;
423       int i;
424
425       uint16_t port=PORT;
426       char *cipar="serw.cip";
427
428       int buffsize=MAXMFRL*2;
429       char *buffer;
430
431       WTFUN_ARRAY *awtfp=NULL;
432
433       if (argc == 1) {
434           printf("%s",cicopyr("Utility SERW"));
435           printf("\n");
436           //printf("serw [tell/debug] [cipar=<file>] [port=1417|<port>] \"msg[|]\" \"msg[|]\".. \n");
437           printf("serw [tell/debug] [cipar=<file>] [port=1417|<port>]");
438//#if GEN_MAINLOAD
439           printf(" \"msg[|]\" \"msg[|]\"..");
440//#endif
441           printf(" \n");
442           printf("\n");
443           exit (EXIT_FAILURE);
444       }
445
446       /* working area */
447       buffer=(char *)loadfile(NULL,'@',"",NULL, buffsize, '\0');
448       if (!buffer) {
449            fprintf(stderr, "serw: exit_failure buffer=%d bytes\n", buffsize);
450            exit (EXIT_FAILURE);
451       }
452
453       /* setup or loadcoll()
454       */
455       for (i=1; i < argc; i++) {
456            char *p=argv[i];
457            if (strcmp(p,"tell") == 0) {
458                cmd=1;
459                continue;
460            }
461            if (strcmp(p,"debug") == 0) {
462                cmd=3;
463                continue;
464            }
465            if (strncmp(p,"cipar=",6) == 0) {
466                cipar=p+6; //dbxcdcip=loadfile(NULL,'\0',p+6,NULL,0L,'\n');
467                continue;
468            }
469            if (strncmp(p,"port=",5) == 0) {
470                LONGX xval;
471                if (sscanf(p+5,"%"_LD_,&xval) != 1) fatal(p);
472                port=(uint16_t)xval;
473                continue;
474            }
475//#if GEN_MAINLOAD
476            if (p) {
477                char *p;
478
479                if (!dbxcdcip) dbxcdcip=loadfile(NULL,'\0',cipar,NULL,0L,'\n'); // env
480                if (!awtfp) awtfp=wtfnew((argc>1)?atoi(argv[1]):0,dbxcdcip);    // new
481
482                for (p=argv[i]; *p; p++) if (*p=='|') *p='\n'; // test text=..|..
483
484                rc = loadcoll(cmd, awtfp, argv[i], buffer);
485                if (rc < 0) { 
486                    if (cmd >= 3) fprintf(stderr, "loadcoll failure %d \n", rc);
487                    exit (EXIT_FAILURE);
488                }
489                else printf("%s",buffer);
490           }
491//#else /*  GEN_MAINLOAD */
492//           fatal(p);
493//#endif /*  GEN_MAINLOAD */
494       }
495   
496#if !GEN_MAINLOAD
497       // cipar environment
498       if (!dbxcdcip) dbxcdcip=loadfile(NULL,'\0',cipar,NULL,0L,'\n'); // env
499
500       // new wtrig function
501       if (!awtfp) awtfp=wtfnew((argc>1)?atoi(argv[1]):0,dbxcdcip);    // new
502       
503       // server
504       rc=(-1);
505       if (awtfp) {
506           if (cmd >= 3) fprintf(stderr, "serw: %d \n",port);
507           rc = mainserver(cmd, awtfp, port, buffer, buffsize, 1);
508           //free awtfp
509       }
510#endif /* !GEN_MAINLOAD */
511       
512       //free buffer
513
514       if (rc < 0) {
515           if (cmd >= 3) fprintf(stderr, "serw: exit_failure %d \n", rc);
516           exit (EXIT_FAILURE);
517       }
518
519       if (cmd >= 3) fprintf(stderr, "serw: exit_success \n");
520       exit (EXIT_SUCCESS);
521
522       return 1;
523     }
524#endif /*  GEN_MAIN */
525
526//#undef P000
527//#undef GEN_MAINLOAD
528//#undef GEN_MAIN
Note: See TracBrowser for help on using the browser.