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

📄 dpi.c

📁 浏览器的源代码,可移植到嵌入式设备.
💻 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 "Url.h"#include "IO.h"#include "../misc.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;   gchar *Tok;   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 *//* * Task: given a tag and an attribute name, return its value. *       (character stuffing is removed here) * Return value: the attribute value, or NULL if not present or malformed. */char *Get_attr_value(char *tag, int tagsize, char *attrname){   char *p, *q, *ltag, quote, *start, *val = NULL;   ltag = g_strndup(tag, tagsize);   if ((p = strstr(ltag, attrname)) &&       (p = strchr(p, '=')) &&       (p = strpbrk(p, "'\"")) ) {      quote = *p;      start = ++p;      while ((q = strchr(p, quote)) && q[1] == quote)         p = q + 2;      if (q) {         val = g_strndup(start, q - start);         for (p = q = val; (*q = *p); ++p, ++q)            if ((*p == '"' || *p == '\'') && p[1] == p[0])               ++p;      }   }   g_free(ltag);   return val;}/* * 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->Tok = 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, io->Status);      memcpy(conn->Buf + conn->BufSize, io->Buf, 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 */static gint Dpi_get_token(conn_data_t *conn){   gint 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->Tok = buf + 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->Tok = buf + 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 */      while (conn->BufIdx < conn->BufSize && buf[conn->BufIdx] != '>')         ++conn->BufIdx;      if (conn->BufIdx < conn->BufSize) {         /* found EOT */         conn->TokIsTag = 1;         conn->TokSize = buf + conn->BufIdx - conn->Tok + 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->Tok, conn->TokSize, 0);      a_Chain_fcb(OpSend, conn->InfoRecv, dbuf, "send_page_2eof");      g_free(dbuf);      return;   }   tag = g_strndup(conn->Tok, conn->TokSize);   MSG("Dpi_parse_token: [%s]\n", tag);   g_free(tag);   cmd = Get_attr_value(conn->Tok, conn->TokSize, "cmd");   if (strcmp(cmd, "send_status_message") == 0) {      msg = Get_attr_value(conn->Tok, conn->TokSize, "msg");      a_Chain_fcb(OpSend, conn->InfoRecv, msg, cmd);      g_free(msg);   } else if (strcmp(cmd, "chat") == 0) {      msg = Get_attr_value(conn->Tok, conn->TokSize, "msg");      a_Chain_fcb(OpSend, conn->InfoRecv, msg, cmd);      g_free(msg);   } else if (strcmp(cmd, "start_send_page") == 0) {      urlstr = Get_attr_value(conn->Tok, conn->TokSize, "url");      a_Chain_fcb(OpSend, conn->InfoRecv, urlstr, cmd);      g_free(urlstr);      /* todo:  Get_attr_value(conn->Tok, conn->TokSize, "send_mode")  */      conn->Send2EOF = 1;   } else if (strcmp(cmd, "reload_request") == 0) {      urlstr = Get_attr_value(conn->Tok, conn->TokSize, "url");      a_Chain_fcb(OpSend, conn->InfoRecv, urlstr, cmd);      g_free(urlstr);   }   g_free(cmd);}/* * 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(){   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");      close(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));            write(st_pipe[1], "ERROR", 5);            close(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));   } else {      /* This is the parent process, check our child status... */      close(st_pipe[1]);      n = read(st_pipe[0], buf, 16);      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. */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 {         close(SockFD);         ret = 0;      }   }   return ret;}/* * Return the directory where the UDS are in, * NULL if it can't be found. */gchar *Dpi_get_dpid_uds_dir(void)

⌨️ 快捷键说明

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