lynx-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

LYNX-DEV Patches for DIRED


From: Klaus Weide
Subject: LYNX-DEV Patches for DIRED
Date: Wed, 30 Oct 1996 14:06:03 -0600 (CST)

Here are patches to fix problems with DIRED_SUPPORT, some of them severe
and lots of smaller ones.  The changes should not affect non-DIRED behavior,
or anything other than handling of local files.  Please test them.
There are several compile time and runtime options that change how local
file listings are handled, so if several people test these with their own 
choices of settings chances to catch problems are better than what I could
do.  If there are no new problems with these changes, they should be 
incorporated into the mainstream.  These are fixes, not addition of new
features.

Somebody could still give the DIRED code a more thorough overhaul, there
are probably problems left.  It looks like this part of code is not as
well-tested as the rest of Lynx code.

Patches are against Hiram's Composite ("Last updated on 10/22/96"), but
work fine against unmodified Lynx2.6.

Also includes two small fixes I sent to the list before, see
   Linkname: Lynx-Dev Archives: LYNX-DEV MIME types, DIRED stuff
        URL: http://lynx.cc.ukans.edu/lynx-dev/9609/0116.html
and
   Linkname: LYNX-DEV DIRED source showinfo bug & fix
   Filename: http://lynx.cc.ukans.edu/lynx-dev/9610/0733.html


            Klaus


10-30-96
*  Numerous changes to make DIRED_SUPPORT work as intended, mostly in 
   LYLocal.c.
*  Changed to use the library's HTList_* functions and macros for managing
   the list of tagged file URLs.  This replaces some code where invalid 
   pointers could be used.
*  Keep track of proper level of URL escaping, so that unusual filenames
   which contain #% etc. are handled properly.  Can now edit, move, etc.
   Abc%25252525def.html, #xy#~, ...
*  New function HTUnEscape_some(). - KW


*** /usr/tmphda3/lynx/lynx2-6/src/LYGlobalDefs.h        Thu Aug 15 15:24:58 1996
--- lynx2-6/src/LYGlobalDefs.h  Fri Oct 25 16:48:39 1996
***************
*** 48,54 ****
  extern BOOLEAN lynx_edit_mode;
  extern BOOLEAN no_dired_support;
  extern BOOLEAN dir_list_style;
! extern taglink *tagged;
  #define FILES_FIRST 1
  #define MIXED_STYLE 2
  #ifdef OK_OVERRIDE
--- 48,54 ----
  extern BOOLEAN lynx_edit_mode;
  extern BOOLEAN no_dired_support;
  extern BOOLEAN dir_list_style;
! extern HTList *tagged;
  #define FILES_FIRST 1
  #define MIXED_STYLE 2
  #ifdef OK_OVERRIDE
*** /usr/tmphda3/lynx/lynx2-6/src/LYLocal.c     Sun Sep  1 20:24:44 1996
--- lynx2-6/src/LYLocal.c       Wed Oct 30 00:54:17 1996
***************
*** 5,11 ****
        Added OK_PERMIT compilation option.
        Support replacement of compiled-in f)ull menu configuration via
          DIRED_MENU definitions in lynx.cfg, so that more than one menu
!         can be driven by the same executable.
  */
  
  #ifdef DIRED_SUPPORT
--- 5,20 ----
        Added OK_PERMIT compilation option.
        Support replacement of compiled-in f)ull menu configuration via
          DIRED_MENU definitions in lynx.cfg, so that more than one menu
!         can be driven by the same executable. */
! /* Modified Oct-96 Klaus Weide (address@hidden):
! **  - Changed to use the library's HTList_* functions and macros for
! **    managing the list of tagged file URLs. (also changes in LYMainLoop.c)
! **  - Keep track of proper level of URL escaping, so that unusual filenames
! **    which contain #% etc. are handled properly. (also changes in LYMainLoop)
! **    some HTUnEscape_some()'s left in to be conservative, and to document
! **    where superfluous unescaping took place before.
! **  - Dynamic memory instead of fixed lenth buffers in a few cases.
! **  - other minor changes to make things work as intended.
  */
  
  #ifdef DIRED_SUPPORT
***************
*** 19,24 ****
--- 28,35 ----
  #include "LYStrings.h"
  #include "LYStructs.h"
  #include "LYGetFile.h"
+ #include "LYHistory.h"                /* for LYpop() */
+ #include "LYUpload.h"
  #include "LYLocal.h"
  #include "LYSystem.h"
  
***************
*** 30,36 ****
  
  #define FREE(x) if (x) {free(x); x = NULL;}
  
- PRIVATE void clear_tags NOPARAMS;
  PRIVATE int my_spawn PARAMS((char *path, char **argv, char *msg));
  PRIVATE char *filename PARAMS((char *prompt, char *buf, int bufsize));
  
--- 41,46 ----
***************
*** 39,45 ****
                                        char ** newpath));
  #endif /* OK_PERMIT */
  
! PRIVATE char *render_item PARAMS((char *s, char *path, char *dir, char *buf));
  
  PRIVATE struct dired_menu *menu_head = NULL;
  struct dired_menu {
--- 49,56 ----
                                        char ** newpath));
  #endif /* OK_PERMIT */
  
! PRIVATE char *render_item PARAMS((char *s, char *path, char *dir, char *buf,
!                                 int bufsize, BOOLEAN url_syntax));
  
  PRIVATE struct dired_menu *menu_head = NULL;
  struct dired_menu {
***************
*** 129,135 ****
  
  #ifdef OK_ZIP
  { DE_DIR,           "", "Package and compress",
!            "(using zip)", "LYNXDIRED://ZIP%f",                        NULL },
  #endif /* OK_ZIP */
  
  { DE_FILE,          "", "Compress",
--- 140,146 ----
  
  #ifdef OK_ZIP
  { DE_DIR,           "", "Package and compress",
!            "(using zip)", "LYNXDIRED://ZIP%p",                        NULL },
  #endif /* OK_ZIP */
  
  { DE_FILE,          "", "Compress",
***************
*** 142,152 ****
  
  #ifdef OK_ZIP
  { DE_FILE,          "", "Compress",
!            "(using zip)", "LYNXDIRED://ZIP%f",                        NULL },
  #endif /* OK_ZIP */
  
  { DE_TAG,           "", "Move all tagged items to another location.",
!                     "", "LYNXDIRED://MOVE_TAGGED",            NULL },
  
  { DE_TAG,           "", "Remove all tagged files and directories.",
                      "", "LYNXDIRED://REMOVE_TAGGED",          NULL },
--- 153,163 ----
  
  #ifdef OK_ZIP
  { DE_FILE,          "", "Compress",
!            "(using zip)", "LYNXDIRED://ZIP%p",                        NULL },
  #endif /* OK_ZIP */
  
  { DE_TAG,           "", "Move all tagged items to another location.",
!                     "", "LYNXDIRED://MOVE_TAGGED%d",          NULL },
  
  { DE_TAG,           "", "Remove all tagged files and directories.",
                      "", "LYNXDIRED://REMOVE_TAGGED",          NULL },
***************
*** 162,174 ****
     int c, ans;
     char *cp,*tp;
     char tmpbuf[1024];
!    char testpath[512];
     struct stat dir_info;
     int count,i;
!    taglink *tag;
     char *args[5];
  
!    if (tagged == NULL) return 0; /* should never happen */
  
     _statusline("Remove all tagged files and directories (y or n): ");
     c = LYgetch();
--- 173,185 ----
     int c, ans;
     char *cp,*tp;
     char tmpbuf[1024];
!    char * testpath = NULL;
     struct stat dir_info;
     int count,i;
!    HTList *tag;
     char *args[5];
  
!    if HTList_isEmpty(tagged) return 0; /* should never happen */
  
     _statusline("Remove all tagged files and directories (y or n): ");
     c = LYgetch();
***************
*** 176,190 ****
  
     count = 0;
     tag = tagged;
!    while(ans == 'Y' && tag != NULL) {
!       cp = tag->name;
        if(is_url(cp) == FILE_URL_TYPE) { /* unecessary check */
         tp = cp;
         if(!strncmp(tp,"file://localhost",16))
           tp += 16;
         else if(!strncmp(tp,"file:",5))
           tp += 5;
!        strcpy(testpath,tp);
         HTUnEscape(testpath);
         if((i = strlen(testpath)) && testpath[i-1] == '/')
           testpath[i-1] = '\0';
--- 187,200 ----
  
     count = 0;
     tag = tagged;
!    while(ans == 'Y' && (cp = (char *)HTList_nextObject(tag)) != NULL) {
        if(is_url(cp) == FILE_URL_TYPE) { /* unecessary check */
         tp = cp;
         if(!strncmp(tp,"file://localhost",16))
           tp += 16;
         else if(!strncmp(tp,"file:",5))
           tp += 5;
!        StrAllocCopy(testpath,tp);
         HTUnEscape(testpath);
         if((i = strlen(testpath)) && testpath[i-1] == '/')
           testpath[i-1] = '\0';
***************
*** 202,214 ****
            args[2] = testpath;
            args[3] = (char *) 0;
            sprintf(tmpbuf, "remove %s", testpath);
!           if (my_spawn(RM_PATH, args, tmpbuf) <= 0)
                return count;
            ++count;
         }
        }
-       tag = tag->next;
     }
     clear_tags();
     return count;
  }
--- 212,226 ----
            args[2] = testpath;
            args[3] = (char *) 0;
            sprintf(tmpbuf, "remove %s", testpath);
!           if (my_spawn(RM_PATH, args, tmpbuf) <= 0) {
!               FREE(testpath);
                return count;
+           }
            ++count;
         }
        }
     }
