about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorThomas E. Dickey <dickey@invisible-island.net>2008-02-10 23:30:04 -0500
committerThomas E. Dickey <dickey@invisible-island.net>2008-02-10 23:30:04 -0500
commitacdfec8f90ac4aa21cfc20b6b7ad3ecb7e56ea90 (patch)
tree86c9e3563afd079f3dde28d94be992c75627c8fa /src
parent92e120361baf8d55566015fe7bf09ac91f06a6e6 (diff)
downloadlynx-snapshots-acdfec8f90ac4aa21cfc20b6b7ad3ecb7e56ea90.tar.gz
snapshot of project "lynx", label v2-8-7dev_c-pbm
Diffstat (limited to 'src')
-rw-r--r--src/GridText.c238
-rw-r--r--src/HTAlert.c72
-rw-r--r--src/LYGetFile.c14
-rw-r--r--src/LYGlobalDefs.h19
-rw-r--r--src/LYHistory.c11
-rw-r--r--src/LYHistory.h1
-rw-r--r--src/LYKeymap.c16
-rw-r--r--src/LYKeymap.h6
-rw-r--r--src/LYMain.c53
-rw-r--r--src/LYMainLoop.c76
-rw-r--r--src/LYOptions.c38
-rw-r--r--src/LYReadCFG.c19
-rw-r--r--src/LYSession.c270
-rw-r--r--src/LYSession.h16
-rw-r--r--src/LYStrings.c13
-rw-r--r--src/LYUtils.c10
-rw-r--r--src/LYUtils.h25
-rw-r--r--src/LYrcFile.c6
-rw-r--r--src/LYrcFile.h15
-rw-r--r--src/chrtrans/makeuctb.c4
-rw-r--r--src/makefile.dos3
-rw-r--r--src/makefile.dsl3
-rw-r--r--src/makefile.wsl3
23 files changed, 879 insertions, 52 deletions
diff --git a/src/GridText.c b/src/GridText.c
index 3c010735..0212d43a 100644
--- a/src/GridText.c
+++ b/src/GridText.c
@@ -1,5 +1,5 @@
 /*
- * $LynxId: GridText.c,v 1.142 2007/08/02 19:30:32 tom Exp $
+ * $LynxId: GridText.c,v 1.143 2008/02/10 23:25:38 tom Exp $
  *
  *		Character grid hypertext object
  *		===============================
@@ -14236,3 +14236,239 @@ int HTMainText_Get_UCLYhndl(void)
 	    HTAnchor_getUCLYhndl(HTMainText->node_anchor, UCT_STAGE_MIME)
 	    : -1);
 }
+
+#ifdef USE_CACHEJAR
+static int LYHandleCache(const char *arg,
+			 HTParentAnchor *anAnchor,
+			 HTFormat format_out,
+			 HTStream *sink)
+{
+    HTFormat format_in = WWW_HTML;
+    HTStream *target = NULL;
+    char c;
+    char *buf = NULL;
+    char *title = NULL;
+    char *address = NULL;
+    char *content_type = NULL;
+    char *content_language = NULL;
+    char *content_encoding = NULL;
+    char *content_location = NULL;
+    char *date = NULL;
+    char *owner = NULL;
+    char *subject = NULL;
+    char *expires = NULL;
+    char *ETag = NULL;
+    char *server = NULL;
+    char *FileCache = NULL;
+    char *last_modified = NULL;
+    char *cache_control = NULL;
+
+#ifdef USE_SOURCE_CACHE
+    char *source_cache_file = NULL;
+#endif
+    int Size = 0;
+    int x = -1;
+    int cached = 0;
+
+    /*
+     * Check if there is something to do.
+     */
+    if ((cached = HTList_count(loaded_texts)) == 0) {
+	HTProgress(CACHE_JAR_IS_EMPTY);
+	LYSleepMsg();
+	HTNoDataOK = 1;
+	return (HT_NO_DATA);
+    }
+
+    /*
+     * If # of LYNXCACHE:/# is number ask user if he/she want to delete it.
+     */
+    if (sscanf(arg, STR_LYNXCACHE "/%d", &x) == 1 && x > 0) {
+	CTRACE((tfp, "LYNXCACHE number is %d\n", x));
+	_statusline(CACHE_D_OR_CANCEL);
+	c = LYgetch_single();
+	if (c == 'D') {
+	    HText *t = (HText *) HTList_objectAt(loaded_texts, x - 1);
+
+	    HTList_removeObjectAt(loaded_texts, x - 1);
+	    HText_free(t);
+	}
+	return (HT_NO_DATA);
+    }
+
+    /*
+     * If we get to here, it was a LYNXCACHE:/ URL for creating and displaying
+     * the Cache Jar Page.
+     * Set up an HTML stream and return an updated Cache Jar Page.
+     */
+    target = HTStreamStack(format_in,
+			   format_out,
+			   sink, anAnchor);
+    if (!target || target == NULL) {
+	HTSprintf0(&buf, CANNOT_CONVERT_I_TO_O,
+		   HTAtom_name(format_in), HTAtom_name(format_out));
+	HTAlert(buf);
+	FREE(buf);
+	return (HT_NOT_LOADED);
+    }
+
+    /*
+     * Load HTML strings into buf and pass buf to the target for parsing and
+     * rendering.
+     */
+#define PUTS(buf)    (*target->isa->put_block)(target, buf, strlen(buf))
+
+    HTSprintf0(&buf,
+	       "<html>\n<head>\n<title>%s</title>\n</head>\n<body>\n",
+	       CACHE_JAR_TITLE);
+    PUTS(buf);
+    HTSprintf0(&buf, "<h1>%s (%s)%s<a href=\"%s%s\">%s</a></h1>\n",
+	       LYNX_NAME, LYNX_VERSION,
+	       HELP_ON_SEGMENT,
+	       helpfilepath, CACHE_JAR_HELP, CACHE_JAR_TITLE);
+    PUTS(buf);
+
+    HTSprintf0(&buf, "<pre>\n");
+    PUTS(buf);
+
+    /*
+     * Max number of cached documents is always same as HTCacheSize.
+     * We count them from oldest to newest. Currently cached document
+     * is *never* listed, resulting in maximal entries of Cache Jar
+     * to be HTCacheSize - 1
+     */
+    for (x = HTList_count(loaded_texts) - 1; x > 0; x--) {
+	/*
+	 * The number of the document in the cache list, its title in a link,
+	 * and its address and memory allocated for each cached document.
+	 */
+	HText *cachedoc = (HText *) HTList_objectAt(loaded_texts, x);
+
+	if (cachedoc != 0) {
+	    HTParentAnchor *docanchor = cachedoc->node_anchor;
+
+	    Size = docanchor->content_length;
+	    if (docanchor != 0) {
+#ifdef USE_SOURCE_CACHE
+		source_cache_file = docanchor->source_cache_file;
+#endif
+		title = docanchor->title;
+		address = docanchor->address;
+		content_type = docanchor->content_type;
+		content_language = docanchor->content_language;
+		content_encoding = docanchor->content_encoding;
+		content_location = docanchor->content_location;
+		owner = docanchor->owner;
+		subject = docanchor->subject;
+		date = docanchor->date;
+		expires = docanchor->expires;
+		ETag = docanchor->ETag;
+		server = docanchor->server;
+		FileCache = docanchor->FileCache;
+		last_modified = docanchor->last_modified;
+		cache_control = docanchor->cache_control;
+	    }
+	}
+
+	HTSprintf0(&buf, "%s<em>%d</em>. <tab id=t%d>",
+		   (x > 99 ? "" : x < 10 ? "  " : " "), x, x);
+	PUTS(buf);
+	HTSprintf0(&buf, "<a href=\"%s%d\">", STR_LYNXCACHE, x);
+	PUTS(buf);
+	HTSprintf0(&buf, "%s</a>\n%s", title == NULL ? address : title,
+		   (x > 99 ? " " : x < 10 ? "   " : "  "));
+	PUTS(buf);
+	HTSprintf0(&buf, "URL: <a href=\"%s\">%s</a>\n%s", address, address,
+		   (x > 99 ? "  " : x < 10 ? "    " : "   "));
+	PUTS(buf);
+	if (Size > 0) {
+	    HTSprintf0(&buf, "Size: %d  ", Size);
+	    PUTS(buf);
+	}
+	if (cachedoc->Lines > 0) {
+	    HTSprintf0(&buf, "Lines: %d  ", cachedoc->Lines);
+	    PUTS(buf);
+	}
+	if (FileCache != NULL) {
+	    HTSprintf0(&buf, "File-Cache: %s  ", FileCache);
+	    PUTS(buf);
+	}
+	if (cache_control != NULL) {
+	    HTSprintf0(&buf, "Cache-Control: %s  ", cache_control);
+	    PUTS(buf);
+	}
+	if (content_type != NULL) {
+	    HTSprintf0(&buf, "Content-Type: %s  ", content_type);
+	    PUTS(buf);
+	}
+	if (content_language != NULL) {
+	    HTSprintf0(&buf, "Content-Language: %s  ", content_language);
+	    PUTS(buf);
+	}
+	if (content_encoding != NULL) {
+	    HTSprintf0(&buf, "Content-Encoding: %s  ", content_encoding);
+	    PUTS(buf);
+	}
+	if (content_location != NULL) {
+	    HTSprintf0(&buf, "Content-Location: %s  ", content_location);
+	    PUTS(buf);
+	}
+	if (subject != NULL) {
+	    HTSprintf0(&buf, "Subject: %s  ", subject);
+	    PUTS(buf);
+	}
+	if (owner != NULL) {
+	    HTSprintf0(&buf, "Owner: %s  ", owner);
+	    PUTS(buf);
+	}
+	if (date != NULL) {
+	    HTSprintf0(&buf, "Date: %s  ", date);
+	    PUTS(buf);
+	}
+	if (expires != NULL) {
+	    HTSprintf0(&buf, "Expires: %s  ", expires);
+	    PUTS(buf);
+	}
+	if (last_modified != NULL) {
+	    HTSprintf0(&buf, "Last-Modified: %s  ", last_modified);
+	    PUTS(buf);
+	}
+	if (ETag != NULL) {
+	    HTSprintf0(&buf, "ETag: %s  ", ETag);
+	    PUTS(buf);
+	}
+	if (server != NULL) {
+	    HTSprintf0(&buf, "Server: %s  ", server);
+	    PUTS(buf);
+	}
+#ifdef USE_SOURCE_CACHE
+	if (source_cache_file != NULL) {
+	    HTSprintf0(&buf,
+		       "Source-Cache-File: <a href=\"file://%s\">%s</a>",
+		       source_cache_file, source_cache_file);
+	    PUTS(buf);
+	}
+#endif
+	HTSprintf0(&buf, "<tab to=t%d>\n", x);
+	PUTS(buf);
+    }
+    HTSprintf0(&buf, "</pre>\n</body>\n</html>\n");
+    PUTS(buf);
+
+    /*
+     * Free the target to complete loading of the Cache Jar Page, and report a
+     * successful load.
+     */
+    (*target->isa->_free) (target);
+    FREE(buf);
+    return (HT_LOADED);
+}
+
+#ifdef GLOBALDEF_IS_MACRO
+#define _LYCACHE_C_GLOBALDEF_1_INIT { "LYNXCACHE",LYHandleCache,0}
+GLOBALDEF(HTProtocol, LYLynxCache, _LYCACHE_C_GLOBALDEF_1_INIT);
+#else
+GLOBALDEF HTProtocol LYLynxCache =
+{"LYNXCACHE", LYHandleCache, 0};
+#endif /* GLOBALDEF_IS_MACRO */
+#endif /* USE_CACHEJAR */
diff --git a/src/HTAlert.c b/src/HTAlert.c
index c43c22e9..498163e8 100644
--- a/src/HTAlert.c
+++ b/src/HTAlert.c
@@ -1,4 +1,7 @@
-/*	Displaying messages and getting input for Lynx Browser
+/*
+ * $LynxId: HTAlert.c,v 1.78 2008/02/10 21:39:42 tom Exp $
+ *
+ *	Displaying messages and getting input for Lynx Browser
  *	==========================================================
  *
  *	REPLACE THIS MODULE with a GUI version in a GUI environment!
@@ -247,9 +250,10 @@ void HTReadProgress(long bytes, long total)
 	bytes = bytes_last;
 	total = total_last;
     }
+
+    /* 1 sec delay for transfer_rate calculation without g-t-o-d */
     if ((bytes > 0) &&
-	(now > first))
-	/* 1 sec delay for transfer_rate calculation without g-t-o-d */  {
+	(now > first)) {
 	if (transfer_rate <= 0)	/* the very first time */
 	    transfer_rate = (long) ((bytes) / (now - first));	/* bytes/sec */
 	total_last = total;
@@ -286,16 +290,45 @@ void HTReadProgress(long bytes, long total)
 		was_units = 0;
 	    sprint_bytes(bytesp, bytes, was_units);
 
-	    if (total > 0)
-		HTSprintf0(&line, gettext("Read %s of %s of data"), bytesp, totalp);
-	    else
+	    switch ((TransferRate) LYTransferRate) {
+#ifdef USE_PROGRESSBAR
+	    case rateBAR:
+		/*
+		 * If we know the total size of the file, we can compute
+		 * a percentage, and show a corresponding progress bar.
+		 */
 		HTSprintf0(&line, gettext("Read %s of data"), bytesp);
 
-	    if (LYTransferRate != rateOFF
-		&& transfer_rate > 0) {
-		sprint_bytes(transferp, transfer_rate, 0);
-		HTSprintf(&line, gettext(", %s/sec"), transferp);
+		if (total > 0) {
+		    float percent = bytes / (float) total;
+		    int meter = (LYcolLimit * percent) - 5;
+
+		    CTRACE((tfp, "rateBAR: bytes: %ld, total: %ld\n", bytes, total));
+		    CTRACE((tfp, "meter = %d\n", meter));
+
+		    HTSprintf0(&line, "%d%% ", (int) (percent * 100));
+		    while (meter-- > 0)
+			StrAllocCat(line, "I");
+
+		    CTRACE((tfp, "%s\n", line));
+		    CTRACE_FLUSH(tfp);
+		}
+		break;
+#endif
+	    default:
+		if (total > 0)
+		    HTSprintf0(&line, gettext("Read %s of %s of data"), bytesp, totalp);
+		else
+		    HTSprintf0(&line, gettext("Read %s of data"), bytesp);
+
+		if (LYTransferRate != rateOFF
+		    && transfer_rate > 0) {
+		    sprint_bytes(transferp, transfer_rate, 0);
+		    HTSprintf(&line, gettext(", %s/sec"), transferp);
+		}
+		break;
 	    }
+
 #ifdef USE_READPROGRESS
 	    if (LYTransferRate == rateEtaBYTES
 		|| LYTransferRate == rateEtaKB) {
@@ -312,7 +345,22 @@ void HTReadProgress(long bytes, long total)
 	    }
 #endif
 
-	    StrAllocCat(line, ".");
+	    switch ((TransferRate) LYTransferRate) {
+#ifdef USE_PROGRESSBAR
+	    case rateBAR:
+		/*
+		 * If we were not able to show a progress bar, just show
+		 * a "." for progress.
+		 */
+		if (total <= 0)
+		    StrAllocCat(line, ".");
+		break;
+#endif
+	    default:
+		StrAllocCat(line, ".");
+		break;
+	    }
+
 	    if (total < -1)
 		StrAllocCat(line, gettext(" (Press 'z' to abort)"));
 
@@ -320,7 +368,7 @@ void HTReadProgress(long bytes, long total)
 	    statusline(line);
 	    CTRACE((tfp, "%s\n", line));
 	}
-	}
+    }
 #ifdef LY_FIND_LEAKS
     FREE(line);
 #endif
