From: J C Lawrence <claw@kanga.nu>
Subject: [svlug] browser-history patch (checkpoint feature) (fwd)
Date: Fri, 29 Sep 2000 17:18:50 -0700

------- =_aaaaaaaaaa0
Content-Type: text/plain; charset="us-ascii"
Content-ID: <3907.970268246.1@kanga.nu>

In all the recent discussion of Netscape instability, foibles,
browsing habits, etc, I finally polished up some hacks I've made to
browser-history.  What is browser-history?  See:

  http://www-sop.inria.fr/koala/colas/browser-history/

Why use this?  If your netscape keeps crashing, you can use
browser-history with this patch to be able to easily restore your
next invocation of netscape to where you were.  How?  In addition to
the normal browser-history functions of logging every URL you visit,
you can now also checkpoint all the URLs that are currently being
viewed by a browser window (if that browser is supported by
browser-history) so that you have a stored list of exactly where you
were.  Then just bring up the browser-history, and middle-click away
on the checkpointed URLs to quickly recover.

Enjoy.

-- 
J C Lawrence                                 Home: claw@kanga.nu
---------(*)                               Other: coder@kanga.nu
http://www.kanga.nu/~claw/        Keys etc: finger claw@kanga.nu
--=| A man is as sane as he is dangerous to his environment |=--

------- =_aaaaaaaaaa0
Content-Type: message/rfc822
Content-ID: <3907.970268246.2@kanga.nu>
Content-Description: forwarded message

To: karlheg@debian.org
bcc: 
Subject: browser-history patch (checkpoint feature)
X-face: ?<YUs-cNP1\Oc-H>^_yw@fA`CEX&}--=*&XqXbF-oePvxaT4(kyt\nwM9]{]N!>b^K}-Mb9
 YH%saz^>nq5usBlD"s{(.h'_w|U^3ldUq7wVZz$`u>MB(-4$f\a6Eu8.e=Pf\
X-image-url: http://www.kanga.nu/~claw/kanga.face.tiff
X-url: http://www.kanga.nu/~claw/
Date: Fri, 29 Sep 2000 15:45:23 -0700
Message-ID: <3222.970267523@kanga.nu>
From: J C Lawrence <claw@kanga.nu>


The following patch when applied to the 2.4 Debian sources (note
that the current release of browser-history is 2.8) adds the
following feature:

  If "browser-history -c" is run, the currently running instance of
  browser-history will save a list of all the URLs and their titles
  that are currently being viewed by a browser-history compatable
  browser (eg Netscape, Amaya, etc) to the normal history file as a
  "Checkpoint".

I wrote this specifically as I tend to have many netscape windows
open at a time (20 - 30 is about average) and I tend to preserve
state and context within those windows (what I'm interested in, what
I want to get back to, etc).  Now, by hanging "browser-history -c"
off a root menu item, or a window manager's GUI button I can
checkpoint the exact list of sites I'm currently viewing so I can
later easily restore that context later (eg machine crash due to the
2.4.0-test* kernels I'm running).

I'll be updating this patch to the current v2.8 release and sending
it to the author as well.

-- 
J C Lawrence                                 Home: claw@kanga.nu
---------(*)                               Other: coder@kanga.nu
http://www.kanga.nu/~claw/        Keys etc: finger claw@kanga.nu
--=| A man is as sane as he is dangerous to his environment |=--

$ diff -C 2 browser-history-2.4/browser-history.c browser-history-2.4.new/browser-history.c
*** browser-history-2.4/browser-history.c       Fri Sep 29 15:17:42 2000
--- browser-history-2.4.new/browser-history.c   Fri Sep 29 15:01:47 2000
***************
*** 115,118 ****
--- 115,119 ----
  int verbose = 0;                      /* verbose mode? */
  int must_reinit = 0;                  /* do we need to re-read init files? */
+ int checkpoint = 0;            /* do we need to checkpoint all URLS? */
  
  Browser_win browser_windows;          /* the list of existing N wins */
***************
*** 173,176 ****
--- 174,178 ----
  void record_URL(int number, char *name, char *url);
  void reinit_handler();
+ void checkpoint_handler();
  int verboseXHandler(Display *dpy, XErrorEvent *error);
  int terseXHandler(Display *dpy, XErrorEvent *error);
***************
*** 178,184 ****
--- 180,189 ----
  int decode_ARENA_LOCATION(char *full_name, char **namep, char **urlp);
  void init_log_file(int first, FILE *fd);
+ void checkpoint_header (char *datestring, struct tm *times);
+ void checkpoint_footer (char *datestring, struct tm *times);
  void add_log_entry(char *name, char *url, unsigned int win,
                   char *datestring, struct tm *times, int separator);
  void reinit();
+ void checkpointURLs ();
  Window create_tag_window(int mode, int version, char *machine, int pid);
  char *date2string(struct tm *times);
***************
*** 227,230 ****
--- 232,238 ----
        if (must_reinit)                /* signal 1 was sent */
            reinit();
+   if (checkpoint) {    /* signal SIGUSR1 was sent */
+     checkpointURLs ();
+   }
        switch (event.type) {
  
***************
*** 330,333 ****
--- 338,344 ----
            case 'D':                   /* -DontGrab */
                dontgrab = 1;
+     case 'c': /* Checkpoint all currently displayed URLs */
+         tag_mode = 3;
+         continue;
                continue;
            }
***************
*** 356,360 ****
        sigaction(SIGHUP, &action, 0);
      }
! 
      /* init X */
      dpy = XOpenDisplay (displayname);
--- 367,379 ----
        sigaction(SIGHUP, &action, 0);
      }
