⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dpi.c

📁 基于minigui的浏览器. 这是最新版本.
💻 C
📖 第 1 页 / 共 2 页
字号:
 * Return the dpid's UDS name, NULL on failure. */static gchar *Dpi_get_dpid_uds_name(void){   gchar *dpid_uds_dir, *dpid_uds_name = NULL;   if ((dpid_uds_dir = Dpi_get_dpid_uds_dir()) != NULL)      dpid_uds_name= g_strconcat(dpid_uds_dir, "/", "dpid.srs", NULL);   g_free(dpid_uds_dir);   return dpid_uds_name;}/* * Confirm that the dpid is running. If not, start it. * Return: 0 running OK, 1 starting (EAGAIN), 2 Error. */static gint Dpi_check_dpid(void){   static gint starting = 0;   gchar *dpid_uds_name;   gint check_st = 1, ret = 2;   if ((dpid_uds_name = Dpi_get_dpid_uds_name()))      check_st = Dpi_check_uds(dpid_uds_name);   _MSG("Dpi_check_dpid: dpid_uds_name=%s, check_st=%d\n",        dpid_uds_name, check_st);   if (check_st == 0) {      /* connection test with dpi server passed */      starting = 0;      ret = 0;   } else if (!dpid_uds_name || check_st) {      if (!starting) {         /* start dpid */         if (Dpi_start_dpid() == 0) {            starting = 1;            ret = 1;         }      } else if (++starting < 25) {         ret = 1;      } else {         /* we waited too much, report an error... */         starting = 0;      }   }   g_free(dpid_uds_name);   DEBUG_MSG(2, "Dpi_check_dpid:: %s\n",             (ret == 0) ? "OK" : (ret == 1 ? "EAGAIN" : "ERROR"));   return ret;}/* * Return the UDS name of a dpi server. * (A query is sent to dpid and then its answer parsed) * note: as the available servers and/or the dpi socket directory can *       change at any time, we'll ask each time. If someday we find *       that connecting each time significantly degrades performance, *       an optimized approach can be tried. */static gchar *Dpi_get_server_uds_name(const gchar *server_name){   gchar *dpid_uds_dir, *dpid_uds_name = NULL,         *server_uds_name = NULL;   gint st;   g_return_val_if_fail (server_name != NULL, NULL);   DEBUG_MSG(2, "Dpi_get_server_uds_name:: server_name = [%s]\n", server_name);   dpid_uds_dir = Dpi_get_dpid_uds_dir();   if (dpid_uds_dir) {      struct sockaddr_un dpid;      gint sock, req_sz, rdlen;      gchar buf[128], *cmd, *request, *rply;      size_t buflen;      /* Get the server's uds name from dpid */      sock = socket(AF_LOCAL, SOCK_STREAM, 0);      dpid.sun_family = AF_LOCAL;      dpid_uds_name = g_strconcat(dpid_uds_dir, "/", "dpid.srs", NULL);      _MSG("dpid_uds_name = [%s]\n", dpid_uds_name);      strncpy(dpid.sun_path, dpid_uds_name, sizeof(dpid.sun_path));      if (connect(sock, (struct sockaddr *) &dpid, sizeof(dpid)) == -1)         perror("connect");      /* ask dpid to check the server plugin and send its UDS name back */      request = a_Dpip_build_cmd("cmd=%s msg=%s", "check_server", server_name);      DEBUG_MSG(2, "[%s]\n", request);      do         st = write(sock, request, strlen(request));      while (st < 0 && errno == EINTR);      if (st < 0 && errno != EINTR)         perror("writing request");      g_free(request);      shutdown(sock, 1); /* signals no more writes to dpid */      /* Get the reply */      rply = NULL;      buf[0] = '\0';      buflen = sizeof(buf)/sizeof(buf[0]);      for (req_sz = 0; (rdlen = read(sock, buf, buflen)) != 0;           req_sz += rdlen) {         if (rdlen == -1 && errno == EINTR)               continue;         if (rdlen == -1) {            perror(" ** Dpi_get_server_uds_name **");            break;         }         rply = g_realloc(rply, (guint)(req_sz + rdlen + 1));         if (req_sz == 0)            rply[0] = '\0';         strncat(rply, buf, (size_t)rdlen);      }      Dpi_close_fd(sock);      DEBUG_MSG(2, "rply = [%s]\n", rply);      /* Parse reply */      if (rdlen == 0 && rply) {         cmd = a_Dpip_get_attr(rply, (gint)strlen(rply), "cmd");         if (strcmp(cmd, "send_data") == 0)            server_uds_name = a_Dpip_get_attr(rply, (gint)strlen(rply), "msg");         g_free(cmd);         g_free(rply);      }   }   g_free(dpid_uds_dir);   g_free(dpid_uds_name);   DEBUG_MSG(2, "Dpi_get_server_uds_name:: %s\n", server_uds_name);   return server_uds_name;}/* * Connect a socket to a dpi server and return the socket's FD. * We have to ask 'dpid' (dpi daemon) for the UDS of the target dpi server. * Once we have it, then the proper file descriptor is returned (-1 on error). */static gint Dpi_connect_socket(const gchar *server_name, gint retry){   char *server_uds_name;   struct sockaddr_un pun;   gint SockFD, err;   /* Query dpid for the UDS name for this server */   server_uds_name = Dpi_get_server_uds_name(server_name);   DEBUG_MSG(2, "server_uds_name = [%s]\n", server_uds_name);   if (access(server_uds_name, F_OK) != 0) {      MSG("server socket was NOT found\n");      return -1;   }   /* connect with this server's socket */   memset(&pun, 0, sizeof(struct sockaddr_un));   pun.sun_family = AF_LOCAL;   strncpy(pun.sun_path, server_uds_name, sizeof (pun.sun_path));   g_free(server_uds_name);   if ((SockFD = socket(AF_LOCAL, SOCK_STREAM, 0)) == -1)      perror("[dpi::socket]");   else if (connect(SockFD, (void*)&pun, D_SUN_LEN(&pun)) == -1) {      err = errno;      SockFD = -1;      MSG("[dpi::connect] errno:%d %s\n", errno, g_strerror(errno));      if (retry) {         switch (err) {            case ECONNREFUSED: case EBADF: case ENOTSOCK: case EADDRNOTAVAIL:               /* the server may crash and its socket name survive */               unlink(pun.sun_path);               SockFD = Dpi_connect_socket(server_name, FALSE);               break;         }      }   }   return SockFD;}/* * CCC function for the Dpi module */void a_Dpi_ccc(int Op, int Branch, int Dir, ChainLink *Info,               void *Data1, void *Data2){   GSList *list;   gint SockFD = -1, st;   a_Chain_debug_msg("a_Dpi_ccc", Op, Branch, Dir);   if (Branch == 1) {      if (Dir == BCK) {         /* Cache request, return the FD. */         /* (Data1 = Url;  Data2 = Web) */         switch (Op) {         case OpStart:            /* We'll know the FD later, enqueue this connection.             * (The Url is used as an identifier for the connection) */            Info->LocalKey = a_Url_dup(Data1);            PendingNodes = g_slist_append(PendingNodes, (gpointer)Info);            break;         }      } else {  /* FWD */         switch (Op) {         case OpEnd:            /* End this requesting branch */            a_Url_free(Info->LocalKey);            a_Chain_fcb(OpEnd, Info, NULL, NULL);            break;         case OpAbort:            list = g_slist_find_custom(                      PendingNodes, Info->LocalKey, Dpi_node_cmp);            if (list) {               /* The connection is not pending anymore */               PendingNodes = g_slist_remove(PendingNodes, list->data);            }            a_Url_free(Info->LocalKey);            a_Chain_fcb(OpAbort, Info, NULL, NULL);            break;         }      }   } else if (Branch == 2) {      if (Dir == BCK) {         /* Send commands to dpi-server */         switch (Op) {         case OpStart:            if ((st = Dpi_check_dpid()) == 0) {               SockFD = Dpi_connect_socket(Data1, TRUE);               if (SockFD != -1) {                  gint *fd = g_new(gint, 1);                  *fd = SockFD;                  Info->LocalKey = fd;                  a_Chain_link_new(Info, a_Dpi_ccc, BCK, a_IO_ccc, 3, 2);                  a_Chain_bcb(OpStart, Info, Info->LocalKey, NULL);                  /* tell the capi to start the receiving branch */                  a_Chain_fcb(OpSend, Info, Info->LocalKey, "SockFD");               }            }            if (st == 0 && SockFD != -1)               a_Chain_fcb(OpSend, Info, NULL, (void*)"DpidOK");            else if (st == 1)               a_Chain_fcb(OpSend, Info, NULL, (void*)"DpidEAGAIN");            else {               DEBUG_MSG(4, "dpi.c: ERROR, can't start dpi daemon\n");               a_Dpi_ccc(OpAbort, 2, FWD, Info, "ERR_dpid", NULL);            }            break;         case OpSend:            a_Chain_bcb(OpSend, Info, Data1, NULL);            break;         case OpEnd:            a_Chain_bcb(OpEnd, Info, NULL, NULL);            g_free(Info->LocalKey);            g_free(Info);            break;         case OpAbort:            MSG("a_Dpi_ccc: OpAbort[2B], Not implemented\n");            g_free(Info->LocalKey);            g_free(Info);            break;         }      } else {  /* FWD */         /* Send commands to dpi-server (status) */         switch (Op) {         case OpEnd:            a_Chain_del_link(Info, BCK);            g_free(Info);            break;         case OpSend:         case OpAbort:            a_Chain_fcb(OpAbort, Info, Data1, NULL);            g_free(Info);            break;         }      }   } else if (Branch == 3) {      if (Dir == FWD) {         /* Receiving from server */         switch (Op) {         case OpSend:            Dpi_process_io(IORead, Data1, Info->LocalKey);            break;         case OpEnd:            a_Chain_del_link(Info, BCK);            Dpi_process_io(IOClose, Data1, Info->LocalKey);            Dpi_conn_data_free(Info->LocalKey);            a_Chain_fcb(OpEnd, Info, NULL, NULL);            break;         case OpAbort:            MSG(" Not implemented\n");            break;         }      } else {  /* BCK */         switch (Op) {         case OpStart:            {            IOData_t *io2;            Info->LocalKey = Dpi_conn_data_new(Info);            io2 = a_IO_new(IORead, *(int*)Data1); /* SockFD */            a_IO_set_buf(io2, NULL, IOBufLen);            a_Chain_link_new(Info, a_Dpi_ccc, BCK, a_IO_ccc, 2, 3);            a_Chain_bcb(OpStart, Info, io2, NULL);            break;            }         case OpSend:            /* now that we have the FD, resume the connection.             * (Data1 = FD, Data2 = Url) */            list = g_slist_find_custom(PendingNodes, Data2, Dpi_node_cmp);            if (list) {               ChainLink *P_Info = list->data;               /* Tell the cache to start the receiving CCC */               a_Chain_fcb(OpSend, P_Info, Data1, NULL);               /* The connection is not pending anymore */               PendingNodes = g_slist_remove(PendingNodes, list->data);               /* End this requesting CCC */               a_Dpi_ccc(OpEnd, 1, FWD, P_Info, NULL, NULL);            }            break;         case OpStop:            /* Stop transfer, abort the pending node.             * (Data1 = Url, Data2 = NULL) */            list = g_slist_find_custom(PendingNodes, Data1, Dpi_node_cmp);            if (list) {               ChainLink *P_Info = list->data;               /* Abort this requesting CCC */               a_Dpi_ccc(OpAbort, 1, FWD, P_Info, Data1, NULL);            }            break;         case OpAbort:            MSG(" Not implemented\n");            break;         }      }   } else if (Branch == 4) {      /* Unused */      g_assert_not_reached();   }}/*! Send DpiBye to dpid * Note: currently disabled. Maybe it'd be better to have a * dpid_idle_timeout variable in the config file. */void a_Dpi_bye_dpid(){   char *DpiBye_cmd;   struct sockaddr_un sa;   size_t sun_path_len, addr_len;   char *srs_name;   int new_socket;   srs_name = Dpi_get_dpid_uds_name();   sun_path_len = sizeof(sa.sun_path);   addr_len = sizeof(sa);   sa.sun_family = AF_LOCAL;   if ((new_socket = socket(AF_LOCAL, SOCK_STREAM, 0)) == -1) {      DEBUG_MSG(4, "a_Dpi_bye_dpid: %s\n", g_strerror(errno));   }   strncpy(sa.sun_path, srs_name, sizeof (sa.sun_path));   if (connect(new_socket, (struct sockaddr *) &sa, addr_len) == -1) {      DEBUG_MSG(4, "a_Dpi_bye_dpid: %s\n", g_strerror(errno));      fprintf(stderr, "%s\n", sa.sun_path);   }   DpiBye_cmd = a_Dpip_build_cmd("cmd=%s", "DpiBye");   (void) write(new_socket, DpiBye_cmd, strlen(DpiBye_cmd));   g_free(DpiBye_cmd);   Dpi_close_fd(new_socket);}/* * Send a command to a dpi server, and block until the answer is got. * Return value: the dpip tag answer as an string, NULL on error. */char *a_Dpi_send_blocking_cmd(const gchar *server_name, const gchar *cmd){   gint i, cst, SockFD;   ssize_t st;   gchar buf[16384], *retval = NULL;   /* test the dpid, and wait a bit for it to start if necessary */   for (i = 0; (cst = Dpi_check_dpid()) == 1 && i < 2; ++i)      sleep(1);   if (cst != 0)      return retval;   SockFD = Dpi_connect_socket(server_name, TRUE);   if (SockFD != -1) {      /* todo: handle the case of (st < strlen(cmd)) */      do         st = write(SockFD, cmd, strlen(cmd));      while (st == -1 && errno == EINTR);      /* todo: if the answer is too long... */      do         st = read(SockFD, buf, 16384);      while (st < 0 && errno == EINTR);      if (st == -1)         perror("[a_Dpi_send_blocking_cmd]");      else if (st > 0)         retval = g_strndup(buf, (guint)st);      Dpi_close_fd(SockFD);   } else {      perror("[a_Dpi_send_blocking_cmd]");   }   return retval;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -