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

📄 dillo.c

📁 浏览器的源代码,可移植到嵌入式设备.
💻 C
字号:
/* * Dillo web browser * * Copyright 1997 Raph Levien <raph@acm.org> * Copyright 1999-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. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include <stdio.h>#include <gtk/gtk.h>#include <sys/types.h>#include <sys/stat.h>#include <string.h>#include <errno.h>#include <fcntl.h>#include <unistd.h>#include <stdlib.h>#include <signal.h>#include <sys/wait.h>#include <ctype.h>#include <locale.h>#include <config.h>#include "msg.h"#include "dillo.h"#include "misc.h"#include "nav.h"#include "history.h"#include "bookmark.h"#include "dicache.h"#include "dns.h"#include "IO/mime.h"#include "prefs.h"#include "interface.h"#include "dw.h"#include "cookies.h"/* * Command line options structure */typedef struct {   char *sh_opt; /* must be non NULL */   char *lg_opt; /* must be non NULL */   int opt_argc; /* positive: mandatory, negative: optional */   int opt_flg;  /* 1 << n */   char *help;   /* can be NULL */} CLI_options;enum {   DILLO_CLI_XID           = 1 << 1,   DILLO_CLI_FULLWINDOW    = 1 << 2,   DILLO_CLI_HELP          = 1 << 3,   DILLO_CLI_VERSION       = 1 << 4,   DILLO_CLI_LOCAL         = 1 << 5,   DILLO_CLI_GEOMETRY      = 1 << 6,   DILLO_CLI_DBG_RENDERING = 1 << 7,   DILLO_CLI_ERROR         = 1 << 31};enum {   O_SEARCH, O_FOUND, O_NOTFOUND, O_OK, O_ERROR, O_DONE};/* * Global variables from command line options; */gboolean dillo_dbg_rendering = FALSE;/* * Forward declarations */static void Dillo_check_home_dir(char *dir);static guint32 Dillo_get_opt(CLI_options *options, int argc,                             char **argv, char ***opt_arg, gint *idx);static void Dillo_print_help(CLI_options *options);static void Dillo_print_version(void);/* * Local data */static CLI_options Options[] = {   {"-x", "--xid",        1, DILLO_CLI_XID,    "  -x, --xid XID          Open first Dillo window in an existing\n"    "                         GtkSocket which window ID is XID (decimal)."},   {"-v", "--version",    0, DILLO_CLI_VERSION,    "  -v, --version          Display version info and exit."},   {"-h", "--help",       0, DILLO_CLI_HELP,    "  -h, --help             Display this help text and exit."},   {"-f", "--fullwindow", 0, DILLO_CLI_FULLWINDOW,    "  -f, --fullwindow       Start in full window mode."},   {"-l", "--local",      0, DILLO_CLI_LOCAL,    "  -l, --local            Don't follow links for this URL(s)."},   {"-g", "-geometry",    1, DILLO_CLI_GEOMETRY,    "  -g, -geometry GEO      Set initial window position where GEO is\n"    "                         <width>x<height>{+-}<x>{+-}<y>"},   {"-D", "--debug-rendering",                          0, DILLO_CLI_DBG_RENDERING,    "  -D, --debug-rendering  Draw additionaly several lines in a web page,\n"    "                         representing its structure. For debugging. "},   {NULL, NULL, 0, 0, NULL}};/* * Return the maximum number of option arguments */static gint Dillo_get_max_opt(CLI_options *options){   gint i, max;   for (i = 0, max = 0; options[i].sh_opt; i++)      if (abs(options[i].opt_argc) > max)         max = abs(options[i].opt_argc);   return max;}/* * Given a command line argument, build a DilloUrl for it. */static DilloUrl *Dillo_make_start_url(gchar *str){   gchar *url_str, *p, *cd;   DilloUrl *start_url;   gint is_file = FALSE;   /* This check is for files with non-URL characters */   if (access(str, F_OK) == 0) {      p = a_Misc_escape_chars(str, "% ");      url_str = g_strdup(p ? p : str);      is_file = TRUE;   } else {      /* Filter URL string */      url_str = a_Url_string_strip_delimiters(str);   }   if (is_file || access(url_str, F_OK) == 0) {      GString *UrlStr = g_string_sized_new(128);      if (url_str[0] == '/') {         g_string_sprintf(UrlStr, "file:%s", url_str);      } else {         cd = g_get_current_dir();         p = a_Misc_escape_chars(cd, "% ");         g_string_sprintf(UrlStr, "file:%s", p ? p : cd);         g_free(p);         g_free(cd);         if (UrlStr->str[UrlStr->len - 1] != '/')            g_string_append(UrlStr, "/");         g_string_append(UrlStr, url_str);      }      start_url = a_Url_new(UrlStr->str, NULL, 0, 0, 0);      g_string_free(UrlStr, TRUE);   } else {      start_url = a_Url_new(url_str, NULL, 0, 0, 0);   }   g_free(url_str);   return start_url;}/* * Get status code to avoid zombies! */static void Dillo_sigchld_handler(int signum){  int pid, status, serrno;  serrno = errno;  while (1) {     pid = waitpid (-1, &status, WNOHANG);     if (pid < 0) {        perror ("waitpid");        break;     }     if (pid == 0)       break;     /* notice_termination (pid, status); */  }  errno = serrno;}/* * ******************************** MAIN ************************************* */gint main(int argc, char *argv[]){   gchar *dir, *curr_locale;   DilloUrl *start_url;   BrowserWindow *bw;   guint32 xid = 0;   guint32 options_got = 0;   gint idx = 0;   guint opt_flg;   gint i;   char **opt_argv = NULL;   gint xpos = D_GEOMETRY_DEFAULT_XPOS, ypos = D_GEOMETRY_DEFAULT_YPOS;   gint width = D_GEOMETRY_DEFAULT_WIDTH, height = D_GEOMETRY_DEFAULT_HEIGHT;   /* set locale */   curr_locale = g_strdup(setlocale(LC_ALL, NULL));   gtk_set_locale();   /* Initialize GUI and parse GTK related args */   gtk_init(&argc, &argv);   gdk_rgb_init();   gtk_widget_set_default_colormap (gdk_rgb_get_cmap());   gtk_widget_set_default_visual (gdk_rgb_get_visual());   /* Handle command line options */   while ((opt_flg = Dillo_get_opt(Options, argc, argv, &opt_argv, &idx))) {     options_got |= opt_flg;     switch (opt_flg) {     case DILLO_CLI_VERSION:        Dillo_print_version();        return 0;        break;     case DILLO_CLI_HELP:        Dillo_print_help(Options);        return 0;        break;     case DILLO_CLI_XID:        if (opt_argv[0][0] >= '0' && opt_argv[0][0] <= '9') {           xid = strtol(opt_argv[0], NULL, 10);        } else {           g_printerr("Error: the XID must be an unsigned decimal numerical "                      "value.\nThe offending value was: %s\n", opt_argv[0]);           return -1;        }        break;     case DILLO_CLI_FULLWINDOW:     case DILLO_CLI_LOCAL:        break;     case DILLO_CLI_DBG_RENDERING:        dillo_dbg_rendering = TRUE;        break;     case DILLO_CLI_GEOMETRY:       if (a_Misc_parse_geometry(opt_argv[0], &xpos, &ypos, &width, &height))          break;     default:        g_printerr("Error in command line options.\n");        return -1;        break;     }   }   /* Send a delayed locale-related message */   MSG("Setting locale to %s...\n", curr_locale);   g_free(curr_locale);   /* This lets threads in the file module end peacefully when aborted    * todo: implement a cleaner mechanism (in file.c) */   signal(SIGPIPE, SIG_IGN);   /* This avoids making zombies when dpi-programs finish. */   signal(SIGCHLD, Dillo_sigchld_handler);   /* check that ~/.dillo exists, create it if it doesn't */   dir = a_Misc_prepend_user_home(".dillo");   Dillo_check_home_dir(dir);   g_free(dir);   a_Prefs_init();   a_Dns_init();   a_Http_init();   a_Mime_init();   a_Cache_init();   a_Dicache_init();   a_Interface_init();   a_Dw_init();   a_Cookies_init();   /* -f overrides dillorc */   if (options_got & DILLO_CLI_FULLWINDOW)      prefs.fullwindow_start = TRUE;   /* override dillorc geometry */   if (options_got & DILLO_CLI_GEOMETRY) {       prefs.width = width;       prefs.height = height;       prefs.xpos = xpos;       prefs.ypos = ypos;   }   /* a_Nav_init() has been moved into this call because it needs to be    * initialized with the new browser_window structure */   bw = a_Interface_browser_window_new(prefs.width, prefs.height, xid);   if ((prefs.xpos != D_GEOMETRY_DEFAULT_XPOS) ||       (prefs.ypos != D_GEOMETRY_DEFAULT_YPOS))      gtk_widget_set_uposition(bw->main_window, prefs.xpos, prefs.ypos);   a_Bookmarks_init();   /* Send dillo's startup screen */   a_Nav_push(bw, prefs.start_page);   for (i = idx; i < argc; i++) {      /* If more than one URL/FILE, open in new window */      if (i > idx)         bw = a_Interface_browser_window_new(prefs.width, prefs.height, 0);      start_url = Dillo_make_start_url(argv[i]);      if (options_got & DILLO_CLI_LOCAL)         a_Url_set_flags(start_url, URL_FLAGS(start_url) | URL_SpamSafe);      a_Nav_push(bw, start_url);      a_Url_free(start_url);   }   if (prefs.http_proxyuser && !a_Http_proxy_auth())      a_Interface_proxy_passwd_dialog(bw);   /* Start the GTK+ cycle */   gtk_main();   /*    * Memory deallocating routines    * (This can be left to the OS, but we'll do it, with a view to test    *  and fix our memory management)    */   a_Cookies_freeall();   a_Cache_freeall();   a_Dicache_freeall();   a_Http_freeall();   a_Dns_freeall();   a_Prefs_freeall();   a_Dw_freeall();   a_History_free();   //a_Dpi_bye_dpid();   MSG("Dillo: normal exit!\n");   return 0;}/* * Check if '~/.dillo' directory exists. * If not, try to create it. */static void Dillo_check_home_dir(char *dir){   struct stat st;   if ( stat(dir, &st) == -1 ) {      if ( errno == ENOENT && mkdir(dir, 0700) < 0 ) {         MSG("Dillo: error creating directory %s: %s\n",             dir, g_strerror(errno));      } else         MSG("Dillo: error reading %s: %s\n", dir, g_strerror(errno));   }}/* * Get next command line option. * Return value: *  opt_flg of the option *  0 if no more options found * -1 if an unrecognised option is found or if a mandatory option *    argument is not found. */static guint32Dillo_get_opt(CLI_options *options, int argc,              char **argv, char ***opt_argv, gint *cli_idx){   gint i = 0, opt_flg = 0, n_arg, state;   static int idx = 1;   guint32 ret_val = 0;   /* Allocate opt_argv */   if (*opt_argv == NULL)      *opt_argv = g_new0(gchar*, Dillo_get_max_opt(options) + 1);   state = O_SEARCH;   if (idx >= argc)      state = O_DONE;   while (1) {      switch (state) {      case O_SEARCH:         for (i = 0; options[i].sh_opt; i++)            if (strcmp(options[i].sh_opt, argv[idx]) == 0 ||                strcmp(options[i].lg_opt, argv[idx]) == 0)               break;         state = (options[i].sh_opt) ? O_FOUND : O_NOTFOUND;         break;      case O_FOUND:         ++idx;         opt_flg  = options[i].opt_flg;         n_arg = options[i].opt_argc;         /* Find the required/optional arguments of the option */         for (i = 0; idx < argc && i < abs(n_arg) && argv[idx][0] != '-'; i++)            (*opt_argv)[i] = argv[idx++];         (*opt_argv)[i] = NULL;         /* Optional arguments have opt_argc < 0 */         if (i < n_arg) {            g_printerr("Option %s requires %d argument(s)\n",                       argv[idx - i - 1], n_arg);            state = O_ERROR;         } else            state = O_OK;         break;      case O_NOTFOUND:         state = O_DONE;         if (strcmp(argv[idx], "--") == 0)            idx++;         else if (argv[idx][0] == '-')            state = O_ERROR;         break;      case O_OK:         *cli_idx = idx;         return opt_flg;         break;      case O_ERROR:         ret_val = DILLO_CLI_ERROR;         state = O_DONE;         break;      case O_DONE:         g_free(*opt_argv);         *cli_idx = idx;         return ret_val;         break;      }   }}/* * Print a short help text automatically generated from the options structure */static void Dillo_print_help(CLI_options *options){   g_print("\nUsage: dillo [OPTIONS] [URL|FILE]...\n"              "Options:\n");   for (; options && options->sh_opt; options++) {      if (options->help)         g_print("%s\n", options->help);      else         g_print("  %s, %s   *Undocumented*\n", options->sh_opt,                 options->lg_opt);   }   g_print("  URL                    URL to browse.\n"           "  FILE                   Local FILE to view.\n");   g_print("\n");}/* * Print version (TODO: and maybe a copyright notice) */static void Dillo_print_version(void){   g_print("Dillo %s\n", VERSION);}

⌨️ 快捷键说明

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