1ceae5869793ce9be9fb5eef460ccc9a4cced19d
[yaz-moved-to-github.git] / server / statserv.c
1 /*
2  * Copyright (C) 1994, Index Data I/S 
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: statserv.c,v $
7  * Revision 1.4  1995-03-14 16:59:48  quinn
8  * Bug-fixes
9  *
10  * Revision 1.3  1995/03/14  11:30:15  quinn
11  * Works better now.
12  *
13  * Revision 1.2  1995/03/14  10:28:03  quinn
14  * More work on demo server.
15  *
16  * Revision 1.1  1995/03/10  18:22:45  quinn
17  * The rudiments of an asynchronous server.
18  *
19  */
20
21 /*
22  * Simple, static server. I wouldn't advise a static server unless you
23  * really have to, but it's great for debugging memory management.  :)
24  */
25
26 #include <stdio.h>
27
28 #include <options.h>
29 #include <eventl.h>
30 #include <session.h>
31 #include <eventl.h>
32 #include <comstack.h>
33 #include <tcpip.h>
34 #include <xmosi.h>
35
36 static char *me = "";
37
38 #define DEFAULT_LISTENER "tcp:localhost:9999"
39
40 /*
41  * handle incoming connect requests.
42  */
43 void listener(IOCHAN h, int event)
44 {
45     COMSTACK line = (COMSTACK) iochan_getdata(h);
46     association *newas;
47
48     if (event == EVENT_INPUT)
49     {
50         if (cs_listen(line, 0, 0) < 0)
51         {
52             if (cs_errno(line) == CSNODATA)
53                 return;
54             fprintf(stderr, "cs_listen failed.\n");
55             exit(1);
56         }
57         iochan_setflags(h, EVENT_OUTPUT); /* set us up for accepting */
58     }
59     else if (event == EVENT_OUTPUT)
60     {
61         COMSTACK new_line;
62         IOCHAN new_chan;
63
64         if (!(new_line = cs_accept(line)))
65         {
66             fprintf(stderr, "Accept failed.\n");
67             exit(1);
68         }
69         if (!(new_chan = iochan_create(cs_fileno(new_line), ir_session,
70             EVENT_INPUT)))
71         {
72             fprintf(stderr, "Failed to create iochan\n");
73             exit(1);
74         }
75         if (!(newas = create_association(new_chan, new_line)))
76         {
77             fprintf(stderr, "Failed to create new assoc.\n");
78             exit(1);
79         }
80         iochan_setdata(new_chan, newas);
81         iochan_setflags(h, EVENT_INPUT); /* reset for listening */
82     }
83     else
84     {
85         fprintf(stderr, "Bad event on listener.\n");
86         exit(1);
87     }
88 }
89
90 /*
91  * Set up a listening endpoint, and give it to the event-handler.
92  */
93 void add_listener(char *where)
94 {
95     COMSTACK l;
96     CS_TYPE type;
97     char mode[100], addr[100];
98     void *ap;
99     IOCHAN lst;
100
101     fprintf(stderr, "Adding listener on %s\n", where);
102     if (!where || sscanf(where, "%[^:]:%s", mode, addr) != 2)
103     {
104         fprintf(stderr, "%s: Address format: ('tcp'|'osi')':'<address>.\n",
105             me);
106         exit(1);
107     }
108     if (!strcmp(mode, "tcp"))
109     {
110         if (!(ap = tcpip_strtoaddr(addr)))
111         {
112             fprintf(stderr, "Address resolution failed for TCP.\n");
113             exit(1);
114         }
115         type = tcpip_type;
116     }
117 #if 0
118     else if (!strcmp(mode, "osi"))
119     {
120         if (!(ap = mosi_strtoaddr(addr)))
121         {
122             fprintf(stderr, "Address resolution failed for TCP.\n");
123             exit(1);
124         }
125         type = mosi_type;
126     }
127 #endif
128     else
129     {
130         fprintf(stderr, "You must specify either 'osi:' or 'tcp:'.\n");
131         exit(1);
132     }
133     if (!(l = cs_create(type, 1)))
134     {
135         fprintf(stderr, "Failed to create listener\n");
136         exit(1);
137     }
138     if (cs_bind(l, ap, CS_SERVER) < 0)
139     {
140         fprintf(stderr, "Failed to bind.\n");
141         perror(where);
142         exit(1);
143     }
144     if (!(lst = iochan_create(cs_fileno(l), listener, EVENT_INPUT)))
145     {
146         fprintf(stderr, "Failed to create IOCHAN-type\n");
147         exit(1);
148     }
149     iochan_setdata(lst, l);
150 }
151
152 int main(int argc, char **argv)
153 {
154     int ret, listeners = 0;
155     char *arg;
156
157     me = argv[0];
158     while ((ret = options("l:", argv, argc, &arg)) != -2)
159         switch (ret)
160         {
161             case 0: me = arg; break;
162             case 'l': add_listener(arg); listeners++; break;
163             default:
164                 fprintf(stderr, "Usage: %s [-l <listener-addr>]\n", me);
165                 exit(1);
166         }
167     if (!listeners)
168         add_listener(DEFAULT_LISTENER);
169     return event_loop();
170 }