+    FREE(testpath);
     clear_tags();
     return count;
  }
***************
*** 216,221 ****
--- 228,237 ----
  /* Move all tagged files and directories to a new location. */
  /* Input is current directory. */
  
+ /* The tests in this function can, at best, prevent some user mistakes -
+    anybody who relies on them for security is seriously misguided.
+    If a user has enough permissions to move a file somewhere, the same 
+    uid with Lynx & dired can do the same thing. */
  PRIVATE BOOLEAN modify_tagged ARGS1(
        char *,         testpath)
  {
***************
*** 224,236 ****
     ino_t inode;
     uid_t owner;
     char tmpbuf[1024];
!    char savepath[512];
     struct stat dir_info;
     char *args[5];
!    int count;
!    taglink *tag;
  
!    if (tagged == NULL) return 0; /* should never happen */
  
     _statusline("Enter new location for tagged items: ");
  
--- 240,253 ----
     ino_t inode;
     uid_t owner;
     char tmpbuf[1024];
!    char * savepath = NULL;
!    char * srcpath = NULL;
     struct stat dir_info;
     char *args[5];
!    int count = 0;
!    HTList *tag;
  
!    if (HTList_isEmpty(tagged)) return 0; /* should never happen */
  
     _statusline("Enter new location for tagged items: ");
  
***************
*** 240,256 ****
  
  /* determine the ownership of the current location */
  
!       cp = testpath;
        if (!strncmp(cp,"file://localhost",16))
        cp += 16;
        else if (!strncmp(cp,"file:",5))
        cp += 5;
!       strcpy(savepath,cp);
        HTUnEscape(savepath);
        if (stat(savepath,&dir_info) == -1) {
         sprintf(tmpbuf,"Unable to get status of %s ",savepath);
         _statusline(tmpbuf);
         sleep(AlertSecs);
         return 0;
        } 
  
--- 257,294 ----
  
  /* determine the ownership of the current location */
  
! /* This test used to always fail from the dired menu...
!    changed to something that hopefully makes more sense - kw */ 
! 
!       if (testpath && *testpath && 0!=strcmp(testpath,"/")) {
!         /* testpath passed in and is not empty and not
!            a single "/" (which would probably be bogus) - use it */
!         cp = testpath;
!       } else {
!         /* prepare to get directory path from one of the tagged files */
!         cp = HTList_lastObject(tagged);
!         testpath = NULL;      /* won't be needed any more in this function,
!                                set to NULL as a flag */
!         if (!cp)   /* last resort, should never happen */
!             cp = "/";
!       }
        if (!strncmp(cp,"file://localhost",16))
        cp += 16;
        else if (!strncmp(cp,"file:",5))
        cp += 5;
!       if (testpath==NULL) { /* get the directory containing the file or
!                              subdir */
!         cp = strip_trailing_slash(cp);
!         savepath = HTParse(".", cp, PARSE_PATH+PARSE_PUNCTUATION);
!         }
!       else
!         StrAllocCopy(savepath,cp);
        HTUnEscape(savepath);
        if (stat(savepath,&dir_info) == -1) {
         sprintf(tmpbuf,"Unable to get status of %s ",savepath);
         _statusline(tmpbuf);
         sleep(AlertSecs);
+        FREE(savepath);
         return 0;
        } 
  
***************
*** 264,283 ****
  /* replace ~/ references to the home directory */
  
        if (!strncmp(tmpbuf,"~/",2)) {
!        cp = (char *)Home_Dir();
!        strcpy(testpath,cp);
!        strcat(testpath,tmpbuf+1);
!        strcpy(tmpbuf,testpath);
        }
  
  /* if path is relative prefix it with current location */
  
        if (tmpbuf[0] != '/') {
         if (savepath[strlen(savepath)-1] != '/')
!          strcat(savepath,"/");
!        strcat(savepath,tmpbuf);
        } else {
!        strcpy(savepath,tmpbuf);
        }
  
  /* stat the target location to determine type and ownership */
--- 302,330 ----
  /* replace ~/ references to the home directory */
  
        if (!strncmp(tmpbuf,"~/",2)) {
!         char * cp1 = NULL;
!         StrAllocCopy(cp1,(char *)Home_Dir());
!         StrAllocCat(cp1,tmpbuf+1);
!         if (strlen(cp1) > sizeof(tmpbuf)-1) {
!             sprintf(tmpbuf,"%s ","Path too long");
!             _statusline(tmpbuf);
!             sleep(AlertSecs);
!             FREE(savepath);
!             FREE(cp1);
!             return 0;
!         }
!         strcpy(tmpbuf,cp1);
!         FREE(cp1);
        }
  
  /* if path is relative prefix it with current location */
  
        if (tmpbuf[0] != '/') {
         if (savepath[strlen(savepath)-1] != '/')
!            StrAllocCat(savepath,"/");
!        StrAllocCat(savepath,tmpbuf);
        } else {
!        StrAllocCopy(savepath,tmpbuf);
        }
  
  /* stat the target location to determine type and ownership */
***************
*** 286,291 ****
--- 333,339 ----
         sprintf(tmpbuf,"Unable to get status of %s ",savepath);
         _statusline(tmpbuf);
         sleep(AlertSecs);
+        FREE(savepath);
         return 0;
        }
  
***************
*** 295,300 ****
--- 343,349 ----
         _statusline(
           "Source and destination are the same location - request ignored!");
         sleep(AlertSecs);
+        FREE(savepath);
         return 0;
        }
  
***************
*** 308,342 ****
  
  /* move all tagged items to the target location */
  
!           while (tag != NULL) {
!              cp = tag->name;
               if(!strncmp(cp,"file://localhost",16))
                 cp += 16;
               else if(!strncmp(cp,"file:",5))
                 cp += 5;
!              strcpy(testpath,cp);
!              HTUnEscape(testpath);
  
!              sprintf(tmpbuf,"move %s to %s",testpath,savepath);
               args[0] = "mv";
!              args[1] = testpath;
               args[2] = savepath;
               args[3] = (char *) 0;
               if (my_spawn(MV_PATH, args, tmpbuf) <= 0)
                  break;
-              tag = tag->next;
               ++count;
            }
            clear_tags();
            return count;
         } else {
            _statusline("Destination has different owner! Request denied. ");
            sleep(AlertSecs);
            return 0;
         }
        } else {
         _statusline("Destination is not a valid directory! Request denied. ");
         sleep(AlertSecs);
         return 0;
        }
     }
--- 357,394 ----
  
  /* move all tagged items to the target location */
  