!     
!     {
!       /* trap signal SIGUSR1, make it checkpoint */
!       struct sigaction action;
!       sigaction (SIGUSR1, 0, &action);
!       action.sa_handler = checkpoint_handler;
!       sigaction(SIGUSR1, &action, 0);
!     }
!     
      /* init X */
      dpy = XOpenDisplay (displayname);
***************
*** 437,440 ****
--- 456,483 ----
  }
  
+ /* Checkpoint all windows */
+ 
+ void checkpointURLs ()
+ {
+   char *datestring;
+   struct tm *times;
+   time_t seconds;
+   int ndx;
+ 
+   time(&seconds);
+   times = localtime (&seconds);
+   datestring = date2string (times);
+ 
+   checkpoint_header (datestring, times);
+   for (ndx = 0; ndx < browser_windows_size; ndx++) {
+     add_URL(ndx);
+   }
+   checkpoint_footer (datestring, times);
+   
+   /* Done */
+   
+   checkpoint = 0;
+ }
+ 
  int
  not_excluded_URL(char *url)
***************
*** 496,499 ****
--- 539,591 ----
  }
  
+ void checkpoint_header (
+   char *datestring,
+   struct tm *times)
+ {
+   FILE *fd = fopen (logfilepath, "a");
+   if (!fd) {      /* cannot open? try to make dir */
+     char logdir[1024];
+     sprintf(logdir, "%s/%s", homedir, logreldir);
+     mkdir(logdir, 0777);
+     fd = fopen(logfilepath, "a"); /* retry now */
+   }
+   if (!fd) {        /* cannot do anything */
+     P(E, "Warning: could not open %s!\n", logfilepath);
+     return;
+   }
+   if (ftell(fd) == 0) {    /* init file if empty */
+     init_log_file(1, fd);
+     last_times = *times;
+   }
+ 
+   fprintf(fd, "<hr noshade>\n");
+   fprintf(fd, "<h1>Currently viewed URLs (checkpoint):</h1>\n");
+   fclose (fd);
+ }
+ 
+ void checkpoint_footer (
+   char *datestring,
+   struct tm *times)
+ {
+   FILE *fd = fopen (logfilepath, "a");
+   if (!fd) {      /* cannot open? try to make dir */
+     char logdir[1024];
+     sprintf(logdir, "%s/%s", homedir, logreldir);
+     mkdir(logdir, 0777);
+     fd = fopen(logfilepath, "a"); /* retry now */
+   }
+   if (!fd) {        /* cannot do anything */
+     P(E, "Warning: could not open %s!\n", logfilepath);
+     return;
+   }
+   if (ftell(fd) == 0) {    /* init file if empty */
+     init_log_file(1, fd);
+     last_times = *times;
+   }
+ 
+   fprintf(fd, "<hr noshade>\n");
+   fclose (fd);
+ }
+ 
  void
  add_log_entry(char *name, char *url, unsigned int win,
***************
*** 593,596 ****
--- 685,695 ----
  }
  
