prot-a.c 10.8 KB
Newer Older
Linus Tolke Y's avatar
Linus Tolke Y committed
1
/*
2
 * $Id: prot-a.c,v 0.55 1999/02/05 21:49:43 ceder Exp $
Per Cederqvist's avatar
Per Cederqvist committed
3
 * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996  Lysator Academic Computer Association.
Linus Tolke Y's avatar
Linus Tolke Y committed
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 *
 * This file is part of the LysKOM server.
 * 
 * LysKOM is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by 
 * the Free Software Foundation; either version 1, or (at your option) 
 * any later version.
 * 
 * LysKOM is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with LysKOM; see the file COPYING.  If not, write to
 * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN,
 * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, 
 * MA 02139, USA.
 *
 * Please mail bug reports to bug-lyskom@lysator.liu.se. 
 */
Per Cederqvist's avatar
Per Cederqvist committed
25
26
27
28
/*
 * Protocol A.
 */

David Byers's avatar
David Byers committed
29
30
31
32
33

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

34
static const char *
35
rcsid = "$Id: prot-a.c,v 0.55 1999/02/05 21:49:43 ceder Exp $";
36
37
#include "rcs.h"
USE(rcsid);
Per Cederqvist's avatar
Per Cederqvist committed
38

Per Cederqvist's avatar
Per Cederqvist committed
39
40
41
#ifdef HAVE_STDDEF_H
#  include <stddef.h>
#endif
42
43
44
#ifdef HAVE_STDARG_H
#  include <stdarg.h>
#endif
Per Cederqvist's avatar
Per Cederqvist committed
45
#include <setjmp.h>
46
47
48
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
Per Cederqvist's avatar
Per Cederqvist committed
49

Per Cederqvist's avatar
Per Cederqvist committed
50
#include "misc-types.h"
51
#include "s-string.h"
Per Cederqvist's avatar
Per Cederqvist committed
52
#include "kom-types.h"
Per Cederqvist's avatar
Per Cederqvist committed
53
#include "com.h"
54
#include "async.h"
Per Cederqvist's avatar
Per Cederqvist committed
55
#include "connections.h"
Per Cederqvist's avatar
Per Cederqvist committed
56
57
58
59
60
#include "debug.h"
#include "isc-interface.h"
#include "mux.h"
#include "kom-errno.h"
#include "server/smalloc.h"
Per Cederqvist's avatar
Per Cederqvist committed
61
62
63
#include "prot-a.h"
#include "prot-a-output.h"
#include "prot-a-parse.h"
Per Cederqvist's avatar
Per Cederqvist committed
64
#include "isc-parse.h"
65
#include "param.h"
Per Cederqvist's avatar
Per Cederqvist committed
66
#include "kom-memory.h"
Per Cederqvist's avatar
Per Cederqvist committed
67
68
69
70
71

BUGDECL;