!           while((cp = (char *)HTList_nextObject(tag)) != NULL) {
               if(!strncmp(cp,"file://localhost",16))
                 cp += 16;
               else if(!strncmp(cp,"file:",5))
                 cp += 5;
!              StrAllocCopy(srcpath,cp);
!              HTUnEscape(srcpath);
  
!              sprintf(tmpbuf,"move %s to %s",srcpath,savepath);
               args[0] = "mv";
!              args[1] = srcpath;
               args[2] = savepath;
               args[3] = (char *) 0;
               if (my_spawn(MV_PATH, args, tmpbuf) <= 0)
                  break;
               ++count;
            }
+           FREE(srcpath);
+           FREE(savepath);
            clear_tags();
            return count;
         } else {
            _statusline("Destination has different owner! Request denied. ");
            sleep(AlertSecs);
+           FREE(srcpath);
+           FREE(savepath);
            return 0;
         }
        } else {
         _statusline("Destination is not a valid directory! Request denied. ");
         sleep(AlertSecs);
+        FREE(savepath);
         return 0;
        }
     }
***************
*** 548,561 ****
     char testpath[512]; /* a bit ridiculous */
     int count;
  
!    if (tagged != NULL) {
        cp = doc->address;
        if (!strncmp(cp,"file://localhost",16))
        cp += 16;
        else if (!strncmp(cp,"file:",5))
        cp += 5;
        strcpy(testpath,cp);
!       HTUnEscape(testpath);
        count = modify_tagged(testpath);
  
        if (doc->link > (nlinks-count-1)) doc->link = nlinks-count-1;
--- 600,613 ----
     char testpath[512]; /* a bit ridiculous */
     int count;
  
!    if (!HTList_isEmpty(tagged)) {
        cp = doc->address;
        if (!strncmp(cp,"file://localhost",16))
        cp += 16;
        else if (!strncmp(cp,"file:",5))
        cp += 5;
        strcpy(testpath,cp);
!       HTUnEscape_some(testpath,"/");
        count = modify_tagged(testpath);
  
        if (doc->link > (nlinks-count-1)) doc->link = nlinks-count-1;
***************
*** 842,848 ****
     char testpath[512];
     int count,i;
  
!    if (tagged != NULL) {
  
        count = remove_tagged();
  
--- 894,900 ----
     char testpath[512];
     int count,i;
  
!    if (!HTList_isEmpty(tagged)) {
  
        count = remove_tagged();
  
***************
*** 972,979 ****
        fprintf(fp0, "<Html><Head>\n<Title>%s</Title>\n</Head>\n<Body>\n",
                PERMIT_OPTIONS_TITLE);
        fprintf(fp0,"<H1>Permissions for %s</H1>\n", user_filename);
        fprintf(fp0, "<Form Action=\"LYNXDIRED://PERMIT_LOCATION%s\">\n",
!               srcpath);
        
        fprintf(fp0, "<Ol><Li>Specify permissions below:<Br><Br>\n");
        fprintf(fp0, "Owner:<Br>\n");
--- 1024,1035 ----
        fprintf(fp0, "<Html><Head>\n<Title>%s</Title>\n</Head>\n<Body>\n",
                PERMIT_OPTIONS_TITLE);
        fprintf(fp0,"<H1>Permissions for %s</H1>\n", user_filename);
+       {  /* prevent filenames which include '#' or '?' from messing it up */
+           char * srcpath_url = HTEscape(srcpath, URL_PATH);
        fprintf(fp0, "<Form Action=\"LYNXDIRED://PERMIT_LOCATION%s\">\n",
!               srcpath_url);
!           FREE(srcpath_url);
!       }
        
        fprintf(fp0, "<Ol><Li>Specify permissions below:<Br><Br>\n");
        fprintf(fp0, "Owner:<Br>\n");
***************
*** 1038,1044 ****
        char *args[5];
        char amode[10];
        
-       HTUnEscape(destpath);
        cp = destpath;
        while (*cp != '\0' && *cp != '?') { /* Find filename */
            cp++;
--- 1094,1099 ----
***************
*** 1048,1053 ****
--- 1103,1110 ----
        }
        *cp++ = '\0';   /* Null terminate file name
                           and start working on the masks */
+ 
+       HTUnEscape(destpath);   /* will now operate only on filename part */
        
        /* A couple of sanity tests */
        destpath = strip_trailing_slash(destpath);
***************
*** 1121,1126 ****
--- 1178,1184 ----
  }
  #endif /* OK_PERMIT */
  
+ #ifdef NOT_USED
  PUBLIC BOOLEAN is_a_file ARGS1(
        char *,         testname)
  { 
***************
*** 1143,1148 ****
--- 1201,1207 ----
       else
         return 0;
  }
+ #endif /* NOT_USED */
  
  /* display or remove a tag from a given link */
  
***************
*** 1174,1192 ****
  }
  
  PUBLIC void showtags ARGS1(
!       taglink *,      t)
  {
      int i;
!     taglink *s;
!     
      for(i=0;i<nlinks;i++) {
        s = t;
!       while(s != NULL) {
!        if(!strcmp(links[i].lname,s->name)) {
            tagflag(ON,i);
            break;
!        } else
!           s = s->next;
        }
     }
  }
--- 1233,1251 ----
  }
  
  PUBLIC void showtags ARGS1(
!       HTList *,       t)
  {
      int i;
!     HTList *s;
!     char * name;
! 
      for(i=0;i<nlinks;i++) {
        s = t;
!       while((name = HTList_nextObject(s)) != NULL) {
!        if(!strcmp(links[i].lname,name)) {
            tagflag(ON,i);
            break;
!        }
        }
     }
  }
***************
*** 1203,1218 ****
  
  /* Perform file management operations for LYNXDIRED URL's */
  
  PUBLIC int local_dired ARGS1(
        document *,     doc)
  {
!    char *line;
!    char *cp,*tp;
     char tmpbuf[256];
     char buffer[512];
  
!    line = doc->address;
!    HTUnEscape(line);
  
     /* This causes a SIGSEGV later when StrAllocCopy tries to free tp
      * let's make it point to NULL
--- 1262,1290 ----
  
  /* Perform file management operations for LYNXDIRED URL's */
  
+ /* Attempt to be consistent.  These are (pseudo) URLs - i.e. they should
+ ** be in URL syntax: some bytes will be URL-escaped with '%'.  This is 
+ ** necessary because these (pseudo) URLs wil go through some of the same 
+ ** kinds of interpretations and mutilations as real ones: HTParse, stripping
+ ** off #fragments etc.  (Some access schemes currently have special rules 
+ ** about not escaping parsing '#' "the URL way" built into HTParse, but that
+ ** doesn't look like a clean way.)  
+ */
  PUBLIC int local_dired ARGS1(
        document *,     doc)
  {
!    char *line_url;    /* will point to doc's address, which is a URL */
!    char *line = NULL; /* same as line_url, but HTUnEscaped, will be alloced */
!    char *cp,*tp,*bp;
     char tmpbuf[256];
     char buffer[512];
  
!    line_url = doc->address;
!    HTUnEscape_some(line_url,"/");     /* don't mess too much with *doc */
! 
!    StrAllocCopy(line,line_url);
!    HTUnEscape(line);  /* _file_ (not URL) syntax, for those functions
!                          that need it.  DOn't forget to FREE it. */
  
     /* This causes a SIGSEGV later when StrAllocCopy tries to free tp
      * let's make it point to NULL
***************
*** 1226,1231 ****
--- 1298,1304 ----
     } else if (!strncmp(line,"LYNXDIRED://INSTALL_SRC",23)) {
        local_install(NULL, &line[23], &tp);
        StrAllocCopy(doc->address, tp);
+       FREE(line);
        return 0;
     } else if (!strncmp(line,"LYNXDIRED://INSTALL_DEST",24)) {
        local_install(&line[24], NULL, &tp);
***************
*** 1235,1260 ****
     } else if (!strncmp(line,"LYNXDIRED://MODIFY_LOCATION",27)) {
        if (modify_location(&line[27])) ++LYforce_no_cache;
     } else if (!strncmp(line,"LYNXDIRED://MOVE_TAGGED",23)) {
!       if (modify_tagged(&line[23])) ++LYforce_no_cache;
  #ifdef OK_PERMIT
     } else if (!strncmp(line,"LYNXDIRED://PERMIT_SRC",22)) {
        permit_location(NULL, &line[22], &tp);
!       StrAllocCopy(doc->address, tp);
        return 0;
     } else if (!strncmp(line,"LYNXDIRED://PERMIT_LOCATION",27)) {
!        permit_location(&line[27], NULL, &tp);
  #endif /* OK_PERMIT */
     } else if (!strncmp(line,"LYNXDIRED://REMOVE_SINGLE",25)) {
        if (remove_single(&line[25])) ++LYforce_no_cache;
     } else if (!strncmp(line,"LYNXDIRED://REMOVE_TAGGED",25)) {
        if (remove_tagged()) ++LYforce_no_cache;
     } else if (!strncmp(line,"LYNXDIRED://UPLOAD",18)) {
!      if (LYUpload(line)) ++LYforce_no_cache;
     } else {
        if (line[strlen(line)-1] == '/')
        line[strlen(line)-1] = '\0';
!       if ((cp = strrchr(line,'/')) == NULL)
        return 0;
  
  /* Construct the appropriate system command taking care to escape all
     path references to avoid spoofing the shell. */
--- 1308,1341 ----
     } else if (!strncmp(line,"LYNXDIRED://MODIFY_LOCATION",27)) {
        if (modify_location(&line[27])) ++LYforce_no_cache;
     } else if (!strncmp(line,"LYNXDIRED://MOVE_TAGGED",23)) {
!       if (modify_tagged(&line_url[23])) ++LYforce_no_cache;
  #ifdef OK_PERMIT
     } else if (!strncmp(line,"LYNXDIRED://PERMIT_SRC",22)) {
        permit_location(NULL, &line[22], &tp);
!       if (tp)                 /* one of the checks may have failed */
!         StrAllocCopy(doc->address, tp);
!       FREE(line);
        return 0;
     } else if (!strncmp(line,"LYNXDIRED://PERMIT_LOCATION",27)) {
!        permit_location(&line_url[27], NULL, &tp);
  #endif /* OK_PERMIT */
     } else if (!strncmp(line,"LYNXDIRED://REMOVE_SINGLE",25)) {
        if (remove_single(&line[25])) ++LYforce_no_cache;
     } else if (!strncmp(line,"LYNXDIRED://REMOVE_TAGGED",25)) {
        if (remove_tagged()) ++LYforce_no_cache;
     } else if (!strncmp(line,"LYNXDIRED://UPLOAD",18)) {
!               /* They're written by LYUpload_options() HTUnEscaped,
!                don't want to change that for now... so pass through
!                without more unescaping.  Directory names containing
!                '#' will probably fail.. */
!      if (LYUpload(line_url)) ++LYforce_no_cache;
     } else {
        if (line[strlen(line)-1] == '/')
        line[strlen(line)-1] = '\0';
!       if ((cp = strrchr(line,'/')) == NULL) {
!       FREE(line);
        return 0;
+       }
  
  /* Construct the appropriate system command taking care to escape all
     path references to avoid spoofing the shell. */
***************
*** 1347,1358 ****
  #ifdef OK_ZIP
        } else if (!strncmp(line,"LYNXDIRED://ZIP",15)) {
        tp = quote_pathname(line+15);
!       sprintf(buffer,"%s -rq %s.zip %s", ZIP_PATH, tp, tp);
        FREE(tp);
  # ifndef ARCHIVE_ONLY
        } else if (!strncmp(line,"LYNXDIRED://UNZIP",17)) {
        tp = quote_pathname(line+17);
!       sprintf(buffer,"%s -q %s", UNZIP_PATH, tp);
        FREE(tp);
  # endif /* !ARCHIVE_ONLY */
  #endif /* OK_ZIP */
--- 1428,1447 ----
  #ifdef OK_ZIP
        } else if (!strncmp(line,"LYNXDIRED://ZIP",15)) {
        tp = quote_pathname(line+15);
!       *cp++ = '\0';
!       bp = quote_pathname(cp);
!       cp = quote_pathname(line+15);
!       sprintf(buffer,"cd %s; %s -rq %s.zip %s", cp, ZIP_PATH, tp, bp);
!       FREE(cp);
!       FREE(bp);
        FREE(tp);
  # ifndef ARCHIVE_ONLY
        } else if (!strncmp(line,"LYNXDIRED://UNZIP",17)) {
        tp = quote_pathname(line+17);
!       *cp = '\0';
!       cp = quote_pathname(line+17);
!       sprintf(buffer,"cd %s; %s -q %s", cp, UNZIP_PATH, tp);
!       FREE(cp);
        FREE(tp);
  # endif /* !ARCHIVE_ONLY */
  #endif /* OK_ZIP */
***************
*** 1383,1388 ****
--- 1472,1478 ----
        }
     }
  
+    FREE(line);
     LYpop(doc);
     return 0;
  }
