diff options
Diffstat (limited to 'libical/src/libicalss/icalcstpserver.c')
-rw-r--r-- | libical/src/libicalss/icalcstpserver.c | 278 |
1 files changed, 278 insertions, 0 deletions
diff --git a/libical/src/libicalss/icalcstpserver.c b/libical/src/libicalss/icalcstpserver.c new file mode 100644 index 0000000000..1a6ed7b976 --- /dev/null +++ b/libical/src/libicalss/icalcstpserver.c @@ -0,0 +1,278 @@ +/* -*- Mode: C -*- + ====================================================================== + FILE: icalcstpserver.c + CREATOR: ebusboom 13 Feb 01 + + $Id$ + $Locker$ + + (C) COPYRIGHT 2000, Eric Busboom, http://www.softwarestudio.org + + This program is free software; you can redistribute it and/or modify + it under the terms of either: + + The LGPL as published by the Free Software Foundation, version + 2.1, available at: http://www.fsf.org/copyleft/lesser.html + + Or: + + The Mozilla Public License Version 1.0. You may obtain a copy of + the License at http://www.mozilla.org/MPL/ + + + ======================================================================*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "ical.h" +#include "icalcstp.h" +#include "icalcstpserver.h" +#include "pvl.h" + +#include <sys/types.h> /* For send(), others */ +#include <sys/socket.h> /* For send(), others. */ +#include <unistd.h> /* For alarm */ +#include <errno.h> +#include <stdlib.h> /* for malloc */ +#include <string.h> + + + +struct icalcstps_impl { + int timeout; + icalparser *parser; + enum cstps_state major_state; + struct icalcstps_commandfp commandfp; +}; + + + + +/* This state machine is a Mealy-type: actions occur on the + transitions, not in the states. + + Here is the state machine diagram from the CAP draft: + + + STARTTLS / + CAPABILITY + +-------+ + | | +---------------+ + | +-----------+ AUTHENTICATE | | + +-->| Connected |-------------->| Authenticated | + +-----------+ | | + | +---------------+ + | | + | | + | | + | | +-----+ STARTTLS / + | V | | CAPABILITY / + | +---------------+ | IDENTIFY + | | |<-+ + | | Identified |<----+ + | +--------| | | + | | +---------------+ | command + | | | | completes + V |DISCONNECT | | + +--------------+ | |SENDDATA | + | Disconnected |<--+ | | + +--------------+ | | ABORT + A | | + | V | + | DISCONNECT +---------------+ | + +--------------------| Receive |--+ + | |<--+ + +---------------+ | + | | CONTINUTE + +----+ + + In this implmenetation, the transition from CONNECTED to IDENTIFIED + is non-standard. The spec specifies that on the ATHENTICATE + command, the machine transitions from CONNECTED to AUTHENTICATED, + and then immediately goes to IDENTIFIED. This makes AUTHENTICATED a + useless state, so I removed it */ + +struct state_table { + enum cstps_state major_state; + enum icalcstp_command command; + void (*action)(); + enum cstps_state next_state; + +} server_state_table[] = +{ + { CONNECTED, ICAL_CAPABILITY_COMMAND , 0, CONNECTED}, + { CONNECTED, ICAL_AUTHENTICATE_COMMAND , 0, IDENTIFIED}, /* Non-standard */ + { IDENTIFIED, ICAL_STARTTLS_COMMAND, 0, IDENTIFIED}, + { IDENTIFIED, ICAL_IDENTIFY_COMMAND, 0, IDENTIFIED}, + { IDENTIFIED, ICAL_CAPABILITY_COMMAND, 0, IDENTIFIED}, + { IDENTIFIED, ICAL_SENDDATA_COMMAND, 0, RECEIVE}, + { IDENTIFIED, ICAL_DISCONNECT_COMMAND, 0, DISCONNECTED}, + { DISCONNECTED, 0, 0, 0}, + { RECEIVE, ICAL_DISCONNECT_COMMAND, 0, DISCONNECTED}, + { RECEIVE, ICAL_CONTINUE_COMMAND, 0, RECEIVE}, + { RECEIVE, ICAL_ABORT_COMMAND , 0, IDENTIFIED}, + { RECEIVE, ICAL_COMPLETE_COMMAND , 0, IDENTIFIED} +}; + + +/**********************************************************************/ + + + +icalcstps* icalcstps_new(struct icalcstps_commandfp cfp) +{ + struct icalcstps_impl* impl; + + if ( ( impl = (struct icalcstps_impl*) + malloc(sizeof(struct icalcstps_impl))) == 0) { + icalerror_set_errno(ICAL_NEWFAILED_ERROR); + return 0; + } + + impl->commandfp = cfp; + impl->timeout = 10; + + return (icalcstps*)impl; + +} + +void icalcstps_free(icalcstps* cstp); + +int icalcstps_set_timeout(icalcstps* cstp, int sec) +{ + struct icalcstps_impl *impl = (struct icalcstps_impl *) cstp; + + icalerror_check_arg_rz( (cstp!=0), "cstp"); + + impl->timeout = sec; + + return sec; +} + +typedef struct icalcstps_response { + icalrequeststatus code; + char caluid[1024]; + void* result; +} icalcstps_response; + + +icalerrorenum prep_abort(struct icalcstps_impl* impl, char* data) +{ + return ICAL_NO_ERROR; +} +icalerrorenum prep_authenticate(struct icalcstps_impl* impl, char* data) +{ return ICAL_NO_ERROR; +} +icalerrorenum prep_capability(struct icalcstps_impl* impl, char* data) +{ return ICAL_NO_ERROR; +} +icalerrorenum prep_calidexpand(struct icalcstps_impl* impl, char* data) +{ + return ICAL_NO_ERROR; +} +icalerrorenum prep_continue(struct icalcstps_impl* impl, char* data) +{ + return ICAL_NO_ERROR; +} +icalerrorenum prep_disconnect(struct icalcstps_impl* impl, char* data) +{ + return ICAL_NO_ERROR; +} +icalerrorenum prep_identify(struct icalcstps_impl* impl, char* data) +{ + return ICAL_NO_ERROR; +} +icalerrorenum prep_starttls(struct icalcstps_impl* impl, char* data) +{ + return ICAL_NO_ERROR; +} +icalerrorenum prep_upnexpand(struct icalcstps_impl* impl, char* data) +{ + return ICAL_NO_ERROR; +} +icalerrorenum prep_sendata(struct icalcstps_impl* impl, char* data) +{ return ICAL_NO_ERROR; +} + +char* icalcstps_process_incoming(icalcstps* cstp, char* input) +{ + struct icalcstps_impl *impl = (struct icalcstps_impl *) cstp; + char *i; + char *cmd_or_resp; + char *data; + char *input_cpy; + icalerrorenum error; + + icalerror_check_arg_rz(cstp !=0,"cstp"); + icalerror_check_arg_rz(input !=0,"input"); + + if ((input_cpy = (char*)strdup(input)) == 0){ + icalerror_set_errno(ICAL_NEWFAILED_ERROR); + return 0; + } + + i = (char*)strstr(" ",input_cpy); + + cmd_or_resp = input_cpy; + + if (i != 0){ + *i = '\0'; + data = ++i; + } else { + data = 0; + } + + printf("cmd: %s\n",cmd_or_resp); + printf("data: %s\n",data); + + /* extract the command, look up in the state table, and dispatch + to the proper handler */ + + if(strcmp(cmd_or_resp,"ABORT") == 0){ + error = prep_abort(impl,data); + } else if(strcmp(cmd_or_resp,"AUTHENTICATE") == 0){ + error = prep_authenticate(impl,data); + } else if(strcmp(cmd_or_resp,"CAPABILITY") == 0){ + error = prep_capability(impl,data); + } else if(strcmp(cmd_or_resp,"CALIDEXPAND") == 0){ + error = prep_calidexpand(impl,data); + } else if(strcmp(cmd_or_resp,"CONTINUE") == 0){ + error = prep_continue(impl,data); + } else if(strcmp(cmd_or_resp,"DISCONNECT") == 0){ + error = prep_disconnect(impl,data); + } else if(strcmp(cmd_or_resp,"IDENTIFY") == 0){ + error = prep_identify(impl,data); + } else if(strcmp(cmd_or_resp,"STARTTLS") == 0){ + error = prep_starttls(impl,data); + } else if(strcmp(cmd_or_resp,"UPNEXPAND") == 0){ + error = prep_upnexpand(impl,data); + } else if(strcmp(cmd_or_resp,"SENDDATA") == 0){ + error = prep_sendata(impl,data); + } + + return 0; +} + + /* Read data until we get a end of data marker */ + + + +struct icalcstps_server_stubs { + icalerrorenum (*abort)(icalcstps* cstp); + icalerrorenum (*authenticate)(icalcstps* cstp, char* mechanism, + char* data); + icalerrorenum (*calidexpand)(icalcstps* cstp, char* calid); + icalerrorenum (*capability)(icalcstps* cstp); + icalerrorenum (*cont)(icalcstps* cstp, unsigned int time); + icalerrorenum (*identify)(icalcstps* cstp, char* id); + icalerrorenum (*disconnect)(icalcstps* cstp); + icalerrorenum (*sendata)(icalcstps* cstp, unsigned int time, + icalcomponent *comp); + icalerrorenum (*starttls)(icalcstps* cstp, char* command, + char* data); + icalerrorenum (*upnexpand)(icalcstps* cstp, char* upn); + icalerrorenum (*unknown)(icalcstps* cstp, char* command, char* data); +}; + |