prot-a.c 10.2 KB
Newer Older
Linus Tolke Y's avatar
Linus Tolke Y committed
1
/*
Per Cederqvist's avatar
Per Cederqvist committed
2 3
 * $Id: prot-a.c,v 0.27 1994/04/05 08:03:43 ceder Exp $
 * Copyright (C) 1991, 1992, 1993, 1994  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.
 */

Per Cederqvist's avatar
Per Cederqvist committed
29
static char *rcsid = "$Id: prot-a.c,v 0.27 1994/04/05 08:03:43 ceder Exp $";
30 31
#include "rcs.h"
USE(rcsid);
Per Cederqvist's avatar
Per Cederqvist committed
32

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

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

BUGDECL;

void
prot_a_reply(Connection *client,
	     Bool status,
	     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 )
	{
78
	case rt_number:
79 80
	    mux_printf(client, " %lu", (unsigned long)res->number);
	    BUG(("=%lu\n", res->number));
Per Cederqvist's avatar
Per Cederqvist committed
81 82
	    break;

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

92
	case rt_membership:
Per Cederqvist's avatar
Per Cederqvist committed
93 94 95 96
	    prot_a_output_membership(client, &res->membership);
	    BUG(("={Membership struct not listed}\n"));
	    break;

97
	case rt_conf_list:
Per Cederqvist's avatar
Per Cederqvist committed
98 99 100 101
	    prot_a_output_conf_list(client, res->conf_list);
	    BUG(("={Conf_list not listed}\n"));
	    break;

102
	case rt_conf_no_list:
Per Cederqvist's avatar
Per Cederqvist committed
103 104 105 106
	    prot_a_output_conf_no_list(client, res->conf_no_list);
	    BUG(("={Conf_no_list not listed}\n"));
	    break;
	    	    
107
	case rt_conference:
Per Cederqvist's avatar
Per Cederqvist committed
108 109 110 111
	    prot_a_output_conference(client, &res->conference);
	    BUG(("={Conference struct not listed}\n"));
	    break;

112
	case rt_string:
Per Cederqvist's avatar
Per Cederqvist committed
113
	    prot_a_output_string(client, res->string);
114
	    BUG(("={%luH", res->string.len));
Per Cederqvist's avatar
Per Cederqvist committed
115 116 117 118
	    BUGSTR(res->string);
	    BUG(("}\n"));
	    break;
	    
119
	case rt_mark_list:
Per Cederqvist's avatar
Per Cederqvist committed
120 121 122 123
	    prot_a_output_mark_list(client, res->mark_list);
	    BUG(("={Mark_list not listed}\n"));
	    break;
	    
124
	case rt_text_stat:
Per Cederqvist's avatar
Per Cederqvist committed
125 126 127 128
	    prot_a_output_text_stat(client, &res->text_stat);
	    BUG(("={Text_stat struct not listed}\n"));
	    break;
	    
129
	case rt_text_list:
Per Cederqvist's avatar
Per Cederqvist committed
130 131 132 133
	    prot_a_output_text_list(client, res->text_list);
	    BUG(("={Text_list not listed}\n"));
	    break;

134
	case rt_who_info_list:
Per Cederqvist's avatar
Per Cederqvist committed
135 136 137 138
	    prot_a_output_who_info_list(client, res->who_info_list);
	    BUG(("={Who_info_list not listed}\n"));
	    break;

139
	case rt_who_info_list_old:
Per Cederqvist's avatar
Per Cederqvist committed
140 141 142 143 144
	    prot_a_output_who_info_list_old(client,
					    res->who_info_list_old);
	    BUG(("={Old who_info_list not listed}\n"));
	    break;

145
	case rt_session_info:
Per Cederqvist's avatar
Per Cederqvist committed
146 147
	    prot_a_output_session_info(client,
				       &res->session_info);
148 149 150
	    /* 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
151
	    s_clear(&res->session_info.username);
Per Cederqvist's avatar
Per Cederqvist committed
152 153 154
	    BUG(("={Session_info not listed}\n"));
	    break;
    
155
	case rt_info:
Per Cederqvist's avatar
Per Cederqvist committed
156 157 158 159
	    prot_a_output_info(client, &res->info);
	    BUG(("={Who_info struct not listed}\n"));
	    break;

160
	case rt_membership_list:
Per Cederqvist's avatar
Per Cederqvist committed
161 162 163 164
	    prot_a_output_membership_list (client, res->membership_list);
	    BUG (("={Membership_list not listed}\n"));
	    break;
	    
165
	case rt_member_list:
Per Cederqvist's avatar
Per Cederqvist committed
166 167 168 169
	    prot_a_output_member_list (client, res->member_list);
	    BUG(("={Member_list not listed}\n"));
	    break;

170
	case rt_time_date:
Per Cederqvist's avatar
Per Cederqvist committed
171
	    prot_a_output_time (client, res->time_date);
172
	    BUG(("=(time_t)%lu\n", (unsigned long)res->time_date));
Per Cederqvist's avatar
Per Cederqvist committed
173 174
	    break;

175
	case rt_session_no:
Per Cederqvist's avatar
Per Cederqvist committed
176
	    prot_a_output_session_no (client, res->session_no);
177
	    BUG(("=(Session_no)%lu\n", res->session_no));
Per Cederqvist's avatar
Per Cederqvist committed
178
	    break;
179 180 181

	case rt_text_no:
	    prot_a_output_text_no (client, res->text_no);
182
	    BUG(("=(Text_no)%lu\n", res->text_no));
183
	    break;
184 185 186 187 188 189 190 191 192

	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
193
					     &res->session_info_ident);
194 195
	    BUG(("={Session_info_ident not listed}\n"));
	    break;
Per Cederqvist's avatar
Per Cederqvist committed
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240
	}
	mux_putc('\n', client);
    }
    else
    {
	/* Failure. Give a reply with the error message. */
	mux_printf(client, "%%%d %d %d\n",
		client->ref_no, kom_errno, err_stat);
	BUG(("%%Err %d\n", kom_errno));
    }

    mux_flush(client);
}