***************
*** 1402,1408 ****
      struct stat dir_info;
      FILE *fp0;
      char *cp,*tp = NULL;
!     char *escaped;
      int count;
      struct dired_menu *mp;
      char buf[2048];
--- 1492,1501 ----
      struct stat dir_info;
      FILE *fp0;
      char *cp,*tp = NULL;
!     /* char *escaped; */
!     char * dir_url = NULL;
!     char * path_url = NULL;
!     BOOLEAN nothing_tagged;
      int count;
      struct dired_menu *mp;
      char buf[2048];
***************
*** 1430,1435 ****
--- 1523,1531 ----
      else if(!strncmp(cp,"file:",5))
        cp += 5;
      strcpy(dir,cp);
+     StrAllocCopy(dir_url,cp);
+     if (dir_url[strlen(dir_url)-1] == '/')
+       dir_url[strlen(dir_url)-1] = '\0';
      HTUnEscape(dir);
      if (dir[strlen(dir)-1] == '/')
        dir[strlen(dir)-1] = '\0';
***************
*** 1441,1446 ****
--- 1537,1545 ----
         else if(!strncmp(cp,"file:",5))
         cp += 5;
         strcpy(path,cp);
+        StrAllocCopy(path_url,cp);
+        if (path_url[strlen(path_url)-1] == '/')
+          path_url[strlen(path_url)-1] = '\0';
         HTUnEscape(path);
         if (path[strlen(path)-1] == '/')
          path[strlen(path)-1] = '\0';
***************
*** 1449,1465 ****
          sprintf(tmpbuf,"Unable to get status of %s ",path);
          _statusline(tmpbuf);
          sleep(AlertSecs);
          return 0;
         } 
  
         if ((cp = strrchr(path,'.')) != NULL && strlen(path) > strlen(cp)) {
          *cp = '\0';
          tp = strrchr(path,'.');
          *cp = '.';
         }
      } else path[0] = '\0';
  
!     escaped = (char *) HTEscape(path,(unsigned char) 4);
  
      
fprintf(fp0,"<head>\n<title>%s</title></head>\n<body>\n",DIRED_MENU_TITLE);
  
--- 1548,1569 ----
          sprintf(tmpbuf,"Unable to get status of %s ",path);
          _statusline(tmpbuf);
          sleep(AlertSecs);
+         FREE(dir_url);
+         FREE(path_url);
          return 0;
         } 
  
+ #ifdef NOT_USED
         if ((cp = strrchr(path,'.')) != NULL && strlen(path) > strlen(cp)) {
          *cp = '\0';
          tp = strrchr(path,'.');
          *cp = '.';
         }
+ #endif /* NOT_USED */
      } else path[0] = '\0';
  
!   /*escaped = (char *) HTEscape(path,(unsigned char) 4); path_url instead- 
kw*/
!     nothing_tagged = (HTList_isEmpty(tagged));
  
      
fprintf(fp0,"<head>\n<title>%s</title></head>\n<body>\n",DIRED_MENU_TITLE);
  
***************
*** 1468,1474 ****
  
      fprintf(fp0,"Current directory is %s <br>\n",dir);
  