+ void checkpoint_handler (
+   int sig,
+   void *sip,
+   void *uap)
+ {
+   checkpoint = 1;
+ }
  int
  terseXHandler(Display *dpy, XErrorEvent *error) {return 0;}
***************
*** 790,796 ****
        }
      } else
!       return;                         /* unknown browser */
      if (url != nilstring && not_excluded_URL(url)
!       && !URL_already_present(name, url)) {
        char *datestring;
        time(&seconds);
--- 889,895 ----
        }
      } else
!       return;                         /* unknown browser */    
      if (url != nilstring && not_excluded_URL(url)
!       && (!URL_already_present(name, url) || checkpoint)) {
        char *datestring;
        time(&seconds);
***************
*** 900,921 ****
      if (mode == 2)
        exit(0);
!     if (mode == 0) {                  /* check version */
!       int old_version;
!       result = XGetWindowProperty(dpy, w, PROCESS, 0, 63, 0,
!                                   XA_STRING, &actual_type, &actual_format,
!                                   &nitems, &bytes_after_return, &property);
!       old_version = atoi(strchr(property, '=') + 1);
!       XFree(property);
!       if (version > old_version) {
!           if (verbose)
!               P(E, "killing previous version (%d.%d) of browser-history\n", 
!                 old_version/1000, old_version%1000);
!           XKillClient(dpy, w);
!       } else {
!           XUngrabServer(dpy);
!           if (verbose)
!               P(E, "same or more recent version (%d.%d) of browser-history running, aborting\n", old_version/1000, old_version%1000);
!           exit(0);
!       }
      }
      
--- 999,1041 ----
      if (mode == 2)
        exit(0);
!     if ((mode == 0) || (mode == 3)) {                 /* check version */
!       int old_version;
!       pid_t pid;
!       char *pid_str;
!       
!       result = XGetWindowProperty(dpy, w, PROCESS, 0, 63, 0,
!                                   XA_STRING, &actual_type, &actual_format,
!                                   &nitems, &bytes_after_return, &property);
!       old_version = atoi(strchr(property, '=') + 1);
!       
!       /* Get PID of other process.  The PID is in the 4th string */
!       /* e.g:   VERSION=1009\0DATE=96/05/16-09:17:08\0MACHINE=koala\0PID=4345\0 */
!       
!       pid_str = property;
!       pid_str += strlen (pid_str) + 1; /* DATE */
!       pid_str += strlen (pid_str) + 1; /*MACHINE */
!       pid_str += strlen (pid_str) + 1; /* PID */
!       pid = atoi (strchr (pid_str, '=') + 1);
!       
!       XFree(property);
!       if (version > old_version) {
!         if (verbose)
!           P(E, "killing previous version (%d.%d) of browser-history\n", 
!             old_version/1000, old_version%1000);
!         XKillClient(dpy, w);
!       }
!       else if (mode == 0) {
!         XUngrabServer(dpy);
!         if (verbose)
!           P(E, "same or more recent version (%d.%d) of browser-history running, aborting\n", old_version/1000, old_version%1000);
!         exit(0);
!       }
! 
!       /* Checkpoint? */
!       
!       if (mode == 3) {
!         kill (pid, SIGUSR1);
!         exit (0);
!       }
      }


------- =_aaaaaaaaaa0--