void
prot_a_reply(Connection *client,
72
	     Success status,
Per Cederqvist's avatar
Per Cederqvist committed
73
74
75
76
77
78
79
80
81
82
	     Result_holder *res)
{
    /*
     * The function is called. Now return the answer.
     */

    if ( status == OK )
    {
	mux_printf(client, "=%d", client->ref_no);

83
	switch ( fnc_defs[ client->function_index ].result )
Per Cederqvist's avatar
Per Cederqvist committed
84
	{
85
	case rt_number:
86
87
	    mux_printf(client, " %lu", (unsigned long)res->number);
	    BUG(("=%lu\n", res->number));
Per Cederqvist's avatar
Per Cederqvist committed
88
89
	    break;

90
	case rt_success:
Per Cederqvist's avatar
Per Cederqvist committed
91
92
93
	    BUG(("=Success\n"));
	    break;
	    
94
	case rt_person:
Per Cederqvist's avatar
Per Cederqvist committed
95
96
97
98
	    prot_a_output_person(client, &res->person);
	    BUG(("={Person struct not listed}\n"));
	    break;

99
100
101
102
103
	case rt_membership_old:
	    prot_a_output_membership_old(client, &res->membership);
	    BUG(("={Membership struct not listed}\n"));
	    break;

104
	case rt_membership:
Per Cederqvist's avatar
Per Cederqvist committed
105
106
107
108
	    prot_a_output_membership(client, &res->membership);
	    BUG(("={Membership struct not listed}\n"));
	    break;

109
	case rt_conf_list:
Per Cederqvist's avatar
Per Cederqvist committed
110
111
112
113
	    prot_a_output_conf_list(client, res->conf_list);
	    BUG(("={Conf_list not listed}\n"));
	    break;

114
	case rt_conf_no_list:
Per Cederqvist's avatar
Per Cederqvist committed
115
116
117
118
	    prot_a_output_conf_no_list(client, res->conf_no_list);
	    BUG(("={Conf_no_list not listed}\n"));
	    break;
	    	    
119
	case rt_conference:
Per Cederqvist's avatar
Per Cederqvist committed
120
121
122
123
	    prot_a_output_conference(client, &res->conference);
	    BUG(("={Conference struct not listed}\n"));
	    break;

124
125
126
127
128
	case rt_conference_old:
	    prot_a_output_conference_old(client, &res->conference);
	    BUG(("={Conference (old) struct not listed}\n"));
	    break;

129
	case rt_string:
Per Cederqvist's avatar
Per Cederqvist committed
130
	    prot_a_output_string(client, res->string);
131
	    BUG(("={%luH", res->string.len));
Per Cederqvist's avatar
Per Cederqvist committed
132
133
134
135
	    BUGSTR(res->string);
	    BUG(("}\n"));
	    break;
	    
136
	case rt_mark_list:
Per Cederqvist's avatar
Per Cederqvist committed
137
138
139
140
	    prot_a_output_mark_list(client, res->mark_list);
	    BUG(("={Mark_list not listed}\n"));
	    break;
	    
141
142
143
144
145
	case rt_text_stat_old:
	    prot_a_output_text_stat_old(client, &res->text_stat);
	    BUG(("={Text_stat (old) struct not listed}\n"));
	    break;
	    
146
	case rt_text_stat:
Per Cederqvist's avatar
Per Cederqvist committed
147
148
149
150
	    prot_a_output_text_stat(client, &res->text_stat);
	    BUG(("={Text_stat struct not listed}\n"));
	    break;
	    
151
	case rt_who_info_list:
Per Cederqvist's avatar
Per Cederqvist committed
152
153
154
155
	    prot_a_output_who_info_list(client, res->who_info_list);
	    BUG(("={Who_info_list not listed}\n"));
	    break;

156
	case rt_who_info_list_old:
Per Cederqvist's avatar
Per Cederqvist committed
157
158
159
160
161
	    prot_a_output_who_info_list_old(client,
					    res->who_info_list_old);
	    BUG(("={Old who_info_list not listed}\n"));
	    break;

162
	case rt_session_info:
Per Cederqvist's avatar
Per Cederqvist committed
163
164
	    prot_a_output_session_info(client,
				       &res->session_info);
165
166
167
	    /* Clear username, since it is allocated (in get_session_info()
	       in session.c).  See comment abover the definition of
	       typedef Result_holder in connections.h.  */
Per Cederqvist's avatar
Per Cederqvist committed
168
	    s_clear(&res->session_info.username);
Per Cederqvist's avatar
Per Cederqvist committed
169
170
171
	    BUG(("={Session_info not listed}\n"));
	    break;
    
172
	case rt_info:
Per Cederqvist's avatar
Per Cederqvist committed
173
174
175
176
	    prot_a_output_info(client, &res->info);
	    BUG(("={Who_info struct not listed}\n"));
	    break;

177
178
179
180
181
	case rt_info_old:
	    prot_a_output_info_old(client, &res->info);
	    BUG(("={Who_info struct not listed}\n"));
	    break;

182
	case rt_membership_list:
Per Cederqvist's avatar
Per Cederqvist committed
183
184
185
186
	    prot_a_output_membership_list (client, res->membership_list);
	    BUG (("={Membership_list not listed}\n"));
	    break;
	    
187
	case rt_membership_list_old:
188
189
190
	    prot_a_output_membership_list_old (client,
					       res->membership_list_old);
	    BUG (("={Membership_list_old not listed}\n"));
191
192
	    break;
	    
193
	case rt_member_list:
Per Cederqvist's avatar
Per Cederqvist committed
194
195
196
197
	    prot_a_output_member_list (client, res->member_list);
	    BUG(("={Member_list not listed}\n"));
	    break;

198
199
200
201
202
	case rt_member_list_old:
	    prot_a_output_member_list_old (client, res->member_list);
	    BUG(("={Member_list not listed}\n"));
	    break;

203
	case rt_time_date:
Per Cederqvist's avatar
Per Cederqvist committed
204
	    prot_a_output_time (client, res->time_date);
205
	    BUG(("=(time_t)%lu\n", (unsigned long)res->time_date));
Per Cederqvist's avatar
Per Cederqvist committed
206
207
	    break;

208
	case rt_session_no:
Per Cederqvist's avatar
Per Cederqvist committed
209
	    prot_a_output_session_no (client, res->session_no);
210
	    BUG(("=(Session_no)%lu\n", res->session_no));
Per Cederqvist's avatar
Per Cederqvist committed
211
	    break;
212
213
214

	case rt_text_no:
	    prot_a_output_text_no (client, res->text_no);
215
	    BUG(("=(Text_no)%lu\n", res->text_no));
216
	    break;
217
218
219
220
221
222
223
224
225

	case rt_who_info_ident_list:
	    prot_a_output_who_info_ident_list(client,
					      res->who_info_ident_list);
	    BUG(("={Who_info_ident_list not listed}\n"));
	    break;

	case rt_session_info_ident:
	    prot_a_output_session_info_ident(client,
Per Cederqvist's avatar
Per Cederqvist committed
226
					     &res->session_info_ident);
227
228
	    BUG(("={Session_info_ident not listed}\n"));
	    break;
229
230
231
232
233
234
235
236
237
238

	case rt_conf_z_info_list:
	    prot_a_output_conf_z_info_list(client, res->conf_z_info_list);
	    BUG(("={Conf_z_info_list not listed}\n"));
	    break;

	case rt_version_info:
	    prot_a_output_version_info(client, &res->version_info);
	    BUG(("={Version_info not listed}\n"));
	    break;
239
240
241
242
243

	case rt_uconference:
	    prot_a_output_uconference(client, &res->uconference);
	    BUG(("={UConference not listed}\n"));
	    break;
244
245
246
247
248

        case rt_num_list:
            prot_a_output_num_list(client, &res->num_list);
            BUG(("={num_list not listed}\n"));
            break;
249
250
251
252
253
254
255
256
257
258
259
260

	case rt_dynamic_session_info_list:
	    prot_a_output_dynamic_session_info_list(
		client, &res->dynamic_session_info_list);
	    BUG(("={dynamic_session_list not listed}\n"));
	    break;

	case rt_static_session_info:
	    prot_a_output_static_session_info(client,
					      &res->static_session_info);
	    BUG(("={static_session_info not listed"));
	    break;
261
262
263
264
265
266

	case rt_l2g_iterator_as_text_list:
	    prot_a_output_l2g_iterator_as_text_list(
		client, &res->l2g_iterator_as_text_list);
	    BUG(("={l2g_iterator_as_text_list not listed"));
	    break;
267
268
269
270
271

	case rt_text_mapping:
	    prot_a_output_text_mapping(client, &res->text_mapping);
	    BUG(("={text_mapping not listed"));
	    break;
272
273
274
275
276
277
278

#ifdef DEBUG_CALLS
        case rt_memory_info:
            prot_a_output_memory_info(client, &res->memory_info);
            BUG(("={memory_info not listed"));
            break;
#endif
Per Cederqvist's avatar
Per Cederqvist committed
279
280
281
282
283
284
	}
	mux_putc('\n', client);
    }
    else
    {
	/* Failure. Give a reply with the error message. */
285
286
	mux_printf(client, "%%%u %u %lu\n",
		   client->ref_no, kom_errno, err_stat);
Per Cederqvist's avatar
Per Cederqvist committed
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
	BUG(("%%Err %d\n", kom_errno));
    }

    mux_flush(client);
}