!     if (tagged == NULL)
         if (strlen(path))
            fprintf(fp0,"Current selection is %s <p>\n",path);
         else
--- 1572,1578 ----
  
      fprintf(fp0,"Current directory is %s <br>\n",dir);
  
!     if (nothing_tagged)
         if (strlen(path))
            fprintf(fp0,"Current selection is %s <p>\n",path);
         else
***************
*** 1487,1495 ****
      }
  
      for (mp = menu_head; mp != NULL; mp = mp->next) {
!       if (mp->cond != DE_TAG && tagged != NULL)
            continue;
!       if (mp->cond == DE_TAG && tagged == NULL)
            continue;
        if (mp->cond == DE_DIR && (dir_info.st_mode & S_IFMT) != S_IFDIR)
            continue;
--- 1591,1599 ----
      }
  
      for (mp = menu_head; mp != NULL; mp = mp->next) {
!       if (mp->cond != DE_TAG && !nothing_tagged)
            continue;
!       if (mp->cond == DE_TAG && nothing_tagged)
            continue;
        if (mp->cond == DE_DIR && (dir_info.st_mode & S_IFMT) != S_IFDIR)
            continue;
***************
*** 1497,1505 ****
            continue;
        if (strcmp(mp->sfx, &path[strlen(path)-strlen(mp->sfx)]) != 0)
            continue;
!       fprintf(fp0, "<a href=\"%s", render_item(mp->href, path, dir, buf));
!       fprintf(fp0, "\">%s</a> ", render_item(mp->link, path, dir, buf));
!       fprintf(fp0, "%s<br>\n", render_item(mp->rest, path, dir, buf));
      }
  
      if (uploaders != NULL) {
--- 1601,1612 ----
            continue;
        if (strcmp(mp->sfx, &path[strlen(path)-strlen(mp->sfx)]) != 0)
            continue;
!       fprintf(fp0, "<a href=\"%s",
!               render_item(mp->href, path_url, dir_url, buf,2048, YES));
!       fprintf(fp0, "\">%s</a> ",
!               render_item(mp->link, path, dir, buf,2048, NO));
!       fprintf(fp0, "%s<br>\n",
!               render_item(mp->rest, path, dir, buf,2048, NO));
      }
  
      if (uploaders != NULL) {
***************
*** 1513,1519 ****
      fprintf(fp0,"</body>\n");
      fclose(fp0);
  
!     FREE(escaped);
  
      LYforce_no_cache = 1;
  
--- 1620,1628 ----
      fprintf(fp0,"</body>\n");
      fclose(fp0);
  
!     /* FREE(escaped);  not used any more - kw*/
!     FREE(dir_url);
!     FREE(path_url);
  
      LYforce_no_cache = 1;
  
***************
*** 1543,1548 ****
--- 1652,1658 ----
        _statusline(tmpbuf);
        sleep(AlertSecs);
        rc = 0;
+       break;                  /* don't fall thru! - kw */
        case 0:  /* child */
        execv(path, argv);
        exit(-1);    /* execv failed, give wait() something to look at */
***************
*** 1616,1622 ****
     static char savepath[512]; /* this will be the link that is to be 
installed */
     struct stat dir_info;
     char *args[5];
!    taglink *tag;
     int count = 0;
  
  /* Determine the status of the selected item. */
--- 1726,1732 ----
     static char savepath[512]; /* this will be the link that is to be 
installed */
     struct stat dir_info;
     char *args[5];
!    HTList *tag;
     int count = 0;
  
  /* Determine the status of the selected item. */
***************
*** 1671,1710 ****
     args[3] = (char *) 0;
     sprintf(tmpbuf, "install %s", destpath);
     tag = tagged;
-    for (;;) {
-       if (tagged) {
-        args[1] = tag->name;
-        if (strncmp("file://localhost", args[1], 16) == 0)
-           args[1] = tag->name + 16;
-       } else
-          args[1] = savepath;
  
!       if (my_spawn(INSTALL_PATH, args, tmpbuf) <= 0)
!          return count;
!       count++;
!       if (!tagged)
!        break;
!       tag = tag->next;
!       if (!tag)
!       break;
     }
-    if (tagged)
-       clear_tags();
     statusline("Installation complete");
     sleep(InfoSecs);
     return count;
  }
  
! PRIVATE void clear_tags NOARGS
  {
!     taglink *t1;
  
!     while((t1=tagged) != NULL) { 
!       tagged = tagged->next;
!       FREE(t1->name);
!       FREE(t1);
      }
!     tagged = NULL;
  }
  
  PUBLIC void add_menu_item ARGS1(
--- 1781,1819 ----
     args[3] = (char *) 0;
     sprintf(tmpbuf, "install %s", destpath);
     tag = tagged;
  
!    if (HTList_isEmpty(tagged)) {
!          args[1] = savepath;
!        if (my_spawn(INSTALL_PATH, args, tmpbuf) <= 0)
!            return count;
!        count++;
!    } else {
!        char * name;
!        while ((name = (char *)HTList_nextObject(tag))) {
!          args[1] = name;
!          if (strncmp("file://localhost", args[1], 16) == 0)
!              args[1] = name + 16;
! 
!          if (my_spawn(INSTALL_PATH, args, tmpbuf) <= 0)
!              return count;
!          count++;
!        }      
!        clear_tags();
     }
     statusline("Installation complete");
     sleep(InfoSecs);
     return count;
  }
  
! PUBLIC void clear_tags NOARGS
  {
!     char *cp;
  
!     while((cp=HTList_removeLastObject(tagged)) != NULL) { 
!       FREE(cp);
      }
!     if (HTList_isEmpty(tagged))
!       FREE(tagged);
  }
  
  PUBLIC void add_menu_item ARGS1(
***************
*** 1758,1791 ****
        menu_head = new;
  }
  
