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

📄 dpi.c

📁 浏览器的源代码,可移植到嵌入式设备.
💻 C
📖 第 1 页 / 共 2 页
字号:
{   FILE *in;   gchar *saved_name_filename;    /*  :)  */   gchar dpid_uds_dir[256], *p;   saved_name_filename =      g_strconcat(g_get_home_dir(), "/", ".dillo/dpi_socket_dir", NULL);   in = fopen(saved_name_filename, "r");   g_free(saved_name_filename);   if (in != NULL) {      fgets(dpid_uds_dir, 256, in);      fclose(in);      if ((p = strchr(dpid_uds_dir, '\n')))         *p = 0;      if (access(dpid_uds_dir, F_OK) == 0)         p = g_strdup(dpid_uds_dir);         _MSG("Dpi_get_dpid_uds_dir:: %s\n", p);         return p;   }   _MSG("Dpi_get_dpid_uds_dir: %s \n", g_strerror(errno));   return NULL;}/* * Return the dpid's UDS name, NULL on failure. */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. */gint Dpi_check_dpid(){   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. */gchar *Dpi_get_server_uds_name(gchar *server_name){   gchar *dpid_uds_dir, *dpid_uds_name = NULL,         *server_uds_name = NULL;   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, buflen;      gchar buf[128], *cmd, *request, *rply;      /* 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 = g_strdup_printf("<dpi cmd='check_server' msg='%s'>",                                server_name);      DEBUG_MSG(2, "[%s]\n", request);      if (write(sock, request, strlen(request)) == -1)         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 && rdlen != -1;            req_sz += rdlen) {         rply = g_realloc(rply, req_sz + rdlen + 1);         if (req_sz == 0)            rply[0] = '\0';         strncat(rply, buf, rdlen);      }      close(sock);      DEBUG_MSG(2, "rply = [%s]\n", rply);      /* Parse reply */      if (rply) {         cmd = Get_attr_value(rply, strlen(rply), "cmd");         if (strcmp(cmd, "send_data") == 0)            server_uds_name = Get_attr_value(rply, 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(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 = "<dpi cmd='DpiBye'>";   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);   }   (void) write(new_socket, DpiBye_cmd, strlen(DpiBye_cmd));   close(new_socket);}

⌨️ 快捷键说明

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