Example #1
0
File: dpid.c Project: epitron/dillo
/*!
 * Send socket port that matches dpi_id to client
 */
void send_sockport(int sock_fd, char *dpi_tag, struct dp *dpi_attr_list)
{
   int i;
   char *dpi_id, *d_cmd, port_str[16];
   struct service *serv;

   dReturn_if_fail((dpi_id = get_message(sock_fd, dpi_tag)) != NULL);

   serv = dList_find_custom(services_list,dpi_id,(dCompareFunc)service_match);

   if (serv == NULL || (i = serv->dp_index) == -1)
      for (i = 0; i < numdpis; i++)
         if (!strncmp(dpi_attr_list[i].id, dpi_id,
                      dpi_attr_list[i].id - strchr(dpi_attr_list[i].id, '.')))
            break;

   if (i < numdpis) {
      /* found */
      snprintf(port_str, 8, "%d", dpi_attr_list[i].port);
      d_cmd = a_Dpip_build_cmd("cmd=%s msg=%s", "send_data", port_str);
      (void) CKD_WRITE(sock_fd, d_cmd);
      dFree(d_cmd);
   }

   dFree(dpi_id);
}
Example #2
0
/*
 * 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;
         }
      }
   }
}
Example #3
0
/*
 * Receive new data, update the reception buffer (for next read), update the
 * cache, and service the client queue.
 *
 * This function gets called whenever the IO has new data.
 *  'Op' is the operation to perform
 *  'VPtr' is a (void) pointer to the IO control structure
 */
void a_Cache_process_dbuf(int Op, const char *buf, size_t buf_size,
                          const DilloUrl *Url)
{
   int offset, len;
   const char *str;
   Dstr *dstr1, *dstr2, *dstr3;
   CacheEntry_t *entry = Cache_entry_search(Url);

   /* Assert a valid entry (not aborted) */
   dReturn_if_fail (entry != NULL);

   _MSG("__a_Cache_process_dbuf__\n");

   if (Op == IORead) {
      /*
       * Cache_get_header() will set CA_GotHeader if it has a full header, and
       * Cache_parse_header() will unset it if the header ends being
       * merely an informational response from the server (i.e., 100 Continue)
       */
      for (offset = 0; !(entry->Flags & CA_GotHeader) &&
           (len = Cache_get_header(entry, buf + offset, buf_size - offset));
           Cache_parse_header(entry) ) {
         offset += len;
      }

      if (entry->Flags & CA_GotHeader) {
         str = buf + offset;
         len = buf_size - offset;
         entry->TransferSize += len;
         dstr1 = dstr2 = dstr3 = NULL;

         /* Decode arrived data (<= 3 stages) */
         if (entry->TransferDecoder) {
            dstr1 = a_Decode_process(entry->TransferDecoder, str, len);
            str = dstr1->str;
            len = dstr1->len;
         }
         if (entry->ContentDecoder) {
            dstr2 = a_Decode_process(entry->ContentDecoder, str, len);
            str = dstr2->str;
            len = dstr2->len;
         }
         dStr_append_l(entry->Data, str, len);
         if (entry->CharsetDecoder && entry->UTF8Data) {
            dstr3 = a_Decode_process(entry->CharsetDecoder, str, len);
            dStr_append_l(entry->UTF8Data, dstr3->str, dstr3->len);
         }
         dStr_free(dstr1, 1);
         dStr_free(dstr2, 1);
         dStr_free(dstr3, 1);

         if (entry->Data->len)
            entry->Flags &= ~CA_IsEmpty;

         entry = Cache_process_queue(entry);
      }
   } else if (Op == IOClose) {
      if ((entry->ExpectedSize || entry->TransferSize) &&
          entry->TypeHdr == NULL) {
         MSG_HTTP("Message with a body lacked Content-Type header.\n");
      }
      if ((entry->Flags & CA_GotLength) &&
          (entry->ExpectedSize != entry->TransferSize)) {
         MSG_HTTP("Content-Length does NOT match message body,\n"
                  " at: %s\n", URL_STR_(entry->Url));
         MSG("entry->ExpectedSize = %d, entry->TransferSize = %d\n",
             entry->ExpectedSize, entry->TransferSize);
      }
      if (!entry->TransferSize && !(entry->Flags & CA_Redirect) &&
          (entry->Flags & WEB_RootUrl)) {
         char *eol = strchr(entry->Header->str, '\n');
         if (eol) {
            char *status_line = dStrndup(entry->Header->str,
                                         eol - entry->Header->str);
            MSG_HTTP("Body was empty. Server sent status: %s\n", status_line);
            dFree(status_line);
         }
      }
      entry->Flags |= CA_GotData;
      entry->Flags &= ~CA_Stopped;          /* it may catch up! */
      if (entry->TransferDecoder) {
         a_Decode_free(entry->TransferDecoder);
         entry->TransferDecoder = NULL;
      }
      if (entry->ContentDecoder) {
         a_Decode_free(entry->ContentDecoder);
         entry->ContentDecoder = NULL;
      }
      dStr_fit(entry->Data);                /* fit buffer size! */

      if ((entry = Cache_process_queue(entry))) {
         if (entry->Flags & CA_GotHeader) {
            Cache_unref_data(entry);
         }
      }
   } else if (Op == IOAbort) {
      /* unused */
      MSG("a_Cache_process_dbuf Op = IOAbort; not implemented!\n");
   }
}
Example #4
0
/*
 * Set a bit
 */
void a_Bitvec_set_bit(bitvec_t *bvec, int pos)
{
   dReturn_if_fail (pos < bvec->len);
   bvec->vec[pos/BVEC_SIZE] |= 1 << (pos % BVEC_SIZE);
}
Example #5
0
/*
 * 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;
         }
      }
   }
}