! PRIVATE char * render_item ARGS4(
        char *,         s,
        char *,         path,
        char *,         dir,
!       char *,         buf)
  {
        char *cp;
        char *bp;
!       taglink *t1;
!       char *taglist;
! 
        bp = buf;
!       while (*s) {
            if (*s == '%') {
                s++;
                switch (*s) {
                case '%':
!                   *bp++ = '%';
                    break;
                case 'p':
                    cp = path;
                    while (*cp)
!                       *bp++ = *cp++;
                    break;
                case 'd':
                    cp = dir;
                    while (*cp)
!                       *bp++ = *cp++;
                    break;
                case 'f':
                    cp = strrchr(path, '/');
--- 1867,1913 ----
        menu_head = new;
  }
  
! PRIVATE char * render_item ARGS6(
        char *,         s,
        char *,         path,
        char *,         dir,
!       char *,         buf,
!       int,            bufsize,
!       BOOLEAN,        url_syntax)
  {
        char *cp;
        char *bp;
!       char overrun = '\0';
!       char *taglist = NULL;
! #define BP_INC (bp>buf+bufsize-2 ?  &overrun : bp++)
!                               /* Buffer overrun could happen for very long
!                                tag list, if %l or %t are used */
        bp = buf;
!       while (*s && !overrun) {
            if (*s == '%') {
                s++;
                switch (*s) {
                case '%':
!                   *BP_INC = '%';
! #ifdef NOT_USED
!                   /* these chars come from lynx.cfg or the default, let's
!                      just assume there won't be any improper %'s there that
!                      would need escaping. */
!                   if(url_syntax) {
!                       *BP_INC = '2';
!                       *BP_INC = '5';
!                       }
! #endif
                    break;
                case 'p':
                    cp = path;
                    while (*cp)
!                       *BP_INC = *cp++;
                    break;
                case 'd':
                    cp = dir;
                    while (*cp)
!                       *BP_INC = *cp++;
                    break;
                case 'f':
                    cp = strrchr(path, '/');
***************
*** 1794,1824 ****
                    else
                        cp = path;
                    while (*cp)
!                       *bp++ = *cp++;
                    break;
                case 'l':
                case 't':
!                   FREE(taglist);
!                   for (t1=tagged; t1 != NULL; t1 = t1->next) { 
!                       if (*s == 'l' && (cp = strrchr(t1->name, '/')))
!                           cp++;
!                       else
!                           cp = t1->name;
!                       StrAllocCat(taglist, cp);
!                       StrAllocCat(taglist, " ");
                    }
-                   cp = taglist;
-                   while (*cp)
-                       *bp++ = *cp++;
                    break;
                default:
!                   *bp++ = '%';
!                   *bp++ =*s;
                    break;
                }
            } else
!               *bp++ =*s;
            s++;
        }
        *bp = '\0';
        return buf;
--- 1916,1969 ----
                    else
                        cp = path;
                    while (*cp)
!                       *BP_INC = *cp++;
                    break;
                case 'l':
                case 't':
!                   if (!HTList_isEmpty(tagged)) {
!                       HTList * cur = tagged; 
!                       char * name;
!                       while(!overrun &&
!                             (name = (char *)HTList_nextObject(cur))!=NULL) {
!                           if (*s == 'l' && (cp = strrchr(name, '/')))
!                               cp++;
!                           else
!                               cp = name;
!                           StrAllocCat(taglist, cp);
!                           StrAllocCat(taglist, " "); /* should this be %20?*/
!                       }
!                   }
!                   if (taglist) {
!                       /* could HTUnescape here... */
!                       cp = taglist;
!                       while (*cp)
!                           *BP_INC = *cp++;
!                       FREE(taglist);
                    }
                    break;
                default:
!                   *BP_INC = '%';
! #ifdef NOT_USED
!                   if(url_syntax) {
!                       *BP_INC = '2';
!                       *BP_INC = '5';
!                       }
! #endif
!                   *BP_INC =*s;
                    break;
                }
            } else
!               *BP_INC =*s;    /* other chars come from the lynx.cfg or
!                                the default. Let's assume there isn't
!                                anything weird there that needs escaping. */
! 
            s++;
+       }
+       if (overrun & url_syntax) {
+           sprintf(buf,"Temporary URL or list would be too long.");
+           _statusline(buf);
+           sleep(AlertSecs);
+           bp = buf;   /* set to start, will return empty string as URL */
        }
        *bp = '\0';
        return buf;
*** /usr/tmphda3/lynx/lynx2-6/src/LYLocal.h     Mon Dec 18 20:59:36 1995
--- lynx2-6/src/LYLocal.h       Tue Oct 29 18:05:31 1996
***************
*** 40,45 ****
--- 40,48 ----
  extern BOOLEAN local_remove PARAMS((document *doc));
  extern BOOLEAN local_install PARAMS((char *destpath, char *srcpath, char 
**newpath));
  
+ /* MainLoop needs to know about this one for atexit cleanup */
+ extern void clear_tags NOPARAMS;
+ 
  /* Define the PRIVATE routines in case they ever go PUBLIC
  
  extern BOOLEAN modify_name PARAMS((char *testpath));
***************
*** 49,58 ****
  extern BOOLEAN modify_tagged PARAMS((char *testpath));
  extern BOOLEAN remove_tagged NOPARAMS;
  extern BOOLEAN remove_single PARAMS ((char *testpath));
- */
  extern BOOLEAN is_a_file PARAMS((char *testname));
  extern void tagflag PARAMS((int flag, int cur)); 
! extern void showtags PARAMS((taglink *tag));
  extern char * strip_trailing_slash PARAMS((char * dirname));
  extern int local_dired PARAMS((document *doc));
  extern int dired_options PARAMS ((document *doc, char ** newfile));
--- 52,61 ----
  extern BOOLEAN modify_tagged PARAMS((char *testpath));
  extern BOOLEAN remove_tagged NOPARAMS;
  extern BOOLEAN remove_single PARAMS ((char *testpath));
  extern BOOLEAN is_a_file PARAMS((char *testname));
+ */
  extern void tagflag PARAMS((int flag, int cur)); 
! extern void showtags PARAMS((HTList *tag));
  extern char * strip_trailing_slash PARAMS((char * dirname));
  extern int local_dired PARAMS((document *doc));
  extern int dired_options PARAMS ((document *doc, char ** newfile));
*** /usr/tmphda3/lynx/lynx2-6/src/LYMain.c      Sat Aug 17 17:29:34 1996
--- lynx2-6/src/LYMain.c        Sat Oct 26 11:57:40 1996
***************
*** 83,89 ****
  PUBLIC BOOLEAN lynx_edit_mode = FALSE;
  PUBLIC BOOLEAN no_dired_support = FALSE;
  PUBLIC BOOLEAN dir_list_style = MIXED_STYLE;
! PUBLIC taglink *tagged = NULL;
  #ifdef OK_OVERRIDE
  PUBLIC BOOLEAN prev_lynx_edit_mode = FALSE;
  #endif /* OK_OVERRIDE */
--- 83,89 ----
  PUBLIC BOOLEAN lynx_edit_mode = FALSE;
  PUBLIC BOOLEAN no_dired_support = FALSE;
  PUBLIC BOOLEAN dir_list_style = MIXED_STYLE;
! PUBLIC HTList *tagged = NULL;
  #ifdef OK_OVERRIDE
  PUBLIC BOOLEAN prev_lynx_edit_mode = FALSE;
  #endif /* OK_OVERRIDE */
***************
*** 496,507 ****
        StrAllocCopy(lynx_temp_space, temp);
        FREE(temp);
      }
!     StrAllocCopy(LYUserAgent, LYNX_NAME);
!     StrAllocCat(LYUserAgent, "/");
!     StrAllocCat(LYUserAgent, LYNX_VERSION);
!     if (HTLibraryVersion) {
!         StrAllocCat(LYUserAgent, "  libwww-FM/");
!       StrAllocCat(LYUserAgent, HTLibraryVersion);
      }
      StrAllocCopy(LYUserAgentDefault, LYUserAgent);
  #ifdef VMS
--- 496,515 ----
        StrAllocCopy(lynx_temp_space, temp);
        FREE(temp);
      }
!     {
!       char *cp;
! 
!       if ((cp = getenv("LYNX_USER_AGENT")) != (char *)0) {
!       StrAllocCopy(LYUserAgent, cp);
!       } else {
!       StrAllocCopy(LYUserAgent, LYNX_NAME);
!       StrAllocCat(LYUserAgent, "/");
!       StrAllocCat(LYUserAgent, LYNX_VERSION);
!       if (HTLibraryVersion) {
!         StrAllocCat(LYUserAgent, "  libwww-FM/");
!         StrAllocCat(LYUserAgent, HTLibraryVersion);
!       }
!       }
      }
      StrAllocCopy(LYUserAgentDefault, LYUserAgent);
  #ifdef VMS
*** /usr/tmphda3/lynx/lynx2-6/src/LYMainLoop.c  Tue Oct 22 22:51:50 1996
--- lynx2-6/src/LYMainLoop.c    Tue Oct 29 22:53:10 1996
***************
*** 37,42 ****
--- 37,43 ----
  #endif /* VMS */
  
  #ifdef DIRED_SUPPORT
+ #include "HTList.h"
  #include "LYLocal.h"
  #include "LYUpload.h"
  #endif /* DIRED_SUPPORT */
***************
*** 87,92 ****
--- 88,96 ----
      FREE(traversal_host);
      FREE(traversal_link_to_add);
      FREE(CurrentUserAgent);
+ #ifdef DIRED_SUPPORT
+     clear_tags();
+ #endif
  
      return;
  }
***************
*** 138,144 ****
      char *tp;
      char tmpbuf[1024];
      struct stat dir_info;
-     taglink *t1, *t2=NULL;
  #endif /* DIRED_SUPPORT */
  
  /*
--- 142,147 ----
***************
*** 652,658 ****
            HText_pageDisplay(newline, prev_target);
  
  #ifdef DIRED_SUPPORT
!           if (lynx_edit_mode && nlinks > 0 && tagged != NULL)
              showtags(tagged);
  #endif /* DIRED_SUPPORT */
            /* if more equals true then there is more
--- 655,661 ----
            HText_pageDisplay(newline, prev_target);
  
  #ifdef DIRED_SUPPORT
!           if (lynx_edit_mode && nlinks > 0 && !HTList_isEmpty(tagged))
              showtags(tagged);
  #endif /* DIRED_SUPPORT */
            /* if more equals true then there is more
***************
*** 693,699 ****
            HText_pageDisplay(newline, prev_target);
  
  #ifdef DIRED_SUPPORT
!           if (lynx_edit_mode && nlinks > 0 && tagged != NULL)
                showtags(tagged);
  #endif /* DIRED_SUPPORT */
            if (user_mode == NOVICE_MODE)
