aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS2
-rw-r--r--ChangeLog2
-rw-r--r--Doxyfile4
-rw-r--r--configure.ac21
-rw-r--r--devdoc/CCCwork.txt (renamed from doc/CCCwork.txt)0
-rw-r--r--devdoc/Cache.txt (renamed from doc/Cache.txt)0
-rw-r--r--devdoc/Dillo.txt (renamed from doc/Dillo.txt)0
-rw-r--r--devdoc/Dpid.txt (renamed from doc/Dpid.txt)5
-rw-r--r--devdoc/HtmlParser.txt (renamed from doc/HtmlParser.txt)0
-rw-r--r--devdoc/IO.txt (renamed from doc/IO.txt)0
-rw-r--r--devdoc/Images.txt (renamed from doc/Images.txt)3
-rw-r--r--devdoc/NC_design.txt (renamed from doc/NC_design.txt)0
-rw-r--r--devdoc/README51
-rw-r--r--devdoc/dw-changes.doc (renamed from doc/dw-changes.doc)0
-rw-r--r--devdoc/dw-example-screenshot.png (renamed from doc/dw-example-screenshot.png)bin2264 -> 2264 bytes
-rw-r--r--devdoc/dw-floats-01.png (renamed from doc/dw-floats-01.png)bin3410 -> 3410 bytes
-rw-r--r--devdoc/dw-grows.doc (renamed from doc/dw-grows.doc)0
-rw-r--r--devdoc/dw-images-and-backgrounds.doc (renamed from doc/dw-images-and-backgrounds.doc)0
-rw-r--r--devdoc/dw-layout-views.doc (renamed from doc/dw-layout-views.doc)0
-rw-r--r--devdoc/dw-layout-widgets.doc (renamed from doc/dw-layout-widgets.doc)0
-rw-r--r--devdoc/dw-line-breaking.doc (renamed from doc/dw-line-breaking.doc)0
-rw-r--r--devdoc/dw-map.doc (renamed from doc/dw-map.doc)0
-rw-r--r--devdoc/dw-out-of-flow-2.doc (renamed from doc/dw-out-of-flow-2.doc)0
-rw-r--r--devdoc/dw-out-of-flow-floats.doc (renamed from doc/dw-out-of-flow-floats.doc)0
-rw-r--r--devdoc/dw-out-of-flow.doc (renamed from doc/dw-out-of-flow.doc)0
-rw-r--r--devdoc/dw-overview.doc (renamed from doc/dw-overview.doc)0
-rw-r--r--devdoc/dw-size-of-widget.png (renamed from doc/dw-size-of-widget.png)bin1749 -> 1749 bytes
-rw-r--r--devdoc/dw-style-box-model.png (renamed from doc/dw-style-box-model.png)bin3889 -> 3889 bytes
-rw-r--r--devdoc/dw-style-length-absolute.png (renamed from doc/dw-style-length-absolute.png)bin575 -> 575 bytes
-rw-r--r--devdoc/dw-style-length-percentage.png (renamed from doc/dw-style-length-percentage.png)bin890 -> 890 bytes
-rw-r--r--devdoc/dw-style-length-relative.png (renamed from doc/dw-style-length-relative.png)bin868 -> 868 bytes
-rw-r--r--devdoc/dw-textblock-collapsing-spaces-1-1.png (renamed from doc/dw-textblock-collapsing-spaces-1-1.png)bin641 -> 641 bytes
-rw-r--r--devdoc/dw-textblock-collapsing-spaces-1-2.png (renamed from doc/dw-textblock-collapsing-spaces-1-2.png)bin521 -> 521 bytes
-rw-r--r--devdoc/dw-textblock-collapsing-spaces-2-1.png (renamed from doc/dw-textblock-collapsing-spaces-2-1.png)bin802 -> 802 bytes
-rw-r--r--devdoc/dw-textblock-collapsing-spaces-2-2.png (renamed from doc/dw-textblock-collapsing-spaces-2-2.png)bin586 -> 586 bytes
-rw-r--r--devdoc/dw-usage.doc (renamed from doc/dw-usage.doc)0
-rw-r--r--devdoc/dw-viewport-with-scrollbar.png (renamed from doc/dw-viewport-with-scrollbar.png)bin755 -> 755 bytes
-rw-r--r--devdoc/dw-viewport-without-scrollbar.png (renamed from doc/dw-viewport-without-scrollbar.png)bin542 -> 542 bytes
-rw-r--r--devdoc/dw-widget-sizes.doc (renamed from doc/dw-widget-sizes.doc)0
-rw-r--r--devdoc/fltk-problems.doc (renamed from doc/fltk-problems.doc)0
-rw-r--r--devdoc/index.doc (renamed from doc/index.doc)0
-rw-r--r--devdoc/lout.doc (renamed from doc/lout.doc)0
-rw-r--r--devdoc/not-so-simple-container.pngbin0 -> 19319 bytes
-rw-r--r--devdoc/not-so-simple-container.svg785
-rw-r--r--devdoc/rounding-errors.doc (renamed from doc/rounding-errors.doc)0
-rw-r--r--devdoc/uml-legend.doc (renamed from doc/uml-legend.doc)0
-rw-r--r--dillorc2
-rw-r--r--doc/Dw.txt11
-rw-r--r--doc/Imgbuf.txt177
-rw-r--r--doc/Makefile.am47
-rw-r--r--doc/README54
-rw-r--r--doc/Selection.txt149
-rw-r--r--doc/dillo.1.in6
-rw-r--r--doc/not-so-simple-container.pngbin5738 -> 0 bytes
-rw-r--r--dpi/cookies.c22
-rw-r--r--dpi/vsource.c70
-rw-r--r--dpid/dpid_common.h1
-rw-r--r--dpip/dpip.c21
-rw-r--r--dpip/dpip.h1
-rw-r--r--dw/table.cc20
-rw-r--r--dw/table.hh32
-rw-r--r--lout/msg.h1
-rw-r--r--src/IO/IO.c10
-rw-r--r--src/IO/Makefile.am4
-rw-r--r--src/IO/http.c217
-rw-r--r--src/IO/ssl.h47
-rw-r--r--src/IO/tls.c (renamed from src/IO/ssl.c)431
-rw-r--r--src/IO/tls.h47
-rw-r--r--src/cache.c16
-rw-r--r--src/dialog.cc20
-rw-r--r--src/dillo.cc6
-rw-r--r--src/html.cc2
-rw-r--r--src/url.c25
-rw-r--r--src/url.h10
74 files changed, 1434 insertions, 888 deletions
diff --git a/AUTHORS b/AUTHORS
index b22eb755..f92ad655 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -87,5 +87,5 @@ Non-Dillo code:
* src/md5.[ch] contain code by L. Peter Deutsch whose copyright is held by
Aladdin Enterprises.
* src/tipwin.cc contains code by Greg Ercolano.
-* src/IO/ssl.c contains code from wget whose copyright is held by the
+* src/IO/tls.c contains code from wget whose copyright is held by the
Free Software Foundation.
diff --git a/ChangeLog b/ChangeLog
index 3ff1851a..d6b11e2a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -34,6 +34,8 @@ dillo-3.1 [not released yet]
Patches: Sebastian Geerken
+- Image buffer/cache improvements.
- Fix for segfault when there's no dpid and view source is requested.
+ - Fix view-source dpi to handle null characters correctly.
+ - Made view-source dpi use CSS formatting (it's shorter and cleaner).
Patches: Jorge Arellano Cid
+- Crosscompile/buildroot-friendly fltk-config test.
Patch: Peter Seiderer
diff --git a/Doxyfile b/Doxyfile
index df509910..68ffcea9 100644
--- a/Doxyfile
+++ b/Doxyfile
@@ -852,7 +852,7 @@ EXAMPLE_RECURSIVE = NO
# that contain images that are to be included in the documentation (see the
# \image command).
-IMAGE_PATH = doc
+IMAGE_PATH = devdoc
# The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program
@@ -1298,7 +1298,7 @@ QHP_NAMESPACE =
# The default value is: doc.
# This tag requires that the tag GENERATE_QHP is set to YES.
-QHP_VIRTUAL_FOLDER = doc
+QHP_VIRTUAL_FOLDER = devdoc
# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
# filter to add. For more information please see Qt Help Project / Custom
diff --git a/configure.ac b/configure.ac
index db37619d..63f0f40e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -24,10 +24,10 @@ AC_ARG_ENABLE(gprof, [ --enable-gprof Try to compile and run with pro
, enable_gprof=no)
AC_ARG_ENABLE(insure, [ --enable-insure Try to compile and run with Insure++],
, enable_insure=no)
-AC_ARG_ENABLE(ssl, [ --enable-ssl Enable ssl, https (ALPHA CODE)],
+AC_ARG_ENABLE(ssl, [ --enable-ssl Enable SSL/HTTPS/TLS (EXPERIMENTAL CODE)],
, enable_ssl=no)
-AC_ARG_WITH(ca-certs-file, [ --with-ca-certs-file=FILE Specify where to find a bundle of trusted CA certificates for SSL], CA_CERTS_FILE=$withval)
-AC_ARG_WITH(ca-certs-dir, [ --with-ca-certs-dir=DIR Specify where to find a directory containing trusted CA certificates for SSL], CA_CERTS_DIR=$withval)
+AC_ARG_WITH(ca-certs-file, [ --with-ca-certs-file=FILE Specify where to find a bundle of trusted CA certificates for TLS], CA_CERTS_FILE=$withval)
+AC_ARG_WITH(ca-certs-dir, [ --with-ca-certs-dir=DIR Specify where to find a directory containing trusted CA certificates for TLS], CA_CERTS_DIR=$withval)
AC_ARG_ENABLE(ipv6, [ --enable-ipv6 Build with support for IPv6], , )
AC_ARG_ENABLE(cookies,[ --disable-cookies Don't compile support for cookies],
, enable_cookies=yes)
@@ -221,7 +221,10 @@ if test "x$enable_png" = "xyes"; then
dnl Check if the user hasn't set the variable $PNG_CONFIG
if test -z "$PNG_CONFIG"; then
- PNG_CONFIG=`which libpng14-config`
+ PNG_CONFIG=`which libpng16-config`
+ if test -z "$PNG_CONFIG"; then
+ PNG_CONFIG=`which libpng14-config`
+ fi
if test -z "$PNG_CONFIG"; then
PNG_CONFIG=`which libpng12-config`
fi
@@ -247,7 +250,7 @@ dnl For debugging and to be user friendly
AC_MSG_CHECKING([for libpng version])
png_version=`$PNG_CONFIG --version`
case $png_version in
- 1.[[024]].*) AC_MSG_RESULT([$png_version]) ;;
+ 1.[[0246]].*) AC_MSG_RESULT([$png_version]) ;;
*) AC_MSG_RESULT([$png_version (unrecognised version)]) ;;
esac
@@ -287,7 +290,7 @@ if test "x$enable_gif" = "xyes"; then
fi
dnl --------------------------
-dnl Test for support for SSL
+dnl Test for support for SSL/TLS
dnl --------------------------
dnl
if test "x$enable_ssl" = "xyes"; then
@@ -301,14 +304,14 @@ if test "x$enable_ssl" = "xyes"; then
if test "x$ssl_ok" = "xyes"; then
LIBSSL_LIBS="-lcrypto -lssl"
- AC_MSG_WARN([*** Enabling ssl support. THIS IS ALPHA CODE!***])
+ AC_MSG_WARN([*** Enabling SSL/HTTPS/TLS support. THIS IS EXPERIMENTAL CODE ***])
else
- AC_MSG_WARN([*** No libssl found. Disabling ssl support.***])
+ AC_MSG_WARN([*** No libssl found. Disabling SSL/HTTPS/TLS support. ***])
fi
fi
if test "x$ssl_ok" = "xyes"; then
- AC_DEFINE([ENABLE_SSL], [1], [Enable SSL support])
+ AC_DEFINE([ENABLE_SSL], [1], [Enable SSL/HTTPS/TLS support])
fi
dnl --------------------------------------------------------------
diff --git a/doc/CCCwork.txt b/devdoc/CCCwork.txt
index 1ea5d20e..1ea5d20e 100644
--- a/doc/CCCwork.txt
+++ b/devdoc/CCCwork.txt
diff --git a/doc/Cache.txt b/devdoc/Cache.txt
index 4e885df2..4e885df2 100644
--- a/doc/Cache.txt
+++ b/devdoc/Cache.txt
diff --git a/doc/Dillo.txt b/devdoc/Dillo.txt
index a63c9588..a63c9588 100644
--- a/doc/Dillo.txt
+++ b/devdoc/Dillo.txt
diff --git a/doc/Dpid.txt b/devdoc/Dpid.txt
index 82b81311..6c418f57 100644
--- a/doc/Dpid.txt
+++ b/devdoc/Dpid.txt
@@ -285,9 +285,10 @@ commented code in hello.c and start making changes!
Debugging a dpi
---------------
- The simplest way is to add printf() feedback using the MSG*
+ The simplest way is to add printf-like feedback using the MSG*
macros. You can start the dpid by hand on a terminal to force
-messages to go there.
+messages to go there. Filter dpis use sdterr and server dpis
+stdout.
Sometimes more complex dpis need more than MSG*. In this case
you can use gdb like this.
diff --git a/doc/HtmlParser.txt b/devdoc/HtmlParser.txt
index 2eb8be63..2eb8be63 100644
--- a/doc/HtmlParser.txt
+++ b/devdoc/HtmlParser.txt
diff --git a/doc/IO.txt b/devdoc/IO.txt
index cd62a4f5..cd62a4f5 100644
--- a/doc/IO.txt
+++ b/devdoc/IO.txt
diff --git a/doc/Images.txt b/devdoc/Images.txt
index 6a36e6f5..62082e48 100644
--- a/doc/Images.txt
+++ b/devdoc/Images.txt
@@ -1,5 +1,8 @@
January 2009, --Jcid
+Update June 2015: See also doc/dw-images-and-backgrounds.doc, or
+../html/dw-images-and-backgrounds.html (generated by doxygen).
+
------
IMAGES
------
diff --git a/doc/NC_design.txt b/devdoc/NC_design.txt
index 380787f6..380787f6 100644
--- a/doc/NC_design.txt
+++ b/devdoc/NC_design.txt
diff --git a/devdoc/README b/devdoc/README
new file mode 100644
index 00000000..9736a32b
--- /dev/null
+++ b/devdoc/README
@@ -0,0 +1,51 @@
+README: Last update Jul 2009
+
+These documents cover dillo's internals.
+For user help, see http://www.dillo.org/dillo3-help.html
+
+--------------------------------------------------------------------------
+
+These documents need a review.
+*.txt were current with Dillo1, but many have since become more or
+ less out-of-date.
+*.doc are doxygen source for the Dillo Widget (dw) component, and
+ were written for Dillo2.
+
+They will give you an overview of what's going on, but take them
+with a pinch of salt.
+
+ Of course I'd like to have *.txt as doxygen files too!
+If somebody wants to make this conversion, please let me know
+to assign higher priority to updating these docs.
+
+--
+Jorge.-
+
+ --------------------------------------------------------------------------
+ FILE DESCRIPTION STATE
+ --------------------------------------------------------------------------
+ NC_design.txt Naming&Coding design (Be sure to Current
+ read it before any other doc)
+ Dillo.txt General overview of the program Current
+ IO.txt Extensive introduction Current
+ Cache.txt Informative description Current
+ Images.txt Image handling and processing Current
+ HtmlParser.txt A versatile parser Current
+ Dw.txt The New Dillo Widget (Overview) Current
+ Imgbuf.txt Image buffers Pending
+ Selection.txt Selections, and link activation Current (?)
+ Cookies.txt Explains how to enable cookies Current
+ Dpid.txt Dillo plugin daemon Current
+ --------------------------------------------------------------------------
+
+
+ * BTW, there's a small program (srch) within the src/ dir. It searches
+ tokens within the whole code (*.[ch]). It has proven very useful.
+ Ex: ./srch a_Image_write
+ ./srch todo:
+
+ * Please submit your patches with 'hg diff'.
+
+
+ Happy coding!
+ --Jcid
diff --git a/doc/dw-changes.doc b/devdoc/dw-changes.doc
index 7050df9a..7050df9a 100644
--- a/doc/dw-changes.doc
+++ b/devdoc/dw-changes.doc
diff --git a/doc/dw-example-screenshot.png b/devdoc/dw-example-screenshot.png
index 94f272ab..94f272ab 100644
--- a/doc/dw-example-screenshot.png
+++ b/devdoc/dw-example-screenshot.png
Binary files differ
diff --git a/doc/dw-floats-01.png b/devdoc/dw-floats-01.png
index 116d36b3..116d36b3 100644
--- a/doc/dw-floats-01.png
+++ b/devdoc/dw-floats-01.png
Binary files differ
diff --git a/doc/dw-grows.doc b/devdoc/dw-grows.doc
index c255419f..c255419f 100644
--- a/doc/dw-grows.doc
+++ b/devdoc/dw-grows.doc
diff --git a/doc/dw-images-and-backgrounds.doc b/devdoc/dw-images-and-backgrounds.doc
index 8f07766a..8f07766a 100644
--- a/doc/dw-images-and-backgrounds.doc
+++ b/devdoc/dw-images-and-backgrounds.doc
diff --git a/doc/dw-layout-views.doc b/devdoc/dw-layout-views.doc
index d1118489..d1118489 100644
--- a/doc/dw-layout-views.doc
+++ b/devdoc/dw-layout-views.doc
diff --git a/doc/dw-layout-widgets.doc b/devdoc/dw-layout-widgets.doc
index e0215562..e0215562 100644
--- a/doc/dw-layout-widgets.doc
+++ b/devdoc/dw-layout-widgets.doc
diff --git a/doc/dw-line-breaking.doc b/devdoc/dw-line-breaking.doc
index 14ab97c4..14ab97c4 100644
--- a/doc/dw-line-breaking.doc
+++ b/devdoc/dw-line-breaking.doc
diff --git a/doc/dw-map.doc b/devdoc/dw-map.doc
index aebeb7da..aebeb7da 100644
--- a/doc/dw-map.doc
+++ b/devdoc/dw-map.doc
diff --git a/doc/dw-out-of-flow-2.doc b/devdoc/dw-out-of-flow-2.doc
index d9d70565..d9d70565 100644
--- a/doc/dw-out-of-flow-2.doc
+++ b/devdoc/dw-out-of-flow-2.doc
diff --git a/doc/dw-out-of-flow-floats.doc b/devdoc/dw-out-of-flow-floats.doc
index 53c6b220..53c6b220 100644
--- a/doc/dw-out-of-flow-floats.doc
+++ b/devdoc/dw-out-of-flow-floats.doc
diff --git a/doc/dw-out-of-flow.doc b/devdoc/dw-out-of-flow.doc
index eda6994a..eda6994a 100644
--- a/doc/dw-out-of-flow.doc
+++ b/devdoc/dw-out-of-flow.doc
diff --git a/doc/dw-overview.doc b/devdoc/dw-overview.doc
index 0c4ffb53..0c4ffb53 100644
--- a/doc/dw-overview.doc
+++ b/devdoc/dw-overview.doc
diff --git a/doc/dw-size-of-widget.png b/devdoc/dw-size-of-widget.png
index dbdbe0c4..dbdbe0c4 100644
--- a/doc/dw-size-of-widget.png
+++ b/devdoc/dw-size-of-widget.png
Binary files differ
diff --git a/doc/dw-style-box-model.png b/devdoc/dw-style-box-model.png
index bf2fb1f1..bf2fb1f1 100644
--- a/doc/dw-style-box-model.png
+++ b/devdoc/dw-style-box-model.png
Binary files differ
diff --git a/doc/dw-style-length-absolute.png b/devdoc/dw-style-length-absolute.png
index 9ea28cad..9ea28cad 100644
--- a/doc/dw-style-length-absolute.png
+++ b/devdoc/dw-style-length-absolute.png
Binary files differ
diff --git a/doc/dw-style-length-percentage.png b/devdoc/dw-style-length-percentage.png
index b1ad79c9..b1ad79c9 100644
--- a/doc/dw-style-length-percentage.png
+++ b/devdoc/dw-style-length-percentage.png
Binary files differ
diff --git a/doc/dw-style-length-relative.png b/devdoc/dw-style-length-relative.png
index ee79b1a9..ee79b1a9 100644
--- a/doc/dw-style-length-relative.png
+++ b/devdoc/dw-style-length-relative.png
Binary files differ
diff --git a/doc/dw-textblock-collapsing-spaces-1-1.png b/devdoc/dw-textblock-collapsing-spaces-1-1.png
index d528dfb2..d528dfb2 100644
--- a/doc/dw-textblock-collapsing-spaces-1-1.png
+++ b/devdoc/dw-textblock-collapsing-spaces-1-1.png
Binary files differ
diff --git a/doc/dw-textblock-collapsing-spaces-1-2.png b/devdoc/dw-textblock-collapsing-spaces-1-2.png
index 483e79d1..483e79d1 100644
--- a/doc/dw-textblock-collapsing-spaces-1-2.png
+++ b/devdoc/dw-textblock-collapsing-spaces-1-2.png
Binary files differ
diff --git a/doc/dw-textblock-collapsing-spaces-2-1.png b/devdoc/dw-textblock-collapsing-spaces-2-1.png
index 0a03ea80..0a03ea80 100644
--- a/doc/dw-textblock-collapsing-spaces-2-1.png
+++ b/devdoc/dw-textblock-collapsing-spaces-2-1.png
Binary files differ
diff --git a/doc/dw-textblock-collapsing-spaces-2-2.png b/devdoc/dw-textblock-collapsing-spaces-2-2.png
index b89c6254..b89c6254 100644
--- a/doc/dw-textblock-collapsing-spaces-2-2.png
+++ b/devdoc/dw-textblock-collapsing-spaces-2-2.png
Binary files differ
diff --git a/doc/dw-usage.doc b/devdoc/dw-usage.doc
index a23920b8..a23920b8 100644
--- a/doc/dw-usage.doc
+++ b/devdoc/dw-usage.doc
diff --git a/doc/dw-viewport-with-scrollbar.png b/devdoc/dw-viewport-with-scrollbar.png
index 7ac62de3..7ac62de3 100644
--- a/doc/dw-viewport-with-scrollbar.png
+++ b/devdoc/dw-viewport-with-scrollbar.png
Binary files differ
diff --git a/doc/dw-viewport-without-scrollbar.png b/devdoc/dw-viewport-without-scrollbar.png
index 8aa20fec..8aa20fec 100644
--- a/doc/dw-viewport-without-scrollbar.png
+++ b/devdoc/dw-viewport-without-scrollbar.png
Binary files differ
diff --git a/doc/dw-widget-sizes.doc b/devdoc/dw-widget-sizes.doc
index ffc7fb5d..ffc7fb5d 100644
--- a/doc/dw-widget-sizes.doc
+++ b/devdoc/dw-widget-sizes.doc
diff --git a/doc/fltk-problems.doc b/devdoc/fltk-problems.doc
index df4f1f14..df4f1f14 100644
--- a/doc/fltk-problems.doc
+++ b/devdoc/fltk-problems.doc
diff --git a/doc/index.doc b/devdoc/index.doc
index 59de8cd8..59de8cd8 100644
--- a/doc/index.doc
+++ b/devdoc/index.doc
diff --git a/doc/lout.doc b/devdoc/lout.doc
index 4e1503c6..4e1503c6 100644
--- a/doc/lout.doc
+++ b/devdoc/lout.doc
diff --git a/devdoc/not-so-simple-container.png b/devdoc/not-so-simple-container.png
new file mode 100644
index 00000000..f3e2c039
--- /dev/null
+++ b/devdoc/not-so-simple-container.png
Binary files differ
diff --git a/devdoc/not-so-simple-container.svg b/devdoc/not-so-simple-container.svg
new file mode 100644
index 00000000..ce00510e
--- /dev/null
+++ b/devdoc/not-so-simple-container.svg
@@ -0,0 +1,785 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="210mm"
+ height="297mm"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.3.1 r9886"
+ sodipodi:docname="not-so-simple-container.svg"
+ inkscape:export-filename="/home/sg/dev/dillo/dillo/doc/not-so-simple-container.png"
+ inkscape:export-xdpi="69"
+ inkscape:export-ydpi="69">
+ <defs
+ id="defs4">
+ <marker
+ inkscape:stockid="Arrow1Mend"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="Arrow1Mend"
+ style="overflow:visible;">
+ <path
+ id="path3998"
+ d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;"
+ transform="scale(0.4) rotate(180) translate(10,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Send"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="Arrow1Send"
+ style="overflow:visible;">
+ <path
+ id="path4004"
+ d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;"
+ transform="scale(0.2) rotate(180) translate(6,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Lend"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="Arrow1Lend"
+ style="overflow:visible;">
+ <path
+ id="path3992"
+ d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;"
+ transform="scale(0.8) rotate(180) translate(12.5,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Mend"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow1Mend-5"
+ style="overflow:visible">
+ <path
+ inkscape:connector-curvature="0"
+ id="path3998-5"
+ d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+ transform="matrix(-0.4,0,0,-0.4,-4,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Mend"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow1Mend-3"
+ style="overflow:visible">
+ <path
+ inkscape:connector-curvature="0"
+ id="path3998-2"
+ d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+ transform="matrix(-0.4,0,0,-0.4,-4,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Mend"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow1Mend-2"
+ style="overflow:visible">
+ <path
+ inkscape:connector-curvature="0"
+ id="path3998-22"
+ d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+ transform="matrix(-0.4,0,0,-0.4,-4,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Mend"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="marker4917"
+ style="overflow:visible">
+ <path
+ inkscape:connector-curvature="0"
+ id="path4919"
+ d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+ transform="matrix(-0.4,0,0,-0.4,-4,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Mend"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="marker4921"
+ style="overflow:visible">
+ <path
+ inkscape:connector-curvature="0"
+ id="path4923"
+ d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+ transform="matrix(-0.4,0,0,-0.4,-4,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Mend"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow1Mend-9"
+ style="overflow:visible">
+ <path
+ inkscape:connector-curvature="0"
+ id="path3998-7"
+ d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+ transform="matrix(-0.4,0,0,-0.4,-4,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Mend"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow1Mend-6"
+ style="overflow:visible">
+ <path
+ inkscape:connector-curvature="0"
+ id="path3998-6"
+ d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+ transform="matrix(-0.4,0,0,-0.4,-4,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Mend"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow1Mend-51"
+ style="overflow:visible">
+ <path
+ inkscape:connector-curvature="0"
+ id="path3998-3"
+ d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+ transform="matrix(-0.4,0,0,-0.4,-4,0)" />
+ </marker>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1"
+ inkscape:cx="226.09436"
+ inkscape:cy="741.31258"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ inkscape:window-width="1598"
+ inkscape:window-height="876"
+ inkscape:window-x="0"
+ inkscape:window-y="22"
+ inkscape:window-maximized="1">
+ <inkscape:grid
+ type="xygrid"
+ id="grid2985" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Ebene 1"
+ inkscape:groupmode="layer"
+ id="layer1">
+ <rect
+ style="fill:#e0e0e0;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect3010"
+ width="35.433071"
+ height="17.716536"
+ x="442.91339"
+ y="25.611128" />
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Nimbus Mono L;-inkscape-font-specification:Nimbus Mono L"
+ x="496.06299"
+ y="38.581394"
+ id="text3012"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3014"
+ x="496.06299"
+ y="38.581394"
+ style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L">unaffected (in main array)</tspan></text>
+ <flowRoot
+ xml:space="preserve"
+ id="flowRoot3800"
+ style="fill:black;stroke:none;stroke-opacity:1;stroke-width:1px;stroke-linejoin:miter;stroke-linecap:butt;fill-opacity:1;font-family:Nimbus Mono L;font-style:normal;font-weight:normal;font-size:20px;line-height:125%;letter-spacing:0px;word-spacing:0px;-inkscape-font-specification:Nimbus Mono L;font-stretch:normal;font-variant:normal"><flowRegion
+ id="flowRegion3802"><rect
+ id="rect3804"
+ width="276.7818"
+ height="34.345188"
+ x="424.26407"
+ y="20.996433" /></flowRegion><flowPara
+ id="flowPara3806" /></flowRoot> <rect
+ style="fill:#e0e0e0;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect3812"
+ width="70.866142"
+ height="17.716536"
+ x="17.716558"
+ y="60.236198" />
+ <rect
+ style="fill:#b0b0ff;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect3814"
+ width="35.433071"
+ height="17.716536"
+ x="442.91339"
+ y="61.480198" />
+ <rect
+ style="fill:#80ff00;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect3816"
+ width="35.433071"
+ height="17.716536"
+ x="442.91339"
+ y="96.913269" />
+ <rect
+ style="fill:#ffff40;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect3818"
+ width="35.433071"
+ height="17.716536"
+ x="442.91339"
+ y="131.10234" />
+ <rect
+ style="fill:#b0b0ff;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect3816-2"
+ width="88.58268"
+ height="17.716536"
+ x="124.01577"
+ y="60.236198" />
+ <rect
+ style="fill:#e0e0e0;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect3812-5"
+ width="88.582687"
+ height="17.716536"
+ x="301.18112"
+ y="60.236198" />
+ <rect
+ style="fill:#80ff00;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect3816-4"
+ width="35.433071"
+ height="17.716536"
+ x="442.91339"
+ y="96.913269" />
+ <rect
+ style="fill:#80ff00;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect3816-4-2"
+ width="35.433071"
+ height="17.716536"
+ x="88.582703"
+ y="95.669266" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 17.716558,60.236198 70.866142,0 0,17.716536 -70.866142,0"
+ id="path3939"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 389.7638,60.236198 -88.58268,0 0,17.716536 88.58268,0"
+ id="path3941"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc" />
+ <rect
+ style="fill:#e0e0e0;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect3812-3"
+ width="70.866142"
+ height="17.716536"
+ x="17.71656"
+ y="148.81888" />
+ <rect
+ style="fill:#e0e0e0;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect3812-5-7"
+ width="88.582687"
+ height="17.716537"
+ x="301.18112"
+ y="148.81888" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 17.716558,148.81888 70.86614,0 0,17.71653 -70.86614,0"
+ id="path3939-4"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 389.7638,148.81887 -88.58268,1e-5 0,17.71653 88.58268,0"
+ id="path3941-8"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc" />
+ <rect
+ style="fill:#80ff00;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect3816-4-2-6"
+ width="35.433071"
+ height="17.716536"
+ x="124.01577"
+ y="148.81888" />
+ <rect
+ style="fill:#b0b0ff;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect3816-2-5"
+ width="53.149605"
+ height="17.716537"
+ x="159.44885"
+ y="148.81888" />
+ <rect
+ style="fill:#b0b0ff;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect3816-2-50"
+ width="35.433067"
+ height="17.716537"
+ x="212.59845"
+ y="184.25195" />
+ <rect
+ style="fill:#ffff40;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect3818-4"
+ width="53.149609"
+ height="17.716534"
+ x="248.03152"
+ y="184.25195" />
+ <path
+ style="fill:none;stroke:#808080;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 2;stroke-dashoffset:0"
+ d="m 88.5827,148.81887 35.43307,0"
+ id="path4078-6"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#808080;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 2;stroke-dashoffset:0"
+ d="m 88.5827,166.53541 35.43307,0"
+ id="path4078-4-7"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#808080;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 2;stroke-dashoffset:0"
+ d="m 212.59845,60.236198 88.58267,0"
+ id="path4078-66"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#808080;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 2;stroke-dashoffset:0"
+ d="m 212.59845,77.952734 88.58267,0"
+ id="path4078-4-0"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#8080ff;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:2, 4;stroke-dashoffset:0"
+ d="m 88.5827,77.952734 0,17.716535"
+ id="path4156"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#808000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:4, 2;stroke-dashoffset:0"
+ d="m 88.5827,77.952734 0,17.716535"
+ id="path4176"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#808000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:4, 2;stroke-dashoffset:0"
+ d="m 124.01577,95.669269 0,-17.716535"
+ id="path4178"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#808000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:4, 2;stroke-dashoffset:0"
+ d="m 212.59845,166.53541 0,17.71654"
+ id="path4180"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#808000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:4, 2;stroke-dashoffset:0"
+ d="m 301.18112,184.25195 0,-17.71654"
+ id="path4182"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#8080ff;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:4, 2;stroke-dashoffset:0"
+ d="m 88.5827,77.952734 0,17.716535"
+ id="path4186"
+ inkscape:connector-curvature="0"
+ inkscape:export-filename="/home/sg/dev/dillo/dillo/doc/path4188.png"
+ inkscape:export-xdpi="69"
+ inkscape:export-ydpi="69" />
+ <path
+ style="fill:none;stroke:#8080ff;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:4, 2;stroke-dashoffset:0"
+ d="m 124.01577,95.669269 0,-17.716535"
+ id="path4188"
+ inkscape:connector-curvature="0"
+ inkscape:export-xdpi="69"
+ inkscape:export-ydpi="69" />
+ <path
+ style="fill:none;stroke:#8080ff;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:4, 2;stroke-dashoffset:0"
+ d="m 212.59845,166.53541 0,17.71654"
+ id="path4190"
+ inkscape:connector-curvature="0"
+ inkscape:export-filename="/home/sg/dev/dillo/dillo/doc/path4188.png"
+ inkscape:export-xdpi="69"
+ inkscape:export-ydpi="69" />
+ <path
+ style="fill:none;stroke:#8080ff;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:4, 2;stroke-dashoffset:0"
+ d="m 301.18112,184.25195 0,-17.71654"
+ id="path4192"
+ inkscape:connector-curvature="0"
+ inkscape:export-filename="/home/sg/dev/dillo/dillo/doc/path4188.png"
+ inkscape:export-xdpi="69"
+ inkscape:export-ydpi="69" />
+ <path
+ style="fill:none;stroke:#808080;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 2;stroke-dashoffset:0"
+ d="m 88.5827,77.952734 0,17.716535"
+ id="path4078-6-0"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#808080;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 2;stroke-dashoffset:0"
+ d="m 124.01577,77.952734 0,17.716535"
+ id="path4078-6-0-9"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#808080;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 2;stroke-dashoffset:0"
+ d="m 212.59845,166.53541 0,17.71654"
+ id="path4078-6-0-0"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#808080;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 2;stroke-dashoffset:0"
+ d="m 301.18112,166.53541 0,17.71654"
+ id="path4078-6-0-6"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:none;marker-end:url(#Arrow1Mend)"
+ d="m 106.29923,116.92911 c 35.43307,28.34646 0,0 35.43307,28.34646"
+ id="path3803"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:none;marker-end:url(#Arrow1Mend)"
+ d="m 148.81892,81.496041 c 35.43307,63.779529 0,0 35.43307,63.779529"
+ id="path3803-7"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 2;stroke-dashoffset:0"
+ d="m 177.16537,60.236198 0,17.716535"
+ id="path4078-6-0-9-5"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:none;marker-end:url(#Arrow1Mend)"
+ d="m 194.88191,81.496038 c 35.43307,99.212602 0,3e-6 35.43307,99.212602"
+ id="path3803-7-0"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Nimbus Mono L;-inkscape-font-specification:Nimbus Mono L"
+ x="496.06299"
+ y="74.426468"
+ id="text3012-5"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3014-0"
+ x="496.06299"
+ y="74.426468"
+ style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L">main array (moved)</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L"
+ x="496.06299"
+ y="109.85954"
+ id="text4897"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4899"
+ x="496.06299"
+ y="109.85954"
+ style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L">original extra array</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Nimbus Mono L;-inkscape-font-specification:Nimbus Mono L"
+ x="496.06299"
+ y="145.60861"
+ id="text4901"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4903"
+ x="496.06299"
+ y="145.60861"
+ style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L">new inserted area</tspan></text>
+ <rect
+ style="fill:#e0e0e0;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect3812-37"
+ width="53.149609"
+ height="17.716536"
+ x="17.716558"
+ y="272.83463" />
+ <rect
+ style="fill:#b0b0ff;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect3816-2-1"
+ width="35.433067"
+ height="17.716537"
+ x="159.44884"
+ y="272.83463" />
+ <rect
+ style="fill:#e0e0e0;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect3812-5-5"
+ width="53.149582"
+ height="17.716537"
+ x="336.61423"
+ y="272.83463" />
+ <rect
+ style="fill:#80ff00;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect3816-4-2-3"
+ width="88.582664"
+ height="17.716534"
+ x="70.866173"
+ y="308.2677" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 17.716558,272.83462 53.149615,0 0,17.71654 -53.149615,0"
+ id="path3939-43"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 389.7638,272.83462 -53.14961,0 0,17.71654 53.14961,0"
+ id="path3941-6"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc" />
+ <rect
+ style="fill:#e0e0e0;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect3812-3-3"
+ width="53.149624"
+ height="17.716515"
+ x="17.716558"
+ y="361.4173" />
+ <rect
+ style="fill:#e0e0e0;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect3812-5-7-9"
+ width="53.149582"
+ height="17.716543"
+ x="336.61423"
+ y="361.4173" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 17.716559,361.4173 53.149604,0 0,17.71653 -53.149604,1e-5"
+ id="path3939-4-2"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 389.7638,361.4173 -53.14961,0 0,17.71653 53.14961,1e-5"
+ id="path3941-8-1"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc" />
+ <rect
+ style="fill:#80ff00;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect3816-4-2-6-7"
+ width="35.433071"
+ height="17.716536"
+ x="159.44884"
+ y="361.4173" />
+ <rect
+ style="fill:#b0b0ff;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect3816-2-50-6"
+ width="35.433067"
+ height="17.716537"
+ x="248.03151"
+ y="396.85037" />
+ <rect
+ style="fill:#ffff40;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect3818-4-9"
+ width="53.149609"
+ height="17.716534"
+ x="283.4646"
+ y="396.85037" />
+ <path
+ style="fill:none;stroke:#808080;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 2;stroke-dashoffset:0"
+ d="m 70.866173,361.41729 88.582667,1e-5"
+ id="path4078-6-8"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#808080;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 2;stroke-dashoffset:0"
+ d="m 70.866173,379.13383 88.582667,1e-5"
+ id="path4078-4-7-4"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#808080;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 2;stroke-dashoffset:0"
+ d="m 194.88192,272.83462 141.73227,0"
+ id="path4078-66-9"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#808080;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 2;stroke-dashoffset:0"
+ d="m 194.88192,290.55116 141.73227,0"
+ id="path4078-4-0-6"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#8080ff;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:2, 4;stroke-dashoffset:0"
+ d="m 70.866173,290.55116 0,17.71653"
+ id="path4156-9"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#808000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:4, 2;stroke-dashoffset:0"
+ d="m 70.866173,290.55116 0,17.71653"
+ id="path4176-4"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#808000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:4, 2;stroke-dashoffset:0"
+ d="m 106.29924,308.26769 0,-17.71653"
+ id="path4178-9"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#808000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:4, 2;stroke-dashoffset:0"
+ d="m 194.88192,379.13383 0,17.71654"
+ id="path4180-3"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#808000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:4, 2;stroke-dashoffset:0"
+ d="m 336.61419,396.85037 0,-17.71654"
+ id="path4182-8"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#8080ff;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:4, 2;stroke-dashoffset:0"
+ d="m 70.866173,290.55116 0,17.71653"
+ id="path4186-1"
+ inkscape:connector-curvature="0"
+ inkscape:export-filename="/home/sg/dev/dillo/dillo/doc/path4188.png"
+ inkscape:export-xdpi="69"
+ inkscape:export-ydpi="69"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#8080ff;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:4, 2;stroke-dashoffset:0"
+ d="m 106.29924,308.26769 0,-17.71653"
+ id="path4188-2"
+ inkscape:connector-curvature="0"
+ inkscape:export-xdpi="69"
+ inkscape:export-ydpi="69" />
+ <path
+ style="fill:none;stroke:#8080ff;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:4, 2;stroke-dashoffset:0"
+ d="m 194.88192,379.13383 0,17.71654"
+ id="path4190-8"
+ inkscape:connector-curvature="0"
+ inkscape:export-filename="/home/sg/dev/dillo/dillo/doc/path4188.png"
+ inkscape:export-xdpi="69"
+ inkscape:export-ydpi="69" />
+ <path
+ style="fill:none;stroke:#8080ff;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:4, 2;stroke-dashoffset:0"
+ d="m 336.61419,396.85037 0,-17.71654"
+ id="path4192-4"
+ inkscape:connector-curvature="0"
+ inkscape:export-filename="/home/sg/dev/dillo/dillo/doc/path4188.png"
+ inkscape:export-xdpi="69"
+ inkscape:export-ydpi="69" />
+ <path
+ style="fill:none;stroke:#808080;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 2;stroke-dashoffset:0"
+ d="m 70.866173,290.55116 0,17.71653"
+ id="path4078-6-0-4"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#808080;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 2;stroke-dashoffset:0"
+ d="m 159.44883,290.55116 0,17.71653"
+ id="path4078-6-0-9-0"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#808080;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 2;stroke-dashoffset:0"
+ d="m 194.88192,379.13383 0,17.71654"
+ id="path4078-6-0-0-7"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#808080;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 2;stroke-dashoffset:0"
+ d="m 336.61419,379.13383 0,17.71654"
+ id="path4078-6-0-6-1"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <rect
+ style="fill:#80ff00;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect3816-4-2-6-7-8"
+ width="53.149616"
+ height="17.716539"
+ x="194.88191"
+ y="396.85037" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 2;stroke-dashoffset:0"
+ d="m 106.29924,308.26769 0,17.71654"
+ id="path4078-6-0-9-5-1"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:none;marker-end:url(#Arrow1Mend)"
+ d="m 88.5827,329.52754 c 88.58267,28.34645 0,0 88.58267,28.34645"
+ id="path3803-4"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:none;marker-end:url(#Arrow1Mend)"
+ d="m 131.10238,329.52754 c 70.86614,24.80315 53.14961,3.5433 88.58268,63.77952"
+ id="path3803-4-0"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:none;marker-end:url(#Arrow1Mend)"
+ d="m 177.16537,294.09447 c 88.58268,99.21259 0,0 88.58268,99.21259"
+ id="path3803-4-01"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Nimbus Mono L;-inkscape-font-specification:Nimbus Mono L"
+ x="17.716536"
+ y="42.519665"
+ id="text3012-5-7"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3014-0-2"
+ x="17.716536"
+ y="42.519665"
+ style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L">Example 1:</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Nimbus Mono L;-inkscape-font-specification:Nimbus Mono L"
+ x="528"
+ y="389.36218"
+ id="text5205"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan5207"
+ x="528"
+ y="389.36218" /></text>
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Nimbus Mono L;-inkscape-font-specification:Nimbus Mono L"
+ x="17.716536"
+ y="255.11809"
+ id="text3012-5-7-9"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ x="17.716536"
+ y="255.11809"
+ style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L"
+ id="tspan5230">Example 2:</tspan></text>
+ </g>
+</svg>
diff --git a/doc/rounding-errors.doc b/devdoc/rounding-errors.doc
index a442033e..a442033e 100644
--- a/doc/rounding-errors.doc
+++ b/devdoc/rounding-errors.doc
diff --git a/doc/uml-legend.doc b/devdoc/uml-legend.doc
index 54004ccd..54004ccd 100644
--- a/doc/uml-legend.doc
+++ b/devdoc/uml-legend.doc
diff --git a/dillorc b/dillorc
index 9c783a03..18d52dd0 100644
--- a/dillorc
+++ b/dillorc
@@ -189,7 +189,7 @@ search_url="Google http://www.google.com/search?ie=UTF-8&oe=UTF-8&q=%s"
# page/image/stylesheet.
#http_persistent_conns=NO
-# Set the proxy information for http.
+# Set the proxy information for http/https.
# Note that the http_proxy environment variable overrides this setting.
# WARNING: FTP and downloads plugins use wget. To use a proxy with them,
# you will need to configure wget accordingly. See
diff --git a/doc/Dw.txt b/doc/Dw.txt
deleted file mode 100644
index f6909380..00000000
--- a/doc/Dw.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-Last update: Oct 2008
-
-================
-Dw: Dillo Widget
-================
-
-Dw is the internal widget library for rendering HTML. It has excellent
-documentation.
-
- Just run "doxygen" and browse the html/ directory!
-
diff --git a/doc/Imgbuf.txt b/doc/Imgbuf.txt
deleted file mode 100644
index f4a56660..00000000
--- a/doc/Imgbuf.txt
+++ /dev/null
@@ -1,177 +0,0 @@
-Aug 2004, S.Geerken@ping.de
-
-=============
-Image Buffers
-=============
-
-General
-=======
-
-Image buffers depend on the platform (see DwRender.txt), but have a
-general, platform independant interface, which is described in this
-section. The next section describes the Gdk version of Imgbuf.
-
-The structure ImgBuf will become part of the image processing, between
-image data decoding and the widget DwImage. Its purposes are
-
- 1. storing the image data,
- 2. handling scaled versions of this buffer, and
- 3. drawing.
-
-The latter must be done independently from the window.
-
-Storing Image Data
-------------------
-Imgbuf supports five image types, which are listed in the table
-below. The representation defines, how the colors are stored within
-the data, which is passed to a_Imgbuf_copy_row().
-
- | bytes per |
- type | pixel | representation
- ---------------+-----------+-------------------------
- RGB | 3 | red, green, blue
- RGBA | 4 | red, green, blue, alpha
- gray | 1 | gray value
- indexed | 1 | index to colormap
- indexed alpha | 1 | index to colormap
-
-The last two types need a colormap, which is set by
-a_Imgbuf_set_cmap(), which must be called before
-a_Imgbuf_copy_row(). This function expects the colors as 32 bit
-unsigned integers, which have the format 0xrrbbgg (for indexed
-images), or 0xaarrggbb (for indexed alpha), respectively.
-
-Scaling
--------
-The buffer with the original size, which was created by
-a_Imgbuf_new(), is called root buffer. Imgbuf provides the ability to
-scale buffers. Generally, both root buffers, as well as scaled
-buffers, may be shared, memory management is done by reference
-counters.
-
-Via a_Imgbuf_get_scaled_buf(), you can retrieve a scaled buffer. The
-way, how this function works in detail, is described in the code, but
-generally, something like this works always, in an efficient way:
-
- old_buf = cur_buf;
- cur_buf = a_Imgbuf_get_scaled_buf(old_buf, with, height);
- a_Imgbuf_unref (old_buf);
-
-Old_buf may both be a root buffer, or a scaled buffer.
-
-(As an exception, there should always be a reference on the root
-buffer, since scaled buffers cannot exist without the root buffer, but
-on the other side, do not hold references on it. So, if in the example
-above, old_buf would be a root buffer, and there would, at the
-beginning, only be one reference on it, new_buf would also be
-destroyed, along with old_buf. Therefore, an external reference must
-be added to the root buffer, which is in dillo done within the dicache
-module.)
-
-The root buffer keeps a list of all children, and all operations
-operating on the image data (a_Imgbuf_copy_row() and
-a_Imgbuf_set_cmap()) are delegated to the scaled buffers, when
-processed, and inherited, when a new scaled buffer is created. This
-means, that they must only be performed for the root buffer.
-
-Drawing
--------
-There are two situations, when drawing is necessary:
-
- 1. To react on expose events, the function a_Imgbuf_draw() can be
- used. Notice that the exact signature of this function is
- platform dependant.
-
- 2. When a row has been copied, it has to be drawn. To determine the
- area, which has to be drawn, the function
- a_Imgbuf_get_row_area() should be used. In dillo, the dicache
- module will first call a_Img_copy_row(), and then call
- a_Dw_image_draw_row() for the images connected to this image
- buffer. a_Dw_image_draw_row() will then call
- p_Dw_widget_queue_draw(), with an area determined by
- a_Imgbuf_get_row_area().
-
-
-The Gdk Implementation
-======================
-
-The Gdk implementation is used by the Gtk+ platform. [... todo]
-
-
-Global Scalers
-==============
-
-In some cases, there is a context, where images have to be scaled
-often, by a relatively constant factor. For example, the preview
-window (GtkDwPreview) draws images via the Imgbuf draw functions, but
-uses scaled buffers. Scaling such a buffer each time it is needed,
-causes huge performance losses. On the other hand, if the preview
-window would keep these scaled buffers (e.g. by lazy mapping of the
-original buffer to the scaled buffer), the scaled buffers get never
-freed, since the view is not told about, when the original buffer is
-not needed anymore. (n.b., that currently, the scaled buffers are
-destroyed, when the original buffer is destroyed, but this may change,
-and even this would leave "zombies" in this mapping structure, where
-the values refer to dead pointers).
-
-It is sufficient, that references on the scaled buffers are referred
-somehow, so that they do not get destroyed between different
-usages. The caller (in this case the preview) simply requests a scaled
-buffer, but the Imgbuf returns this from the list of already scaled
-buffers.
-
-These references are hold by special structures, which are called
-"scalers". There are two types of scalers, local scalers, which are
-bound to image buffers, and global scalers, which refer to multiple
-scalers.
-
-What happens in different situations:
-
- - The caller (e.g. the preview) requests a scaled buffer. For this,
- it uses a special method, which also passes the global image
- scaler, which was created before (for the preview, there is a 1-1
- association). The Imgbuf uses this global image scaler, to
- identify the caller, and keeps a list of them. If this global
- scaler is not yet in the list, it is added, and a local scaler is
- created.
-
-
-
- -
-
-There are three images in the page, i1a, i1b, and i2. I1a and i1b
-refer to the same image recource, represented by the root image buffer
-iba, which original size is 200 x 200. I1a is displayed in original
-size, while i1b is displayed at 100 x 100. I2 refers to an other
-recource, ibb, which has the size 300 x 300. I2 is shown in original
-size.
-
-
- :DwRenderLayout ------------------- :DwPage ----------.
- / \ |
- ,----' `----. ,------ i1a:DwImage --+
- / \ | |
- view1:GtkDwViewport view2:GtkDwPreview | ,---- i1b:DwImage --|
- | | | |
- ,------------------------------' | | ,-- i2: DwImage --'
- | | | |
- | ,-------------------------------------' | |
- | | ,--------------------------------' |
- | | | ,----'
- | | | |
- | V | V
- | iba:Imgbuf | ibb:Imgbuf -- 30x30
- | | | V | ^
- | | +- 100x100 ,- 20x20 ,- 10x10 | |
- | | | | ^ | ^ | |
- | | `----------+----|---' | `--. ,--'
- | | ,--------------' | | |
- | | | ,------------------' | |
- | | | | | |
- | lca:ImgbufLSc lcb:ImgbufLSc
- | (factor 1/10) (factor 1/10)
- | \ /
- | `-----------. ,-------------------'
- | \ /
- `------------------> scl:ImgbufGSc
- (factor 1/10)
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 7f627d09..7b40d0a2 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -1,51 +1,10 @@
dist_doc_DATA = user_help.html
man_MANS = dillo.1
EXTRA_DIST = \
- index.doc \
- lout.doc \
- dw-map.doc \
- dw-overview.doc \
- dw-usage.doc \
- dw-layout-views.doc \
- dw-layout-widgets.doc \
- dw-widget-sizes.doc \
- dw-changes.doc \
- dw-images-and-backgrounds.doc \
- dw-dw-out-of-flow.doc \
- dw-dw-out-of-flow-2.doc \
- dw-stacking-context.doc \
- fltk-problems.doc \
- rounding-errors.doc \
- uml-legend.doc \
- dw-line-breaking.doc \
- dw-example-screenshot.png \
- dw-viewport-without-scrollbar.png \
- dw-viewport-with-scrollbar.png \
- dw-size-of-widget.png \
- dw-style-box-model.png \
- dw-style-length-absolute.png \
- dw-style-length-percentage.png \
- dw-style-length-relative.png \
- dw-textblock-collapsing-spaces-1-1.png \
- dw-textblock-collapsing-spaces-1-2.png \
- dw-textblock-collapsing-spaces-2-1.png \
- dw-textblock-collapsing-spaces-2-2.png \
- dw-floats-01.png \
- not-so-simple-container.png \
- Cache.txt \
- Cookies.txt \
- Dillo.txt \
- Dw.txt \
- HtmlParser.txt \
- IO.txt \
- Images.txt \
- Imgbuf.txt \
- NC_design.txt \
- Selection.txt \
- Dpid.txt \
- CCCwork.txt \
README \
- dillo.1.in
+ Cookies.txt \
+ dillo.1.in \
+ user_help.html
dillo.1: $(srcdir)/dillo.1.in Makefile
sed 's%/usr/local%${prefix}%g' < $(srcdir)/dillo.1.in > dillo.1
diff --git a/doc/README b/doc/README
index 9736a32b..41c11d87 100644
--- a/doc/README
+++ b/doc/README
@@ -1,51 +1,5 @@
-README: Last update Jul 2009
+Last update: June 2015
-These documents cover dillo's internals.
-For user help, see http://www.dillo.org/dillo3-help.html
-
---------------------------------------------------------------------------
-
-These documents need a review.
-*.txt were current with Dillo1, but many have since become more or
- less out-of-date.
-*.doc are doxygen source for the Dillo Widget (dw) component, and
- were written for Dillo2.
-
-They will give you an overview of what's going on, but take them
-with a pinch of salt.
-
- Of course I'd like to have *.txt as doxygen files too!
-If somebody wants to make this conversion, please let me know
-to assign higher priority to updating these docs.
-
---
-Jorge.-
-
- --------------------------------------------------------------------------
- FILE DESCRIPTION STATE
- --------------------------------------------------------------------------
- NC_design.txt Naming&Coding design (Be sure to Current
- read it before any other doc)
- Dillo.txt General overview of the program Current
- IO.txt Extensive introduction Current
- Cache.txt Informative description Current
- Images.txt Image handling and processing Current
- HtmlParser.txt A versatile parser Current
- Dw.txt The New Dillo Widget (Overview) Current
- Imgbuf.txt Image buffers Pending
- Selection.txt Selections, and link activation Current (?)
- Cookies.txt Explains how to enable cookies Current
- Dpid.txt Dillo plugin daemon Current
- --------------------------------------------------------------------------
-
-
- * BTW, there's a small program (srch) within the src/ dir. It searches
- tokens within the whole code (*.[ch]). It has proven very useful.
- Ex: ./srch a_Image_write
- ./srch todo:
-
- * Please submit your patches with 'hg diff'.
-
-
- Happy coding!
- --Jcid
+This directory contains user documentation. Developer documentation is
+only stored in the Hg repository at <http://hg.dillo.org/dillo/>, in
+the directory "devdoc", but not part of the tarball.
diff --git a/doc/Selection.txt b/doc/Selection.txt
deleted file mode 100644
index 7904bd94..00000000
--- a/doc/Selection.txt
+++ /dev/null
@@ -1,149 +0,0 @@
-Apr 2003, S.Geerken@ping.de
-Last update: Dec 2004
-
-=========
-Selection
-=========
-
-The selection module (selection.[ch]) handles selections, as well as
-activation of links, which is closely related.
-
-
-General Overview
-================
-
-The selection module defines a structure "Selection", which is
-associated to GtkDwViewport, and so to a widget tree. The selection
-state is controlled by "abstract events", which are sent by single
-widgets by calling one of the following functions:
-
- a_Selection_button_press for button press events,
- a_Selection_button_release for button release events, and
- a_Selection_button_motion for motion events (with pressed mouse
- button).
-
-The widget must construct simple iterators (DwIterator), which will be
-transferred to extended iterators (DwExtIterator), see below for more
-details. All event handling functions have the same signature, the
-arguments in detail are:
-
- - DwIterator *it the iterator pointing on the item under
- the mouse pointer,
- - gint char_pos the exact (character) position within
- the iterator,
- - gint link if this item is associated with a link,
- its number (see DwImage, section
- "signals" for the meaning), otherwise
- -1,
- - GdkEventButton *event the event itself; only the button is
- used,
- - gboolean within_content TRUE, if there is some selectable
- content unter the mouse cursor; if set
- to FALSE, the "full screen" feature is
- used on double click.
-
-In some cases, char_pos would be difficult to determine. E.g., when
-the DwPage widget decides that the user is pointing on a position
-_at_the_end_ of an image (DwImage), it constructs a simple iterator
-pointing on this image widget. In a simple iterator, that fact that
-the pointer is at the end, would be represented by char_pos == 1. But
-when transferring this simple iterator into an extended iterator, this
-simple iterator is discarded and instead the stack has an iterator
-pointing to text at the top. As a result, only the first letter of the
-ALT text would be copied.
-
-To avoid this problem, widgets should in this case pass SELECTION_EOW
-(end of word) as char_pos, which is then automatically reduced to the
-actual length of the extended(!) iterator.
-
-The return value is the same as in DwWidget event handling methods.
-I.e., in most cases, they should simply return it. The events
-"link_pressed", "link_released" and "link_clicked" (but not
-"link_entered") are emitted by these functions, so that widgets which
-let the selection module handle links, should only emit "link_entered"
-for themselves. (See DwImage.txt for a description of this.)
-
-
-Selection State
-===============
-
-Selection interferes with handling the activation of links, so the
-latter is also handled by the selection module. Details are based on
-following guidelines:
-
- 1. It should be simple to select links and to start selection in
- links. The rule to distinguish between link activation and
- selection is that the selection starts as soon as the user leaves
- the link. (This is, IMO, a useful feature. Even after drag and
- drop has been implemented in dillo, this should be somehow
- preserved.)
-
- 2. The selection should stay as long as possible, i.e., the old
- selection is only cleared when a new selection is started.
-
-The latter leads to a model with two states: the selection state and
-the link handling state.
-
-The general selection works, for events not pointing on links, like
-this (numbers in parantheses after the event denote the button, "n"
-means arbitrary button):
-
- motion(1)
- ,-----.
- | |
- press(1) on non-link V |
- NONE -----------------------> SELECTING <----------------.
- ^ | |
- | | release(1) |
- | | | press(1)
- | no V yes |
- `----------------------- Anything selected? --------> SELECTED
-
-The selected region is represented by two DwExtIterators.
-
-Links are handled by a different state machine:
-
- ,-----------------------------.
- | |
- | Switch to selection
- | (SELECTING) for n == 1.
- | ^
- | | no
- | | yes
- | Still the same link? --.
- | ^ |
- | | |
- | | motion(n) |
- V press(n) on links | |
- NONE ---------------------> PRESSED(n) <-----'
- ^ |
- | | release(n)
- | |
- | V yes
- | Still the same link? -----------------.
- | | |
- | | no V
- | V Send "clicked" signal.
- | Switch to selection |
- | (SELECTED) for n == 1. |
- | | |
- |`----------------------------' |
- | |
- `----------------------------------------------------------'
-
-Switching to selection simply means that the selection state will
-eventually be SELECTED/SELECTING, with the original and the actual
-position making up the selection region. This happens for button 1,
-events with buttons other than 1 do not affect selection at all.
-
-
-TODO
-====
-
-* a_Selection_button_motion currently always assumes that button 1 has
- been pressed (since otherwise it would not do anything). This should
- be made a bit cleaner.
-
-* The selection should be cleared, when the user selects something
- somewhere else (perhaps switched into "non-active" mode, as some
- Gtk+ widgets do).
diff --git a/doc/dillo.1.in b/doc/dillo.1.in
index 3bb5fe03..0853e6eb 100644
--- a/doc/dillo.1.in
+++ b/doc/dillo.1.in
@@ -1,4 +1,4 @@
-.TH dillo 1 "December 20, 2014" "" "USER COMMANDS"
+.TH dillo 1 "May 28, 2015" "" "USER COMMANDS"
.SH NAME
dillo \- web browser
.SH SYNOPSIS
@@ -11,7 +11,7 @@ dillo \- web browser
Dillo is a lightweight graphical web browser that aims to be secure.
It handles HTTP internally, and FILE, FTP, and
DATA URIs are handled through a plugin system (dpi). In addition,
-.I INSECURE
+.I EXPERIMENTAL
HTTPS support can be enabled. Both FTP and Dillo's download manager use the
.BR wget (1)
downloader.
@@ -68,7 +68,7 @@ Error in command line arguments.
User's home directory.
.TP
.B http_proxy
-URL of proxy to send HTTP traffic through.
+URL of proxy to send HTTP/HTTPS traffic through.
.SH FILES
.TP
.I dpid
diff --git a/doc/not-so-simple-container.png b/doc/not-so-simple-container.png
deleted file mode 100644
index 0af067b5..00000000
--- a/doc/not-so-simple-container.png
+++ /dev/null
Binary files differ
diff --git a/dpi/cookies.c b/dpi/cookies.c
index b858bd53..51767241 100644
--- a/dpi/cookies.c
+++ b/dpi/cookies.c
@@ -1142,14 +1142,14 @@ static int Cookies_set(char *cookie_string, char *url_host,
* Compare the cookie with the supplied data to see whether it matches
*/
static bool_t Cookies_match(CookieData_t *cookie, const char *url_path,
- bool_t host_only_val, bool_t is_ssl)
+ bool_t host_only_val, bool_t is_tls)
{
if (cookie->host_only != host_only_val)
return FALSE;
/* Insecure cookies match both secure and insecure urls, secure
cookies match only secure urls */
- if (cookie->secure && !is_ssl)
+ if (cookie->secure && !is_tls)
return FALSE;
if (!Cookies_path_matches(url_path, cookie->path))
@@ -1163,7 +1163,7 @@ static void Cookies_add_matching_cookies(const char *domain,
const char *url_path,
bool_t host_only_val,
Dlist *matching_cookies,
- bool_t is_ssl)
+ bool_t is_tls)
{
DomainNode *node = dList_find_sorted(domains, domain,
Domain_node_by_domain_cmp);
@@ -1183,7 +1183,7 @@ static void Cookies_add_matching_cookies(const char *domain,
--i; continue;
}
/* Check if the cookie matches the requesting URL */
- if (Cookies_match(cookie, url_path, host_only_val, is_ssl)) {
+ if (Cookies_match(cookie, url_path, host_only_val, is_tls)) {
int j;
CookieData_t *curr;
uint_t path_length = strlen(cookie->path);
@@ -1213,7 +1213,7 @@ static char *Cookies_get(char *url_host, char *url_path,
char *domain_str, *str;
CookieData_t *cookie;
Dlist *matching_cookies;
- bool_t is_ssl, is_ip_addr, host_only_val;
+ bool_t is_tls, is_ip_addr, host_only_val;
Dstr *cookie_dstring;
int i;
@@ -1224,7 +1224,7 @@ static char *Cookies_get(char *url_host, char *url_path,
matching_cookies = dList_new(8);
/* Check if the protocol is secure or not */
- is_ssl = (!dStrAsciiCasecmp(url_scheme, "https"));
+ is_tls = (!dStrAsciiCasecmp(url_scheme, "https"));
is_ip_addr = Cookies_domain_is_ip(url_host);
@@ -1240,17 +1240,17 @@ static char *Cookies_get(char *url_host, char *url_path,
/* e.g., sub.example.com set a cookie with domain ".sub.example.com". */
domain_str = dStrconcat(".", url_host, NULL);
Cookies_add_matching_cookies(domain_str, url_path, host_only_val,
- matching_cookies, is_ssl);
+ matching_cookies, is_tls);
dFree(domain_str);
}
host_only_val = TRUE;
/* e.g., sub.example.com set a cookie with no domain attribute. */
Cookies_add_matching_cookies(url_host, url_path, host_only_val,
- matching_cookies, is_ssl);
+ matching_cookies, is_tls);
host_only_val = FALSE;
/* e.g., sub.example.com set a cookie with domain "sub.example.com". */
Cookies_add_matching_cookies(url_host, url_path, host_only_val,
- matching_cookies, is_ssl);
+ matching_cookies, is_tls);
if (!is_ip_addr) {
for (domain_str = strchr(url_host+1, '.');
@@ -1258,12 +1258,12 @@ static char *Cookies_get(char *url_host, char *url_path,
domain_str = strchr(domain_str+1, '.')) {
/* e.g., sub.example.com set a cookie with domain ".example.com". */
Cookies_add_matching_cookies(domain_str, url_path, host_only_val,
- matching_cookies, is_ssl);
+ matching_cookies, is_tls);
if (domain_str[1]) {
domain_str++;
/* e.g., sub.example.com set a cookie with domain "example.com".*/
Cookies_add_matching_cookies(domain_str, url_path, host_only_val,
- matching_cookies, is_ssl);
+ matching_cookies, is_tls);
}
}
}
diff --git a/dpi/vsource.c b/dpi/vsource.c
index 2f1129cb..9d5694b5 100644
--- a/dpi/vsource.c
+++ b/dpi/vsource.c
@@ -3,7 +3,7 @@
*
* This server is an example. Play with it and modify to your taste.
*
- * Copyright 2010 Jorge Arellano Cid <jcid@dillo.org>
+ * Copyright 2010-2015 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
@@ -25,7 +25,7 @@
* Debugging macros
*/
#define _MSG(...)
-#define MSG(...) printf("[vsource dpi]: " __VA_ARGS__)
+#define MSG(...) fprintf(stderr, "[vsource dpi]: " __VA_ARGS__)
/*---------------------------------------------------------------------------*/
@@ -42,38 +42,41 @@ void send_dpip_tag(Dsh *sh, char *dpip_tag)
/*
* Send source as plain text
+ * (handles embedded null chars correctly).
*/
void send_plain_text(Dsh *sh, int data_size)
{
- int bytes_read = 0;
- char *src_str;
+ char *token;
+ int bytes_read = 0, token_size;
/* Send HTTP header for plain text MIME type */
a_Dpip_dsh_write_str(sh, 0, "Content-type: text/plain\n\n");
while (bytes_read < data_size &&
- (src_str = a_Dpip_dsh_read_token(sh, 1))) {
- bytes_read += strlen(src_str);
- a_Dpip_dsh_write_str(sh, 1, src_str);
- dFree(src_str);
+ (token = a_Dpip_dsh_read_token2(sh, 1, &token_size))) {
+ bytes_read += token_size;
+ _MSG("data_size=%d bytes_read=%d\n", data_size, bytes_read);
+ a_Dpip_dsh_write(sh, 1, token, token_size);
+ dFree(token);
}
}
/*
* Send source as plain text with line numbers
+ * (handles embedded null chars correctly).
*/
void send_numbered_text(Dsh *sh, int data_size)
{
- int bytes_read = 0, line = 1;
- char *p, *q, *src_str, line_str[32];
+ int bytes_read = 0, line = 1, token_size = 0;
+ char *p, *q, *token, line_str[32];
/* Send HTTP header for plain text MIME type */
a_Dpip_dsh_write_str(sh, 0, "Content-type: text/plain\n\n");
while (bytes_read < data_size &&
- (src_str = a_Dpip_dsh_read_token(sh, 1))) {
- bytes_read += strlen(src_str);
- p = q = src_str;
+ (token = a_Dpip_dsh_read_token2(sh, 1, &token_size))) {
+ bytes_read += token_size;
+ p = q = token;
while (*p) {
snprintf(line_str, 32, "%2d: ", line);
@@ -84,28 +87,30 @@ void send_numbered_text(Dsh *sh, int data_size)
++p;
++line;
} else {
- a_Dpip_dsh_write_str(sh, 1, q);
+ /* send all the rest */
+ a_Dpip_dsh_write(sh, 1, q, token_size - (q - token));
break;
}
q = ++p;
}
- dFree(src_str);
+ dFree(token);
}
}
/*
* Send source as html text with line numbers
+ * (handles embedded null chars correctly).
*/
void send_html_text(Dsh *sh, const char *url, int data_size)
{
- int bytes_read = 0, old_line = 0, line = 1;
- char *p, *q, *src_str, line_str[128];
+ int bytes_read = 0, old_line = 0, line = 1, token_size = 0;
+ char *p, *q, *token, line_str[128];
if (dStrnAsciiCasecmp(url, "dpi:", 4) == 0 &&
strncmp(url+4, "/vsource/:", 10) == 0)
url += 14;
- /* Send HTTP header for plain text MIME type */
+ /* Send HTTP header for html text MIME type */
a_Dpip_dsh_write_str(sh, 0, "Content-type: text/html\n\n");
a_Dpip_dsh_write_str(sh, 0, DOCTYPE);
@@ -113,23 +118,25 @@ void send_html_text(Dsh *sh, const char *url, int data_size)
"\n"
"<html><head>\n"
"<title>Source for %s</title>\n"
- "<style type=\"text/css\">PRE {white-space: pre-wrap}\n"
+ "<style type=\"text/css\">\n"
+ " body {white-space: pre-wrap; font-family: monospace}\n"
+ " td.r1 {background-color:#B87333}\n"
+ " td.r2 {background-color:#DD7F32}\n"
"</style>\n"
"</head>\n"
"<body id=\"dillo_vs\">\n<table cellpadding='0'>\n", url);
while (bytes_read < data_size &&
- (src_str = a_Dpip_dsh_read_token(sh, 1))) {
- bytes_read += strlen(src_str);
- p = q = src_str;
+ (token = a_Dpip_dsh_read_token2(sh, 1, &token_size))) {
+ bytes_read += token_size;
+ p = q = token;
while (*p) {
if (line > old_line) {
snprintf(line_str, 128,
- "%s<tr><td bgcolor='%s'>%d%s<td><pre>",
- (line > 1) ? "</pre>" : "",
- (line & 1) ? "#B87333" : "#DD7F32", line,
- (line == 1 || (line % 10) == 0) ? "&nbsp;&nbsp;" : "");
+ "<tr><td class='%s'>%d%s<td>",
+ (line & 1) ? "r1" : "r2", line,
+ (line == 1 || (line % 10) == 0) ? "&nbsp;" : "");
a_Dpip_dsh_write_str(sh, 0, line_str);
old_line = line;
}
@@ -143,17 +150,16 @@ void send_html_text(Dsh *sh, const char *url, int data_size)
a_Dpip_dsh_write(sh, 0, q, p - q);
a_Dpip_dsh_write_str(sh, 0, (*p == '<') ? "&lt;" : "&amp;");
}
- } else {
- a_Dpip_dsh_write_str(sh, 1, q);
+ } else {
+ /* send all the rest */
+ a_Dpip_dsh_write(sh, 1, q, token_size - (q - token));
break;
}
q = ++p;
}
- dFree(src_str);
+ dFree(token);
}
- if (data_size > 0)
- a_Dpip_dsh_write_str(sh, 0, "</pre>");
a_Dpip_dsh_write_str(sh, 1, "</table></body></html>");
}
@@ -194,7 +200,7 @@ int main(void)
* asking from us. a_Dpip_dsh_read_token() will block and return
* a full dpip token or null on error (it's commented in dpip.c) */
dpip_tag = a_Dpip_dsh_read_token(sh, 1);
- MSG("tag = [%s]\n", dpip_tag);
+ _MSG("tag = [%s]\n", dpip_tag);
/* Now that we have the dpip_tag, let's isolate the command and url */
cmd = a_Dpip_get_attr(dpip_tag, "cmd");
diff --git a/dpid/dpid_common.h b/dpid/dpid_common.h
index cc7505a9..6df55ae1 100644
--- a/dpid/dpid_common.h
+++ b/dpid/dpid_common.h
@@ -18,7 +18,6 @@
*/
#define _MSG(...)
#define MSG(...) printf("[dpid]: " __VA_ARGS__)
-#define _MSG_ERR(...)
#define MSG_ERR(...) fprintf(stderr, "[dpid]: " __VA_ARGS__)
#define dotDILLO_DPI ".dillo/dpi"
diff --git a/dpip/dpip.c b/dpip/dpip.c
index f4ce1bf0..2906ba2a 100644
--- a/dpip/dpip.c
+++ b/dpip/dpip.c
@@ -1,7 +1,7 @@
/*
* File: dpip.c
*
- * Copyright 2005-2007 Jorge Arellano Cid <jcid@dillo.org>
+ * Copyright 2005-2015 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
@@ -427,11 +427,13 @@ static void Dpip_dsh_read(Dsh *dsh, int blocking)
/*
* Return a newlly allocated string with the next dpip token in the socket.
- * Return value: token string on success, NULL otherwise
+ * Return value: token string and length on success, NULL otherwise.
+ * (useful for handling null characters in the data stream)
*/
-char *a_Dpip_dsh_read_token(Dsh *dsh, int blocking)
+char *a_Dpip_dsh_read_token2(Dsh *dsh, int blocking, int *DataSize)
{
char *p, *ret = NULL;
+ *DataSize = 0;
/* Read all available data without blocking */
Dpip_dsh_read(dsh, 0);
@@ -462,6 +464,7 @@ char *a_Dpip_dsh_read_token(Dsh *dsh, int blocking)
/* return a full tag */
if ((p = strstr(dsh->rdbuf->str, DPIP_TAG_END))) {
ret = dStrndup(dsh->rdbuf->str, p - dsh->rdbuf->str + 3);
+ *DataSize = p - dsh->rdbuf->str + 3;
dStr_erase(dsh->rdbuf, 0, p - dsh->rdbuf->str + 3);
if (strstr(ret, DPIP_MODE_SWITCH_TAG))
dsh->mode |= DPIP_LAST_TAG;
@@ -470,6 +473,7 @@ char *a_Dpip_dsh_read_token(Dsh *dsh, int blocking)
/* raw mode, return what we have "as is" */
if (dsh->rdbuf->len > 0) {
ret = dStrndup(dsh->rdbuf->str, dsh->rdbuf->len);
+ *DataSize = dsh->rdbuf->len;
dStr_truncate(dsh->rdbuf, 0);
}
}
@@ -478,6 +482,17 @@ char *a_Dpip_dsh_read_token(Dsh *dsh, int blocking)
}
/*
+ * Return a newlly allocated string with the next dpip token in the socket.
+ * Return value: token string on success, NULL otherwise
+ */
+char *a_Dpip_dsh_read_token(Dsh *dsh, int blocking)
+{
+ int token_size;
+
+ return a_Dpip_dsh_read_token2(dsh, blocking, &token_size);
+}
+
+/*
* Close this socket for reading and writing.
* (flush pending data)
*/
diff --git a/dpip/dpip.h b/dpip/dpip.h
index 1a1846df..a63eb658 100644
--- a/dpip/dpip.h
+++ b/dpip/dpip.h
@@ -70,6 +70,7 @@ int a_Dpip_dsh_write_str(Dsh *dsh, int flush, const char *str);
int a_Dpip_dsh_tryflush(Dsh *dsh);
int a_Dpip_dsh_trywrite(Dsh *dsh, const char *Data, int DataSize);
char *a_Dpip_dsh_read_token(Dsh *dsh, int blocking);
+char *a_Dpip_dsh_read_token2(Dsh *dsh, int blocking, int *DataSize);
void a_Dpip_dsh_close(Dsh *dsh);
void a_Dpip_dsh_free(Dsh *dsh);
diff --git a/dw/table.cc b/dw/table.cc
index 460e9a29..8b8fe853 100644
--- a/dw/table.cc
+++ b/dw/table.cc
@@ -907,7 +907,7 @@ void Table::actuallyCalcCellSizes (bool calcHeights)
int childHeight;
core::Extremes extremes;
- // Will also call calcColumnExtremes(), when needed.
+ // Will also call forceCalcColumnExtremes(), when needed.
getExtremes (&extremes);
int availWidth = getAvailWidth (true);
@@ -1285,24 +1285,6 @@ void Table::apportionRowSpan ()
/**
- * \brief Fills dw::Table::colExtremes, only if recalculation is necessary.
- *
- * \bug Some parts are missing.
- */
-void Table::_unused_calcColumnExtremes ()
-{
- // This method is actually not used. Consider removal.
-
- DBG_OBJ_ENTER0 ("resize", 0, "calcColumnExtremes");
-
- if (extremesChanged () || extremesQueued ())
- forceCalcColumnExtremes ();
-
- DBG_OBJ_LEAVE ();
-}
-
-
-/**
* \brief Fills dw::Table::colExtremes in all cases.
*/
void Table::forceCalcColumnExtremes ()
diff --git a/dw/table.hh b/dw/table.hh
index c94514c0..b4f6a7bc 100644
--- a/dw/table.hh
+++ b/dw/table.hh
@@ -43,29 +43,26 @@ namespace dw {
* sizeRequestImpl [color="#0000ff", URL="\ref dw::Table::sizeRequestImpl"];
* sizeAllocateImpl [color="#0000ff",
* URL="\ref dw::Table::sizeAllocateImpl"];
+ * getExtremes [color="#0000ff", URL="\ref dw::core::Widget::getExtremes"];
* getExtremesImpl [color="#0000ff", URL="\ref dw::Table::getExtremesImpl"];
*
- * subgraph cluster_sizes {
- * style="dashed"; color="#8080c0";
- * calcCellSizes [URL="\ref dw::Table::calcCellSizes"];
- * forceCalcCellSizes [URL="\ref dw::Table::forceCalcCellSizes"];
- * }
- *
- * subgraph cluster_extremes {
- * style="dashed"; color="#8080c0";
- * calcColumnExtremes [URL="\ref dw::Table::calcColumnExtremes"];
- * forceCalcColumnExtremes[URL="\ref dw::Table::forceCalcColumnExtremes"];
- * }
+ * calcCellSizes [label="calcCellSizes (calcHeights = true)",
+ * URL="\ref dw::Table::calcCellSizes"];
+ * forceCalcCellSizes [label="forceCalcCellSizes (calcHeights = true)",
+ * URL="\ref dw::Table::forceCalcCellSizes"];
+ * actuallyCalcCellSizes[label="actuallyCalcCellSizes (calcHeights = true)",
+ * URL="\ref dw::Table::actuallyCalcCellSizes"];
+ * forceCalcColumnExtremes[URL="\ref dw::Table::forceCalcColumnExtremes"];
*
* sizeRequestImpl -> forceCalcCellSizes [label="[B]"];
* sizeAllocateImpl -> calcCellSizes [label="[A]"];
* getExtremesImpl -> forceCalcColumnExtremes [label="[B]"];
*
- * forceCalcCellSizes -> calcColumnExtremes;
+ * forceCalcCellSizes -> actuallyCalcCellSizes;
+ * actuallyCalcCellSizes-> getExtremes;
+ * getExtremes -> getExtremesImpl [style="dashed", label="[C]"];
*
* calcCellSizes -> forceCalcCellSizes [style="dashed", label="[C]"];
- * calcColumnExtremes -> forceCalcColumnExtremes [style="dashed",
- * label="[C]"];
* }
* \enddot
*
@@ -78,6 +75,12 @@ namespace dw {
* [C] Whether this function is called, depends on NEEDS_RESIZE /
* RESIZE_QUEUED / EXTREMES_CHANGED / EXTREMES_QUEUED.
*
+ * **TODO:**
+ *
+ * - Are <tt>*[cC]alcCellSizes (calcHeights = *false*)</tt> not
+ * necessary anymore?
+ * - Calculating available sizes (Table::getAvailWidthOfChild) should
+ * be documented in this diagram, too.
*
* <h4>Apportionment</h4>
*
@@ -437,7 +440,6 @@ private:
void actuallyCalcCellSizes (bool calcHeights);
void apportionRowSpan ();
- void _unused_calcColumnExtremes ();
void forceCalcColumnExtremes ();
void calcExtremesSpanMultiCols (int col, int cs,
core::Extremes *cellExtremes,
diff --git a/lout/msg.h b/lout/msg.h
index 4993c105..e52ff986 100644
--- a/lout/msg.h
+++ b/lout/msg.h
@@ -13,7 +13,6 @@
*/
#define _MSG(...)
#define _MSG_WARN(...)
-#define _MSG_ERR(...)
#define MSG(...) \
diff --git a/src/IO/IO.c b/src/IO/IO.c
index e5c5fc79..0cdb9499 100644
--- a/src/IO/IO.c
+++ b/src/IO/IO.c
@@ -21,7 +21,7 @@
#include "../klist.h"
#include "IO.h"
#include "iowatch.hh"
-#include "ssl.h"
+#include "tls.h"
/*
* Symbolic defines for shutdown() function
@@ -163,7 +163,7 @@ static bool_t IO_read(IOData_t *io)
ssize_t St;
bool_t ret = FALSE;
int io_key = io->Key;
- void *conn = a_Ssl_connection(io->FD);
+ void *conn = a_Tls_connection(io->FD);
_MSG(" IO_read\n");
@@ -172,7 +172,7 @@ static bool_t IO_read(IOData_t *io)
io->Status = 0;
while (1) {
- St = conn ? a_Ssl_read(conn, Buf, IOBufLen)
+ St = conn ? a_Tls_read(conn, Buf, IOBufLen)
: read(io->FD, Buf, IOBufLen);
if (St > 0) {
dStr_append_l(io->Buf, Buf, St);
@@ -217,13 +217,13 @@ static bool_t IO_write(IOData_t *io)
{
ssize_t St;
bool_t ret = FALSE;
- void *conn = a_Ssl_connection(io->FD);
+ void *conn = a_Tls_connection(io->FD);
_MSG(" IO_write\n");
io->Status = 0;
while (1) {
- St = conn ? a_Ssl_write(conn, io->Buf->str, io->Buf->len)
+ St = conn ? a_Tls_write(conn, io->Buf->str, io->Buf->len)
: write(io->FD, io->Buf->str, io->Buf->len);
if (St < 0) {
/* Error */
diff --git a/src/IO/Makefile.am b/src/IO/Makefile.am
index ff600521..d8fed40a 100644
--- a/src/IO/Makefile.am
+++ b/src/IO/Makefile.am
@@ -15,8 +15,8 @@ libDiof_a_SOURCES = \
about.c \
Url.h \
http.c \
- ssl.h \
- ssl.c \
+ tls.h \
+ tls.c \
dpi.c \
IO.c \
iowatch.cc \
diff --git a/src/IO/http.c b/src/IO/http.c
index e5c459ee..379d51c1 100644
--- a/src/IO/http.c
+++ b/src/IO/http.c
@@ -27,7 +27,7 @@
#include <arpa/inet.h> /* for inet_ntop */
#include "IO.h"
-#include "ssl.h"
+#include "tls.h"
#include "Url.h"
#include "../msg.h"
#include "../klist.h"
@@ -52,18 +52,18 @@ D_STMT_START { \
static const int HTTP_SOCKET_USE_PROXY = 0x1;
static const int HTTP_SOCKET_QUEUED = 0x2;
static const int HTTP_SOCKET_TO_BE_FREED = 0x4;
-static const int HTTP_SOCKET_SSL = 0x8;
+static const int HTTP_SOCKET_TLS = 0x8;
/* 'web' is just a reference (no need to deallocate it here). */
typedef struct {
int SockFD;
- uint_t connect_port;
uint_t flags;
DilloWeb *web; /* reference to client's web structure */
DilloUrl *url;
Dlist *addr_list; /* Holds the DNS answer */
ChainLink *Info; /* Used for CCC asynchronous operations */
- char *connected_to; /* Used for per-host connection limit */
+ char *connected_to; /* Used for per-server connection limit */
+ uint_t connect_port;
Dstr *https_proxy_reply;
} SocketData_t;
@@ -72,19 +72,23 @@ typedef struct {
*/
typedef struct {
char *host;
+ uint_t port;
+ bool_t https;
+
int active_conns;
+ int running_the_queue;
Dlist *queue;
-} HostConnection_t;
+} Server_t;
typedef struct {
int fd;
int skey;
} FdMapEntry_t;
-static void Http_socket_enqueue(HostConnection_t *hc, SocketData_t* sock);
-static HostConnection_t *Http_host_connection_get(const char *host);
-static void Http_host_connection_remove(HostConnection_t *hc);
-static void Http_connect_socket(ChainLink *Info, HostConnection_t *hc);
+static void Http_socket_enqueue(Server_t *srv, SocketData_t* sock);
+static Server_t *Http_server_get(const char *host, uint_t port, bool_t https);
+static void Http_server_remove(Server_t *srv);
+static void Http_connect_socket(ChainLink *Info);
static char *Http_get_connect_str(const DilloUrl *url);
static void Http_send_query(SocketData_t *S);
static void Http_socket_free(int SKey);
@@ -97,7 +101,7 @@ static Klist_t *ValidSocks = NULL; /* Active sockets list. It holds pointers to
static DilloUrl *HTTP_Proxy = NULL;
static char *HTTP_Proxy_Auth_base64 = NULL;
static char *HTTP_Language_hdr = NULL;
-static Dlist *host_connections;
+static Dlist *servers;
/* TODO: If fd_map will stick around in its present form (FDs and SocketData_t)
* then consider whether having both this and ValidSocks is necessary.
@@ -127,7 +131,7 @@ int a_Http_init(void)
HTTP_Proxy_Auth_base64 = a_Misc_encode_base64(prefs.http_proxyuser);
*/
- host_connections = dList_new(5);
+ servers = dList_new(5);
fd_map = dList_new(20);
return 0;
@@ -211,12 +215,14 @@ void a_Http_connect_done(int fd, bool_t success)
if (fme && (sd = a_Klist_get_data(ValidSocks, fme->skey))) {
ChainLink *info = sd->Info;
+ bool_t valid_web = a_Web_valid(sd->web);
- if (success) {
+ if (success && valid_web) {
a_Chain_bfcb(OpSend, info, &sd->SockFD, "FD");
Http_send_query(sd);
} else {
- MSG_BW(sd->web, 1, "Could not establish connection.");
+ if (valid_web)
+ MSG_BW(sd->web, 1, "Could not establish connection.");
MSG("fd %d is done and failed\n", sd->SockFD);
dClose(fd);
Http_socket_free(VOIDP2INT(info->LocalKey)); /* free sd */
@@ -228,48 +234,56 @@ void a_Http_connect_done(int fd, bool_t success)
}
}
-static void Http_socket_activate(HostConnection_t *hc, SocketData_t *sd)
+static void Http_socket_activate(Server_t *srv, SocketData_t *sd)
{
- dList_remove(hc->queue, sd);
+ dList_remove(srv->queue, sd);
sd->flags &= ~HTTP_SOCKET_QUEUED;
- hc->active_conns++;
- sd->connected_to = hc->host;
+ srv->active_conns++;
+ sd->connected_to = srv->host;
}
-static void Http_connect_queued_sockets(HostConnection_t *hc)
+static void Http_connect_queued_sockets(Server_t *srv)
{
SocketData_t *sd;
int i;
+ srv->running_the_queue++;
+
for (i = 0;
- i < dList_length(hc->queue) && hc->active_conns < prefs.http_max_conns;
+ (i < dList_length(srv->queue) &&
+ srv->active_conns < prefs.http_max_conns);
i++) {
- sd = dList_nth_data(hc->queue, i);
+ sd = dList_nth_data(srv->queue, i);
- if (!(sd->flags & HTTP_SOCKET_TO_BE_FREED)) {
- int connect_ready = SSL_CONNECT_READY;
+ if (sd->flags & HTTP_SOCKET_TO_BE_FREED) {
+ dList_remove(srv->queue, sd);
+ dFree(sd);
+ i--;
+ } else {
+ int connect_ready = TLS_CONNECT_READY;
- if (sd->flags & HTTP_SOCKET_SSL)
- connect_ready = a_Ssl_connect_ready(sd->url);
+ if (sd->flags & HTTP_SOCKET_TLS)
+ connect_ready = a_Tls_connect_ready(sd->url);
- if (connect_ready == SSL_CONNECT_NEVER || !a_Web_valid(sd->web)) {
+ if (connect_ready == TLS_CONNECT_NEVER || !a_Web_valid(sd->web)) {
int SKey = VOIDP2INT(sd->Info->LocalKey);
Http_socket_free(SKey);
- } else if (connect_ready == SSL_CONNECT_READY) {
+ } else if (connect_ready == TLS_CONNECT_READY) {
i--;
- Http_socket_activate(hc, sd);
- Http_connect_socket(sd->Info, hc);
+ Http_socket_activate(srv, sd);
+ Http_connect_socket(sd->Info);
}
}
- if (sd->flags & HTTP_SOCKET_TO_BE_FREED) {
- dList_remove(hc->queue, sd);
- dFree(sd);
- i--;
- }
}
- _MSG("Queue %s len %d\n", hc->host, dList_length(hc->queue));
+ _MSG("Queue http%s://%s:%u len %d\n", srv->https ? "s" : "", srv->host,
+ srv->port, dList_length(srv->queue));
+
+ if (--srv->running_the_queue == 0) {
+ if (srv->active_conns == 0)
+ Http_server_remove(srv);
+ }
}
/*
@@ -290,15 +304,14 @@ static void Http_socket_free(int SKey)
} else {
if (S->SockFD != -1)
Http_fd_map_remove_entry(S->SockFD);
- a_Ssl_reset_server_state(S->url);
+ a_Tls_reset_server_state(S->url);
if (S->connected_to) {
- a_Ssl_close_by_fd(S->SockFD);
+ a_Tls_close_by_fd(S->SockFD);
- HostConnection_t *hc = Http_host_connection_get(S->connected_to);
- hc->active_conns--;
- Http_connect_queued_sockets(hc);
- if (hc->active_conns == 0)
- Http_host_connection_remove(hc);
+ Server_t *srv = Http_server_get(S->connected_to, S->connect_port,
+ (S->flags & HTTP_SOCKET_TLS));
+ srv->active_conns--;
+ Http_connect_queued_sockets(srv);
}
a_Url_free(S->url);
dFree(S);
@@ -478,9 +491,9 @@ static void Http_send_query(SocketData_t *S)
/*
* Prepare an HTTPS connection. If necessary, tunnel it through a proxy.
- * Then perform the SSL handshake.
+ * Then perform the TLS handshake.
*/
-static void Http_connect_ssl(ChainLink *info)
+static void Http_connect_tls(ChainLink *info)
{
int SKey = VOIDP2INT(info->LocalKey);
SocketData_t *S = a_Klist_get_data(ValidSocks, SKey);
@@ -496,7 +509,7 @@ static void Http_connect_ssl(ChainLink *info)
dFree(dbuf);
dFree(connect_str);
} else {
- a_Ssl_handshake(S->SockFD, S->url);
+ a_Tls_handshake(S->SockFD, S->url);
}
}
@@ -504,7 +517,7 @@ static void Http_connect_ssl(ChainLink *info)
* This function is called after the DNS succeeds in solving a hostname.
* Task: Finish socket setup and start connecting the socket.
*/
-static void Http_connect_socket(ChainLink *Info, HostConnection_t *hc)
+static void Http_connect_socket(ChainLink *Info)
{
int i, status;
SocketData_t *S;
@@ -542,7 +555,7 @@ static void Http_connect_socket(ChainLink *Info, HostConnection_t *hc)
sin->sin_port = htons(S->connect_port);
memcpy(&sin->sin_addr, dh->data, (size_t)dh->alen);
if (a_Web_valid(S->web) && (S->web->flags & WEB_RootUrl))
- MSG("Connecting to %s:%d\n", inet_ntoa(sin->sin_addr),
+ MSG("Connecting to %s:%u\n", inet_ntoa(sin->sin_addr),
S->connect_port);
break;
}
@@ -557,7 +570,7 @@ static void Http_connect_socket(ChainLink *Info, HostConnection_t *hc)
memcpy(&sin6->sin6_addr, dh->data, dh->alen);
inet_ntop(dh->af, dh->data, buf, sizeof(buf));
if (a_Web_valid(S->web) && (S->web->flags & WEB_RootUrl))
- MSG("Connecting to %s:%d\n", buf, S->connect_port);
+ MSG("Connecting to %s:%u\n", buf, S->connect_port);
break;
}
#endif
@@ -567,8 +580,8 @@ static void Http_connect_socket(ChainLink *Info, HostConnection_t *hc)
if (status == -1 && errno != EINPROGRESS) {
MSG("Http_connect_socket ERROR: %s\n", dStrerror(errno));
a_Http_connect_done(S->SockFD, FALSE);
- } else if (S->flags & HTTP_SOCKET_SSL) {
- Http_connect_ssl(Info);
+ } else if (S->flags & HTTP_SOCKET_TLS) {
+ Http_connect_tls(Info);
} else {
a_Http_connect_done(S->SockFD, TRUE);
}
@@ -658,7 +671,7 @@ static void Http_dns_cb(int Status, Dlist *addr_list, void *data)
int SKey = VOIDP2INT(data);
bool_t clean_up = TRUE;
SocketData_t *S;
- HostConnection_t *hc;
+ Server_t *srv;
S = a_Klist_get_data(ValidSocks, SKey);
if (S) {
@@ -670,9 +683,10 @@ static void Http_dns_cb(int Status, Dlist *addr_list, void *data)
/* Successful DNS answer; save the IP */
S->addr_list = addr_list;
clean_up = FALSE;
- hc = Http_host_connection_get(host);
- Http_socket_enqueue(hc, S);
- Http_connect_queued_sockets(hc);
+ srv = Http_server_get(host, S->connect_port,
+ (S->flags & HTTP_SOCKET_TLS));
+ Http_socket_enqueue(srv, S);
+ Http_connect_queued_sockets(srv);
} else {
/* DNS wasn't able to resolve the hostname */
MSG_BW(S->web, 0, "ERROR: DNS can't resolve %s", host);
@@ -718,7 +732,7 @@ static int Http_get(ChainLink *Info, void *Data1)
S->connect_port = URL_PORT(url);
S->url = a_Url_dup(S->web->url);
if (!dStrAsciiCasecmp(URL_SCHEME(S->url), "https"))
- S->flags |= HTTP_SOCKET_SSL;
+ S->flags |= HTTP_SOCKET_TLS;
/* Let the user know what we'll do */
MSG_BW(S->web, 1, "DNS resolving %s", hostname);
@@ -734,16 +748,18 @@ static int Http_get(ChainLink *Info, void *Data1)
/*
* Can the old socket's fd be reused for the new socket?
*
- * NOTE: old and new must come from the same HostConnection_t.
+ * NOTE: old and new must come from the same Server_t.
* This is not built to accept arbitrary sockets.
*/
static bool_t Http_socket_reuse_compatible(SocketData_t *old,
SocketData_t *new)
{
+ /*
+ * If we are using TLS through a proxy, we need to ensure that old and new
+ * are going through to the same host:port.
+ */
if (a_Web_valid(new->web) &&
- old->connect_port == new->connect_port &&
- ((old->flags & HTTP_SOCKET_SSL) == (new->flags & HTTP_SOCKET_SSL)) &&
- ((old->flags & HTTP_SOCKET_SSL) == 0 ||
+ ((old->flags & HTTP_SOCKET_TLS) == 0 ||
(old->flags & HTTP_SOCKET_USE_PROXY) == 0 ||
((URL_PORT(old->url) == URL_PORT(new->url)) &&
!dStrAsciiCasecmp(URL_HOST(old->url), URL_HOST(new->url)))))
@@ -760,11 +776,13 @@ static void Http_socket_reuse(int SKey)
SocketData_t *new_sd, *old_sd = a_Klist_get_data(ValidSocks, SKey);
if (old_sd) {
- HostConnection_t *hc = Http_host_connection_get(old_sd->connected_to);
- int i, n = dList_length(hc->queue);
+ Server_t *srv = Http_server_get(old_sd->connected_to,
+ old_sd->connect_port,
+ (old_sd->flags & HTTP_SOCKET_TLS));
+ int i, n = dList_length(srv->queue);
for (i = 0; i < n; i++) {
- new_sd = dList_nth_data(hc->queue, i);
+ new_sd = dList_nth_data(srv->queue, i);
if (!(new_sd->flags & HTTP_SOCKET_TO_BE_FREED) &&
Http_socket_reuse_compatible(old_sd, new_sd)) {
@@ -773,11 +791,11 @@ static void Http_socket_reuse(int SKey)
new_sd->SockFD = old_sd->SockFD;
old_sd->connected_to = NULL;
- hc->active_conns--;
+ srv->active_conns--;
Http_socket_free(SKey);
MSG("Reusing fd %d for %s\n", new_sd->SockFD,URL_STR(new_sd->url));
- Http_socket_activate(hc, new_sd);
+ Http_socket_activate(srv, new_sd);
Http_fd_map_add_entry(new_sd);
a_Http_connect_done(new_sd->SockFD, success);
return;
@@ -863,7 +881,7 @@ void a_Http_ccc(int Op, int Branch, int Dir, ChainLink *Info,
sd->https_proxy_reply->str);
dStr_free(sd->https_proxy_reply, 1);
sd->https_proxy_reply = NULL;
- a_Ssl_handshake(sd->SockFD, sd->url);
+ a_Tls_handshake(sd->SockFD, sd->url);
} else {
MSG_BW(sd->web, 1, "Can't connect through proxy to %s",
URL_HOST(sd->url));
@@ -935,68 +953,77 @@ void a_Http_ccc(int Op, int Branch, int Dir, ChainLink *Info,
* Add socket data to the queue. Pages/stylesheets/etc. have higher priority
* than images.
*/
-static void Http_socket_enqueue(HostConnection_t *hc, SocketData_t* sock)
+static void Http_socket_enqueue(Server_t *srv, SocketData_t* sock)
{
sock->flags |= HTTP_SOCKET_QUEUED;
if ((sock->web->flags & WEB_Image) == 0) {
- int i, n = dList_length(hc->queue);
+ int i, n = dList_length(srv->queue);
for (i = 0; i < n; i++) {
- SocketData_t *curr = dList_nth_data(hc->queue, i);
+ SocketData_t *curr = dList_nth_data(srv->queue, i);
if (a_Web_valid(curr->web) && (curr->web->flags & WEB_Image)) {
- dList_insert_pos(hc->queue, sock, i);
+ dList_insert_pos(srv->queue, sock, i);
return;
}
}
}
- dList_append(hc->queue, sock);
+ dList_append(srv->queue, sock);
}
-static HostConnection_t *Http_host_connection_get(const char *host)
+static Server_t *Http_server_get(const char *host, uint_t port, bool_t https)
{
int i;
- HostConnection_t *hc;
+ Server_t *srv;
- for (i = 0; i < dList_length(host_connections); i++) {
- hc = (HostConnection_t*) dList_nth_data(host_connections, i);
+ for (i = 0; i < dList_length(servers); i++) {
+ srv = (Server_t*) dList_nth_data(servers, i);
- if (dStrAsciiCasecmp(host, hc->host) == 0)
- return hc;
+ if (port == srv->port && https == srv->https &&
+ !dStrAsciiCasecmp(host, srv->host))
+ return srv;
}
- hc = dNew0(HostConnection_t, 1);
- hc->queue = dList_new(10);
- hc->host = dStrdup(host);
- dList_append(host_connections, hc);
+ srv = dNew0(Server_t, 1);
+ srv->queue = dList_new(10);
+ srv->running_the_queue = 0;
+ srv->host = dStrdup(host);
+ srv->port = port;
+ srv->https = https;
+ dList_append(servers, srv);
- return hc;
+ return srv;
}
-static void Http_host_connection_remove(HostConnection_t *hc)
+static void Http_server_remove(Server_t *srv)
{
- assert(dList_length(hc->queue) == 0);
- dList_free(hc->queue);
- dList_remove_fast(host_connections, hc);
- dFree(hc->host);
- dFree(hc);
+ SocketData_t *sd;
+
+ while ((sd = dList_nth_data(srv->queue, 0))) {
+ dList_remove_fast(srv->queue, sd);
+ dFree(sd);
+ }
+ dList_free(srv->queue);
+ dList_remove_fast(servers, srv);
+ dFree(srv->host);
+ dFree(srv);
}
-static void Http_host_connection_remove_all()
+static void Http_servers_remove_all()
{
- HostConnection_t *hc;
+ Server_t *srv;
SocketData_t *sd;
- while (dList_length(host_connections) > 0) {
- hc = (HostConnection_t*) dList_nth_data(host_connections, 0);
- while ((sd = dList_nth_data(hc->queue, 0))) {
- dList_remove(hc->queue, sd);
+ while (dList_length(servers) > 0) {
+ srv = (Server_t*) dList_nth_data(servers, 0);
+ while ((sd = dList_nth_data(srv->queue, 0))) {
+ dList_remove(srv->queue, sd);
dFree(sd);
}
- Http_host_connection_remove(hc);
+ Http_server_remove(srv);
}
- dList_free(host_connections);
+ dList_free(servers);
}
static void Http_fd_map_remove_all()
@@ -1017,7 +1044,7 @@ static void Http_fd_map_remove_all()
*/
void a_Http_freeall(void)
{
- Http_host_connection_remove_all();
+ Http_servers_remove_all();
Http_fd_map_remove_all();
a_Klist_free(&ValidSocks);
a_Url_free(HTTP_Proxy);
diff --git a/src/IO/ssl.h b/src/IO/ssl.h
deleted file mode 100644
index f55479b2..00000000
--- a/src/IO/ssl.h
+++ /dev/null
@@ -1,47 +0,0 @@
-#ifndef __SSL_H__
-#define __SSL_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "../url.h"
-
-#define SSL_CONNECT_NEVER -1
-#define SSL_CONNECT_NOT_YET 0
-#define SSL_CONNECT_READY 1
-
-void a_Ssl_init();
-
-
-#ifdef ENABLE_SSL
-int a_Ssl_connect_ready(const DilloUrl *url);
-void a_Ssl_reset_server_state(const DilloUrl *url);
-
-/* Use to initiate a SSL connection. */
-void a_Ssl_handshake(int fd, const DilloUrl *url);
-
-void *a_Ssl_connection(int fd);
-
-void a_Ssl_freeall();
-
-void a_Ssl_close_by_fd(int fd);
-int a_Ssl_read(void *conn, void *buf, size_t len);
-int a_Ssl_write(void *conn, void *buf, size_t len);
-#else
-
-#define a_Ssl_connect_ready(url) SSL_CONNECT_NEVER
-#define a_Ssl_reset_server_state(url) ;
-#define a_Ssl_handshake(fd, url) ;
-#define a_Ssl_connection(fd) NULL
-#define a_Ssl_freeall() ;
-#define a_Ssl_close_by_fd(fd) ;
-#define a_Ssl_read(conn, buf, len) 0
-#define a_Ssl_write(conn, buf, len) 0
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __SSL_H__ */
-
diff --git a/src/IO/ssl.c b/src/IO/tls.c
index 856d94b5..f0f33215 100644
--- a/src/IO/ssl.c
+++ b/src/IO/tls.c
@@ -1,5 +1,5 @@
/*
- * File: ssl.c
+ * File: tls.c
*
* Copyright 2004 Garrett Kajmowicz <gkajmowi@tbaytel.net>
* (for some bits derived from the https dpi, e.g., certificate handling)
@@ -33,9 +33,9 @@
#ifndef ENABLE_SSL
-void a_Ssl_init()
+void a_Tls_init()
{
- MSG("SSL: Disabled at compilation time.\n");
+ MSG("TLS: Disabled at compilation time.\n");
}
#else
@@ -52,7 +52,7 @@ void a_Ssl_init()
#include "../dialog.hh"
#include "../klist.h"
#include "iowatch.hh"
-#include "ssl.h"
+#include "tls.h"
#include "Url.h"
#include <openssl/ssl.h>
@@ -78,7 +78,7 @@ typedef struct {
} FdMapEntry_t;
/*
- * Data type for SSL connection information
+ * Data type for TLS connection information
*/
typedef struct {
int fd;
@@ -87,22 +87,22 @@ typedef struct {
bool_t connecting;
} Conn_t;
-/* List of active SSL connections */
+/* List of active TLS connections */
static Klist_t *conn_list = NULL;
/*
- * If ssl_context is still NULL, this corresponds to SSL being disabled.
+ * If ssl_context is still NULL, this corresponds to TLS being disabled.
*/
static SSL_CTX *ssl_context;
static Dlist *servers;
static Dlist *fd_map;
-static void Ssl_connect_cb(int fd, void *vssl);
+static void Tls_connect_cb(int fd, void *vconnkey);
/*
* Compare by FD.
*/
-static int Ssl_fd_map_cmp(const void *v1, const void *v2)
+static int Tls_fd_map_cmp(const void *v1, const void *v2)
{
int fd = VOIDP2INT(v2);
const FdMapEntry_t *e = v1;
@@ -110,14 +110,14 @@ static int Ssl_fd_map_cmp(const void *v1, const void *v2)
return (fd != e->fd);
}
-static void Ssl_fd_map_add_entry(int fd, int connkey)
+static void Tls_fd_map_add_entry(int fd, int connkey)
{
FdMapEntry_t *e = dNew0(FdMapEntry_t, 1);
e->fd = fd;
e->connkey = connkey;
- if (dList_find_custom(fd_map, INT2VOIDP(e->fd), Ssl_fd_map_cmp)) {
- MSG_ERR("SSL FD ENTRY ALREADY FOUND FOR %d\n", e->fd);
+ if (dList_find_custom(fd_map, INT2VOIDP(e->fd), Tls_fd_map_cmp)) {
+ MSG_ERR("TLS FD ENTRY ALREADY FOUND FOR %d\n", e->fd);
assert(0);
}
@@ -128,30 +128,30 @@ static void Ssl_fd_map_add_entry(int fd, int connkey)
/*
* Remove and free entry from fd_map.
*/
-static void Ssl_fd_map_remove_entry(int fd)
+static void Tls_fd_map_remove_entry(int fd)
{
- void *data = dList_find_custom(fd_map, INT2VOIDP(fd), Ssl_fd_map_cmp);
+ void *data = dList_find_custom(fd_map, INT2VOIDP(fd), Tls_fd_map_cmp);
//MSG("REMOVE ENTRY %d\n", fd);
if (data) {
dList_remove_fast(fd_map, data);
dFree(data);
} else {
- MSG("SSL FD ENTRY NOT FOUND FOR %d\n", fd);
+ MSG("TLS FD ENTRY NOT FOUND FOR %d\n", fd);
}
}
/*
- * Return SSL connection information for a given file
- * descriptor, or NULL if no SSL connection was found.
+ * Return TLS connection information for a given file
+ * descriptor, or NULL if no TLS connection was found.
*/
-void *a_Ssl_connection(int fd)
+void *a_Tls_connection(int fd)
{
Conn_t *conn;
if (fd_map) {
FdMapEntry_t *fme = dList_find_custom(fd_map, INT2VOIDP(fd),
- Ssl_fd_map_cmp);
+ Tls_fd_map_cmp);
if (fme && (conn = a_Klist_get_data(conn_list, fme->connkey)))
return conn;
@@ -160,9 +160,9 @@ void *a_Ssl_connection(int fd)
}
/*
- * Add a new SSL connection information node.
+ * Add a new TLS connection information node.
*/
-static int Ssl_conn_new(int fd, const DilloUrl *url, SSL *ssl)
+static int Tls_conn_new(int fd, const DilloUrl *url, SSL *ssl)
{
int key;
@@ -174,19 +174,22 @@ static int Ssl_conn_new(int fd, const DilloUrl *url, SSL *ssl)
key = a_Klist_insert(&conn_list, conn);
- Ssl_fd_map_add_entry(fd, key);
+ Tls_fd_map_add_entry(fd, key);
return key;
}
/*
- * Let's monitor for ssl alerts.
+ * Let's monitor for TLS alerts.
*/
-static void Ssl_info_cb(const SSL *ssl, int where, int ret)
+static void Tls_info_cb(const SSL *ssl, int where, int ret)
{
if (where & SSL_CB_ALERT) {
- MSG("SSL ALERT on %s: %s\n", (where & SSL_CB_READ) ? "read" : "write",
- SSL_alert_desc_string_long(ret));
+ const char *str = SSL_alert_desc_string_long(ret);
+
+ if (strcmp(str, "close notify"))
+ MSG("TLS ALERT on %s: %s\n", (where & SSL_CB_READ) ? "read" : "write",
+ str);
}
}
@@ -197,7 +200,7 @@ static void Ssl_info_cb(const SSL *ssl, int where, int ret)
* abysmal openssl documentation, this was worked out from reading discussion
* on the web and then reading openssl source to see what it normally does.
*/
-static void Ssl_load_certificates()
+static void Tls_load_certificates()
{
/* curl-7.37.1 says that the following bundle locations are used on "Debian
* systems", "Redhat and Mandriva", "old(er) Redhat", "FreeBSD", and
@@ -207,7 +210,7 @@ static void Ssl_load_certificates()
*/
uint_t u;
char *userpath;
- static const char *ca_files[] = {
+ static const char *const ca_files[] = {
"/etc/ssl/certs/ca-certificates.crt",
"/etc/pki/tls/certs/ca-bundle.crt",
"/usr/share/ssl/certs/ca-bundle.crt",
@@ -216,7 +219,7 @@ static void Ssl_load_certificates()
CA_CERTS_FILE
};
- static const char *ca_paths[] = {
+ static const char *const ca_paths[] = {
"/etc/ssl/certs/",
CA_CERTS_DIR
};
@@ -247,7 +250,7 @@ static void Ssl_load_certificates()
/*
* Initialize the OpenSSL library.
*/
-void a_Ssl_init(void)
+void a_Tls_init(void)
{
SSL_library_init();
SSL_load_error_strings();
@@ -266,7 +269,7 @@ void a_Ssl_init(void)
return;
}
- SSL_CTX_set_info_callback(ssl_context, Ssl_info_cb);
+ SSL_CTX_set_info_callback(ssl_context, Tls_info_cb);
/* Don't want: eNULL, which has no encryption; aNULL, which has no
* authentication; LOW, which as of 2014 use 64 or 56-bit encryption;
@@ -285,7 +288,7 @@ void a_Ssl_init(void)
/* This lets us deal with self-signed certificates */
SSL_CTX_set_verify(ssl_context, SSL_VERIFY_NONE, NULL);
- Ssl_load_certificates();
+ Tls_load_certificates();
fd_map = dList_new(20);
servers = dList_new(8);
@@ -295,7 +298,7 @@ void a_Ssl_init(void)
* Save certificate with a hashed filename.
* Return: 0 on success, 1 on failure.
*/
-static int Ssl_save_certificate_home(X509 * cert)
+static int Tls_save_certificate_home(X509 * cert)
{
char buf[4096];
@@ -338,16 +341,30 @@ static int Ssl_save_certificate_home(X509 * cert)
}
/*
- * Test whether a URL corresponds to a server.
+ * Ordered comparison of servers.
*/
-static int Ssl_servers_cmp(const void *v1, const void *v2)
+static int Tls_servers_cmp(const void *v1, const void *v2)
{
- Server_t *s = (Server_t *)v1;
+ const Server_t *s1 = (const Server_t *)v1, *s2 = (const Server_t *)v2;
+ int cmp = dStrAsciiCasecmp(s1->hostname, s2->hostname);
+
+ if (!cmp)
+ cmp = s1->port - s2->port;
+ return cmp;
+}
+/*
+ * Ordered comparison of server with URL.
+ */
+static int Tls_servers_by_url_cmp(const void *v1, const void *v2)
+{
+ const Server_t *s = (const Server_t *)v1;
const DilloUrl *url = (const DilloUrl *)v2;
- const char *host = URL_HOST(url);
- int port = URL_PORT(url);
- return (dStrAsciiCasecmp(s->hostname, host) || (port != s->port));
+ int cmp = dStrAsciiCasecmp(s->hostname, URL_HOST(url));
+
+ if (!cmp)
+ cmp = s->port - URL_PORT(url);
+ return cmp;
}
/*
@@ -355,41 +372,31 @@ static int Ssl_servers_cmp(const void *v1, const void *v2)
* Once we have the certificate, know whether we like it -- and whether the
* user accepts it -- HTTP can run through queued sockets as normal.
*
- * Return: 1 means yes, 0 means not yet, -1 means never.
- * TODO: Something clearer or different.
+ * Return: TLS_CONNECT_READY or TLS_CONNECT_NOT_YET or TLS_CONNECT_NEVER.
*/
-int a_Ssl_connect_ready(const DilloUrl *url)
+int a_Tls_connect_ready(const DilloUrl *url)
{
Server_t *s;
- int i, len;
- const char *host = URL_HOST(url);
- const int port = URL_PORT(url);
- int ret = SSL_CONNECT_READY;
+ int ret = TLS_CONNECT_READY;
- dReturn_val_if_fail(ssl_context, SSL_CONNECT_NEVER);
+ dReturn_val_if_fail(ssl_context, TLS_CONNECT_NEVER);
- len = dList_length(servers);
+ if ((s = dList_find_sorted(servers, url, Tls_servers_by_url_cmp))) {
+ if (s->cert_status == CERT_STATUS_RECEIVING)
+ ret = TLS_CONNECT_NOT_YET;
+ else if (s->cert_status == CERT_STATUS_BAD)
+ ret = TLS_CONNECT_NEVER;
- for (i = 0; i < len; i++) {
- s = dList_nth_data(servers, i);
-
- if (!dStrAsciiCasecmp(s->hostname, host) && (port == s->port)) {
- if (s->cert_status == CERT_STATUS_RECEIVING)
- ret = SSL_CONNECT_NOT_YET;
- else if (s->cert_status == CERT_STATUS_BAD)
- ret = SSL_CONNECT_NEVER;
+ if (s->cert_status == CERT_STATUS_NONE)
+ s->cert_status = CERT_STATUS_RECEIVING;
+ } else {
+ s = dNew(Server_t, 1);
- if (s->cert_status == CERT_STATUS_NONE)
- s->cert_status = CERT_STATUS_RECEIVING;
- return ret;
- }
+ s->hostname = dStrdup(URL_HOST(url));
+ s->port = URL_PORT(url);
+ s->cert_status = CERT_STATUS_RECEIVING;
+ dList_insert_sorted(servers, s, Tls_servers_cmp);
}
- s = dNew(Server_t, 1);
-
- s->port = port;
- s->hostname = dStrdup(host);
- s->cert_status = CERT_STATUS_RECEIVING;
- dList_append(servers, s);
return ret;
}
@@ -397,9 +404,9 @@ int a_Ssl_connect_ready(const DilloUrl *url)
* Did we find problems with the certificate, and did the user proceed to
* reject the connection?
*/
-static int Ssl_user_said_no(const DilloUrl *url)
+static int Tls_user_said_no(const DilloUrl *url)
{
- Server_t *s = dList_find_custom(servers, url, Ssl_servers_cmp);
+ Server_t *s = dList_find_sorted(servers, url, Tls_servers_by_url_cmp);
if (!s)
return FALSE;
@@ -407,20 +414,6 @@ static int Ssl_user_said_no(const DilloUrl *url)
return s->cert_status == CERT_STATUS_BAD;
}
-/*
- * Did we find problems with the certificate, and did the user proceed to
- * accept the connection anyway?
- */
-static int Ssl_user_said_yes(const DilloUrl *url)
-{
- Server_t *s = dList_find_custom(servers, url, Ssl_servers_cmp);
-
- if (!s)
- return FALSE;
-
- return s->cert_status == CERT_STATUS_USER_ACCEPTED;
-}
-
/******************** BEGINNING OF STUFF DERIVED FROM wget-1.16.3 */
#define ASTERISK_EXCLUDES_DOT /* mandated by rfc2818 */
@@ -466,13 +459,18 @@ static bool_t pattern_match (const char *pattern, const char *string)
return *n == '\0';
}
-static bool_t Ssl_check_cert_hostname(X509 *cert, const DilloUrl *url,
+/*
+ * Check that the certificate corresponds to the site it's presented for.
+ *
+ * Return TRUE if the hostname matched or the user indicated acceptance.
+ * FALSE on failure.
+ */
+static bool_t Tls_check_cert_hostname(X509 *cert, const char *host,
int *choice)
{
- dReturn_val_if_fail(cert && url, -1);
+ dReturn_val_if_fail(cert && host, FALSE);
char *msg;
- const char *host = URL_HOST(url);
GENERAL_NAMES *subjectAltNames;
bool_t success = TRUE, alt_name_checked = FALSE;;
char common_name[256];
@@ -493,6 +491,10 @@ static bool_t Ssl_check_cert_hostname(X509 *cert, const DilloUrl *url,
{
/* Test subject alternative names */
+ Dstr *err = dStr_new("");
+ dStr_sprintf(err, "Hostname %s does not match any of certificate's "
+ "Subject Alternative Names: ", host);
+
/* Do we want to check for dNSNAmes or ipAddresses (see RFC 2818)?
* Signal it by host_in_octet_string. */
ASN1_OCTET_STRING *host_in_octet_string = a2i_IPADDRESS (host);
@@ -516,6 +518,7 @@ static bool_t Ssl_check_cert_hostname(X509 *cert, const DilloUrl *url,
if (!ASN1_STRING_cmp (host_in_octet_string,
name->d.iPAddress))
break;
+ dStr_sprintfa(err, "%s ", name->d.iPAddress);
}
}
else if (name->type == GEN_DNS)
@@ -537,6 +540,7 @@ static bool_t Ssl_check_cert_hostname(X509 *cert, const DilloUrl *url,
OPENSSL_free (name_in_utf8);
break;
}
+ dStr_sprintfa(err, "%s ", name_in_utf8);
OPENSSL_free (name_in_utf8);
}
}
@@ -549,11 +553,8 @@ static bool_t Ssl_check_cert_hostname(X509 *cert, const DilloUrl *url,
if (alt_name_checked == TRUE && i >= numaltnames)
{
success = FALSE;
- msg = dStrconcat("No certificate subject alternative name matches"
- " requested host name \n", host, NULL);
- *choice = a_Dialog_choice("Dillo SSL security warning",
- msg, "Continue", "Cancel", NULL);
- dFree(msg);
+ *choice = a_Dialog_choice("Dillo TLS security warning",
+ err->str, "Continue", "Cancel", NULL);
switch (*choice){
case 1:
@@ -565,6 +566,7 @@ static bool_t Ssl_check_cert_hostname(X509 *cert, const DilloUrl *url,
break;
}
}
+ dStr_free(err, 1);
}
if (alt_name_checked == FALSE)
@@ -580,7 +582,7 @@ static bool_t Ssl_check_cert_hostname(X509 *cert, const DilloUrl *url,
success = FALSE;
msg = dStrconcat("Certificate common name ", common_name,
" doesn't match requested host name ", host, NULL);
- *choice = a_Dialog_choice("Dillo SSL security warning",
+ *choice = a_Dialog_choice("Dillo TLS security warning",
msg, "Continue", "Cancel", NULL);
dFree(msg);
@@ -626,7 +628,7 @@ static bool_t Ssl_check_cert_hostname(X509 *cert, const DilloUrl *url,
"character). This may be an indication that the "
"host is not who it claims to be -- that is, not "
"the real ", host, NULL);
- *choice = a_Dialog_choice("Dillo SSL security warning",
+ *choice = a_Dialog_choice("Dillo TLS security warning",
msg, "Continue", "Cancel", NULL);
dFree(msg);
@@ -648,18 +650,58 @@ static bool_t Ssl_check_cert_hostname(X509 *cert, const DilloUrl *url,
/******************** END OF STUFF DERIVED FROM wget-1.16.3 */
/*
+ * Get the certificate at the end of the chain, or NULL on failure.
+ *
+ * Rumor has it that the stack can be NULL if a connection has been reused
+ * and that the stack can then be reconstructed if necessary, but it doesn't
+ * sound like a case we'll encounter.
+ */
+static X509 *Tls_get_end_of_chain(SSL *ssl)
+{
+ STACK_OF(X509) *sk = SSL_get_peer_cert_chain(ssl);
+
+ return sk ? sk_X509_value(sk, sk_X509_num(sk) - 1) : NULL;
+}
+
+static void Tls_get_issuer_name(X509 *cert, char *buf, uint_t buflen)
+{
+ if (cert) {
+ X509_NAME_oneline(X509_get_issuer_name(cert), buf, buflen);
+ } else {
+ strncpy(buf, "(unknown)", buflen);
+ buf[buflen-1] = '\0';
+ }
+}
+
+static void Tls_get_expiration_str(X509 *cert, char *buf, uint_t buflen)
+{
+ ASN1_TIME *exp_date = X509_get_notAfter(cert);
+ BIO *b = BIO_new(BIO_s_mem());
+ int rc = ASN1_TIME_print(b, exp_date);
+
+ if (rc > 0) {
+ rc = BIO_gets(b, buf, buflen);
+ }
+ if (rc <= 0) {
+ strncpy(buf, "(unknown)", buflen);
+ buf[buflen-1] = '\0';
+ }
+ BIO_free(b);
+}
+
+/*
* Examine the certificate, and, if problems are detected, ask the user what
* to do.
* Return: -1 if connection should be canceled, or 0 if it should continue.
*/
-static int Ssl_examine_certificate(SSL *ssl, const DilloUrl *url)
+static int Tls_examine_certificate(SSL *ssl, Server_t *srv,const char *host)
{
X509 *remote_cert;
long st;
- char buf[4096], *cn, *msg;
+ const uint_t buflen = 4096;
+ char buf[buflen], *cn, *msg;
int choice = -1, ret = -1;
- char *title = dStrconcat("Dillo SSL security warning: ",URL_HOST(url),NULL);
- Server_t *srv = dList_find_custom(servers, url, Ssl_servers_cmp);
+ char *title = dStrconcat("Dillo TLS security warning: ", host, NULL);
remote_cert = SSL_get_peer_certificate(ssl);
if (remote_cert == NULL){
@@ -674,7 +716,7 @@ static int Ssl_examine_certificate(SSL *ssl, const DilloUrl *url)
ret = 0;
}
- } else if (Ssl_check_cert_hostname(remote_cert, url, &choice)) {
+ } else if (Tls_check_cert_hostname(remote_cert, host, &choice)) {
/* Figure out if (and why) the remote system can't be trusted */
st = SSL_get_verify_result(ssl);
switch (st) {
@@ -713,7 +755,7 @@ static int Ssl_examine_certificate(SSL *ssl, const DilloUrl *url)
/* Save certificate to a file here and recheck the chain */
/* Potential security problems because we are writing
* to the filesystem */
- Ssl_save_certificate_home(remote_cert);
+ Tls_save_certificate_home(remote_cert);
ret = 1;
break;
default:
@@ -761,14 +803,15 @@ static int Ssl_examine_certificate(SSL *ssl, const DilloUrl *url)
break;
case X509_V_ERR_CERT_HAS_EXPIRED:
case X509_V_ERR_CRL_HAS_EXPIRED:
- choice = a_Dialog_choice(title,
- "The remote certificate has expired. The certificate "
- "wasn't designed to last this long. You should avoid "
- "this site.",
- "Continue", "Cancel", NULL);
+ Tls_get_expiration_str(remote_cert, buf, buflen);
+ msg = dStrconcat("The remote certificate expired on: ", buf,
+ ". This site can no longer be trusted.", NULL);
+
+ choice = a_Dialog_choice(title, msg, "Continue", "Cancel", NULL);
if (choice == 1) {
ret = 0;
}
+ dFree(msg);
break;
case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
@@ -812,23 +855,24 @@ static int Ssl_examine_certificate(SSL *ssl, const DilloUrl *url)
}
break;
case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
- choice = a_Dialog_choice(title,
- "Self signed certificate in certificate chain. The certificate "
- "chain could be built up using the untrusted certificates but the "
- "root could not be found locally.",
- "Continue", "Cancel", NULL);
+ Tls_get_issuer_name(Tls_get_end_of_chain(ssl), buf, buflen);
+ msg = dStrconcat("Certificate chain led to a self-signed certificate "
+ "instead of a trusted root. Name: ", buf , NULL);
+ choice = a_Dialog_choice(title, msg, "Continue", "Cancel", NULL);
if (choice == 1) {
ret = 0;
}
+ dFree(msg);
break;
case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
- choice = a_Dialog_choice(title,
- "Unable to get local issuer certificate. The issuer certificate "
- "of an untrusted certificate cannot be found.",
- "Continue", "Cancel", NULL);
+ Tls_get_issuer_name(Tls_get_end_of_chain(ssl), buf, buflen);
+ msg = dStrconcat("The issuer certificate of an untrusted certificate "
+ "cannot be found. Issuer: ", buf, NULL);
+ choice = a_Dialog_choice(title, msg, "Continue", "Cancel", NULL);
if (choice == 1) {
ret = 0;
}
+ dFree(msg);
break;
default: /* Need to add more options later */
snprintf(buf, 80,
@@ -859,10 +903,10 @@ static int Ssl_examine_certificate(SSL *ssl, const DilloUrl *url)
* If the connection was closed before we got the certificate, we need to
* reset state so that we'll try again.
*/
-void a_Ssl_reset_server_state(const DilloUrl *url)
+void a_Tls_reset_server_state(const DilloUrl *url)
{
if (servers) {
- Server_t *s = dList_find_custom(servers, url, Ssl_servers_cmp);
+ Server_t *s = dList_find_sorted(servers, url, Tls_servers_by_url_cmp);
if (s && s->cert_status == CERT_STATUS_RECEIVING)
s->cert_status = CERT_STATUS_NONE;
@@ -870,14 +914,14 @@ void a_Ssl_reset_server_state(const DilloUrl *url)
}
/*
- * Close an open SSL connection.
+ * Close an open TLS connection.
*/
-static void Ssl_close_by_key(int connkey)
+static void Tls_close_by_key(int connkey)
{
Conn_t *c;
if ((c = a_Klist_get_data(conn_list, connkey))) {
- a_Ssl_reset_server_state(c->url);
+ a_Tls_reset_server_state(c->url);
if (c->connecting) {
a_IOwatch_remove_fd(c->fd, -1);
dClose(c->fd);
@@ -886,24 +930,100 @@ static void Ssl_close_by_key(int connkey)
SSL_free(c->ssl);
a_Url_free(c->url);
- Ssl_fd_map_remove_entry(c->fd);
+ Tls_fd_map_remove_entry(c->fd);
a_Klist_remove(conn_list, connkey);
dFree(c);
}
}
+static void Tls_print_cert_chain(SSL *ssl)
+{
+ STACK_OF(X509) *sk = SSL_get_peer_cert_chain(ssl);
+
+ if (sk) {
+ const uint_t buflen = 4096;
+ char buf[buflen];
+ int rc, i, n = sk_X509_num(sk);
+ X509 *cert = NULL;
+ EVP_PKEY *public_key;
+ int key_type, key_bits;
+ const char *type_str;
+ BIO *b;
+
+ for (i = 0; i < n; i++) {
+ cert = sk_X509_value(sk, i);
+ public_key = X509_get_pubkey(cert);
+
+ /* We are trying to find a way to get the hash function used
+ * with a certificate. This way, which is not very pleasant, puts
+ * a string such as "sha256WithRSAEncryption" in our buffer and we
+ * then trim off the "With..." part.
+ */
+ b = BIO_new(BIO_s_mem());
+ rc = i2a_ASN1_OBJECT(b, cert->sig_alg->algorithm);
+
+ if (rc > 0) {
+ rc = BIO_gets(b, buf, buflen);
+ }
+ if (rc <= 0) {
+ strcpy(buf, "(unknown)");
+ buf[buflen-1] = '\0';
+ } else {
+ char *s = strstr(buf, "With");
+
+ if (s) {
+ *s = '\0';
+ if (!strcmp(buf, "sha1")) {
+ MSG_WARN("In 2015, browsers have begun to deprecate SHA1 "
+ "certificates.\n");
+ } else if (!strncmp(buf, "md", 2)) {
+ MSG_ERR("Browsers stopped accepting MD5 certificates around "
+ "2012.\n");
+ }
+ }
+ }
+ BIO_free(b);
+ MSG("%s ", buf);
+
+
+ key_type = EVP_PKEY_type(public_key->type);
+ type_str = key_type == EVP_PKEY_RSA ? "RSA" :
+ key_type == EVP_PKEY_DSA ? "DSA" :
+ key_type == EVP_PKEY_DH ? "DH" :
+ key_type == EVP_PKEY_EC ? "EC" : "???";
+ key_bits = EVP_PKEY_bits(public_key);
+ X509_NAME_oneline(X509_get_subject_name(cert), buf, buflen);
+ buf[buflen-1] = '\0';
+ MSG("%d-bit %s: %s\n", key_bits, type_str, buf);
+ EVP_PKEY_free(public_key);
+
+ if (key_type == EVP_PKEY_RSA && key_bits <= 1024) {
+ /* TODO: Gather warnings into one popup. */
+ MSG_WARN("In 2014/5, browsers have been deprecating 1024-bit RSA "
+ "keys.\n");
+ }
+ }
+
+ if (cert) {
+ X509_NAME_oneline(X509_get_issuer_name(cert), buf, buflen);
+ buf[buflen-1] = '\0';
+ MSG("root: %s\n", buf);
+ }
+ }
+}
+
/*
* Connect, set a callback if it's still not completed. If completed, check
* the certificate and report back to http.
*/
-static void Ssl_connect(int fd, int connkey)
+static void Tls_connect(int fd, int connkey)
{
int ret;
bool_t ongoing = FALSE, failed = TRUE;
Conn_t *conn;
if (!(conn = a_Klist_get_data(conn_list, connkey))) {
- MSG("Ssl_connect: conn for fd %d not valid\n", fd);
+ MSG("Tls_connect: conn for fd %d not valid\n", fd);
return;
}
@@ -917,10 +1037,10 @@ static void Ssl_connect(int fd, int connkey)
err1_ret == SSL_ERROR_WANT_WRITE) {
int want = err1_ret == SSL_ERROR_WANT_READ ? DIO_READ : DIO_WRITE;
- _MSG("iowatching fd %d for ssl -- want %s\n", fd,
+ _MSG("iowatching fd %d for tls -- want %s\n", fd,
err1_ret == SSL_ERROR_WANT_READ ? "read" : "write");
a_IOwatch_remove_fd(fd, -1);
- a_IOwatch_add_fd(fd, want, Ssl_connect_cb, INT2VOIDP(connkey));
+ a_IOwatch_add_fd(fd, want, Tls_connect_cb, INT2VOIDP(connkey));
ongoing = TRUE;
failed = FALSE;
} else if (err1_ret == SSL_ERROR_SYSCALL || err1_ret == SSL_ERROR_SSL) {
@@ -934,14 +1054,14 @@ static void Ssl_connect(int fd, int connkey)
} else {
/* nothing in the error queue */
if (ret == 0) {
- MSG("SSL connect error: \"an EOF was observed that violates "
+ MSG("TLS connect error: \"an EOF was observed that violates "
"the protocol\"\n");
/*
* I presume we took too long on our side and the server grew
* impatient.
*/
} else if (ret == -1) {
- MSG("SSL connect error: %s\n", dStrerror(errno));
+ MSG("TLS connect error: %s\n", dStrerror(errno));
/* If the following can happen, I'll add code to handle it, but
* I don't want to add code blindly if it isn't getting used
@@ -956,9 +1076,24 @@ static void Ssl_connect(int fd, int connkey)
MSG("SSL_get_error() returned %d on a connect.\n", err1_ret);
}
} else {
- if (Ssl_user_said_yes(conn->url) ||
- (Ssl_examine_certificate(conn->ssl, conn->url) != -1))
+ Server_t *srv = dList_find_sorted(servers, conn->url,
+ Tls_servers_by_url_cmp);
+
+ if (srv->cert_status == CERT_STATUS_RECEIVING) {
+ /* Making first connection with the server. Show some information. */
+ SSL *ssl = conn->ssl;
+ const char *version = SSL_get_version(ssl);
+ const SSL_CIPHER *cipher = SSL_get_current_cipher(ssl);
+
+ MSG("%s: %s, cipher %s\n", URL_AUTHORITY(conn->url), version,
+ SSL_CIPHER_get_name(cipher));
+ Tls_print_cert_chain(ssl);
+ }
+
+ if (srv->cert_status == CERT_STATUS_USER_ACCEPTED ||
+ (Tls_examine_certificate(conn->ssl, srv, URL_HOST(conn->url))!=-1)) {
failed = FALSE;
+ }
}
/*
@@ -970,7 +1105,7 @@ static void Ssl_connect(int fd, int connkey)
if (a_Klist_get_data(conn_list, connkey)) {
conn->connecting = FALSE;
if (failed) {
- Ssl_close_by_key(connkey);
+ Tls_close_by_key(connkey);
}
a_IOwatch_remove_fd(fd, DIO_READ|DIO_WRITE);
a_Http_connect_done(fd, failed ? FALSE : TRUE);
@@ -980,15 +1115,15 @@ static void Ssl_connect(int fd, int connkey)
}
}
-static void Ssl_connect_cb(int fd, void *vconnkey)
+static void Tls_connect_cb(int fd, void *vconnkey)
{
- Ssl_connect(fd, VOIDP2INT(vconnkey));
+ Tls_connect(fd, VOIDP2INT(vconnkey));
}
/*
- * Perform the SSL handshake on an open socket.
+ * Perform the TLS handshake on an open socket.
*/
-void a_Ssl_handshake(int fd, const DilloUrl *url)
+void a_Tls_handshake(int fd, const DilloUrl *url)
{
SSL *ssl;
bool_t success = TRUE;
@@ -997,7 +1132,7 @@ void a_Ssl_handshake(int fd, const DilloUrl *url)
if (!ssl_context)
success = FALSE;
- if (success && Ssl_user_said_no(url)) {
+ if (success && Tls_user_said_no(url)) {
success = FALSE;
}
@@ -1011,7 +1146,7 @@ void a_Ssl_handshake(int fd, const DilloUrl *url)
success = FALSE;
}
- /* assign SSL connection to this file descriptor */
+ /* assign TLS connection to this file descriptor */
if (success && !SSL_set_fd(ssl, fd)) {
unsigned long err_ret = ERR_get_error();
do {
@@ -1021,7 +1156,7 @@ void a_Ssl_handshake(int fd, const DilloUrl *url)
}
if (success)
- connkey = Ssl_conn_new(fd, url, ssl);
+ connkey = Tls_conn_new(fd, url, ssl);
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
/* Server Name Indication. From the openssl changelog, it looks like this
@@ -1032,42 +1167,42 @@ void a_Ssl_handshake(int fd, const DilloUrl *url)
#endif
if (!success) {
- a_Ssl_reset_server_state(url);
+ a_Tls_reset_server_state(url);
a_Http_connect_done(fd, success);
} else {
- Ssl_connect(fd, connkey);
+ Tls_connect(fd, connkey);
}
}
/*
- * Read data from an open SSL connection.
+ * Read data from an open TLS connection.
*/
-int a_Ssl_read(void *conn, void *buf, size_t len)
+int a_Tls_read(void *conn, void *buf, size_t len)
{
Conn_t *c = (Conn_t*)conn;
return SSL_read(c->ssl, buf, len);
}
/*
- * Write data to an open SSL connection.
+ * Write data to an open TLS connection.
*/
-int a_Ssl_write(void *conn, void *buf, size_t len)
+int a_Tls_write(void *conn, void *buf, size_t len)
{
Conn_t *c = (Conn_t*)conn;
return SSL_write(c->ssl, buf, len);
}
-void a_Ssl_close_by_fd(int fd)
+void a_Tls_close_by_fd(int fd)
{
FdMapEntry_t *fme = dList_find_custom(fd_map, INT2VOIDP(fd),
- Ssl_fd_map_cmp);
+ Tls_fd_map_cmp);
if (fme) {
- Ssl_close_by_key(fme->connkey);
+ Tls_close_by_key(fme->connkey);
}
}
-static void Ssl_servers_freeall()
+static void Tls_servers_freeall()
{
if (servers) {
Server_t *s;
@@ -1082,7 +1217,7 @@ static void Ssl_servers_freeall()
}
}
-static void Ssl_fd_map_remove_all()
+static void Tls_fd_map_remove_all()
{
if (fd_map) {
FdMapEntry_t *fme;
@@ -1099,12 +1234,12 @@ static void Ssl_fd_map_remove_all()
/*
* Clean up the OpenSSL library
*/
-void a_Ssl_freeall(void)
+void a_Tls_freeall(void)
{
if (ssl_context)
SSL_CTX_free(ssl_context);
- Ssl_fd_map_remove_all();
- Ssl_servers_freeall();
+ Tls_fd_map_remove_all();
+ Tls_servers_freeall();
}
#endif /* ENABLE_SSL */
diff --git a/src/IO/tls.h b/src/IO/tls.h
new file mode 100644
index 00000000..e3892cb2
--- /dev/null
+++ b/src/IO/tls.h
@@ -0,0 +1,47 @@
+#ifndef __TLS_H__
+#define __TLS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "../url.h"
+
+#define TLS_CONNECT_NEVER -1
+#define TLS_CONNECT_NOT_YET 0
+#define TLS_CONNECT_READY 1
+
+void a_Tls_init();
+
+
+#ifdef ENABLE_SSL
+int a_Tls_connect_ready(const DilloUrl *url);
+void a_Tls_reset_server_state(const DilloUrl *url);
+
+/* Use to initiate a TLS connection. */
+void a_Tls_handshake(int fd, const DilloUrl *url);
+
+void *a_Tls_connection(int fd);
+
+void a_Tls_freeall();
+
+void a_Tls_close_by_fd(int fd);
+int a_Tls_read(void *conn, void *buf, size_t len);
+int a_Tls_write(void *conn, void *buf, size_t len);
+#else
+
+#define a_Tls_connect_ready(url) TLS_CONNECT_NEVER
+#define a_Tls_reset_server_state(url) ;
+#define a_Tls_handshake(fd, url) ;
+#define a_Tls_connection(fd) NULL
+#define a_Tls_freeall() ;
+#define a_Tls_close_by_fd(fd) ;
+#define a_Tls_read(conn, buf, len) 0
+#define a_Tls_write(conn, buf, len) 0
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TLS_H__ */
+
diff --git a/src/cache.c b/src/cache.c
index 2cc8c0aa..d8f1a123 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -756,6 +756,7 @@ static void Cache_parse_header(CacheEntry_t *entry)
if (!web->requester ||
a_Url_same_organization(entry->Url, web->requester)) {
+ /* If cookies are third party, don't even consider them. */
char *server_date = Cache_parse_field(header, "Date");
a_Cookies_set(Cookies, entry->Url, server_date);
@@ -764,10 +765,6 @@ static void Cache_parse_header(CacheEntry_t *entry)
}
}
}
- if (i >= dList_length(ClientQueue)) {
- MSG("Cache: cookies not accepted from '%s'\n", URL_STR(entry->Url));
- }
-
for (i = 0; (data = dList_nth_data(Cookies, i)); ++i)
dFree(data);
dList_free(Cookies);
@@ -857,17 +854,6 @@ static void Cache_finish_msg(CacheEntry_t *entry)
MSG("Expected size: %d, Transfer size: %d\n",
entry->ExpectedSize, entry->TransferSize);
}
- if (!entry->TransferSize && !(entry->Flags & CA_Redirect) &&
- (entry->Flags & WEB_RootUrl)) {
- char *eol = strchr(entry->Header->str, '\n');
- if (eol) {
- char *status_line = dStrndup(entry->Header->str,
- eol - entry->Header->str);
- MSG_HTTP("Body of %s was empty. Server sent status: %s\n",
- URL_STR_(entry->Url), status_line);
- dFree(status_line);
- }
- }
entry->Flags |= CA_GotData;
entry->Flags &= ~CA_Stopped; /* it may catch up! */
if (entry->TransferDecoder) {
diff --git a/src/dialog.cc b/src/dialog.cc
index 10988c98..03949a1c 100644
--- a/src/dialog.cc
+++ b/src/dialog.cc
@@ -325,6 +325,7 @@ static void choice_cb(Fl_Widget *button, void *number)
{
choice_answer = VOIDP2INT(number);
_MSG("choice_cb: %d\n", choice_answer);
+
button->window()->hide();
}
@@ -358,16 +359,15 @@ int a_Dialog_choice(const char *title, const char *msg, ...)
Fl_Window *window = new Fl_Window(ww, wh, title);
window->set_modal();
window->begin();
- Fl_Group *ib = new Fl_Group(0, 0, window->w(), window->h());
- ib->begin();
- window->resizable(ib);
- if (msg != NULL){
- Fl_Box *box = new Fl_Box(0, 0, ww, wh - bh, msg);
- box->labelfont(FL_HELVETICA);
- box->labelsize(14);
- box->align(FL_ALIGN_WRAP);
- }
+ Fl_Text_Buffer *buf = new Fl_Text_Buffer();
+ buf->text(msg);
+ Fl_Text_Display *td = new Fl_Text_Display(0, 0, ww, wh - bh);
+ td->buffer(buf);
+ td->textsize((int) rint(14.0 * prefs.font_factor));
+ td->wrap_mode(Fl_Text_Display::WRAP_AT_BOUNDS, 0);
+
+ window->resizable(td);
int xpos = gap;
va_start(ap, msg);
@@ -386,6 +386,8 @@ int a_Dialog_choice(const char *title, const char *msg, ...)
while (window->shown())
Fl::wait();
_MSG("Dialog_choice answer = %d\n", answer);
+ td->buffer(NULL);
+ delete buf;
delete window;
return choice_answer;
diff --git a/src/dillo.cc b/src/dillo.cc
index 847c9d63..17747c59 100644
--- a/src/dillo.cc
+++ b/src/dillo.cc
@@ -45,7 +45,7 @@
#include "dns.h"
#include "web.hh"
-#include "IO/ssl.h"
+#include "IO/tls.h"
#include "IO/Url.h"
#include "IO/mime.h"
#include "capi.h"
@@ -477,7 +477,7 @@ int main(int argc, char **argv)
a_Dns_init();
a_Web_init();
a_Http_init();
- a_Ssl_init();
+ a_Tls_init();
a_Mime_init();
a_Capi_init();
a_Dicache_init();
@@ -599,7 +599,7 @@ int main(int argc, char **argv)
a_Cache_freeall();
a_Dicache_freeall();
a_Http_freeall();
- a_Ssl_freeall();
+ a_Tls_freeall();
a_Dns_freeall();
a_History_freeall();
a_Prefs_freeall();
diff --git a/src/html.cc b/src/html.cc
index 3e4f27a8..a92771d3 100644
--- a/src/html.cc
+++ b/src/html.cc
@@ -2514,8 +2514,6 @@ static void
if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "href"))) {
url = a_Html_url_new(html, attrbuf, NULL, 0);
dReturn_if_fail ( url != NULL );
- if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "alt")))
- a_Url_set_alt(url, attrbuf);
link = Html_set_new_link(html, &url);
}
diff --git a/src/url.c b/src/url.c
index aa211fb7..e2eac48a 100644
--- a/src/url.c
+++ b/src/url.c
@@ -204,7 +204,6 @@ void a_Url_free(DilloUrl *url)
dFree((char *)url->hostname);
dFree((char *)url->buffer);
dStr_free(url->data, 1);
- dFree((char *)url->alt);
dFree(url);
}
}
@@ -213,7 +212,6 @@ void a_Url_free(DilloUrl *url)
* Resolve the URL as RFC3986 suggests.
*/
static Dstr *Url_resolve_relative(const char *RelStr,
- DilloUrl *BaseUrlPar,
const char *BaseStr)
{
char *p, *s, *e;
@@ -224,9 +222,7 @@ static Dstr *Url_resolve_relative(const char *RelStr,
/* parse relative URL */
RelUrl = Url_object_new(RelStr);
- if (BaseUrlPar) {
- BaseUrl = BaseUrlPar;
- } else if (RelUrl->scheme == NULL) {
+ if (RelUrl->scheme == NULL) {
/* only required when there's no <scheme> in RelStr */
BaseUrl = Url_object_new(BaseStr);
}
@@ -336,8 +332,7 @@ static Dstr *Url_resolve_relative(const char *RelStr,
done:
dStr_free(Path, TRUE);
a_Url_free(RelUrl);
- if (BaseUrl != BaseUrlPar)
- a_Url_free(BaseUrl);
+ a_Url_free(BaseUrl);
return SolvedUrl;
}
@@ -356,7 +351,6 @@ done:
* port = 8080
* flags = URL_Get
* data = Dstr * ("")
- * alt = NULL
* ismap_url_len = 0
* }
*
@@ -406,7 +400,7 @@ DilloUrl* a_Url_new(const char *url_str, const char *base_url)
}
/* Resolve the URL */
- SolvedUrl = Url_resolve_relative(urlstr, NULL, base_url);
+ SolvedUrl = Url_resolve_relative(urlstr, base_url);
_MSG("SolvedUrl = %s\n", SolvedUrl->str);
/* Fill url data */
@@ -435,7 +429,6 @@ DilloUrl* a_Url_dup(const DilloUrl *ori)
url->url_string = dStr_new(URL_STR(ori));
url->port = ori->port;
url->flags = ori->flags;
- url->alt = dStrdup(ori->alt);
url->ismap_url_len = ori->ismap_url_len;
url->illegal_chars = ori->illegal_chars;
url->illegal_chars_spc = ori->illegal_chars_spc;
@@ -495,17 +488,6 @@ void a_Url_set_data(DilloUrl *u, Dstr **data)
}
/*
- * Set DilloUrl alt (alternate text to the URL. Used by image maps)
- */
-void a_Url_set_alt(DilloUrl *u, const char *alt)
-{
- if (u) {
- dFree((char *)u->alt);
- u->alt = dStrdup(alt);
- }
-}
-
-/*
* Set DilloUrl ismap coordinates
* (this is optimized for not hogging the CPU)
*/
@@ -516,7 +498,6 @@ void a_Url_set_ismap_coords(DilloUrl *u, char *coord_str)
if (!u->ismap_url_len) {
/* Save base-url length (without coords) */
u->ismap_url_len = URL_STR_(u) ? u->url_string->len : 0;
- a_Url_set_flags(u, URL_FLAGS(u) | URL_Ismap);
}
if (u->url_string) {
dStr_truncate(u->url_string, u->ismap_url_len);
diff --git a/src/url.h b/src/url.h
index 6920f769..93d198f8 100644
--- a/src/url.h
+++ b/src/url.h
@@ -22,12 +22,8 @@
*/
#define URL_Get (1 << 0)
#define URL_Post (1 << 1)
-#define URL_ISindex (1 << 2)
-#define URL_Ismap (1 << 3)
-#define URL_RealmAccess (1 << 4)
#define URL_E2EQuery (1 << 5)
-#define URL_ReloadImages (1 << 6)
#define URL_ReloadPage (1 << 7)
#define URL_ReloadFromCache (1 << 8)
@@ -47,7 +43,6 @@
#define URL_QUERY_(u) (u)->query
#define URL_FRAGMENT_(u) (u)->fragment
#define URL_HOST_(u) a_Url_hostname(u)
-#define URL_ALT_(u) (u)->alt
#define URL_STR_(u) a_Url_str(u)
/* this returns a Dstr* */
#define URL_DATA_(u) (u)->data
@@ -69,9 +64,8 @@
#define URL_QUERY(u) NPTR2STR(URL_QUERY_(u))
#define URL_FRAGMENT(u) NPTR2STR(URL_FRAGMENT_(u))
#define URL_HOST(u) NPTR2STR(URL_HOST_(u))
-#define URL_DATA(u) URL_DATA_(u)
-#define URL_ALT(u) NPTR2STR(URL_ALT_(u))
#define URL_STR(u) NPTR2STR(URL_STR_(u))
+#define URL_DATA(u) URL_DATA_(u)
#define URL_PORT(u) URL_PORT_(u)
#define URL_FLAGS(u) URL_FLAGS_(u)
#define URL_ILLEGAL_CHARS(u) URL_ILLEGAL_CHARS_(u)
@@ -94,7 +88,6 @@ typedef struct {
int port;
int flags;
Dstr *data; /* POST */
- const char *alt; /* "alt" text (used by image maps) */
int ismap_url_len; /* Used by server side image maps */
int illegal_chars; /* number of illegal chars */
int illegal_chars_spc; /* number of illegal space chars */
@@ -109,7 +102,6 @@ DilloUrl* a_Url_dup(const DilloUrl *u);
int a_Url_cmp(const DilloUrl *A, const DilloUrl *B);
void a_Url_set_flags(DilloUrl *u, int flags);
void a_Url_set_data(DilloUrl *u, Dstr **data);
-void a_Url_set_alt(DilloUrl *u, const char *alt);
void a_Url_set_ismap_coords(DilloUrl *u, char *coord_str);
char *a_Url_decode_hex_str(const char *str);
char *a_Url_encode_hex_str(const char *str);