root/trunk/serw.c

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