--- 696,702 ----
            HText_pageDisplay(newline, prev_target);
  
  #ifdef DIRED_SUPPORT
!           if (lynx_edit_mode && nlinks > 0 && !HTList_isEmpty(tagged))
                showtags(tagged);
  #endif /* DIRED_SUPPORT */
            if (user_mode == NOVICE_MODE)
***************
*** 1756,1762 ****
  #ifdef DIRED_SUPPORT
                    if (lynx_edit_mode) {
                          HTuncache_current_document();
!                         HTUnEscape(newdoc.address);
                          strip_trailing_slash(newdoc.address);
                    }
  #endif /* DIRED_SUPPORT */
--- 1759,1768 ----
  #ifdef DIRED_SUPPORT
                    if (lynx_edit_mode) {
                          HTuncache_current_document();
!                         HTUnEscape_some(newdoc.address,"/");
!                         /* undoing escaping of some slash chars seems
!                            necessary here, but avoid double unescaping
!                            and too-early unescaping of other chars. - kw */
                          strip_trailing_slash(newdoc.address);
                    }
  #endif /* DIRED_SUPPORT */
***************
*** 2397,2432 ****
  #ifdef DIRED_SUPPORT
        case LYK_TAG_LINK:  /* tag or untag the current link */
           if (lynx_edit_mode && nlinks > 0 && !no_dired_support) {
              if (dir_list_style == MIXED_STYLE) {
                 if (!strcmp(links[curdoc.link].hightext,"../")) 
                   break;
              } else if (!strncmp(links[curdoc.link].hightext,"Up to ",6)) 
                 break;
!             t1 = tagged;
!             while (t1 != NULL) {
!                if (!strcmp(links[curdoc.link].lname,t1->name)) {
!                   if (t1 == tagged) 
!                     tagged = t1->next;
!                   else 
!                     t2->next = t1->next;
!                   FREE(t1->name);
!                   FREE(t1);
!                   tagflag(OFF,curdoc.link);
!                   break;
!                }
!                t2 = t1;
!                t1 = t1->next;
!             }
!             if (t1 == NULL) {
!                t1 = (taglink *) malloc(sizeof(taglink));
!                if (tagged == NULL) 
!                  tagged = t1;
!                else 
!                  t2->next = t1;
!                t1->next = NULL;
!                t1->name = NULL;
!                StrAllocCopy(t1->name,links[curdoc.link].lname);
!                tagflag(ON,curdoc.link);
              }
              if (curdoc.link < nlinks-1) {
                highlight(OFF, curdoc.link);
--- 2403,2436 ----
  #ifdef DIRED_SUPPORT
        case LYK_TAG_LINK:  /* tag or untag the current link */
           if (lynx_edit_mode && nlinks > 0 && !no_dired_support) {
+             if (!strcmp(links[curdoc.link].hightext,"..")) 
+                  break;          /* Never tag the parent directory */
              if (dir_list_style == MIXED_STYLE) {
                 if (!strcmp(links[curdoc.link].hightext,"../")) 
                   break;
              } else if (!strncmp(links[curdoc.link].hightext,"Up to ",6)) 
                 break;
!             {      /* changed management of tag list, see LYLocal.c - kw */
!                 HTList * t1 = tagged;
!                 char * tagname;
!                 BOOLEAN found = FALSE;
!                 while ((tagname = (char *)HTList_nextObject(t1)) != NULL) {
!                     if (!strcmp(links[curdoc.link].lname,tagname)) {
!                         found = TRUE;
!                         HTList_removeObject(tagged, tagname);
!                         FREE(tagname);
!                         tagflag(OFF,curdoc.link);
!                         break;
!                     }
!                 }
!                 if (!found) {
!                     if (tagged == NULL)
!                         tagged = HTList_new();
!                     tagname = NULL;
!                     StrAllocCopy(tagname,links[curdoc.link].lname);
!                     HTList_addObject(tagged,tagname);
!                     tagflag(ON,curdoc.link);
!                 }
              }
              if (curdoc.link < nlinks-1) {
                highlight(OFF, curdoc.link);
***************
*** 2504,2510 ****
                    } else {
                       if (((dir_info.st_mode) & S_IFMT) == S_IFREG) {
                          strcpy(tmpbuf,cp);
!                         HTUnEscape(tmpbuf);
                          if (edit_current_file(tmpbuf,curdoc.link,newline))
                          {
                                HTuncache_current_document();
--- 2508,2514 ----
                    } else {
                       if (((dir_info.st_mode) & S_IFMT) == S_IFREG) {
                          strcpy(tmpbuf,cp);
!                         HTUnEscape_some(tmpbuf,"/");
                          if (edit_current_file(tmpbuf,curdoc.link,newline))
                          {
                                HTuncache_current_document();
*** /usr/tmphda3/lynx/lynx2-6/src/LYShowInfo.c  Sun Sep  1 20:26:08 1996
--- lynx2-6/src/LYShowInfo.c    Wed Oct 23 05:43:37 1996
***************
*** 97,103 ****
      fprintf(fp0,"<h2>%s Version %s</h2>\n", LYNX_NAME, LYNX_VERSION);
  
  #ifdef DIRED_SUPPORT
!     if (lynx_edit_mode) {
        fprintf(fp0,
                "<h2>Directory that you are currently viewing</h2>\n<pre>");
  
--- 97,103 ----
      fprintf(fp0,"<h2>%s Version %s</h2>\n", LYNX_NAME, LYNX_VERSION);
  
  #ifdef DIRED_SUPPORT
!     if (lynx_edit_mode && nlinks > 0) {
        fprintf(fp0,
                "<h2>Directory that you are currently viewing</h2>\n<pre>");
  
*** /usr/tmphda3/lynx/lynx2-6/src/LYStructs.h   Fri Jul 21 06:54:28 1995
--- lynx2-6/src/LYStructs.h     Wed Oct 30 00:18:42 1996
***************
*** 36,45 ****
--- 36,48 ----
  } document;
  
  #ifdef DIRED_SUPPORT
+ /* No need for this any more - use library's HTList instead for tags. - kw */
+ #if 0
  typedef struct _taglink {
     char *name;
     struct _taglink *next;
  } taglink;
+ #endif
  #endif
  
  #ifndef HTFORMS_H
*** /usr/tmphda3/lynx/lynx2-6/WWW/Library/Implementation/HTParse.c      Thu Aug 
15 15:22:32 1996
--- lynx2-6/WWW/Library/Implementation/HTParse.c        Wed Oct 30 00:22:12 1996
***************
*** 603,606 ****
--- 603,634 ----
      
  } /* HTUnEscape */
  
+ /* Unescape only some characters, given by the do_trans string. - kw */
  
+ /* @@@ Have to define shortname? anybody still using?? */
+ PUBLIC char * HTUnEscape_some ARGS2(
+       char *,         str,
+         CONST char *,   do_trans)
+ {
+     char * p = str;
+     char * q = str;
+     char testcode;
+     while (*p) {
+         if (*p == HEX_ESCAPE &&
+           p[1] && p[2] &&     /* tests shouldn't be needed, but.. */
+           isxdigit((unsigned char)p[1]) &&
+           isxdigit((unsigned char)p[2]) &&
+           (testcode = from_hex(p[1])*16 + from_hex(p[2])) && /* %00 no good*/
+           strchr(do_trans,testcode)) { /* it's one of the ones we want */
+ 
+           *q++ = FROMASCII(testcode); 
+           p +=3;
+       } else {
+           *q++ = *p++; 
+       }
+     }
+     
+     *q++ = '\0';
+     return str;
+     
+ } /* HTUnEscape_some */
*** /usr/tmphda3/lynx/lynx2-6/WWW/Library/Implementation/HTFile.c       Tue Aug 
13 18:19:52 1996
--- lynx2-6/WWW/Library/Implementation/HTFile.c Fri Oct 25 10:32:29 1996
***************
*** 998,1004 ****
        CONST char *,   entry)
  {
      char * relative;
!     char * escaped = HTEscape(entry, URL_XPALPHAS);
  
  
      if (tail == NULL || *tail == '\0') {
--- 998,1009 ----
        CONST char *,   entry)
  {
      char * relative;
!     char * escaped = NULL;
! 
!     if (0==strcmp(entry,"../"))       /* undo slash appending for anchor 
creation */
!       StrAllocCopy(escaped,"..");
!     else
!       escaped = HTEscape(entry, URL_XPALPHAS);
  
  
      if (tail == NULL || *tail == '\0') {
***************
*** 1038,1043 ****
--- 1043,1049 ----
                TOUPPER(*(cp+6)) == 'I')
                *cp = '\0';
        }
+       cp = NULL;
      }
      current = strrchr(path, '/');     /* last part or "" */
  
***************
*** 1056,1062 ****
          FREE(cp);
        }
  #else 
!       StrAllocCopy(printable, (current + 1));
  #endif /* DIRED_SUPPORT */
  
        START(HTML_HEAD);
--- 1062,1068 ----
          FREE(cp);
        }
  #else 
!       StrAllocCopy(printable, (current ? current + 1 : ""));
  #endif /* DIRED_SUPPORT */
  
        START(HTML_HEAD);
***************
*** 1129,1135 ****
            DIR  * dp=NULL;
  
            if (LYisLocalFile(logical)) {
!               if ((dp = opendir(relative)) == NULL) {
                    FREE(logical);
                    FREE(relative);
                    FREE(path);
--- 1135,1160 ----
            DIR  * dp=NULL;
  
            if (LYisLocalFile(logical)) {
!               /* We need an absolute file path for the opendir.
!                  We also need to unescape for this test.
!                  Don't worry about %2F now, they presumably have been
!                  dealt with above, and shouldn't appear for local
!                  files anyway...  Assume OS / filesystem will just
!                  ignore superfluous slashes. - kw */
!               char * fullparentpath = NULL;
!               
!               StrAllocCopy(fullparentpath, path);
!                                       /* path has been shortened above */
!               if (0 == strcmp(current,"..")) {/* guard against weirdness */
!                   StrAllocCat(fullparentpath,"/../..");
!               }
!               else if (0 == strcmp(current,".")) {/* another weirdness */
!                   StrAllocCat(fullparentpath,"/..");
!               }
!               HTUnEscape(fullparentpath);
! 
!               if ((dp = opendir(fullparentpath)) == NULL) {
!                   FREE(fullparentpath);
                    FREE(logical);
                    FREE(relative);
                    FREE(path);
***************
*** 1137,1142 ****
--- 1162,1168 ----
                }
                if (dp)
                    closedir(dp);
+               FREE(fullparentpath);
            }
        }
  #endif /* !VMS */
***************
*** 1151,1160 ****
  #ifdef DIRED_SUPPORT
           if (dir_list_style == MIXED_STYLE) {
              PUTS("../");
!          } else {
! #else
!          {
  #endif /* DIRED_SUPPORT */
              char * printable = NULL;
              StrAllocCopy(printable, parent + 1);
              HTUnEscape(printable);
--- 1177,1190 ----
  #ifdef DIRED_SUPPORT
           if (dir_list_style == MIXED_STYLE) {
              PUTS("../");
!          } else
  #endif /* DIRED_SUPPORT */
+          if ((0==strcmp(current,".")) ||
+              (0==strcmp(current,".."))) {/* shouldn't happen, but if it does
+                                    at least avoid giving misleading
+                                    info - kw */
+              PUTS("..");
+          } else {
              char * printable = NULL;
              StrAllocCopy(printable, parent + 1);
              HTUnEscape(printable);
***************
*** 1588,1594 ****
                    while ((dirbuf = readdir(dp))!=0)
                    {
                        /* while there are directory entries to be read */
!                       HTBTElement * dirname = NULL;
                        extern BOOLEAN no_dotfiles, show_dotfiles;
  
                        if (dirbuf->d_ino == 0)
--- 1618,1624 ----
                    while ((dirbuf = readdir(dp))!=0)
                    {
                        /* while there are directory entries to be read */
!                       char * dirname = NULL;
                        extern BOOLEAN no_dotfiles, show_dotfiles;
  
                        if (dirbuf->d_ino == 0)
***************
*** 1607,1613 ****
                             * begins with '.' */
                            continue;
  
!                       dirname = (HTBTElement *)malloc(
                                        strlen(dirbuf->d_name) + 4);
                        if (dirname == NULL)
                            outofmem(__FILE__,"DirRead");
--- 1637,1643 ----
                             * begins with '.' */
                            continue;
  
!                       dirname = (char *)malloc(
                                        strlen(dirbuf->d_name) + 4);
                        if (dirname == NULL)
                            outofmem(__FILE__,"DirRead");
*** /usr/tmphda3/lynx/lynx2-6/WWW/Library/Implementation/HTParse.h      Thu Aug 
15 15:22:42 1996
--- lynx2-6/WWW/Library/Implementation/HTParse.h        Sat Oct 26 08:38:25 1996
***************
*** 148,153 ****
--- 148,158 ----
  extern char * HTUnEscape PARAMS((
        char *          str));
  
+ /* The same, but only for some characters given by string do_trans */
+ extern char * HTUnEscape_some PARAMS((
+       char *          str,
+       CONST char *    do_trans));
+ 
  
  #endif  /* HTPARSE_H */
  
*** /usr/tmphda3/lynx/lynx2-6/lynx.cfg  Fri Aug 30 19:26:06 1996
--- lynx2-6/lynx.cfg    Tue Oct 29 22:22:08 1996
***************
*** 1251,1257 ****
  #DIRED_MENU:DIR::Tar and compress:(using GNU gzip):LYNXDIRED://TAR_GZ%p
  
  # Following depends on OK_ZIP
! #DIRED_MENU:DIR::Package and compress:(using zip):LYNXDIRED://ZIP%f
  
  #DIRED_MENU:FILE::Compress:(using Unix compress):LYNXDIRED://COMPRESS%p
  
--- 1251,1257 ----
  #DIRED_MENU:DIR::Tar and compress:(using GNU gzip):LYNXDIRED://TAR_GZ%p
  
  # Following depends on OK_ZIP
! #DIRED_MENU:DIR::Package and compress:(using zip):LYNXDIRED://ZIP%p
  
  #DIRED_MENU:FILE::Compress:(using Unix compress):LYNXDIRED://COMPRESS%p
  
***************
*** 1259,1267 ****
  #DIRED_MENU:FILE::Compress:(using gzip):LYNXDIRED://GZIP%p
  
  # Following depends on OK_ZIP
! #DIRED_MENU:FILE::Compress:(using zip):LYNXDIRED://ZIP%f
  
! #DIRED_MENU:TAG::Move all tagged items to another 
location.::LYNXDIRED://MOVE_TAGGED
  #DIRED_MENU:TAG::Remove all tagged files and 
directories.::LYNXDIRED://REMOVE_TAGGED
  
  # COLORS (only available if compiled with slang)
--- 1259,1267 ----
  #DIRED_MENU:FILE::Compress:(using gzip):LYNXDIRED://GZIP%p
  
  # Following depends on OK_ZIP
! #DIRED_MENU:FILE::Compress:(using zip):LYNXDIRED://ZIP%p
  
! #DIRED_MENU:TAG::Move all tagged items to another 
location.::LYNXDIRED://MOVE_TAGGED%d
  #DIRED_MENU:TAG::Remove all tagged files and 
directories.::LYNXDIRED://REMOVE_TAGGED
  
  # COLORS (only available if compiled with slang)
;
; To UNSUBSCRIBE:  Send a mail message to address@hidden
;                  with "unsubscribe lynx-dev" (without the
;                  quotation marks) on a line by itself.
;



reply via email to

[Prev in Thread] Current Thread [Next in Thread]