/* * CCC function for the HTTP module */ void a_Http_ccc(int Op, int Branch, int Dir, ChainLink *Info, void *Data1, void *Data2) { int SKey = VOIDP2INT(Info->LocalKey); (void)Data2; /* suppress unused parameter warning */ dReturn_if_fail( a_Chain_check("a_Http_ccc", Op, Branch, Dir, Info) ); if (Branch == 1) { if (Dir == BCK) { /* HTTP query branch */ switch (Op) { case OpStart: /* ( Data1 = Web ) */ SKey = Http_sock_new(); Info->LocalKey = INT2VOIDP(SKey); /* link IO */ a_Chain_link_new(Info, a_Http_ccc, BCK, a_IO_ccc, 1, 1); a_Chain_bcb(OpStart, Info, NULL, NULL); /* async. connection */ Http_get(Info, Data1); break; case OpEnd: /* finished the HTTP query branch */ a_Chain_bcb(OpEnd, Info, NULL, NULL); Http_socket_free(SKey); dFree(Info); break; case OpAbort: /* something bad happened... */ a_Chain_bcb(OpAbort, Info, NULL, NULL); Http_socket_free(SKey); dFree(Info); break; } } else { /* 1 FWD */ /* HTTP send-query status branch */ switch (Op) { default: MSG_WARN("Unused CCC\n"); break; } } } }
/* * CCC function for the CAPI module */ void a_Capi_ccc(int Op, int Branch, int Dir, ChainLink *Info, void *Data1, void *Data2) { capi_conn_t *conn; dReturn_if_fail( a_Chain_check("a_Capi_ccc", Op, Branch, Dir, Info) ); if (Branch == 1) { if (Dir == BCK) { /* Command sending branch */ switch (Op) { case OpStart: /* Data1 = conn; Data2 = {Web | server} */ conn = Data1; Capi_conn_ref(conn); Info->LocalKey = conn; conn->InfoSend = Info; if (strcmp(conn->server, "http") == 0) { a_Chain_link_new(Info, a_Capi_ccc, BCK, a_Http_ccc, 1, 1); a_Chain_bcb(OpStart, Info, Data2, NULL); } else { a_Chain_link_new(Info, a_Capi_ccc, BCK, a_Dpi_ccc, 1, 1); a_Chain_bcb(OpStart, Info, Data2, NULL); } break; case OpSend: /* Data1 = dbuf */ a_Chain_bcb(OpSend, Info, Data1, NULL); break; case OpEnd: conn = Info->LocalKey; conn->InfoSend = NULL; a_Chain_bcb(OpEnd, Info, NULL, NULL); Capi_conn_unref(conn); dFree(Info); break; case OpAbort: conn = Info->LocalKey; conn->InfoSend = NULL; a_Chain_bcb(OpAbort, Info, NULL, NULL); Capi_conn_unref(conn); dFree(Info); break; default: MSG_WARN("Unused CCC\n"); break; } } else { /* 1 FWD */ /* Command sending branch (status) */ switch (Op) { case OpSend: if (!Data2) { MSG_WARN("Capi.c: Opsend [1F] Data2 = NULL\n"); } else if (strcmp(Data2, "FD") == 0) { conn = Info->LocalKey; conn->SockFD = *(int*)Data1; /* communicate the FD through the answer branch */ a_Capi_ccc(OpSend, 2, BCK, conn->InfoRecv, &conn->SockFD, "FD"); } else if (strcmp(Data2, "DpidOK") == 0) { /* resume pending dpi requests */ Capi_conn_resume(); } break; case OpAbort: conn = Info->LocalKey; conn->InfoSend = NULL; if (Data2) { if (!strcmp(Data2, "DpidERROR")) { a_UIcmd_set_msg(conn->bw, "ERROR: can't start dpid daemon " "(URL scheme = '%s')!", conn->url ? URL_SCHEME(conn->url) : ""); } else if (!strcmp(Data2, "Both") && conn->InfoRecv) { /* abort the other branch too */ a_Capi_ccc(OpAbort, 2, BCK, conn->InfoRecv, NULL, NULL); } } /* if URL == expect-url */ a_Nav_cancel_expect_if_eq(conn->bw, conn->url); /* finish conn */ Capi_conn_unref(conn); dFree(Info); break; default: MSG_WARN("Unused CCC\n"); break; } } } else if (Branch == 2) { if (Dir == BCK) { /* Answer branch */ switch (Op) { case OpStart: /* Data1 = conn; Data2 = {"http" | "<dpi server name>"} */ conn = Data1; Capi_conn_ref(conn); Info->LocalKey = conn; conn->InfoRecv = Info; a_Chain_link_new(Info, a_Capi_ccc, BCK, a_Dpi_ccc, 2, 2); a_Chain_bcb(OpStart, Info, NULL, Data2); break; case OpSend: /* Data1 = FD */ if (Data2 && strcmp(Data2, "FD") == 0) { a_Chain_bcb(OpSend, Info, Data1, Data2); } break; case OpAbort: conn = Info->LocalKey; conn->InfoRecv = NULL; a_Chain_bcb(OpAbort, Info, NULL, NULL); /* remove the cache entry for this URL */ a_Cache_entry_remove_by_url(conn->url); Capi_conn_unref(conn); dFree(Info); break; default: MSG_WARN("Unused CCC\n"); break; } } else { /* 2 FWD */ /* Server listening branch */ switch (Op) { case OpSend: conn = Info->LocalKey; if (strcmp(Data2, "send_page_2eof") == 0) { /* Data1 = dbuf */ DataBuf *dbuf = Data1; a_Cache_process_dbuf(IORead, dbuf->Buf, dbuf->Size, conn->url); } else if (strcmp(Data2, "send_status_message") == 0) { a_UIcmd_set_msg(conn->bw, "%s", Data1); } else if (strcmp(Data2, "chat") == 0) { a_UIcmd_set_msg(conn->bw, "%s", Data1); a_Bookmarks_chat_add(NULL, NULL, Data1); } else if (strcmp(Data2, "dialog") == 0) { a_Dpiapi_dialog(conn->bw, conn->server, Data1); } else if (strcmp(Data2, "reload_request") == 0) { a_Nav_reload(conn->bw); } else if (strcmp(Data2, "start_send_page") == 0) { /* prepare the cache to receive the data stream for this URL * * a_Capi_open_url() already added a new cache entry, * and a client for it. */ } break; case OpEnd: conn = Info->LocalKey; conn->InfoRecv = NULL; a_Cache_process_dbuf(IOClose, NULL, 0, conn->url); if (conn->InfoSend) { /* Propagate OpEnd to the sending branch too */ a_Capi_ccc(OpEnd, 1, BCK, conn->InfoSend, NULL, NULL); } Capi_conn_unref(conn); dFree(Info); break; default: MSG_WARN("Unused CCC\n"); break; } } } }