/*
 * Set up all data structures that are private to protocol A. This
 * function is called from connections.c whenever a connection says
 * that it is of type A.
 */
void
prot_a_init(Connection *conn)
{
    conn->parse_pos = 0;
    conn->fnc_parse_pos = 0;
304
    conn->array_parse_index = 0;
Per Cederqvist's avatar
Per Cederqvist committed
305
306
307
308
    conn->array_parse_pos = 0;
    conn->struct_parse_pos = 0;
    conn->string_parse_pos = 0;
    conn->ref_no = 0;
309
    conn->function = call_fnc_login_old;
Per Cederqvist's avatar
Per Cederqvist committed
310
311
312
313
314
315
316
317
    conn->num0 = 0;
    conn->num1 = 0;
    conn->num2 = 0;
    conn->num3 = 0;
    conn->c_string0 = EMPTY_STRING;
    conn->c_string1 = EMPTY_STRING;
    conn->string0 = EMPTY_STRING;
    conn->c_misc_info_p = NULL;
318
319
    conn->aux_item_list.items = NULL;
    conn->aux_item_list.length = 0;
Per Cederqvist's avatar
Per Cederqvist committed
320
    conn->c_local_text_no_p = NULL;
321
322
    init_priv_bits(&conn->priv_bits);
    init_conf_type(&conn->conf_type);
Per Cederqvist's avatar
Per Cederqvist committed
323
324
325
326
327
}

