edbrowse, a line oriented editor browser.
Maintained by Chris Brannon, chris@the-brannons.com
Written and maintained by Karl Dahlke, eklhad@gmail.com
See COPYING for licensing agreements.

------------------------------------------------------------

Disclaimer: this software is provided as-is,
with no guarantee that it will perform as expected.
It might trash your precious files.
It might send bad data across the Internet,
causing you to buy a $37,000 elephant instead of
$37 worth of printer supplies.
It may delete all the rows in your mysql customer table.
Use this program at your own risk.

------------------------------------------------------------

Netscape and Explorer are graphical browsers.
Lynx and Links are screen browsers.
This is a command line browser; the only one of its kind.

The user's guide can be found in doc/usersguide.html (in this package).
Of course this reasoning is a bit circular.
You need to use a browser to read the documentation,
which describes how to use the browser.
Well you can always do this:

cd doc ; lynx -dump usersguide.html >usersguide.txt

This produces the documentation in text form,
which you can read using your favorite editor.
Of course we hope edbrowse will eventually become your
favorite editor, whence you can browse the documentation directly.

The doc directory also includes a sample config file, and a script to help you
set up your own, customized config file.
Run setup.ebrc and answer the questions.
(This assumes you are using bash.)

------------------------------------------------------------

Ok, I'm going to assume you've read the documentation.
No need to repeat all that here.
You're here because you want to compile and/or package the program,
or modify the source in some way.  Great!

I haven't developed a configure script, and I should do that some day,
but meantime just type make and hope for the best.

As you may know, edbrowse was originally a perl script.
As such, it was only natural to use perl regular expressions for
my search/substitute functions in the editor.
And once you've experienced the power of perl regexp, you'll never
go back to ed.  So I use the perl compatible regular expression
library, /lib/libpcre.so.0, available on most Linux systems.
If you don't have this file, check your installation disks.
the pcre and pcre-devel packages might be there, just not installed.
You need version 8.10 or higher.
If you can't find them there, you can get the pcre source here.

ftp://ftp.sourceforge.net/pub/sourceforge/pcre/

Note that my files include <pcre.h>.
Some distributions put it in /usr/include/pcre/pcre.h,
so you'll have to adjust the source, the -I path, or make a link.
Yeah I know, that's something a configure script should do for you,
but I'm just not there yet.

You also need libcurl, which is included in almost every Linux distro.
This is used for ftp, http, and https.
Check for /usr/include/curl/curl.h
Edbrowse requires version 7.29.0 or later.  If you compiled with a version
prior to 7.29.0, the program will inform you that you need to upgrade.
If you have to compile curl from source, be sure to specify
--ENABLE-VERSION-SYMBOLS (or some such) at the configure script.

Finally, you need the Spider Monkey javascript engine from Mozilla.org
ftp://ftp.mozilla.org/pub/mozilla.org/js/
Edbrowse 3.4.7 or less requires Mozilla js version 1.5.
Edbrowse 3.4.8 requires Mozilla js version 1.8.5.
Edbrowse 3.5.1 requires Mozilla js version 2.4.
If this is not available in your distribution, download into /usr/local,
expand, cd js/src, ./configure, make, and make install.
https://ftp.mozilla.org/pub/mozilla.org/js/mozjs-24.2.0.tar.bz2
Lots of warning messages in the build, don't worry about those.
This creats /usr/local/lib/libmozjs-24.so, and with /usr/local/lib
already in my /etc/ld.so.conf, I thought I'd be fine,
but I had to run ldconfig again anyways, not sure why.
Back in your edbrowse/src directory,
you may need to set some flags on the command line
if you had to install Mozilla js as above.
The following works for me.

make JS_CXXFLAGS=-I/usr/local/include/mozjs-24 JSLIB=-lmozjs-24 edbrowse

If you want database access, you need unixODBC and unixODBC-devel.
Make edbrowseodbc, rather than edbrowse.
ODBC has been very stable for a long time.
unixODBC version 2.2.14 seems to satisfy edbrowseodbc.

