aboutsummaryrefslogtreecommitdiffstats
path: root/libical/src/libicalss/icalcstp.c
diff options
context:
space:
mode:
Diffstat (limited to 'libical/src/libicalss/icalcstp.c')
-rw-r--r--libical/src/libicalss/icalcstp.c376
1 files changed, 376 insertions, 0 deletions
diff --git a/libical/src/libicalss/icalcstp.c b/libical/src/libicalss/icalcstp.c
new file mode 100644
index 0000000000..2c86ddcc2c
--- /dev/null
+++ b/libical/src/libicalss/icalcstp.c
@@ -0,0 +1,376 @@
+/* -*- Mode: C -*-
+ ======================================================================
+ FILE: icalcstps.c
+ CREATOR: ebusboom 23 Jun 2000
+
+ $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 "pvl.h"
+
+#include <sys/types.h> /* For send(), others */
+#include <sys/socket.h> /* For send(), others. */
+#include <unistd.h> /* For alarm */
+#include <errno.h>
+
+enum cstps_state {
+ NO_STATE,
+ CONNECTED,
+ AUTHENTICATED,
+ IDENTIFIED,
+ DISCONNECTED,
+ RECEIVE,
+};
+
+struct icalcstps_impl {
+ int timeout;
+ icalparser *parser;
+ enum cstps_state major_state;
+ struct icalcstps_stubs stubs;
+};
+
+
+enum cstp_command {
+ ABORT,
+ AUTHENTICATE,
+ CAPABILITY,
+ CONTINUE,
+ EXPANDCALID,
+ IDENTIFY,
+ DISCONNECT,
+ SENDDATA,
+ STARTTLS,
+ EXPANDUPN,
+ COMMAND_COMPLETE,
+ UNKNOWN
+};
+
+struct command_map {
+ enum cstp_command command;
+ char *str;
+} command_map[] =
+{
+ {ABORT,"ABORT"},
+ {AUTHENTICATE,"AUTHENTICATE"},
+ {CAPABILITY,"CAPABILITY"},
+ {CONTINUE,"CONTINUE"},
+ {EXPANDCALID,"EXPANDCALID"},
+ {IDENTIFY,"IDENTIFY"},
+ {DISCONNECT,"DISCONNECT"},
+ {SENDDATA,"SENDDATA"},
+ {STARTTLS,"STARTTLS"},
+ {EXPANDUPN,"EXPANDUPN"},
+ {UNKNOWN,"UNKNOWN"}
+};
+
+
+
+/* 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 cstp_command command;
+ void (*action)();
+ enum cstps_state next_state;
+
+} server_state_table[] =
+{
+ { CONNECTED, CAPABILITY , 0, CONNECTED},
+ { CONNECTED, AUTHENTICATE , 0, IDENTIFIED}, /* Non-standard */
+ { IDENTIFIED, STARTTLS, 0, IDENTIFIED},
+ { IDENTIFIED, IDENTIFY, 0, IDENTIFIED},
+ { IDENTIFIED, CAPABILITY, 0, IDENTIFIED},
+ { IDENTIFIED, SENDDATA, 0, RECEIVE},
+ { IDENTIFIED, DISCONNECT, 0, DISCONNECTED},
+ { DISCONNECTED, 0, 0, 0},
+ { RECEIVE, DISCONNECT, 0, DISCONNECTED},
+ { RECEIVE, CONTINUE, 0, RECEIVE},
+ { RECEIVE, ABORT , 0, IDENTIFIED},
+ { RECEIVE, COMMAND_COMPLETE , 0, IDENTIFIED}
+};
+
+
+/**********************************************************************/
+
+
+
+icalcstps* icalcstps_new(struct icalcstps_stubs stubs)
+{
+ struct icalcstps_impl* impl;
+
+ if ( ( impl = (struct icalcstps_impl*)
+ malloc(sizeof(struct icalcstps_impl))) == 0) {
+ icalerror_set_errno(ICAL_NEWFAILED_ERROR);
+ return 0;
+ }
+
+ impl->stubs = stubs;
+ 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;
+
+int line_is_command(char* line);
+int line_is_response(char* line);
+int line_is_endofdata(char* line);
+int line_is_mime(char* line);
+
+icalerrorenum prep_abort(struct icalcstps_impl* impl, char* data);
+icalerrorenum prep_authenticate(struct icalcstps_impl* impl, char* data);
+icalerrorenum prep_capability(struct icalcstps_impl* impl, char* data);
+icalerrorenum prep_calidexpand(struct icalcstps_impl* impl, char* data);
+icalerrorenum prep_continue(struct icalcstps_impl* impl, char* data);
+icalerrorenum prep_disconnect(struct icalcstps_impl* impl, char* data);
+icalerrorenum prep_identify(struct icalcstps_impl* impl, char* data);
+icalerrorenum prep_starttls(struct icalcstps_impl* impl, char* data);
+icalerrorenum prep_upnexpand(struct icalcstps_impl* impl, char* data);
+icalerrorenum prep_sendata(struct icalcstps_impl* impl, char* data);
+
+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*)index(" ",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);
+ }
+
+
+}
+
+ /* 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);
+};
+
+
+/********************** Client (Sender) Interfaces **************************/
+
+struct icalcstpc_impl {
+ int timeout;
+ icalparser *parser;
+ enum cstp_command command;
+ char* next_output;
+ char* next_input;
+};
+
+icalcstps* icalcstpc_new();
+
+void* icalcstpc_free(icalcstpc* cstpc);
+
+/* Get the next string to send to the server */
+char* icalcstpc_next_output(icalcstpc* cstp)
+{
+}
+
+/* process the next string to send to the server */
+int icalcstpc_next_input(icalcstpc* cstp)
+{
+}
+
+/* After icalcstpc_next_input returns a 0, there are responses
+ ready. use these to get them */
+icalcstpc_response icalcstpc_first_response(icalcstpc* cstp);
+icalcstpc_response icalcstpc_next_response(icalcstpc* cstp);
+
+int icalcstpc_set_timeout(icalcstpc* cstp, int sec);
+
+icalerrorenum icalcstpc_abort(icalcstpc* cstp)
+{
+ struct icalcstpc_impl* impl = (struct icalcstpc_impl*)cstp;
+
+ icalerror_check_arg_re(cstp!=0,"cstp",ICAL_BADARG_ERROR);
+
+ impl->next_output = "ABORT";
+
+}
+
+icalerrorenum icalcstpc_authenticate(icalcstpc* cstp, char* mechanism,
+ char* data, char* f(char*))
+{
+}
+
+icalerrorenum icalcstpc_capability(icalcstpc* cstp)
+{
+}
+
+icalerrorenum icalcstpc_calidexpand(icalcstpc* cstp,char* calid)
+{
+}
+
+icalerrorenum icalcstpc_continue(icalcstpc* cstp, unsigned int time)
+{
+}
+
+icalerrorenum icalcstpc_disconnect(icalcstpc* cstp)
+{
+}
+
+icalerrorenum icalcstpc_identify(icalcstpc* cstp, char* id)
+{
+}
+
+icalerrorenum icalcstpc_starttls(icalcstpc* cstp, char* command,
+ char* data, char * f(char*))
+{
+}
+
+icalerrorenum icalcstpc_upnexpand(icalcstpc* cstp,char* calid)
+{
+}
+
+icalerrorenum icalcstpc_sendata(icalcstpc* cstp, unsigned int time,
+ icalcomponent *comp)
+{
+}
+
+
+
+