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