diff --git a/src/LYGetFile.c b/src/LYGetFile.c
index a73ddb2a..53b48170 100644
--- a/src/LYGetFile.c
+++ b/src/LYGetFile.c
@@ -1,4 +1,4 @@
-/* $LynxId: LYGetFile.c,v 1.77 2007/05/20 23:28:43 Thorsten.Glaser Exp $ */
+/* $LynxId: LYGetFile.c,v 1.78 2008/01/08 00:19:25 tom Exp $ */
 #include <HTUtils.h>
 #include <HTTP.h>
 #include <HTAnchor.h>		/* Anchor class */
@@ -192,6 +192,9 @@ int getfile(DocInfo *doc, int *target)
 		  url_type == LYNXKEYMAP_URL_TYPE ||
 		  url_type == LYNXIMGMAP_URL_TYPE ||
 		  url_type == LYNXCOOKIE_URL_TYPE ||
+#ifdef USE_CACHEJAR
+		  url_type == LYNXCACHE_URL_TYPE ||
+#endif
 		  url_type == LYNXMESSAGES_URL_TYPE ||
 		  (url_type == LYNXOPTIONS_URL_TYPE &&
 		   WWWDoc.post_data) ||
@@ -225,6 +228,9 @@ int getfile(DocInfo *doc, int *target)
 		  url_type == LYNXKEYMAP_URL_TYPE ||
 		  url_type == LYNXIMGMAP_URL_TYPE ||
 		  url_type == LYNXCOOKIE_URL_TYPE ||
+#ifdef USE_CACHEJAR
+		  url_type == LYNXCACHE_URL_TYPE ||
+#endif
 		  url_type == LYNXPRINT_URL_TYPE ||
 		  url_type == LYNXOPTIONS_URL_TYPE ||
 		  url_type == LYNXCFG_URL_TYPE ||
@@ -560,6 +566,9 @@ int getfile(DocInfo *doc, int *target)
 		   url_type != LYNXIMGMAP_URL_TYPE &&
 		   url_type != LYNXCOOKIE_URL_TYPE &&
 		   url_type != LYNXMESSAGES_URL_TYPE &&
+#ifdef USE_CACHEJAR
+		   url_type != LYNXCACHE_URL_TYPE &&
+#endif
 		   url_type != LYNXCGI_URL_TYPE &&
 		   !(url_type == NEWS_URL_TYPE &&
 		     strncmp(doc->address, "news://", 7)) &&
