/* * $Id: prot-a.c,v 0.8 1991/09/21 13:06:53 ceder Exp $ * Copyright (C) 1991 Lysator Academic Computer Association. * * 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. */ /* * Protocol A. */ static char *rcsid = "$Id: prot-a.c,v 0.8 1991/09/21 13:06:53 ceder Exp $"; #include <stdio.h> #include <setjmp.h> #include <kom-errno.h> #include <kom-types.h> #include <server/smalloc.h> #include "lyskomd.h" #include "com.h" #include "connections.h" #include "isc-parse.h" #include "prot-a.h" #include "prot-a-output.h" #include "prot-a-parse.h" #include <debug.h> #include "isc-interface.h" #include "mux.h" 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 ) { case rt_number: mux_printf(client, " %ld", (u_long)res->number); BUG(("=%d\n", res->number)); break; case rt_success: BUG(("=Success\n")); break; case rt_person: prot_a_output_person(client, &res->person); BUG(("={Person struct not listed}\n")); break; case rt_membership: prot_a_output_membership(client, &res->membership); BUG(("={Membership struct not listed}\n")); break; case rt_conf_list: prot_a_output_conf_list(client, res->conf_list); BUG(("={Conf_list not listed}\n")); break; case rt_conf_no_list: prot_a_output_conf_no_list(client, res->conf_no_list); BUG(("={Conf_no_list not listed}\n")); break; case rt_conference: prot_a_output_conference(client, &res->conference); BUG(("={Conference struct not listed}\n")); break; case rt_string: prot_a_output_string(client, res->string); BUG(("={%dH", res->string.len)); BUGSTR(res->string); BUG(("}\n")); break; case rt_mark_list: prot_a_output_mark_list(client, res->mark_list); BUG(("={Mark_list not listed}\n")); break; case rt_text_stat: prot_a_output_text_stat(client, &res->text_stat); BUG(("={Text_stat struct not listed}\n")); break; case rt_text_list: prot_a_output_text_list(client, res->text_list); BUG(("={Text_list not listed}\n")); break; case rt_who_info_list: prot_a_output_who_info_list(client, res->who_info_list); BUG(("={Who_info_list not listed}\n")); break; case rt_who_info_list_old: prot_a_output_who_info_list_old(client, res->who_info_list_old); BUG(("={Old who_info_list not listed}\n")); break; case rt_session_info: prot_a_output_session_info(client, &res->session_info); BUG(("={Session_info not listed}\n")); break; case rt_info: prot_a_output_info(client, &res->info); BUG(("={Who_info struct not listed}\n")); break; case rt_membership_list: prot_a_output_membership_list (client, res->membership_list); BUG (("={Membership_list not listed}\n")); break; case rt_member_list: prot_a_output_member_list (client, res->member_list); BUG(("={Member_list not listed}\n")); break; case rt_time_date: prot_a_output_time (client, res->time_date); BUG(("=(time_t)%d\n", res->time_date)); break; case rt_session_no: prot_a_output_session_no (client, res->session_no); BUG(("=(Session_no)%d\n", res->session_no)); break; } 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; conn->priv_bits = DEFAULT_PRIV_BITS; conn->conf_type = NULL_CONF_TYPE; } 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) { case call_fnc_login: 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: case call_fnc_mark_text: 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: case call_fnc_sync: case call_fnc_shutdown: 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: case call_fnc_set_user_area: return TRUE; default: return FALSE; } } void prot_a_parse_packet(Connection *client) { if ( s_empty(client->username) ) { /* Connection not established yet */ prot_a_parse_string(client, &client->c_string0, USERNAME_LEN); 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... */ if ( s_strcat(&client->username, s_fcrea_str((const unsigned char *)"@")) != OK ) restart_kom("prot_a_parse_packet: s_strcat\n"); if ( s_strcat(&client->username, client->hostname) != OK ) restart_kom("prot_a_parse_packet: s_strcat II\n"); mux_printf(client, "LysKOM\n"); mux_flush(client); BUG(("[Client %d is logged on]\n", client->session_no)); } 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. */ fnc_defs[client->function].parser(client); /* Fall through */ default: client->parse_pos = 0; } }