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