void
prot_a_destruct(Connection *conn)
{
328
    int i;
Per Cederqvist's avatar
Per Cederqvist committed
329
330
331
332
333
334
335
336
337
338

    /*
     * All strings et c should already by free:d - that is done at the
     * end of each atomic call. But free them anyhow, just in case
     * this client is forced of.
     */

    s_clear(&conn->string0);
    s_clear(&conn->c_string0);
    s_clear(&conn->c_string1);
339
340
341
342
343
344
345
    s_clear(&conn->aux_item.data);

    for (i = 0; i < conn->aux_item_list.length; i++)
        s_clear(&conn->aux_item_list.items[i].data);
    conn->aux_item_list.length = 0;
    sfree(conn->aux_item_list.items);
    conn->aux_item_list.items = NULL;
Per Cederqvist's avatar
Per Cederqvist committed
346
347
348
349
350
    sfree(conn->c_misc_info_p);
    sfree(conn->c_local_text_no_p);
}


351
352
353
/*
 * Check if it is a legal function.
 */
354
static int
Per Cederqvist's avatar
Per Cederqvist committed
355
356
prot_a_is_legal_fnc(Call_header fnc)
{
357
#include "prot-a-is-legal-fnc.incl"
Per Cederqvist's avatar
Per Cederqvist committed
358
359
360
361
362
363
}    


void
prot_a_parse_packet(Connection *client)
{
364
    if ( client->username_valid == FALSE )
Per Cederqvist's avatar
Per Cederqvist committed
365
366
367
    {
	/* Connection not established yet */

368
369
	prot_a_parse_string(client, &client->c_string0, 
			    param.username_len);
Per Cederqvist's avatar
Per Cederqvist committed
370
371
372
373

	client->username = client->c_string0; /* Kludge to deal with */
	client->c_string0 = EMPTY_STRING;     /* "A5B" as first input. */
				/* Protokoll B will not suffer from this... */
374
375

	client->username_valid = TRUE;
Per Cederqvist's avatar
Per Cederqvist committed
376
377
	mux_printf(client, "LysKOM\n");
	mux_flush(client);
378
	BUG(("[Client %lu is logged on]\n", client->session_no));
Per Cederqvist's avatar
Per Cederqvist committed
379
380
381
382
383
384
385
386
387
    }	

    switch(client->parse_pos)
    {
    case 0:			/* Get ref_no */
	client->ref_no = prot_a_parse_long(client);
	client->parse_pos = 1;
	/* Fall through */
    case 1:			/* Get fnc_no */
David Byers's avatar
David Byers committed
388
389
390
391
392
393
        /*
          FIXME: Omigawd this is ugly. The stupid compiler will complain
          FIXME: if I try to cast to a call_header directly, but I can
          FIXME: cast it to an int first. Jeez...
        */
	client->function = (enum call_header)(int)prot_a_parse_long(client);
394
395
	if ((client->function_index = prot_a_is_legal_fnc(client->function)) == -1 )
        {
396
	    client->function = illegal_fnc;
397
398
            client->function_index = num_fnc_defs - 1;
        }
Per Cederqvist's avatar
Per Cederqvist committed
399
400
401
402
	client->parse_pos = 2;
	/* Fall through */
    case 2:
	/* Call the function that parses the arguments for this call. */
403
	(*fnc_defs[client->function_index].parser)(client);
Per Cederqvist's avatar
Per Cederqvist committed
404
405
406
407
408
	/* Fall through */
    default:
	client->parse_pos = 0;
    }
}