@@ -840,6 +849,9 @@ int getfile(DocInfo *doc, int *target)
 		     url_type == LYNXCOMPILE_OPTS_URL_TYPE ||
 		     url_type == LYNXHIST_URL_TYPE ||
 		     url_type == LYNXCOOKIE_URL_TYPE ||
+#ifdef USE_CACHEJAR
+		     url_type == LYNXCACHE_URL_TYPE ||
+#endif
 		     url_type == LYNXMESSAGES_URL_TYPE ||
 		     (LYValidate &&
 		      url_type != HTTP_URL_TYPE &&
diff --git a/src/LYGlobalDefs.h b/src/LYGlobalDefs.h
index d73fe1e2..3f8f5d5e 100644
--- a/src/LYGlobalDefs.h
+++ b/src/LYGlobalDefs.h
@@ -1,4 +1,4 @@
-/* $LynxId: LYGlobalDefs.h,v 1.106 2008/01/03 00:41:02 Joey.Schulze Exp $ */
+/* $LynxId: LYGlobalDefs.h,v 1.107 2008/01/10 23:26:25 tom Exp $ */
 /* global variable definitions */
 
 #ifndef LYGLOBALDEFS_H
@@ -22,6 +22,7 @@
 #define ALT_EDIT_HELP		"keystrokes/alt_edit_help.html"
 #define BASHLIKE_EDIT_HELP	"keystrokes/bashlike_edit_help.html"
 #define COOKIE_JAR_HELP		"Lynx_users_guide.html#Cookies"
+#define CACHE_JAR_HELP		"Lynx_users_guide.html#Cache"
 #define CURRENT_KEYMAP_HELP	"keystrokes/keystroke_help.html"
 #define DIRED_MENU_HELP		"keystrokes/dired_help.html"
 #define DOWNLOAD_OPTIONS_HELP	"Lynx_users_guide.html#RemoteSource"
@@ -179,6 +180,9 @@ extern "C" {
 	,rateEtaBYTES
 	,rateEtaKB
 #endif
+#ifdef USE_PROGRESSBAR
+	,rateBAR
+#endif
     } TransferRate;
 
 #ifdef USE_READPROGRESS
@@ -192,6 +196,9 @@ extern "C" {
     extern BOOLEAN LYCursesON;	/* start_curses()->TRUE, stop_curses()->FALSE */
     extern BOOLEAN LYJumpFileURL;	/* URL from the jump file shortcuts? */
     extern BOOLEAN LYNewsPosting;	/* News posting supported if TRUE */
+#ifdef USE_SESSIONS
+    extern BOOLEAN LYAutoSession;	/* Auto restore/save session? */
+#endif
     extern BOOLEAN LYShowCursor;	/* Show the cursor or hide it?      */
     extern BOOLEAN LYShowTransferRate;
     extern BOOLEAN LYUnderlineLinks;	/* Show the links underlined vs bold */
@@ -239,6 +246,12 @@ extern "C" {
     extern char *LYRequestTitle;	/* newdoc.title in calls to getfile() */
     extern char *LYTransferName;	/* abbreviation for Kilobytes */
     extern char *LynxHome;
+#ifdef USE_SESSIONS
+    extern char *LYSessionFile;	/* file for auto-session */
+    extern char *session_file;	/* file for -session= */
+    extern char *sessionin_file;	/* file for -sessionin= */
+    extern char *sessionout_file;	/* file for -sessionout= */
+#endif
     extern char *LynxSigFile;	/* Signature file, in or off home */
     extern char *helpfile;
     extern char *helpfilepath;
@@ -276,6 +289,10 @@ extern "C" {
     extern int max_cookies_buffer;
     extern int max_cookies_domain;
     extern int max_cookies_global;
+#ifdef USE_SESSIONS
+    extern short session_limit;	/* maximal entries saved/restored
+				   in session file */
+#endif
     extern int user_mode;	/* novice or advanced */
     extern int www_search_result;
 
diff --git a/src/LYHistory.c b/src/LYHistory.c
index 66ec15ca..d56c71e5 100644
--- a/src/LYHistory.c
+++ b/src/LYHistory.c
@@ -1,3 +1,4 @@
+/* $LynxId: LYHistory.c,v 1.71 2008/02/10 21:48:35 tom Exp $ */
 #include <HTUtils.h>
 #include <HTTP.h>
 #include <GridText.h>
@@ -29,8 +30,9 @@
 #include <LYLeaks.h>
 #include <HTCJK.h>
 
-static HTList *Visited_Links = NULL;	/* List of safe popped docs. */
+HTList *Visited_Links = NULL;	/* List of safe popped docs. */
 int Visited_Links_As = VISITED_LINKS_AS_LATEST | VISITED_LINKS_REVERSE;
+
 static VisitedLink *PrevVisitedLink = NULL;	/* NULL on auxillary */
 static VisitedLink *PrevActiveVisitedLink = NULL;	/* Last non-auxillary */
 static VisitedLink Latest_first;
@@ -383,8 +385,10 @@ int LYpush(DocInfo *doc, BOOLEAN force_push)
 
     /*
      * If file is identical to one before it, don't push it.
+     * But do not duplicate it if there is only one on the stack,
+     * note that HDOC() starts from 0, so nhist should be > 0.
      */
-    if (nhist > 1 && are_identical(&(history[nhist - 1]), doc)) {
+    if (nhist >= 1 && are_identical(&(history[nhist - 1]), doc)) {
 	if (HDOC(nhist - 1).internal_link == doc->internal_link) {
 	    /* But it is nice to have the last position remembered!
 	       - kw */
@@ -945,8 +949,11 @@ int LYShowVisitedLinks(char **newfile)
 
 /*
  * Keep cycled buffer for statusline messages.
+ * But allow user to change how big it will be from userdefs.h
  */
+#ifndef STATUSBUFSIZE
 #define STATUSBUFSIZE   40
+#endif
 static char *buffstack[STATUSBUFSIZE];
 static int topOfStack = 0;
 
diff --git a/src/LYHistory.h b/src/LYHistory.h
index 249304f5..37315ca5 100644
--- a/src/LYHistory.h
+++ b/src/LYHistory.h
@@ -26,6 +26,7 @@ extern "C" {
     extern void LYstore_message(const char *message);
     extern void LYstore_message2(const char *message, const char *argument);
 
+    extern HTList *Visited_Links;
     extern int nhist_extra;
 
 #ifdef __cplusplus
diff --git a/src/LYKeymap.c b/src/LYKeymap.c
index c948e859..1b7f7256 100644
--- a/src/LYKeymap.c
+++ b/src/LYKeymap.c
@@ -1,4 +1,4 @@
-/* $LynxId: LYKeymap.c,v 1.64 2007/05/13 15:34:50 Thorsten.Glaser Exp $ */
+/* $LynxId: LYKeymap.c,v 1.65 2008/01/08 00:19:25 tom Exp $ */
 #include <HTUtils.h>
 #include <LYUtils.h>
 #include <LYGlobalDefs.h>
@@ -79,11 +79,16 @@ LYK_REFRESH,      LYK_ACTIVATE,     LYK_DOWN_TWO,      0,
 LYK_UP_TWO,       LYK_CHG_CENTER,   LYK_RELOAD,    LYK_TO_CLIPBOARD,
 /* ^P */            /* XON */       /* ^R */       /* ^S */
 
-LYK_TRACE_TOGGLE,       0,        LYK_SWITCH_DTD,  LYK_REFRESH,
+LYK_TRACE_TOGGLE,  LYK_NEXT_DOC,  LYK_SWITCH_DTD,  LYK_REFRESH,
 /* ^T */            /* ^U */        /* ^V */       /* ^W */
 
+#ifdef USE_CACHEJAR
+LYK_CACHE_JAR,          0,              0,             0,
+/* ^X */            /* ^Y */        /* ^Z */       /* ESC */
+#else
 0,                      0,              0,             0,
 /* ^X */            /* ^Y */        /* ^Z */       /* ESC */
+#endif
 
 0,                      0,              0,             0,
 /* ^\ */            /* ^] */        /* ^^ */       /* ^_ */
@@ -382,7 +387,7 @@ LYKeymap_t key_override[KEYMAP_SIZE] = {
     0,                  0,              0,            0,
 /* ^P */            /* XON */       /* ^R */      /* XOFF */
 
-    0,            LYK_PREV_DOC,         0,            0,
+    0,            LYK_NEXT_DOC,         0,            0,
 /* ^T */            /* ^U */        /* ^V */      /* ^W */
 
     0,                  0,              0,            0,
@@ -972,6 +977,11 @@ static Kcmd revmap[] = {
 	LYK_NESTED_TABLES, "NESTED_TABLES",
 	"toggle nested-table parsing on/off" ),
 #endif
+#ifdef USE_CACHEJAR
+    DATA(
+	LYK_CACHE_JAR, "CACHE_JAR",
+	"examine list of cached documents" ),
+#endif
     DATA(
 	LYK_UNKNOWN, NULL,
 	"" )
diff --git a/src/LYKeymap.h b/src/LYKeymap.h
index a6549615..aa49c17b 100644
--- a/src/LYKeymap.h
+++ b/src/LYKeymap.h
@@ -264,6 +264,12 @@ extern "C" {
 #define LYK_NESTED_TABLES  LYK_UNKNOWN
 #endif
 
+#ifdef USE_CACHEJAR
+	,LYK_CACHE_JAR
+#else
+#define LYK_CACHE_JAR LYK_UNKNOWN
+#endif
+
     } LYKeymapCode;
 
 /*
diff --git a/src/LYMain.c b/src/LYMain.c
index 1f0502ec..c5dd20c7 100644
--- a/src/LYMain.c
+++ b/src/LYMain.c
@@ -1,4 +1,4 @@
-/* $LynxId: LYMain.c,v 1.177 2008/01/06 18:55:37 tom Exp $ */
+/* $LynxId: LYMain.c,v 1.178 2008/01/08 00:48:59 tom Exp $ */
 #include <HTUtils.h>
 #include <HTTP.h>
 #include <HTParse.h>
@@ -27,6 +27,11 @@
 #include <HTForms.h>
 #include <LYList.h>
 #include <LYJump.h>
+
+#ifdef USE_SESSIONS
+#include <LYSession.h>
+#endif
+
 #include <LYMainLoop.h>
 #include <LYBookmark.h>
 #include <LYCookie.h>
@@ -440,6 +445,19 @@ char *personal_type_map = NULL;	/* .mailcap */
 char *pref_charset = NULL;	/* preferred character set */
 char *proxyauth_info[2] =
 {NULL, NULL};			/* Id:Password for protected proxy servers */
+
+#ifdef USE_SESSIONS
+BOOLEAN LYAutoSession = FALSE;	/* enable/disable auto saving/restoring of
+
+				   session */
+char *LYSessionFile = NULL;	/* the session file from lynx.cfg */
+char *session_file = NULL;	/* the current session file */
+char *sessionin_file = NULL;	/* only resume session from this file */
+char *sessionout_file = NULL;	/* only save session to this file */
+short session_limit = 250;	/* maximal number of entries saved for
+
+				   session file, rest will be ignored */
+#endif /* USE_SESSIONS */
 char *startfile = NULL;		/* the first file */
 char *startrealm = NULL;	/* the startfile realm */
 char *system_mail = NULL;	/* The path for sending mail */
@@ -2165,7 +2183,13 @@ int main(int argc,
 #endif
 
 	ena_csi((BOOLEAN) (LYlowest_eightbit[current_char_set] > 155));
+#ifdef USE_SESSIONS
+	RestoreSession();
+	status = mainloop();
+	SaveSession();
+#else
 	status = mainloop();
+#endif
 	LYCloseCloset(RECALL_URL);
 	LYCloseCloset(RECALL_MAIL);
 #if defined(PDCURSES) && defined(PDC_BUILD) && PDC_BUILD >= 2401
@@ -2185,13 +2209,17 @@ int main(int argc,
 /*
  * Called by HTAccessInit to register any protocols supported by lynx.
  * Protocols added by lynx:
- *    LYNXKEYMAP, lynxcgi, LYNXIMGMAP, LYNXCOOKIE, LYNXMESSAGES
+ *    LYNXKEYMAP, lynxcgi, LYNXIMGMAP, LYNXCOOKIE, LYNXCACHE, LYNXMESSAGES
  */
 #ifdef GLOBALREF_IS_MACRO
 extern GLOBALREF (HTProtocol, LYLynxKeymap);
 extern GLOBALREF (HTProtocol, LYLynxCGI);
 extern GLOBALREF (HTProtocol, LYLynxIMGmap);
 extern GLOBALREF (HTProtocol, LYLynxCookies);
+
+#ifdef USE_CACHEJAR
+extern GLOBALREF (HTProtocol, LYLynxCache);
+#endif
 extern GLOBALREF (HTProtocol, LYLynxStatusMessages);
 
 #else
@@ -2199,6 +2227,10 @@ GLOBALREF HTProtocol LYLynxKeymap;
 GLOBALREF HTProtocol LYLynxCGI;
 GLOBALREF HTProtocol LYLynxIMGmap;
 GLOBALREF HTProtocol LYLynxCookies;
+
+#ifdef USE_CACHEJAR
+GLOBALREF HTProtocol LYLynxCache;
+#endif
 GLOBALREF HTProtocol LYLynxStatusMessages;
 #endif /* GLOBALREF_IS_MACRO */
 
@@ -2208,6 +2240,9 @@ void LYRegisterLynxProtocols(void)
     HTRegisterProtocol(&LYLynxCGI);
     HTRegisterProtocol(&LYLynxIMGmap);
     HTRegisterProtocol(&LYLynxCookies);
+#ifdef USE_CACHEJAR
+    HTRegisterProtocol(&LYLynxCache);
+#endif
     HTRegisterProtocol(&LYLynxStatusMessages);
 }
 
@@ -3766,6 +3801,20 @@ with the PREV_DOC command or from the History List"
       "selective",	4|FUNCTION_ARG,		selective_fun,
       "require .www_browsable files to browse directories"
    ),
+#ifdef USE_SESSIONS
+   PARSE_STR(
+      "session",	2|NEED_LYSTRING_ARG,	session_file,
+      "=FILENAME\nresumes from specified file on startup and saves session to that file on exit"
+   ),
+   PARSE_STR(
+      "sessionin",	2|NEED_LYSTRING_ARG,	sessionin_file,
+      "=FILENAME\nresumes session from specified file"
+   ),
+   PARSE_STR(
+      "sessionout",	2|NEED_LYSTRING_ARG,	sessionout_file,
+      "=FILENAME\nsaves session to specified file"
+   ),
+#endif /* USE_SESSIONS */
    PARSE_SET(
       "short_url",	4|SET_ARG,		long_url_ok,
       "enables examination of beginning and end of long URL in\nstatus line"
diff --git a/src/LYMainLoop.c b/src/LYMainLoop.c
index f3327629..24c3ad80 100644
--- a/src/LYMainLoop.c
+++ b/src/LYMainLoop.c
@@ -1,4 +1,4 @@
-/* $LynxId: LYMainLoop.c,v 1.148 2007/07/02 00:09:22 tom Exp $ */
+/* $LynxId: LYMainLoop.c,v 1.149 2008/02/10 23:02:08 tom Exp $ */
 #include <HTUtils.h>
 #include <HTAccess.h>
 #include <HTParse.h>
@@ -40,6 +40,10 @@
 #include <LYMainLoop.h>
 #include <LYPrettySrc.h>
 
+#ifdef USE_SESSIONS
+#include <LYSession.h>
+#endif
+
 #ifdef KANJI_CODE_OVERRIDE
 #include <HTCJK.h>
 #endif
@@ -641,6 +645,9 @@ static void do_check_goto_URL(char *user_input_buffer,
 	{ STR_LYNXCFG,		&no_goto_configinfo },
 	{ STR_LYNXCFLAGS,	&no_goto_configinfo },
 	{ STR_LYNXCOOKIE,	&always },
+#ifdef USE_CACHEJAR
+	{ STR_LYNXCACHE,	&always },
+#endif
 	{ STR_LYNXDIRED,	&always },
 	{ STR_LYNXDOWNLOAD,	&always },
 	{ STR_LYNXOPTIONS,	&always },
@@ -1118,6 +1125,9 @@ static int handle_LYK_ACTIVATE(int *c,
 		 * FM
 		 */
 		if (isLYNXCOOKIE(links[curdoc.link].l_form->submit_action) ||
+#ifdef USE_CACHEJAR
+		    isLYNXCACHE(links[curdoc.link].l_form->submit_action) ||
+#endif
 #ifdef DIRED_SUPPORT
 #ifdef OK_PERMIT
 		    (isLYNXDIRED(links[curdoc.link].l_form->submit_action) &&
@@ -1288,7 +1298,12 @@ static int handle_LYK_ACTIVATE(int *c,
 	    if (no_file_url && isFILE_URL(links[curdoc.link].lname)) {
 		if (!isFILE_URL(curdoc.address) &&
 		    !((isLYNXKEYMAP(curdoc.address) ||
+#ifndef USE_CACHEJAR
 		       isLYNXCOOKIE(curdoc.address)) &&
+#else
+		       isLYNXCOOKIE(curdoc.address) ||
+		       isLYNXCACHE(curdoc.address)) &&
+#endif
 		      !strncmp(links[curdoc.link].lname,
 			       helpfilepath,
 			       strlen(helpfilepath)))) {
@@ -1308,6 +1323,11 @@ static int handle_LYK_ACTIVATE(int *c,
 	    if ((isLYNXCOOKIE(links[curdoc.link].lname) &&
 		 (strcmp(NonNull(curdoc.title), COOKIE_JAR_TITLE) ||
 		  !isLYNXCOOKIE(curdoc.address))) ||
+#ifdef USE_CACHEJAR
+		(isLYNXCACHE(links[curdoc.link].lname) &&
+		 (strcmp(NonNull(curdoc.title), CACHE_JAR_TITLE) ||
+		  !isLYNXCACHE(curdoc.address))) ||
+#endif
 #ifdef DIRED_SUPPORT
 		(isLYNXDIRED(links[curdoc.link].lname) &&
 		 !LYIsUIPage(curdoc.address, UIP_DIRED_MENU) &&
@@ -1474,7 +1494,11 @@ static int handle_LYK_ACTIVATE(int *c,
 		    strip_trailing_slash(newdoc.address);
 	    }
 #endif /* DIRED_SUPPORT  && !__DJGPP__ */
+#ifndef USE_CACHEJAR
 	    if (isLYNXCOOKIE(curdoc.address)) {
+#else
+	    if (isLYNXCOOKIE(curdoc.address) || isLYNXCACHE(curdoc.address)) {
+#endif
 		HTuncache_current_document();
 	    }
 	}
@@ -1540,6 +1564,9 @@ static void handle_LYK_ADD_BOOKMARK(BOOLEAN *refresh_screen,
 #endif /* DIRED_SUPPORT */
 	!LYIsUIPage(curdoc.address, UIP_DOWNLOAD_OPTIONS) &&
 	!isLYNXCOOKIE(curdoc.address) &&
+#ifdef USE_CACHEJAR
+	!isLYNXCACHE(curdoc.address) &&
+#endif
 	!LYIsUIPage(curdoc.address, UIP_OPTIONS_MENU) &&
 	((nlinks <= 0) ||
 	 (links[curdoc.link].lname != NULL &&
@@ -1548,6 +1575,9 @@ static void handle_LYK_ADD_BOOKMARK(BOOLEAN *refresh_screen,
 	  !isLYNXDIRED(links[curdoc.link].lname) &&
 	  !isLYNXDOWNLOAD(links[curdoc.link].lname) &&
 	  !isLYNXCOOKIE(links[curdoc.link].lname) &&
+#ifdef USE_CACHEJAR
+	  !isLYNXCACHE(links[curdoc.link].lname) &&
+#endif
 	  !isLYNXPRINT(links[curdoc.link].lname)))) {
 	if (nlinks > 0) {
 	    if (curdoc.post_data == NULL &&
@@ -1810,6 +1840,34 @@ static void handle_LYK_COMMENT(BOOLEAN *refresh_screen,
     }
 }
 
+#ifdef USE_CACHEJAR
+static BOOLEAN handle_LYK_CACHE_JAR(int *cmd)
+{
+    /*
+     * Don't do this if already viewing cache jar.
+     */
+    if (!isLYNXCACHE(curdoc.address)) {
+	set_address(&newdoc, STR_LYNXCACHE "/");
+	LYFreePostData(&newdoc);
+	FREE(newdoc.bookmark);
+	newdoc.isHEAD = FALSE;
+	newdoc.safe = FALSE;
+	newdoc.internal_link = FALSE;
+	LYforce_no_cache = TRUE;
+	if (LYValidate || check_realm) {
+	    LYPermitURL = TRUE;
+	}
+    } else {
+	/*
+	 * If already in the cache jar, get out.
+	 */
+	*cmd = LYK_PREV_DOC;
+	return TRUE;
+    }
+    return FALSE;
+}
+#endif /* USE_CACHEJAR */
+
 static BOOLEAN handle_LYK_COOKIE_JAR(int *cmd)
 {
     /*
@@ -2055,7 +2113,6 @@ static int handle_LYK_DOWNLOAD(int *cmd,
 		*old_c = real_c;
 		HTUserMsg(NO_DOWNLOAD_COOKIES);
 	    }
-
 	} else if (LYIsUIPage(curdoc.address, UIP_PRINT_OPTIONS)) {
 	    if (*old_c != real_c) {
 		*old_c = real_c;
@@ -2136,6 +2193,9 @@ static int handle_LYK_DOWNLOAD(int *cmd,
 	    }
 
 	} else if (isLYNXCOOKIE(links[curdoc.link].lname) ||
+#ifdef USE_CACHEJAR
+		   isLYNXCACHE(links[curdoc.link].lname) ||
+#endif
 		   isLYNXDIRED(links[curdoc.link].lname) ||
 		   isLYNXDOWNLOAD(links[curdoc.link].lname) ||
 		   isLYNXPRINT(links[curdoc.link].lname) ||
@@ -5260,7 +5320,9 @@ int mainloop(void)
     curdoc.style = NULL;
     newdoc.style = NULL;
 #endif
+#ifndef USE_SESSIONS
     nhist = 0;
+#endif
     user_input_buffer[(sizeof(user_input_buffer) - 1)] = '\0';
     *prev_target = '\0';
     *user_input_buffer = '\0';
@@ -5591,6 +5653,9 @@ int mainloop(void)
 			HTMainText &&
 			nlinks > 0 && curdoc.link < nlinks &&
 			!isLYNXHIST(NonNull(newdoc.address)) &&
+#ifdef USE_CACHEJAR
+			!isLYNXCACHE(NonNull(newdoc.address)) &&
+#endif
 			!isLYNXCOOKIE(NonNull(newdoc.address))) {
 			char *mail_owner = NULL;
 
@@ -7091,6 +7156,13 @@ int mainloop(void)
 		goto new_cmd;
 	    break;
 
+#ifdef USE_CACHEJAR
+	case LYK_CACHE_JAR:	/* show the cache jar */
+	    if (handle_LYK_CACHE_JAR(&cmd))
+		goto new_cmd;
+	    break;
+#endif
+
 	case LYK_HISTORY:	/* show the history page */
 	    if (handle_LYK_HISTORY(ForcePush))
 		break;
diff --git a/src/LYOptions.c b/src/LYOptions.c
index c9e57226..bca4c93b 100644
--- a/src/LYOptions.c
+++ b/src/LYOptions.c
@@ -1,4 +1,4 @@
-/* $LynxId: LYOptions.c,v 1.121 2007/07/02 00:09:49 tom Exp $ */
+/* $LynxId: LYOptions.c,v 1.122 2008/01/08 00:48:58 tom Exp $ */
 #include <HTUtils.h>
 #include <HTFTP.h>
 #include <HTTP.h>		/* 'reloading' flag */
@@ -2302,6 +2302,11 @@ static OptValues mbm_values[] =
 
 static const char *single_bookmark_string = RC_BOOKMARK_FILE;
 
+#ifdef USE_SESSIONS
+static const char *auto_session_string = RC_AUTO_SESSION;
+static const char *single_session_string = RC_SESSION_FILE;
+#endif
+
 /*
  * Character Set Options
  */
@@ -2371,6 +2376,9 @@ static OptValues rate_values[] =
     {rateEtaBYTES, N_("Show %s/sec, ETA"), "rate_eta_bytes"},
     {rateEtaKB, N_("Show %s/sec, ETA"), "rate_eta_kb"},
 #endif
+#ifdef USE_PROGRESSBAR
+    {rateBAR, N_("Show progressbar"), "rate_bar"},
+#endif
     {0, 0, 0}
 };
 #endif /* USE_READPROGRESS */
@@ -2939,6 +2947,21 @@ int postoptions(DocInfo *newdoc)
 		StrAllocCopy(bookmark_page, data[i].value);
 	    }
 	}
+#ifdef USE_SESSIONS
+	/* Auto Session: ON/OFF */
+	if (!strcmp(data[i].tag, auto_session_string)
+	    && GetOptValues(bool_values, data[i].value, &code)) {
+	    LYAutoSession = (BOOL) code;
+	}
+
+	/* Default Session filename: INPUT */
+	if (!strcmp(data[i].tag, single_session_string)) {
+	    if (strcmp(data[i].value, "")) {
+		FREE(LYSessionFile);
+		StrAllocCopy(LYSessionFile, data[i].value);
+	    }
+	}
+#endif
 
 	/* Assume Character Set: SELECT */
 	if (!strcmp(data[i].tag, assume_char_set_string)) {
@@ -3876,6 +3899,19 @@ static int gen_options(char **newfile)
 		     NonNull(bookmark_page), text_len, "");
     }
 
+#ifdef USE_SESSIONS
+    /* Auto Session: ON/OFF */
+    PutLabel(fp0, gettext("Auto Session"), auto_session_string);
+    BeginSelect(fp0, auto_session_string);
+    PutOptValues(fp0, LYAutoSession, bool_values);
+    EndSelect(fp0);
+
+    /* Session File Menu: INPUT */
+    PutLabel(fp0, gettext("Session file"), single_session_string);
+    PutTextInput(fp0, single_session_string,
+		 NonNull(LYSessionFile), text_len, "");
+#endif
+
     /* Visited Pages: SELECT */
     PutLabel(fp0, gettext("Visited Pages"), visited_links_string);
     LYMenuVisitedLinks(fp0, disable_all);
diff --git a/src/LYReadCFG.c b/src/LYReadCFG.c
index f75b9770..f489d88f 100644
--- a/src/LYReadCFG.c
+++ b/src/LYReadCFG.c
@@ -1,4 +1,4 @@
-/* $LynxId: LYReadCFG.c,v 1.125 2008/01/03 00:50:26 Joey.Schulze Exp $ */
+/* $LynxId: LYReadCFG.c,v 1.126 2008/02/10 22:05:02 tom Exp $ */
 #ifndef NO_RULES
 #include <HTRules.h>
 #else
@@ -1212,6 +1212,18 @@ static int read_htmlsrc_tagname_xform(char *str)
 }
 #endif
 
+#ifdef USE_SESSIONS
+static int session_limit_fun(char *value)
+{
+    session_limit = (short) atoi(value);
+    if (session_limit < 1)
+	session_limit = 1;
+    else if (session_limit > MAX_SESSIONS)
+	session_limit = MAX_SESSIONS;
+    return 0;
+}
+#endif /* USE_SESSIONS */
+
 #if defined(PDCURSES) && defined(PDC_BUILD) && PDC_BUILD >= 2401
 static int screen_size_fun(char *value)
 {
@@ -1493,6 +1505,11 @@ static Config_Type Config_Table [] =
 #endif
      PARSE_SET(RC_SEEK_FRAG_AREA_IN_CUR, LYSeekFragAREAinCur),
      PARSE_SET(RC_SEEK_FRAG_MAP_IN_CUR, LYSeekFragMAPinCur),
+#ifdef USE_SESSIONS
+     PARSE_SET(RC_AUTO_SESSION,         LYAutoSession),
+     PARSE_STR(RC_SESSION_FILE,         LYSessionFile),
+     PARSE_FUN(RC_SESSION_LIMIT,        session_limit_fun),
+#endif
      PARSE_SET(RC_SET_COOKIES,          LYSetCookies),
      PARSE_SET(RC_SHOW_CURSOR,          LYShowCursor),
      PARSE_STR(RC_SHOW_KB_NAME,         LYTransferName),
diff --git a/src/LYSession.c b/src/LYSession.c
new file mode 100644
index 00000000..d578c7c4
--- /dev/null
+++ b/src/LYSession.c
@@ -0,0 +1,270 @@
+/* $LynxId: LYSession.c,v 1.3 2008/01/12 01:32:08 tom Exp $ */
+
+#include <LYSession.h>
+
+#include <LYUtils.h>
+#include <LYStrings.h>
+#include <LYHistory.h>
+#include <LYGlobalDefs.h>
+#include <LYMainLoop.h>
+#include <GridText.h>
+
+#ifdef USE_SESSIONS
+
+/* Example of how a session file may look:
+ */
+
+/* # lynx session
+ * / files
+ * / hereby
+ * / reduce
+ * g file://localhost/COPYRIGHT
+ * g http://lynx.isc.org
+ * h 1 -1 file://localhost/COPYRIGHT       Entry into main screen
+ * h 1 0 LYNXCACHE:/       Cache Jar
+ * h 1 16 file://localhost/usr/local/share/lynx_help/Lynx_users_guide.html#Cache   Lynx Users Guide v2.8.6
+ * h 1 -1 file://localhost/COPYRIGHT       Entry into main screen
+ * h 1 2 file://localhost/tmp/lynxmSefvcbXes/L12110-6407TMP.html#current   Visited Links Page
+ * h 1 -1 file://localhost/COPYRIGHT       Entry into main screen
+ * h 1 -1 LYNXMESSAGES:/   Your recent statusline messages
+ * V 0 file://localhost/COPYRIGHT  Entry into main screen
+ * V 3 file://localhost/usr/local/share/lynx_help/Lynx_users_guide.html#Bookmarks  Lynx Users Guide v2.8.6
+ */
+
+static char *get_filename(char *given_name)
+{
+    char *actual_filename = given_name;
+
+    /*
+     * If the specific "-sessionin" or "-sessionout" value is not given,
+     * try the "-session" value (if the AUTO_SESSION configuration is set).
+     * Finally try the SESSION_FILE configuration value.
+     */
+    if (isEmpty(actual_filename)) {
+	actual_filename = session_file;
+	if (isEmpty(actual_filename)) {
+	    if (LYAutoSession) {
+		actual_filename = LYSessionFile;
+	    }
+	}
+    }
+
+    return actual_filename;
+}
+
+/* Restore session from file, pretty slow, but it should be fine
+ * for everyday, normal use.
+ */
+BOOLEAN RestoreSession(void)
+{
+    int code;
+    char *my_filename = get_filename(sessionin_file);
+    FILE *fp;
+    char *buffer = 0;
+    DocInfo doc;
+    VisitedLink *vl;
+    int i = 0;
+    short errors = 10;		/* how much syntax errors are allowed in
+
+				   session file before abort. */
+    char *value1, *value2, *line, *linktext, *level;
+
+    /*
+     * This should be done only once, here:  iff USE_SESSIONS is defined or: 
+     * in mainloop(), otherwise history entries are lost
+     */
+    nhist = 0;
+
+    if (my_filename == NULL) {
+	/* nothing to do, so exit */
+	return (TRUE);
+    }
+
+    CTRACE((tfp, "RestoreSession %s\n", my_filename));
+    SetDefaultMode(O_TEXT);
+    if ((fp = fopen(my_filename, TXT_R)) != NULL) {
+	code = TRUE;
+
+	/*
+	 * This should be safe, entries are added to lynx until memory i
+	 * exhausteds
+	 */
+	while (LYSafeGets(&buffer, fp) != 0) {
+	    LYTrimNewline(buffer);
+	    if (*buffer == '/') {
+#ifdef SEARCH_OUT_SESSION
+		if ((value1 = strchr(buffer, ' ')) == 0) {
+		    continue;
+		} else {
+		    value1++;
+		    HTAddSearchQuery(value1);
+		}
+#endif /* SEARCH_OUT_SESSION */
+	    } else if (*buffer == 'g') {
+#ifdef GOTOURL_OUT_SESSION
+		if ((value1 = strchr(buffer, ' ')) == 0)
+		    continue;
+		else {
+		    value1++;
+		    HTAddGotoURL(value1);
+		}
+#endif /* GOTOURL_OUT_SESSION */
+	    } else if (*buffer == 'h') {
+#ifdef HISTORY_OUT_SESSION
+		if ((line = strchr(buffer, ' ')) == 0)
+		    continue;
+		else {
+		    line++;
+		    if ((linktext = strchr(line, ' ')) == 0)
+			continue;
+		    else
+			*linktext++ = 0;
+		    if ((value1 = strchr(linktext, ' ')) == 0)
+			continue;
+		    else
+			*value1++ = 0;
+		    if ((value2 = strchr(value1, '\t')) != 0) {
+			*value2++ = 0;
+			doc.line = atoi(line);
+			doc.link = atoi(linktext);
+			StrAllocCopy(doc.address, value1);
+			StrAllocCopy(doc.title, value2);
+			LYpush(&doc, TRUE);
+		    }
+		}
+#endif /* HISTORY_OUT_SESSION */
+	    } else if (*buffer == 'V') {
+#ifdef VLINK_OUT_SESSION
+		if ((level = strchr(buffer, ' ')) == 0)
+		    continue;
+		else {
+		    level++;
+		    if ((value1 = strchr(level, ' ')) == 0)
+			continue;
+		    else
+			*value1++ = 0;
+		    if ((value2 = strchr(value1, '\t')) != 0) {
+			*value2++ = 0;
+			StrAllocCopy(doc.address, value1);
+			StrAllocCopy(doc.title, value2);
+			LYAddVisitedLink(&doc);
+			vl = (VisitedLink *)
+			    HTList_objectAt(Visited_Links, i);
+			if (vl != NULL) {
+			    vl->level = atoi(level);
+			    i++;
+			}
+		    }
+		}
+#endif /* VLINK_OUT_SESSION */
+	    } else if (*buffer == '#') {
+		/* This is comment; ignore it */
+		continue;
+	    } else if (errors-- < 0) {
+		FREE(buffer);
+		break;
+	    } else
+		continue;
+	}
+
+	LYCloseOutput(fp);
+    }
+    SetDefaultMode(O_BINARY);
+    return (TRUE);
+}
+
+/* Save session to file, overwriting one.
+ * Fast as much as lynx allow.
+ * If it is still slow for you improve following functions:
+ * HTListObjectAt() and HTList_count().
+ */
+BOOLEAN SaveSession(void)
+{
+    int code = FALSE;
+    char *my_filename = get_filename(sessionout_file);
+    FILE *fp;
+    VisitedLink *vl;
+    int i, j, k;
+
+    if (my_filename == NULL) {
+	/* nothing to do, so exit */
+	return (TRUE);
+    }
+
+    CTRACE((tfp, "SaveSession %s\n", my_filename));
+
+    SetDefaultMode(O_TEXT);
+    if ((fp = fopen(my_filename, TXT_W)) != NULL) {
+	code = TRUE;
+
+	fprintf(fp, "# lynx session\n");	/* @@@ simple for now */
+
+	/* Note use of session_limit, the most recent entries in list,
+	   from end of list, are saved */
+
+#ifdef SEARCH_IN_SESSION
+	k = HTList_count(search_queries);
+	if (k > session_limit)
+	    j = k - session_limit;
+	else
+	    j = 0;
+	for (i = j; i < k; i++) {
+	    fprintf(fp, "/ ");
+	    fputs((char *) HTList_objectAt(search_queries, i), fp);
+	    fprintf(fp, "\n");
+	}
+#endif /* SEARCH_IN_SESSION */
+
+#ifdef GOTOURL_IN_SESSION
+	k = HTList_count(Goto_URLs);
+	if (k > session_limit)
+	    j = k - session_limit;
+	else
+	    j = 0;
+	for (i = j; i < k; i++) {
+	    fprintf(fp, "g ");
+	    fputs((char *) HTList_objectAt(Goto_URLs, i), fp);
+	    fprintf(fp, "\n");
+	}
+#endif /* GOTOURL_IN_SESSION */
+
+#ifdef HISTORY_IN_SESSION
+	k = nhist + nhist_extra;
+	if (k > session_limit)
+	    j = k - session_limit;
+	else
+	    j = 0;
+
+	for (i = j; i < k; i++) {
+	    fprintf(fp, "h %d %d ", HDOC(i).line, HDOC(i).link);
+	    fputs(HDOC(i).address, fp);
+	    fprintf(fp, "\t");
+	    fputs(HDOC(i).title, fp);
+	    fprintf(fp, "\n");
+	}
+#endif /* HISTORY_IN_SESSION */
+
+#ifdef VLINK_IN_SESSION
+	k = HTList_count(Visited_Links);
+	if (k > session_limit)
+	    j = k - session_limit;
+	else
+	    j = 0;
+
+	for (i = j; i < k; i++) {
+	    vl = (VisitedLink *) HTList_objectAt(Visited_Links, i);
+	    fprintf(fp, "V %d ", vl->level);
+	    fputs(vl->address, fp);
+	    fprintf(fp, "\t");
+	    fputs(vl->title, fp);
+	    fprintf(fp, "\n");
+	}
+	LYCloseOutput(fp);
+#endif /* VLINK_IN_SESSION */
+
+    }
+    SetDefaultMode(O_BINARY);
+    return (code);
+}
+
+#endif /* USE_SESSIONS */
diff --git a/src/LYSession.h b/src/LYSession.h
new file mode 100644
index 00000000..f6c26a01
--- /dev/null
+++ b/src/LYSession.h
@@ -0,0 +1,16 @@
+/* $LynxId: LYSession.h,v 1.2 2008/01/10 23:50:45 tom Exp $ */
+#ifndef LYSESSION_H
+#define LYSESSION_H
+
+#include <HTUtils.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+    extern BOOLEAN RestoreSession(void);
+    extern BOOLEAN SaveSession(void);
+
+#ifdef __cplusplus
+}
+#endif
+#endif				/* LYSESSION_H */
diff --git a/src/LYStrings.c b/src/LYStrings.c
index a9493a36..050856d1 100644
--- a/src/LYStrings.c
+++ b/src/LYStrings.c
@@ -1,4 +1,4 @@
-/* $LynxId: LYStrings.c,v 1.128 2007/08/02 19:24:50 tom Exp $ */
+/* $LynxId: LYStrings.c,v 1.129 2008/01/08 00:19:25 tom Exp $ */
 #include <HTUtils.h>
 #include <HTCJK.h>
 #include <UCAux.h>
@@ -1487,6 +1487,9 @@ static int LYmouse_menu(int x, int y, int atlink, int code)
 	{"End of document",		LYK_END,		ENT_ONLY_DOC},
 	{"Bookmarks",			LYK_VIEW_BOOKMARK,	ENT_ONLY_DOC},
 	{"Cookie jar",			LYK_COOKIE_JAR,		ENT_ONLY_DOC},
+#ifdef USE_CACHEJAR
+	{"Cache jar",			LYK_CACHE_JAR,		ENT_ONLY_DOC},
+#endif
 	{"Search index",		LYK_INDEX_SEARCH,	ENT_ONLY_DOC},
 	{"Set Options",			LYK_OPTIONS,		ENT_ONLY_DOC},
 	{"Activate this link",		LYK_SUBMIT,		ENT_ONLY_LINK},
@@ -1553,6 +1556,9 @@ static int LYmouse_menu(int x, int y, int atlink, int code)
 	case LYK_END:
 	case LYK_VIEW_BOOKMARK:
 	case LYK_COOKIE_JAR:
+#ifdef USE_CACHEJAR
+	case LYK_CACHE_JAR:
+#endif
 	case LYK_INDEX_SEARCH:
 	case LYK_OPTIONS:
 	    mouse_link = -3;	/* so LYgetch_for() passes it on - kw */
@@ -4086,8 +4092,9 @@ int LYhandlePopupList(int cur_choice,
     /*
      * Clear the command line and write the popup statusline.  - FM
      */
-    LYmove((LYlines - 2), 0);
-    LYclrtoeol();
+    /* nothing usefull, these two lines bellow should be removed */
+/*    LYmove((LYlines - 2), 0);
+    LYclrtoeol(); */
     if (disabled) {
 	popup_status_msg = CHOICE_LIST_UNM_MSG;
     } else if (!for_mouse) {
diff --git a/src/LYUtils.c b/src/LYUtils.c
index df8a516a..1c7ceed3 100644
--- a/src/LYUtils.c
+++ b/src/LYUtils.c
@@ -1,4 +1,4 @@
-/* $LynxId: LYUtils.c,v 1.165 2008/01/06 18:31:26 Thorsten.Glaser Exp $ */
+/* $LynxId: LYUtils.c,v 1.166 2008/01/08 00:48:59 tom Exp $ */
 #include <HTUtils.h>
 #include <HTTCP.h>
 #include <HTParse.h>
@@ -2316,6 +2316,14 @@ UrlTypes is_url(char *filename)
 		 */
 		result = LYNXHIST_URL_TYPE;
 
+#ifdef USE_CACHEJAR
+	    } else if (compare_type(cp, STR_LYNXCACHE, LEN_LYNXCACHE)) {
+		/* 
+		 * Special Internal Lynx type.
+		 */
+		result = LYNXCACHE_URL_TYPE;
+#endif
+
 	    } else if (compare_type(cp, STR_LYNXKEYMAP, LEN_LYNXKEYMAP)) {
 		/*
 		 * Special Internal Lynx type.
diff --git a/src/LYUtils.h b/src/LYUtils.h
index 9d44c9d0..67b4460b 100644
--- a/src/LYUtils.h
+++ b/src/LYUtils.h
@@ -1,4 +1,4 @@
-/* $LynxId: LYUtils.h,v 1.76 2007/07/02 23:43:21 tom Exp $ */
+/* $LynxId: LYUtils.h,v 1.77 2008/02/10 21:45:40 tom Exp $ */
 #ifndef LYUTILS_H
 #define LYUTILS_H
 
@@ -328,26 +328,27 @@ extern "C" {
 
 	DATA_URL_TYPE,
 
+	LYNXCGI_URL_TYPE,
 	LYNXEXEC_URL_TYPE,
 	LYNXPROG_URL_TYPE,
-	LYNXCGI_URL_TYPE,
 
 	NEWSPOST_URL_TYPE,
 	NEWSREPLY_URL_TYPE,
 	SNEWSPOST_URL_TYPE,
 	SNEWSREPLY_URL_TYPE,
 
-	LYNXPRINT_URL_TYPE,
-	LYNXHIST_URL_TYPE,
-	LYNXDOWNLOAD_URL_TYPE,
-	LYNXKEYMAP_URL_TYPE,
-	LYNXIMGMAP_URL_TYPE,
-	LYNXCOOKIE_URL_TYPE,
-	LYNXDIRED_URL_TYPE,
-	LYNXOPTIONS_URL_TYPE,
+	LYNXCACHE_URL_TYPE,
 	LYNXCFG_URL_TYPE,
 	LYNXCOMPILE_OPTS_URL_TYPE,
+	LYNXCOOKIE_URL_TYPE,
+	LYNXDIRED_URL_TYPE,
+	LYNXDOWNLOAD_URL_TYPE,
+	LYNXHIST_URL_TYPE,
+	LYNXIMGMAP_URL_TYPE,
+	LYNXKEYMAP_URL_TYPE,
 	LYNXMESSAGES_URL_TYPE,
+	LYNXOPTIONS_URL_TYPE,
+	LYNXPRINT_URL_TYPE,
 
 	PROXY_URL_TYPE
 
@@ -423,6 +424,10 @@ extern "C" {
 #define isWAIS_URL(addr)     !strncasecomp(addr, STR_WAIS_URL, LEN_WAIS_URL)
 
 /* internal URLs */
+#define STR_LYNXCACHE        "LYNXCACHE:"
+#define LEN_LYNXCACHE        10
+#define isLYNXCACHE(addr)    !strncasecomp(addr, STR_LYNXCACHE, LEN_LYNXCACHE)
+
 #define STR_LYNXCFG          "LYNXCFG:"
 #define LEN_LYNXCFG          8
 #define isLYNXCFG(addr)      !strncasecomp(addr, STR_LYNXCFG, LEN_LYNXCFG)
diff --git a/src/LYrcFile.c b/src/LYrcFile.c
index 06a5e913..d761ec02 100644
--- a/src/LYrcFile.c
+++ b/src/LYrcFile.c
@@ -1,4 +1,4 @@
-/* $LynxId: LYrcFile.c,v 1.71 2008/01/06 18:51:40 tom Exp $ */
+/* $LynxId: LYrcFile.c,v 1.72 2008/01/08 00:19:25 tom Exp $ */
 #include <HTUtils.h>
 #include <HTFTP.h>
 #include <LYUtils.h>
@@ -123,6 +123,10 @@ Config_Enum tbl_transfer_rate[] = {
     { "KB,ETA",		rateEtaKB },
     { "BYTES,ETA",	rateEtaBYTES },
 #endif
+#ifdef USE_PROGRESSBAR
+    { "METER",		rateBAR },
+    { "FALSE",		rateBAR },
+#endif
     { NULL,		-1 },
 };
 
diff --git a/src/LYrcFile.h b/src/LYrcFile.h
index 061f1aba..6834941e 100644
--- a/src/LYrcFile.h
+++ b/src/LYrcFile.h
@@ -1,5 +1,5 @@
 /*
- * $LynxId: LYrcFile.h,v 1.23 2008/01/03 00:42:21 Joey.Schulze Exp $
+ * $LynxId: LYrcFile.h,v 1.24 2008/02/10 22:45:46 tom Exp $
  */
 #ifndef LYRCFILE_H
 #define LYRCFILE_H
@@ -19,6 +19,7 @@
 #define RC_ASSUME_CHARSET               "assume_charset"
 #define RC_ASSUME_LOCAL_CHARSET         "assume_local_charset"
 #define RC_ASSUME_UNREC_CHARSET         "assume_unrec_charset"
+#define RC_AUTO_SESSION                 "auto_session"
 #define RC_AUTO_UNCACHE_DIRLISTS        "auto_uncache_dirlists"
 #define RC_BIBP_BIBHOST                 "bibp_bibhost"
 #define RC_BIBP_GLOBALSERVER            "bibp_globalserver"
@@ -129,9 +130,9 @@
 #define RC_MAIL_SYSTEM_ERROR_LOGGING    "mail_system_error_logging"
 #define RC_MAKE_LINKS_FOR_ALL_IMAGES    "make_links_for_all_images"
 #define RC_MAKE_PSEUDO_ALTS_FOR_INLINES "make_pseudo_alts_for_inlines"
-#define RC_MAX_COOKIES_BUFFER		"max_cookies_buffer"
-#define RC_MAX_COOKIES_DOMAIN		"max_cookies_domain"
-#define RC_MAX_COOKIES_GLOBAL		"max_cookies_global"
+#define RC_MAX_COOKIES_BUFFER           "max_cookies_buffer"
+#define RC_MAX_COOKIES_DOMAIN           "max_cookies_domain"
+#define RC_MAX_COOKIES_GLOBAL           "max_cookies_global"
 #define RC_MESSAGESECS                  "messagesecs"
 #define RC_MINIMAL_COMMENTS             "minimal_comments"
 #define RC_MKDIR_PATH                   "mkdir_path"
@@ -169,9 +170,9 @@
 #define RC_PERSONAL_MAILCAP             "personal_mailcap"
 #define RC_PERSONAL_MAIL_ADDRESS        "personal_mail_address"
 #define RC_PREFERRED_CHARSET            "preferred_charset"
-#define RC_PREFERRED_MEDIA_TYPES        "preferred_media_types"
 #define RC_PREFERRED_ENCODING           "preferred_encoding"
 #define RC_PREFERRED_LANGUAGE           "preferred_language"
+#define RC_PREFERRED_MEDIA_TYPES        "preferred_media_types"
 #define RC_PREPEND_BASE_TO_SOURCE       "prepend_base_to_source"
 #define RC_PREPEND_CHARSET_TO_SOURCE    "prepend_charset_to_source"
 #define RC_PRETTYSRC                    "prettysrc"
@@ -197,6 +198,8 @@
 #define RC_SEEK_FRAG_AREA_IN_CUR        "seek_frag_area_in_cur"
 #define RC_SEEK_FRAG_MAP_IN_CUR         "seek_frag_map_in_cur"
 #define RC_SELECT_POPUPS                "select_popups"
+#define RC_SESSION_FILE                 "session_file"
+#define RC_SESSION_LIMIT                "session_limit"
 #define RC_SET_COOKIES                  "set_cookies"
 #define RC_SHOW_COLOR                   "show_color"
 #define RC_SHOW_CURSOR                  "show_cursor"
@@ -209,6 +212,7 @@
 #define RC_SOFT_DQUOTES                 "soft_dquotes"
 #define RC_SOURCE_CACHE                 "source_cache"
 #define RC_SOURCE_CACHE_FOR_ABORTED     "source_cache_for_aborted"
+#define RC_SSL_CERT_FILE                "ssl_cert_file"
 #define RC_STARTFILE                    "startfile"
 #define RC_STRIP_DOTDOT_URLS            "strip_dotdot_urls"
 #define RC_SUBSTITUTE_UNDERSCORES       "substitute_underscores"
@@ -251,7 +255,6 @@
 #define RC_XLOADIMAGE_COMMAND           "xloadimage_command"
 #define RC_ZCAT_PATH                    "zcat_path"
 #define RC_ZIP_PATH                     "zip_path"
-#define RC_SSL_CERT_FILE                "ssl_cert_file"
 
 extern Config_Enum tbl_force_prompt[];
 extern Config_Enum tbl_keypad_mode[];
diff --git a/src/chrtrans/makeuctb.c b/src/chrtrans/makeuctb.c
index 24372894..604ff24d 100644
--- a/src/chrtrans/makeuctb.c
+++ b/src/chrtrans/makeuctb.c
@@ -1,5 +1,5 @@
 /*
- * $LynxId: makeuctb.c,v 1.36 2008/01/06 18:23:33 tom Exp $
+ * $LynxId: makeuctb.c,v 1.37 2008/01/09 23:29:20 tom Exp $
  *
  *  makeuctb.c, derived from conmakehash.c   - kw
  *
@@ -327,7 +327,7 @@ int main(int argc, char **argv)
     } else if (ctbl == stdin) {
 	chdr = stdout;
 	hdrname = "stdout";
-    } else if ((outname = malloc(strlen(tblname) + 3)) != 0) {
+    } else if ((outname = (char *) malloc(strlen(tblname) + 3)) != 0) {
 	strcpy(outname, tblname);
 	hdrname = outname;
 	if ((p = strrchr(outname, '.')) == 0)
diff --git a/src/makefile.dos b/src/makefile.dos
index 14ded8d3..5aeee682 100644
--- a/src/makefile.dos
+++ b/src/makefile.dos
@@ -1,8 +1,9 @@
+# $LynxId: makefile.dos,v 1.30 2008/01/08 00:54:14 tom Exp $
 OBJS= UCdomap.o UCAux.o UCAuto.o \
 LYClean.o LYShowInfo.o LYEdit.o LYStrings.o \
 LYMail.o HTAlert.o GridText.o LYGetFile.o \
 LYMain.o LYMainLoop.o LYCurses.o LYBookmark.o LYUtils.o \
-LYOptions.o LYReadCFG.o LYSearch.o LYHistory.o \
+LYOptions.o LYReadCFG.o LYSearch.o LYHistory.o LYSession.o \
 LYForms.o LYPrint.o LYrcFile.o LYDownload.o LYNews.o LYKeymap.o \
 HTML.o HTFWriter.o HTInit.o DefaultStyle.o LYLocal.o LYUpload.o \
 LYLeaks.o LYexit.o LYJump.o LYList.o LYCgi.o LYTraversal.o \
diff --git a/src/makefile.dsl b/src/makefile.dsl
index 1af08539..beb0ccf6 100644
--- a/src/makefile.dsl
+++ b/src/makefile.dsl
@@ -1,8 +1,9 @@
+# $LynxId: makefile.dsl,v 1.17 2008/01/08 00:54:07 tom Exp $
 OBJS= UCdomap.o UCAux.o UCAuto.o \
 LYClean.o LYShowInfo.o LYEdit.o LYStrings.o \
 LYMail.o HTAlert.o GridText.o LYGetFile.o \
 LYMain.o LYMainLoop.o LYCurses.o LYBookmark.o LYUtils.o \
-LYOptions.o LYReadCFG.o LYSearch.o LYHistory.o \
+LYOptions.o LYReadCFG.o LYSearch.o LYHistory.o LYSession.o \
 LYForms.o LYPrint.o LYrcFile.o LYDownload.o LYNews.o LYKeymap.o \
 HTML.o HTFWriter.o HTInit.o DefaultStyle.o LYLocal.o LYUpload.o \
 LYLeaks.o LYexit.o LYJump.o LYList.o LYCgi.o LYTraversal.o \
diff --git a/src/makefile.wsl b/src/makefile.wsl
index ad594411..342d6854 100644
--- a/src/makefile.wsl
+++ b/src/makefile.wsl
@@ -1,8 +1,9 @@
+# $LynxId: makefile.wsl,v 1.13 2008/01/08 00:53:56 tom Exp $
 OBJS= UCdomap.o UCAux.o UCAuto.o \
 LYClean.o LYShowInfo.o LYEdit.o LYStrings.o \
 LYMail.o HTAlert.o GridText.o LYGetFile.o \
 LYMain.o LYMainLoop.o LYCurses.o LYBookmark.o LYUtils.o \
-LYOptions.o LYReadCFG.o LYSearch.o LYHistory.o \
+LYOptions.o LYReadCFG.o LYSearch.o LYHistory.o LYSession.o \
 LYForms.o LYPrint.o LYrcFile.o LYDownload.o LYNews.o LYKeymap.o \
 HTML.o HTFWriter.o HTInit.o DefaultStyle.o LYLocal.o LYUpload.o \
 LYLeaks.o LYexit.o LYJump.o LYList.o LYCgi.o LYTraversal.o \