/*
 * Check if it is a legal function.
 *
 * BUG: This should be generated from fncdef.txt.
 */


/*
 * 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;
    conn->array_parse_pos = 0;
    conn->struct_parse_pos = 0;
    conn->string_parse_pos = 0;
    conn->ref_no = 0;
    conn->function = 0;
    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;
    conn->c_local_text_no_p = NULL;
241 242
    init_priv_bits(&conn->priv_bits);
    init_conf_type(&conn->conf_type);
Per Cederqvist's avatar
Per Cederqvist committed
243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267
}

void
prot_a_destruct(Connection *conn)
{

    /*
     * 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);
    sfree(conn->c_misc_info_p);
    sfree(conn->c_local_text_no_p);
}


static Bool
prot_a_is_legal_fnc(Call_header fnc)
{
    switch(fnc)
    {
268
    case call_fnc_login_old:
Per Cederqvist's avatar
Per Cederqvist committed
269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291
    case call_fnc_logout: 
    case call_fnc_pepsi: 
    case call_fnc_change_name: 
    case call_fnc_change_what_i_am_doing: 
    case call_fnc_create_person: 
    case call_fnc_get_person_stat_old:
    case call_fnc_set_priv_bits:
    case call_fnc_set_passwd: 
    case call_fnc_query_read_texts: 
    case call_fnc_create_conf: 
    case call_fnc_delete_conf: 
    case call_fnc_lookup_name: 
    case call_fnc_get_conf_stat_old: 
    case call_fnc_add_member: 
    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: 
292
    case call_fnc_mark_text_old: 
Per Cederqvist's avatar
Per Cederqvist committed
293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310
    case call_fnc_get_text: 
    case call_fnc_get_text_stat: 
    case call_fnc_mark_as_read: 
    case call_fnc_create_text: 
    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:
    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
311
    case call_fnc_sync_kom:
Per Cederqvist's avatar
Per Cederqvist committed
312
    case call_fnc_shutdown_kom:
Per Cederqvist's avatar
Per Cederqvist committed
313 314 315 316 317 318 319 320 321 322 323 324
    case call_fnc_broadcast:
    case call_fnc_get_membership:
    case call_fnc_get_created_texts:
    case call_fnc_get_members:
    case call_fnc_get_person_stat:
    case call_fnc_get_conf_stat:
    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
325
    case call_fnc_set_user_area:
326
    case call_fnc_get_last_text:
Per Cederqvist's avatar
Per Cederqvist committed
327
    case call_fnc_create_anonymous_text:
328 329
    case call_fnc_find_next_text_no:
    case call_fnc_find_previous_text_no:
330 331 332
    case call_fnc_who_is_on_ident:
    case call_fnc_get_session_info_ident:
    case call_fnc_login:
333 334
    case call_fnc_re_lookup_person:
    case call_fnc_re_lookup_conf:
335 336 337 338 339 340 341
    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:
Per Cederqvist's avatar
Per Cederqvist committed
342 343 344 345 346 347 348 349 350 351 352
	return TRUE;

    default:
	return FALSE;
    }
}    


void
prot_a_parse_packet(Connection *client)
{
353
    if ( client->username_valid == FALSE )
Per Cederqvist's avatar
Per Cederqvist committed
354 355 356
    {
	/* Connection not established yet */

357 358
	prot_a_parse_string(client, &client->c_string0, 
			    param.username_len);
Per Cederqvist's avatar
Per Cederqvist committed
359 360 361 362

	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... */
363 364

	client->username_valid = TRUE;
Per Cederqvist's avatar
Per Cederqvist committed
365 366
	mux_printf(client, "LysKOM\n");
	mux_flush(client);
367
	BUG(("[Client %lu is logged on]\n", client->session_no));
Per Cederqvist's avatar
Per Cederqvist committed
368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383
    }	

    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 */
	client->function = prot_a_parse_long(client);
	if ( !prot_a_is_legal_fnc(client->function) )
	    longjmp(parse_env, ISC_PROTOCOL_ERR);
	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
384
	(*fnc_defs[client->function].parser)(client);
Per Cederqvist's avatar
Per Cederqvist committed
385 386 387 388 389 390
	/* Fall through */
    default:
	client->parse_pos = 0;
    }

}