------------------------------------------------------------

The code in this project is indented via the script Lindent,
which is in the tools directory, and is taken from the Linux kernel source.
In other words, the indenting style is the same as the Linux kernel.
If you modify some source, you may want to run it through
../tools/Lindent before the commit.
An exception is eb.p.
The extern "C" { }, mandated by C++, indents everything for no reason.
So I maintain this file by hand.
It is flush with the left, and it doesn't change very often.

------------------------------------------------------------

Debug levels:
0: silent
1: show the sizes of files and web pages as they are read and written
2: show the url as you call up a web page,
   and javascript execution errors
3: show each url through redirection,
   cookies, http codes, form data, and sql statements logged.
4: show the socket connections, and the http headers in and out
5: url resolution
6: free and alloc text lines, show javascript
7: reformatted regular expressions, breakline chunks.
8: text lines freed, debug garbage collection
9: not used

------------------------------------------------------------

Sourcefiles (in the src directory).

main.c:
Read and parse the config file.
Entry point.
Command line options.
Invoke mail client if mail options are present.
If run as editor/browser, treat arguments as files or URLs
and read them into buffers.
Read commands from stdin and invoke them via the command
interpreter in buffers.c.

buffers.c:
Manage all the text buffers.
Interpret the standard ed commands, move, copy, delete, substitute, etc.

stringfile.c:
Helper functions to manage memory, strings, files, directories.
Hides many of the OS specific quirks.

url.c:
Split a url into its components.
Decide if it's a proxy url.
Watch for infinite loops during url redirection.
Resolve relative url into absolute url
based on the location of the current web page.

format.c:
Parse html tags and comments.
Translate common unicode sequences.
Arrange text into lines and paragraphs.

http.c:
Send the http request, and read the data from the web server.
Handles https connections as well,
and 301/302 redirection.
Uncompresses html data if necessary.

html.cpp:
Render the html tags and format the text.
Update input fields.
Submit/reset forms.

cookies.c:
Send and receive cookies.  Maintain the cookie jar.

auth.c:
Remember user and password for web pages that require authentication.
Only the basic method is implemented at this time.

sendmail.c:
Send mail (smtp).  Encode attachments.

fetchmail.c:
Fetch mail (pop3).  Decode attachments.
Browse mail files, separate mime components.

messages.h:
Symbolic constants for the warning/error messages of edbrowse.

messages.c:
Strings corresponding to these error messages,
in various languages.
Also some international print routines to display the correct string,
according to your locale.

jsdom.cpp:
Document object model under javascript.
Build objects for the hyperlinks, forms, elements, etc.
Includes basic methods like alert() prompt() window.open() etc.

jsloc.cpp:
The location object, and other objects (like document.cookie)
with strange side effects.

startwindow.js:
Javascript that is run at the start of each session.
This creates certain support methods that client js will need.
It is converted into a const string in startwindow.c,
thus startwindow.c is not a source file.

jsrt:
This is the javascript regression test for edbrowse.
It exercises some of the javascript DOM interactions.

dbops.c:
Database operations; insert update delete.

dbodbc.c:
Connect edbrowse to odbc.

dbinfx.ec:
Connect edbrowse directly to Informix.

------------------------------------------------------------

Error conventions.
Unix commands return 0 for ok, and a negative number for a problem.
I return true for success and false for error.
The error message is in a buffer, which you can see by typing h,
in the /bin/ed fashion.
Sometimes the error is displayed no matter what,
like when you are reading or writing files.
error messages are created according to your locale, i.e. in your language,
if a translation is available.
Some error messages in the database world have not yet been internationalized.
Some are beyond my control, as they come from odbc or its native driver.

------------------------------------------------------------

Multiple Representations.

