prot-a.c 13.5 KB
Newer Older
Linus Tolke Y's avatar
Linus Tolke Y committed
1
/*
2
 * $Id: prot-a.c,v 0.46 1998/07/08 13:41:58 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.
 */

29 30
static const char *
rcsid = "$Id: prot-a.c,v 0.46 1998/07/08 13:41:58 ceder Exp $";
31 32
#include "rcs.h"
USE(rcsid);
Per Cederqvist's avatar
Per Cederqvist committed
33

Per Cederqvist's avatar
Per Cederqvist committed
34 35 36
#ifdef HAVE_STDDEF_H
#  include <stddef.h>
#endif
37 38 39
#ifdef HAVE_STDARG_H
#  include <stdarg.h>
#endif
Per Cederqvist's avatar
Per Cederqvist committed
40
#include <setjmp.h>
41 42 43
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
Per Cederqvist's avatar
Per Cederqvist committed
44

Per Cederqvist's avatar
Per Cederqvist committed
45
#include "misc-types.h"
46
#include "s-string.h"
Per Cederqvist's avatar
Per Cederqvist committed
47
#include "kom-types.h"
Per Cederqvist's avatar
Per Cederqvist committed
48
#include "com.h"
49
#include "async.h"
Per Cederqvist's avatar
Per Cederqvist committed
50
#include "connections.h"
Per Cederqvist's avatar
Per Cederqvist committed
51 52 53 54 55
#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
56 57 58
#include "prot-a.h"
#include "prot-a-output.h"
#include "prot-a-parse.h"
Per Cederqvist's avatar
Per Cederqvist committed
59
#include "isc-parse.h"
60
#include "param.h"
Per Cederqvist's avatar
Per Cederqvist committed
61
#include "kom-memory.h"
Per Cederqvist's avatar
Per Cederqvist committed
62 63 64 65 66

BUGDECL;

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

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

	switch ( fnc_defs[ client->function ].result )
	{
80
	case rt_number:
81 82
	    mux_printf(client, " %lu", (unsigned long)res->number);
	    BUG(("=%lu\n", res->number));
Per Cederqvist's avatar
Per Cederqvist committed
83 84
	    break;

85
	case rt_success:
Per Cederqvist's avatar
Per Cederqvist committed
86 87 88
	    BUG(("=Success\n"));
	    break;
	    
89
	case rt_person:
Per Cederqvist's avatar
Per Cederqvist committed
90 91 92 93
	    prot_a_output_person(client, &res->person);
	    BUG(("={Person struct not listed}\n"));
	    break;

94 95 96 97 98
	case rt_membership_old:
	    prot_a_output_membership_old(client, &res->membership);
	    BUG(("={Membership struct not listed}\n"));
	    break;

99
	case rt_membership:
Per Cederqvist's avatar
Per Cederqvist committed
100 101 102 103
	    prot_a_output_membership(client, &res->membership);
	    BUG(("={Membership struct not listed}\n"));
	    break;

104
	case rt_conf_list:
Per Cederqvist's avatar
Per Cederqvist committed
105 106 107 108
	    prot_a_output_conf_list(client, res->conf_list);
	    BUG(("={Conf_list not listed}\n"));
	    break;

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

119 120 121 122 123
	case rt_conference_old:
	    prot_a_output_conference_old(client, &res->conference);
	    BUG(("={Conference (old) struct not listed}\n"));
	    break;

124
	case rt_string:
Per Cederqvist's avatar
Per Cederqvist committed
125
	    prot_a_output_string(client, res->string);
126
	    BUG(("={%luH", res->string.len));
Per Cederqvist's avatar
Per Cederqvist committed
127 128 129 130
	    BUGSTR(res->string);
	    BUG(("}\n"));
	    break;
	    
131
	case rt_mark_list:
Per Cederqvist's avatar
Per Cederqvist committed
132 133 134 135
	    prot_a_output_mark_list(client, res->mark_list);
	    BUG(("={Mark_list not listed}\n"));
	    break;
	    
136 137 138 139 140
	case rt_text_stat_old:
	    prot_a_output_text_stat_old(client, &res->text_stat);
	    BUG(("={Text_stat (old) struct not listed}\n"));
	    break;
	    
141
	case rt_text_stat:
Per Cederqvist's avatar
Per Cederqvist committed
142 143 144 145
	    prot_a_output_text_stat(client, &res->text_stat);
	    BUG(("={Text_stat struct not listed}\n"));
	    break;
	    
146
	case rt_text_list:
Per Cederqvist's avatar
Per Cederqvist committed
147 148 149 150
	    prot_a_output_text_list(client, res->text_list);
	    BUG(("={Text_list 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 188 189 190 191
	case rt_membership_list_old:
	    prot_a_output_membership_list_old (client, res->membership_list);
	    BUG (("={Membership_list not listed}\n"));
	    break;
	    
192
	case rt_member_list:
Per Cederqvist's avatar
Per Cederqvist committed
193 194 195 196
	    prot_a_output_member_list (client, res->member_list);
	    BUG(("={Member_list not listed}\n"));
	    break;

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

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

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

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

	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
225
					     &res->session_info_ident);
226 227
	    BUG(("={Session_info_ident not listed}\n"));
	    break;
228 229 230 231 232 233 234 235 236 237

	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;
238 239 240 241 242

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

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

	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;
Per Cederqvist's avatar
Per Cederqvist committed
260 261 262 263 264 265
	}
	mux_putc('\n', client);
    }
    else
    {
	/* Failure. Give a reply with the error message. */
266 267
	mux_printf(client, "%%%u %u %lu\n",
		   client->ref_no, kom_errno, err_stat);
Per Cederqvist's avatar
Per Cederqvist committed
268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284
	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;
285
    conn->array_parse_index = 0;
Per Cederqvist's avatar
Per Cederqvist committed
286 287 288 289
    conn->array_parse_pos = 0;
    conn->struct_parse_pos = 0;
    conn->string_parse_pos = 0;
    conn->ref_no = 0;
290
    conn->function = call_fnc_login_old;
Per Cederqvist's avatar
Per Cederqvist committed
291 292 293 294 295 296 297 298
    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;
299 300
    conn->aux_item_list.items = NULL;
    conn->aux_item_list.length = 0;
Per Cederqvist's avatar
Per Cederqvist committed
301
    conn->c_local_text_no_p = NULL;
302 303
    init_priv_bits(&conn->priv_bits);
    init_conf_type(&conn->conf_type);
Per Cederqvist's avatar
Per Cederqvist committed
304 305 306 307 308
}

