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

📄 dpi.c

📁 基于minigui的浏览器. 这是最新版本.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * File: dpi.c * * Copyright (C) 2002, 2003 Jorge Arellano Cid <jcid@dillo.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. *//* * (Prototype code) * * Dillo plugins (small programs that interact with dillo) * This should be able to handle: *   bookmarks, cookies, FTP, downloads, preferences, https and *   a lot of any-to-html filters. */#include <unistd.h>#include <stdlib.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <string.h>#include <stdio.h>#include <errno.h>           /* for errno */#include <stdio.h>#include <sys/socket.h>#include <sys/un.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netdb.h>#include "../msg.h"#include "IO.h"#include "Url.h"#include "../misc.h"#include "../../dpip/dpip.h"/* #define DEBUG_LEVEL 2 */#define DEBUG_LEVEL 4#include "../debug.h"/* This one is tricky, some sources state it should include the byte * for the terminating NULL, and others say it shouldn't. */# define D_SUN_LEN(ptr) ((size_t) (((struct sockaddr_un *) 0)->sun_path) \                        + strlen ((ptr)->sun_path))/* Solaris may not have this one... */#ifndef AF_LOCAL#define AF_LOCAL AF_UNIX#endiftypedef struct {   gint FreeBuf;   gint InTag, InData;   gint PipeActive;   gint Send2EOF;   gint DataTotalSize;   gint DataRecvSize;   void *Buf;   gint BufIdx;   gint BufSize;   gint TokIdx;   gint TokSize;   gint TokIsTag;   ChainLink *InfoRecv;} conn_data_t;/* * Local data *//* list for dpi connections waiting for a FD; * it holds pointers to Info structures (i.e. CCC Nodes). */static GSList *PendingNodes = NULL;/* * Forward references *//* * Close a FD handling EINTR */static void Dpi_close_fd(gint fd){   gint st;   do      st = close(fd);   while (st < 0 && errno == EINTR);}/* * Create a new connection data structure */static conn_data_t *Dpi_conn_data_new(ChainLink *Info){   conn_data_t *conn = g_new0(conn_data_t, 1);   conn->Buf = NULL;   conn->InfoRecv = Info;   return conn;}/* * Free a connection data structure */static void Dpi_conn_data_free(conn_data_t *conn){   if (conn->FreeBuf)      g_free(conn->Buf);   g_free(conn);}/* * Append the new buffer in 'io' to Buf in 'conn' */static void Dpi_append_io_buf(conn_data_t *conn, IOData_t *io){   if (io->Status > 0) {      conn->Buf = g_realloc(conn->Buf, conn->BufSize + (gulong)io->Status);      memcpy((gchar*)conn->Buf + conn->BufSize, io->Buf, (size_t)io->Status);      conn->BufSize += io->Status;      conn->FreeBuf = 0;   }}/* * Split the data stream into tokens. * Here, a token is either: *    a) a dpi tag *    b) a raw data chunk * * Return Value: 0 upon a new token, -1 on not enough data. * * TODO: define an API and move this function into libDpip.a.*/static gint Dpi_get_token(conn_data_t *conn){   gint i, resp = -1;   gchar *buf = conn->Buf;   if (conn->FreeBuf || conn->BufIdx == conn->BufSize) {      g_free(conn->Buf);      conn->Buf = NULL;      conn->BufIdx = conn->BufSize = 0;      conn->FreeBuf = 0;      return resp;   }   if (conn->Send2EOF) {      conn->TokIdx = conn->BufIdx;      conn->TokSize = conn->BufSize - conn->BufIdx;      conn->BufIdx = conn->BufSize;      return 0;   }   if (!conn->InTag && !conn->InData) {      /* search for start of tag *//*gchar *pbuf=NULL;MSG("conn->BufIdx = %d; conn->BufSize = %d\n", conn->BufIdx,conn->BufSize);pbuf = g_strndup(buf, conn->BufSize - conn->BufIdx);MSG("buf: [%s]\n", pbuf);g_free(pbuf);*/      while (conn->BufIdx < conn->BufSize && buf[conn->BufIdx] != '<')         ++conn->BufIdx;      if (conn->BufIdx < conn->BufSize) {         /* found */         conn->InTag = 1;         conn->TokIdx = conn->BufIdx;      } else {         MSG("ERROR: [Dpi_get_token] Can't find token start\n");         conn->FreeBuf = 1;         return Dpi_get_token(conn);      }   }   if (conn->InTag) {      /* search for end of tag (EOT=" '>") */      for (i = conn->BufIdx; i < conn->BufSize; ++i)         if (buf[i] == '>' && i >= 2 && buf[i-1] == '\'' && buf[i-2] == ' ')            break;      conn->BufIdx = i;      if (conn->BufIdx < conn->BufSize) {         /* found EOT */         conn->TokIsTag = 1;         conn->TokSize = conn->BufIdx - conn->TokIdx + 1;         ++conn->BufIdx;         conn->InTag = 0;         resp = 0;      }   }   if (conn->InData) {      conn->TokIsTag = 0;      if (conn->DataRecvSize + conn->BufSize - conn->BufIdx <          conn-> DataTotalSize) {         conn->TokSize += conn->BufSize - conn->BufIdx;         conn->DataRecvSize += conn->BufSize - conn->BufIdx;         conn->FreeBuf = 1;         resp = 0;      } else {         /* srch end of data */         MSG("ERROR: [Dpi_get_token] *** NULL code here ***\n");         while (conn->BufIdx < conn->BufSize)            ++conn->BufIdx;         resp = -1;      }   }   return resp;}/* * Parse a dpi tag and take the appropriate actions */static void Dpi_parse_token(conn_data_t *conn){   gchar *tag, *cmd, *msg, *urlstr;   DataBuf *dbuf;   if (conn->Send2EOF) {      /* we're receiving data chunks from a HTML page */      dbuf = a_Chain_dbuf_new(conn->Buf + conn->TokIdx, conn->TokSize, 0);      a_Chain_fcb(OpSend, conn->InfoRecv, dbuf, "send_page_2eof");      g_free(dbuf);      return;   }   tag = g_strndup(conn->Buf + conn->TokIdx, (guint)conn->TokSize);   MSG("Dpi_parse_token: {%s}\n", tag);   cmd = a_Dpip_get_attr(conn->Buf + conn->TokIdx, conn->TokSize, "cmd");   if (strcmp(cmd, "send_status_message") == 0) {      msg = a_Dpip_get_attr(conn->Buf + conn->TokIdx, conn->TokSize, "msg");      a_Chain_fcb(OpSend, conn->InfoRecv, msg, cmd);      g_free(msg);   } else if (strcmp(cmd, "chat") == 0) {      msg = a_Dpip_get_attr(conn->Buf + conn->TokIdx, conn->TokSize, "msg");      a_Chain_fcb(OpSend, conn->InfoRecv, msg, cmd);      g_free(msg);   } else if (strcmp(cmd, "dialog") == 0) {      /* For now will send the dpip tag... */      a_Chain_fcb(OpSend, conn->InfoRecv, tag, cmd);   } else if (strcmp(cmd, "start_send_page") == 0) {      urlstr = a_Dpip_get_attr(conn->Buf + conn->TokIdx, conn->TokSize, "url");      a_Chain_fcb(OpSend, conn->InfoRecv, urlstr, cmd);      g_free(urlstr);      /* todo: a_Dpip_get_attr(conn->Buf + conn->TokIdx,       *                       conn->TokSize, "send_mode") */      conn->Send2EOF = 1;   } else if (strcmp(cmd, "reload_request") == 0) {      urlstr = a_Dpip_get_attr(conn->Buf + conn->TokIdx, conn->TokSize, "url");      a_Chain_fcb(OpSend, conn->InfoRecv, urlstr, cmd);      g_free(urlstr);   }   g_free(cmd);   g_free(tag);}/* * Compare function for searching a CCC Node with a 'web' pointer. */static gint Dpi_node_cmp(gconstpointer node, gconstpointer key){   return a_Url_cmp(key, ((ChainLink *)node)->LocalKey);}/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *//* * Get a new data buffer (within an 'io'), save it into local data, * split in tokens and parse the contents. */static void Dpi_process_io(int Op, void *Data1, conn_data_t *conn){   IOData_t *io = Data1;   /* Very useful for debugging: show the data stream as received. */   /* fwrite(io->Buf, io->Status, 1, stdout); */   if (Op == IORead) {      Dpi_append_io_buf(conn, io);      while (Dpi_get_token(conn) != -1) {         Dpi_parse_token(conn);      }   } else if (Op == IOClose) {      MSG("Dpi: [Dpi_process_io] IOClose\n");   }}/* * Start dpid. * Return: 0 starting now, 1 Error. */static gint Dpi_start_dpid(void){   pid_t pid;   gint st_pipe[2], n, ret = 1;   gchar buf[16];   /* create a pipe to track our child's status */   if (pipe(st_pipe))      return 1;   pid = fork();   if (pid == 0) {      /* This is the child process.  Execute the command. */      gchar *path1 = a_Misc_prepend_user_home(".dillo/dpid");      Dpi_close_fd(st_pipe[0]);      if (execl(path1, "dpid", NULL) == -1) {         g_free(path1);         if (execlp("dpid", "dpid", NULL) == -1) {            DEBUG_MSG(4, "Dpi_start_dpid (child): %s\n", g_strerror(errno));            do               n = write(st_pipe[1], "ERROR", 5);            while (n == -1 && errno == EINTR);            Dpi_close_fd(st_pipe[1]);            _exit (EXIT_FAILURE);         }      }   } else if (pid < 0) {      /* The fork failed.  Report failure.  */      DEBUG_MSG(4, "Dpi_start_dpid: %s\n", g_strerror(errno));      /* close the unused pipe */      Dpi_close_fd(st_pipe[0]);      Dpi_close_fd(st_pipe[1]);   } else {      /* This is the parent process, check our child status... */      Dpi_close_fd(st_pipe[1]);      do         n = read(st_pipe[0], buf, 16);      while (n == -1 && errno == EINTR);      DEBUG_MSG(2, "Dpi_start_dpid: n = %d\n", n);      if (n != 5)         ret = 0;      else         DEBUG_MSG(4, "Dpi_start_dpid: %s\n", g_strerror(errno));   }   return ret;}/* * Make a connection test for a UDS. * Return: 0 OK, 1 Not working. */static gint Dpi_check_uds(gchar *uds_name){   struct sockaddr_un pun;   gint SockFD, ret = 1;   if (access(uds_name, W_OK) == 0) {      /* socket connection test */      memset(&pun, 0, sizeof(struct sockaddr_un));      pun.sun_family = AF_LOCAL;      strncpy(pun.sun_path, uds_name, sizeof (pun.sun_path));      if ((SockFD = socket(AF_LOCAL, SOCK_STREAM, 0)) == -1 ||          connect(SockFD, (void*)&pun, D_SUN_LEN(&pun)) == -1) {         DEBUG_MSG(4, "Dpi_check_uds: %s %s\n", g_strerror(errno), uds_name);      } else {         Dpi_close_fd(SockFD);         ret = 0;      }   }   return ret;}/* * Return the directory where the UDS are in, * NULL if it can't be found. */static gchar *Dpi_get_dpid_uds_dir(void){   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;}/*

⌨️ 快捷键说明

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