A web form asks for your name, and you type in Fred Flintstone.
This piece of data is part of your edbrowse buffer.
In this sense it is merely text.
You can make corrections with the substitute command,
use the undo command to back up, etc.
Yet it is also carried into the html tags in html.c,
so that it can be sent when you push the submit button.
This is a second copy of the data.
As if that weren't bad enough, I now need a third copy for javascript.
When js accesses form.fullname.value, it needs to find,
and in some cases change, the text that you entered.
I believe the first representation, in your editor, must be separate
from the second and third (which I have managed to merge together).
Remember that an input field could be an antire text area,
i.e. the text in another editing session.
When you are in that session, composing your thoughts,
am I really going to take every textual change, every substitute,
every delete, every insert, every undo,
and map those changes over to the html tag that goes with this session,
and the java variable that goes with this session?
I don't think so!
So I'm stuck with something almost as bad.
As part of the browse command, the field data, whether set up by html
or modified by javascript, must be copied into your editor text.
Then you can change it to your heart's content, but when you submit the form,
or run any javascript for any reason, all that text has to be carried
back to the javascript world.
This is accomplished by jSyncup() in html.c.
When javascript is done, any changes it has made to the fields have
to be mapped back to the editor, where you can see them.
This is done by javaSetsTagVar() in html.c.

You should really receive some alerts if fields
have been changed out from under you.
A sighted person would see the screen change, but you can't.
You know that field says Fred Flintstone, that's what you typed
in, but javascript has changed it to Barney Rubble, and you need
to be notified.
Edbrowse does this for you.

Line 357 has been updated.

------------------------------------------------------------

Yes, some of this code looks like it was written, well,
in my spare time; and it was, because I needed this tool desperately.
No careful methodology, just "Gitter Duhn".

Along with some cleanup, and even some modest enhancements, edbrowse
really needs a rewrite, at least with respect to browsing and javascript.
Today, it takes html text and tags, and builds
javascript objects to go along with those tags; and it builds the screen,
(I'll call it a screen, it's really a text buffer),
in parallel, at the same time.
But what it should do is not build the screen at all on the first pass.
Text would simply be turned into a string
and put in as an attribute in whatever object we are working on at the time,
or the document object if no tag has appeared yet.
All internal.
Then you run the javascript, and it perhaps creates more objects,
creates lists dynamically,
builds entirely new paragraphs, images, links, whatever it does.
Then pass 3, render the screen by traversing the tree of objects
depth first.
That is your text buffer.

Now, if anything changes, through some onclick code perhaps,
you have a new tree of objects,
so Simply rerender the screen.
In our case that builds a new text buffer.
Maybe this is what standard browsers do; I don't know.
But there's something we should do that they don't.
Keep a copy of the old screen and run diff.
If one or two lines have changed,
or if a menu has changed behind the scenes, report that to the user.
It's something a sighted person would notice right away,
but I would be left in the dark.
If there are many changes, just say "entire buffer has changed".
Anyways, this is the kind of rewrite that needs to happen.
Think of this as version 4.1.

In parallel, we are moving from C to C++, as mandated by mozjs 24.
All that code dedicated to growing strings dynamically,
and freeing them without memory leaks, etc, etc, has become a royal pain,
and will be much nicer with string objects.
Also my list macros will become array methods.
Version 4.2.

After this, enhance the DOM with the createElement methods.
This lets javascript create its own tables, paragraphs, lists, images, etc,
and yes, some websites do indeed do this.
https://developer.mozilla.org/en/docs/Traversing_an_HTML_table_with_JavaScript_and_DOM_Interfaces
Version 4.3.

Then, stop turning html tags into javascript objects by hand;
that is reinventing the wheel.
When you run into <P>, simply call createElement("paragraph"),
or something along those lines.
We have to implement all this in DOM JS eventually, so once this is done,
why not take advantage of it.
Version 4.4.

The beginning of this new approach can bee seen in rebuildSelector() in jsloc.cpp.
If javascript rebuilds a dropdown list of options, that is detected,
and mapped back into html tags, and the user is notified.
See jsrt states and colors for this feature.