void
prot_a_destruct(Connection *conn)
{
309
    int i;
Per Cederqvist's avatar
Per Cederqvist committed
310 311 312 313 314 315 316 317 318 319

    /*
     * 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);
320 321 322 323 324 325 326
    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
327 328 329 330 331
    sfree(conn->c_misc_info_p);
    sfree(conn->c_local_text_no_p);
}


332 333 334 335 336
/*
 * Check if it is a legal function.
 *
 * BUG: This should be generated from fncdef.txt.
 */
Per Cederqvist's avatar
Per Cederqvist committed
337 338 339 340 341
static Bool
prot_a_is_legal_fnc(Call_header fnc)
{
    switch(fnc)
    {
342
    case call_fnc_login_old:
343 344 345 346 347
    case call_fnc_logout:
    case call_fnc_change_conference:
    case call_fnc_change_name:
    case call_fnc_change_what_i_am_doing:
    case call_fnc_create_person_old:
Per Cederqvist's avatar
Per Cederqvist committed
348
    case call_fnc_set_priv_bits:
349
    case call_fnc_set_passwd:
350
    case call_fnc_query_read_texts_old:
351 352 353 354
    case call_fnc_create_conf_old:
    case call_fnc_delete_conf:
    case call_fnc_lookup_name:
    case call_fnc_get_conf_stat_older:
355
    case call_fnc_add_member_old:
356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377
    case call_fnc_sub_member:
    case call_fnc_set_presentation:
    case call_fnc_set_etc_motd:
    case call_fnc_set_supervisor:
    case call_fnc_set_permitted_submitters:
    case call_fnc_set_super_conf:
    case call_fnc_set_conf_type:
    case call_fnc_set_garb_nice:
    case call_fnc_get_marks:
    case call_fnc_mark_text_old:
    case call_fnc_get_text:
    case call_fnc_get_text_stat_old:
    case call_fnc_mark_as_read:
    case call_fnc_create_text_old:
    case call_fnc_delete_text:
    case call_fnc_add_recipient:
    case call_fnc_sub_recipient:
    case call_fnc_add_comment:
    case call_fnc_sub_comment:
    case call_fnc_get_map:
    case call_fnc_get_time:
    case call_fnc_get_info_old:
Per Cederqvist's avatar
Per Cederqvist committed
378 379 380 381 382 383
    case call_fnc_add_footnote:
    case call_fnc_sub_footnote:
    case call_fnc_who_is_on_old:
    case call_fnc_set_unread:
    case call_fnc_set_motd_of_lyskom:
    case call_fnc_enable:
Per Cederqvist's avatar
Per Cederqvist committed
384
    case call_fnc_sync_kom:
Per Cederqvist's avatar
Per Cederqvist committed
385
    case call_fnc_shutdown_kom:
Per Cederqvist's avatar
Per Cederqvist committed
386
    case call_fnc_broadcast:
387
    case call_fnc_get_membership_old:
Per Cederqvist's avatar
Per Cederqvist committed
388
    case call_fnc_get_created_texts:
389
    case call_fnc_get_members_old:
390 391
    case call_fnc_get_person_stat_old:
    case call_fnc_get_conf_stat_old:
Per Cederqvist's avatar
Per Cederqvist committed
392 393 394 395 396 397
    case call_fnc_who_is_on:
    case call_fnc_get_unread_confs:
    case call_fnc_send_message:
    case call_fnc_get_session_info:
    case call_fnc_disconnect:
    case call_fnc_who_am_i:
Per Cederqvist's avatar
Per Cederqvist committed
398
    case call_fnc_set_user_area:
399
    case call_fnc_get_last_text:
400
    case call_fnc_create_anonymous_text_old:
401 402
    case call_fnc_find_next_text_no:
    case call_fnc_find_previous_text_no:
403
    case call_fnc_login:
404 405
    case call_fnc_who_is_on_ident:
    case call_fnc_get_session_info_ident:
406 407
    case call_fnc_re_lookup_person:
    case call_fnc_re_lookup_conf:
408 409 410 411 412 413 414
    case call_fnc_lookup_person:
    case call_fnc_lookup_conf:
    case call_fnc_set_client_version:
    case call_fnc_get_client_name:
    case call_fnc_get_client_version:
    case call_fnc_mark_text:
    case call_fnc_unmark_text:
415 416
    case call_fnc_re_z_lookup:
    case call_fnc_get_version_info:
417
    case call_fnc_lookup_z_name:
Kent Engström's avatar
Kent Engström committed
418
    case call_fnc_set_last_read:
419
    case call_fnc_get_uconf_stat:
420
    case call_fnc_set_info:
421 422
    case call_fnc_accept_async:
    case call_fnc_query_async:
423 424 425
    case call_fnc_user_active:
    case call_fnc_who_is_on_dynamic:
    case call_fnc_get_static_session_info:
426 427 428 429 430 431 432 433 434 435 436 437 438 439
    case call_fnc_get_collate_table:
    case call_fnc_create_text:
    case call_fnc_create_anonymous_text:
    case call_fnc_create_person:
    case call_fnc_create_conf:
    case call_fnc_get_text_stat:
    case call_fnc_get_conf_stat:
    case call_fnc_get_person_stat:
    case call_fnc_modify_text_info:
    case call_fnc_modify_conf_info:
    case call_fnc_get_info:
    case call_fnc_modify_server_info:
    case call_fnc_query_predefined_aux_items:
    case call_fnc_set_expire:
440 441 442 443 444
    case call_fnc_query_read_texts:
    case call_fnc_add_member:
    case call_fnc_get_membership:
    case call_fnc_get_members:
    case call_fnc_set_membership_type:
Per Cederqvist's avatar
Per Cederqvist committed
445 446 447 448 449 450 451 452 453 454 455
	return TRUE;

    default:
	return FALSE;
    }
}    


void
prot_a_parse_packet(Connection *client)
{
456
    if ( client->username_valid == FALSE )
Per Cederqvist's avatar
Per Cederqvist committed
457 458 459
    {
	/* Connection not established yet */

460 461
	prot_a_parse_string(client, &client->c_string0, 
			    param.username_len);
Per Cederqvist's avatar
Per Cederqvist committed
462 463 464 465

	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... */
466 467

	client->username_valid = TRUE;
Per Cederqvist's avatar
Per Cederqvist committed
468 469
	mux_printf(client, "LysKOM\n");
	mux_flush(client);
470
	BUG(("[Client %lu is logged on]\n", client->session_no));
Per Cederqvist's avatar
Per Cederqvist committed
471 472 473 474 475 476 477 478 479
    }	

    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 */
480
	client->function = (enum call_header)prot_a_parse_long(client);
Per Cederqvist's avatar
Per Cederqvist committed
481
	if ( !prot_a_is_legal_fnc(client->function) )
482
	    client->function = illegal_fnc;
Per Cederqvist's avatar
Per Cederqvist committed
483 484 485 486
	client->parse_pos = 2;
	/* Fall through */
    case 2:
	/* Call the function that parses the arguments for this call. */
Per Cederqvist's avatar
Per Cederqvist committed
487
	(*fnc_defs[client->function].parser)(client);
Per Cederqvist's avatar
Per Cederqvist committed
488 489 490 491 492
	/* Fall through */
    default:
	client->parse_pos = 0;
    }
}