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