lynx-dev
[Top][All Lists]
Advanced

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

lynx-dev 2.8.3dev.2 patch 1 - dired mostly, + HTTP


From: Klaus Weide
Subject: lynx-dev 2.8.3dev.2 patch 1 - dired mostly, + HTTP
Date: Mon, 21 Jun 1999 03:45:35 -0500 (CDT)

Note to Tom: configure set INSTALL_PATH to "/path/to/install -c"
and didn't set INSTALL_ARGS for me.  The change below to configure.in
should change that, but is untested (I didn't try to regenerate
configure).

   Klaus

* Revived dired "install" functionality, more or less as it was
  (apparently) originally meant to be used, but with various checks
  added.  Compilation is now conditional on new symbol OK_INSTALL.
  The "install" function is the closest we have to a "copy file"
  function, and could be used instead; the actual command executed
  depends on macros INSTALL_PATH and possibly INSTALL_ARGS, one can
  define INSTALL_PATH for example to "/bin/cp" before compilation to
  effectively get something like a dired "copy" function.
  Note the the "install" function requires a special file in the home
  directory, which can be customized, see samples/installdirs.html.
* New function HTURLPath_toFile in HTFile.c.  Use it if we don't have
  a full URL where HTnameOfFile_WWW was used previously, this avoids
  misparsing of some unusual URL forms for files.
* Other changes for dired support:
  - various corrections with respect to URL-unescaping: don't escape
    too often or too little, dired operations could fail on filenames
    with special characters
  - avoid some unnecessary copying and allocation for filenames
  - avoid some more static buffers
  - add some buffer overflow checks
* Make local directory display somewhat interruptible even without
  partial page display.
* Make do_readme in HTFile.c 8-bit clean.
* Tweak in HTTP.c to avoid doing strlen() on received data that are to
  be passed on raw; raw NUL bytes within the first block read could lead
  to data loss.

Index: lynx2-8-3/WWW/Library/Implementation/HTTP.c
--- lynx2-8-3.old/WWW/Library/Implementation/HTTP.c Mon, 21 Jun 1999 00:31:29 
-0500
+++ lynx2-8-3/WWW/Library/Implementation/HTTP.c Mon, 21 Jun 1999 02:24:06 -0500
@@ -117,7 +117,7 @@
   BOOL show_407 = FALSE;
   BOOL auth_proxy = NO;        /* Generate a proxy authorization. - AJL */
 
-  int length, rv;
+  int length, rawlength, rv;
   BOOL doing_redirect, already_retrying = FALSE, bad_location = FALSE;
   int len = 0;
 
@@ -768,6 +768,8 @@
     while (!eol && !end_of_file && bytes_already_read < 100);
   } /* Scope of loop variables */
 
+  /* save total length, in case we decide later to show it all - kw */
+  rawlength = length;
 
   /*   We now have a terminated unfolded line.  Parse it.
   **   --------------------------------------------------
@@ -1462,7 +1464,7 @@
              doing_redirect = FALSE;
              permanent_redirection = FALSE;
              start_of_data = line_kept_clean;
-             length = strlen(start_of_data);
+             length = rawlength;
              if (!bad_location) {
                  HTAlert(gettext("Got redirection with no Location header."));
                  HTProgress(line_buffer);
@@ -1718,7 +1720,7 @@
       **  It was a HEAD request, or we want the headers and source.
       */
       start_of_data = line_kept_clean;
-      length = strlen(start_of_data);
+      length = rawlength;
       format_in = HTAtom_for("text/plain");
   }
 
Index: lynx2-8-3/WWW/Library/Implementation/HTFile.h
--- lynx2-8-3.old/WWW/Library/Implementation/HTFile.h Fri, 04 Jun 1999 20:11:44 
-0500
+++ lynx2-8-3/WWW/Library/Implementation/HTFile.h Mon, 21 Jun 1999 00:42:34 
-0500
@@ -42,6 +42,7 @@
 /*
 **  Convert filenames between local and WWW formats
 */
+extern char * HTURLPath_toFile PARAMS((CONST char * name, BOOL expand_all));
 extern char * HTnameOfFile_WWW PARAMS((CONST char * name, BOOL WWW_prefix, 
BOOL expand_all));
 #define HTLocalName(name)      HTnameOfFile_WWW(name,TRUE,TRUE)
 #define HTfullURL_toFile(name) HTnameOfFile_WWW(name,FALSE,TRUE)
Index: lynx2-8-3/WWW/Library/Implementation/HTFile.c
--- lynx2-8-3.old/WWW/Library/Implementation/HTFile.c Mon, 21 Jun 1999 00:31:29 
-0500
+++ lynx2-8-3/WWW/Library/Implementation/HTFile.c Mon, 21 Jun 1999 00:43:20 
-0500
@@ -558,6 +558,50 @@
 }
 #endif /* NOT_IMPLEMENTED */
 
+/*     Convert filename from URL-path syntax to local path format
+**     ----------------------------------------------------------
+**     Input name is assumed to be the URL-path of a local file
+**      URL, i.e. what comes after the "file://localhost".
+**      '#'-fragments to be treated as such must already be stripped.
+**      If expand_all is FALSE, unescape only escaped '/'. - kw
+**
+**  On exit:
+**     Returns a malloc'ed string which must be freed by the caller.
+*/
+PUBLIC char * HTURLPath_toFile ARGS2(
+       CONST char *,   name,
+       BOOL,           expand_all)
+{
+    char * path = NULL;
+    char * result = NULL;
+
+    StrAllocCopy(path, name);
+    if (expand_all)
+       HTUnEscape(path);               /* Interpret all % signs */
+    else
+       HTUnEscapeSome(path, "/");      /* Interpret % signs for path delims */
+
+    CTRACE(tfp, "URLPath `%s' means path `%s'\n", name, path);
+#ifdef DOSPATH
+    StrAllocCopy(result, HTDOS_name(path));
+#else
+#ifdef __EMX__
+    if (path[0] == '/'
+       && isalpha(path[1])
+       && path[2] == ':') /* pesky leading slash */
+       StrAllocCopy(result, path+1);
+    else
+       StrAllocCopy(result, path);
+    CTRACE(tfp, "EMX hack changed `%s' to `%s'\n", path, result);
+#else
+    StrAllocCopy(result, path);
+#endif /* __EMX__ */
+#endif /* DOSPATH */
+
+    FREE(path);
+
+    return result;
+}
 /*     Convert filenames between local and WWW formats.
 **     ------------------------------------------------
 **     Make up a suitable name for saving the node in
@@ -568,6 +612,11 @@
 **  On exit:
 **     Returns a malloc'ed string which must be freed by the caller.
 */
+/* NOTE: Don't use this function if you know that the input is a URL path
+        rather than a full URL, use HTURLPath_toFile instead.  Otherwise
+        this function will return the wrong thing for some unusual
+        paths (like ones containing "//", possibly escaped). - kw
+*/
 PUBLIC char * HTnameOfFile_WWW ARGS3(
        CONST char *,   name,
        BOOL,           WWW_prefix,
@@ -579,9 +628,9 @@
     char * home;
     char * result = NULL;
 
-    if (expand_all)
+    if (expand_all) {
        HTUnEscape(path);               /* Interpret all % signs */
-    else
+    } else
        HTUnEscapeSome(path, "/");      /* Interpret % signs for path delims */
 
     if (0 == strcmp(acc_method, "file")        /* local file */
@@ -1193,9 +1242,9 @@
 **  On exit:
 **     Returns TRUE if an "Up to <parent>" link was not created
 **     for a readable local directory because LONG_LIST is defined
-**     and NO_PARENT_DIR_REFERENCE is not defined, such that the
-**     calling function use LYListFmtParse() to create a link to
-**     the parent directory.  Otherwise, it returns FALSE. - FM
+**     and NO_PARENT_DIR_REFERENCE is not defined, so that the
+**     calling function should use LYListFmtParse() to create a link
+**     to the parent directory.  Otherwise, it returns FALSE. - FM
 */
 PUBLIC BOOL HTDirTitles ARGS3(
        HTStructured *, target,
@@ -1211,7 +1260,7 @@
 
 #ifdef DOSPATH
     BOOL local_link = FALSE;
-    if (logical[18] == ':') local_link = TRUE;
+    if (strlen(logical) > 18 && logical[18] == ':') local_link = TRUE;
 #endif
     /*
     ** Check tildeIsTop for treating home directory as Welcome
@@ -1246,10 +1295,11 @@
       char * printable = NULL;
 
 #ifdef DIRED_SUPPORT
-      printable = HTfullURL_toFile(
+      printable = HTURLPath_toFile(
            (0 == strncasecomp(path, "/%2F", 4))        /* "//" ? */
            ? (path+1)
-           : path);
+           : path,
+           TRUE);
       if (0 == strncasecomp(printable, "/vmsysu:", 8) ||
          0 == strncasecomp(printable, "/anonymou.", 10)) {
          StrAllocCopy(cp, (printable+1));
@@ -1441,8 +1491,8 @@
        targetClass =  *target->isa;    /* (Can't init agregate in K&R) */
        START(HTML_PRE);
        for (;;){
-           char c = fgetc(fp);
-           if (c == (char)EOF) break;
+           int c = fgetc(fp);
+           if (c == EOF) break;
 #ifdef NOTDEFINED
            switch (c) {
                case '&':
@@ -1458,10 +1508,10 @@
                        PUTC('\r');
 Bug removed thanks to address@hidden */
                default:
-                       PUTC(c);
+                       PUTC((char)c);
            }
 #else
-           PUTC(c);
+           PUTC((char)c);
 #endif /* NOTDEFINED */
        }
        END(HTML_PRE);
@@ -1652,7 +1702,7 @@
        {
            HTBTElement * next_element = HTBTree_next(bt,NULL);
                /* pick up the first element of the list */
-           int num_of_entries_partial = 0; /* lines counter */
+           int num_of_entries_output = 0; /* lines counter */
 
            char state;
                /* I for initial (.. file),
@@ -1667,19 +1717,28 @@
            while (next_element != NULL) {
                char *entry, *file_extra;
 
+#ifndef DISP_PARTIAL
+               if (num_of_entries_output % HTMAX(display_lines,10) == 0) {
+                   if (HTCheckForInterrupt()) {
+                       _HTProgress ("Data transfer interrupted.");
+                       status = HT_PARTIAL_CONTENT;
+                       break;
+                   }
+               }
+#endif
                StrAllocCopy(tmpfilename,localname);
                if (strcmp(localname, "/"))
                    /*
                    **  If filename is not root directory.
                    */
-                   StrAllocCat(tmpfilename, "/");
+                   LYAddHtmlSep(&tmpfilename);
 
-               StrAllocCat(tmpfilename,
-                           (char *)HTBTree_object(next_element)+1);
+               entry = (char*)HTBTree_object(next_element)+1;
                /*
                **  Append the current entry's filename
                **  to the path.
                */
+               StrAllocCat(tmpfilename, entry);
                HTSimplify(tmpfilename);
                /*
                **  Output the directory entry.
@@ -1753,7 +1812,6 @@
                    START(HTML_LI);
 #endif /* !LONG_LIST */
                }
-               entry = (char*)HTBTree_object(next_element)+1;
                file_extra = NULL;
 
 #ifdef LONG_LIST
@@ -1777,10 +1835,10 @@
 
                /* optimize for expensive operation: */
 #ifdef DISP_PARTIAL
-               if (num_of_entries_partial %
+               if (num_of_entries_output %
                    (partial_threshold > 0 ? partial_threshold : display_lines)
                    == 0) {
-                   /* num_of_entries, num_of_entries_partial... */
+                   /* num_of_entries, num_of_entries_output... */
                    /* HTReadProgress...(bytes, 0); */
                    HTDisplayPartial();
 
@@ -1790,7 +1848,7 @@
                        break;
                    }
                }
-               num_of_entries_partial++;
+               num_of_entries_output++;
 #endif /* DISP_PARTIAL */
 
            } /* end while next_element */
@@ -2131,7 +2189,7 @@
        FREE(filename);
     }
 
-#else /* Unix: */
+#else /* not VMS: */
 
     FREE(filename);
 
Index: lynx2-8-3/src/LYLocal.c
--- lynx2-8-3.old/src/LYLocal.c Mon, 21 Jun 1999 00:31:29 -0500
+++ lynx2-8-3/src/LYLocal.c Mon, 21 Jun 1999 00:53:00 -0500
@@ -82,6 +82,10 @@
 #define EXT_Z      ".Z"
 #endif
 
+#ifndef DIRED_MAXBUF
+#define DIRED_MAXBUF 512
+#endif
+
 PRIVATE int LYExecv PARAMS((
        char *          path,
        char **         argv,
@@ -91,6 +95,15 @@
 PUBLIC char LYPermitFileURL[LY_MAXPATH] = "\0";
 PUBLIC char LYDiredFileURL[LY_MAXPATH] = "\0";
 
+#ifdef OK_INSTALL
+PUBLIC char LYInstallFileURL[LY_MAXPATH] = "\0";
+#ifdef FNAMES_8_3
+#define INSTALLDIRS_FILE "instdirs.htm"
+#else
+#define INSTALLDIRS_FILE ".installdirs.html"
+#endif /* FNAMES_8_3 */
+#endif /* OK_INSTALL */
+
 PRIVATE char *get_filename PARAMS((
        char *          prompt,
        char *          buf,
@@ -105,8 +118,8 @@
 
 PRIVATE char *render_item PARAMS((
        CONST char *    s,
-       char *          path,
-       char *          dir,
+       CONST char *    path,
+       CONST char *    dir,
        char *          buf,
        int             bufsize,
        BOOLEAN         url_syntax));
@@ -136,10 +149,17 @@
 { 0,                 "", "New Directory",
 "(in current directory)", "LYNXDIRED://NEW_FOLDER%d",          NULL },
 
+#ifdef OK_INSTALL
 { DE_FILE,           "", "Install",
-"(of current selection)", "LYNXDIRED://INSTALL_SRC%p",         NULL },
+"selected file to new location", "LYNXDIRED://INSTALL_SRC%p",  NULL },
+/* The following (installing a directory) doesn't work for me, at least
+   with the "install" from GNU fileutils 4.0.  I leave it in anyway, in
+   case one compiles with INSTALL_PATH / INSTALL_ARGS defined to some
+   other command for which it works (like a script, or maybe "cp -a"). - kw
+*/
 { DE_DIR,            "", "Install",
-"(of current selection)", "LYNXDIRED://INSTALL_SRC%p",         NULL },
+"selected directory to new location", "LYNXDIRED://INSTALL_SRC%p",     NULL },
+#endif /* OK_INSTALL */
 
 { DE_FILE,           "", "Modify File Name",
 "(of current selection)", "LYNXDIRED://MODIFY_NAME%p",         NULL },
@@ -249,6 +269,11 @@
 { DE_TAG,            "", "Move all tagged items to another location.",
                      "", "LYNXDIRED://MOVE_TAGGED%d",          NULL },
 
+#ifdef OK_INSTALL
+{ DE_TAG,            "", "Install tagged files into another directory.",
+                     "", "LYNXDIRED://INSTALL_SRC%00",         NULL },
+#endif
+
 { DE_TAG,            "", "Remove all tagged files and directories.",
                      "", "LYNXDIRED://REMOVE_TAGGED",          NULL },
 
@@ -259,7 +284,7 @@
                    NULL, NULL,                                 NULL }
 };
 
-PRIVATE BOOLEAN cannot_stat ARGS1(char *, name)
+PRIVATE BOOLEAN cannot_stat ARGS1(CONST char *, name)
 {
     char *tmpbuf = 0;
     HTSprintf(&tmpbuf, gettext("Unable to get status of '%s'."), name);
@@ -268,7 +293,7 @@
     return FALSE;
 }
 
-PRIVATE BOOLEAN ok_stat ARGS2(char *, name, struct stat*, sb)
+PRIVATE BOOLEAN ok_stat ARGS2(CONST char *, name, struct stat*, sb)
 {
     CTRACE(tfp, "testing ok_stat(%s)\n", name);
     if (stat(name, sb) < 0) {
@@ -300,20 +325,23 @@
     return TRUE;
 }
 
-PRIVATE BOOLEAN ok_localname ARGS2(char*, dst, char*, src)
+#ifdef OK_INSTALL              /* currently only used in local_install */
+PRIVATE BOOLEAN ok_localname ARGS2(char*, dst, CONST char*, src)
 {
-    char *s = HTfullURL_toFile(strip_trailing_slash(src));
     struct stat dir_info;
 
-    if (!ok_stat(s, &dir_info)
+    if (!ok_stat(src, &dir_info)
      || !ok_file_or_dir(&dir_info)) {
-       FREE(s);
        return FALSE;
     }
-    strcpy(dst, s);
-    FREE(s);
+    if (strlen(src) >= DIRED_MAXBUF) {
+       CTRACE(tfp, "filename too long in ok_localname!\n");
+       return FALSE;
+    }
+    strcpy(dst, src);
     return TRUE;
 }
+#endif /* OK_INSTALL */
 
 PRIVATE int move_file ARGS2(char *, source, char *, target)
 {
@@ -437,7 +465,7 @@
     ino_t inode;
     uid_t owner;
     char tmpbuf[1024];
-    char *savepath = NULL;
+    char *savepath;
     char *srcpath = NULL;
     struct stat dir_info;
     int count = 0;
@@ -471,21 +499,28 @@
            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 (testpath == NULL) {
            /*
             *  Get the directory containing the file or subdir.
             */
-           cp = HTfullURL_toFile(strip_trailing_slash(cp));
-           savepath = HTParse(".", cp, PARSE_PATH+PARSE_PUNCTUATION);
+           if (cp) {
+               cp = strip_trailing_slash(cp);
+               cp = HTParse(".", cp, PARSE_PATH+PARSE_PUNCTUATION);
+               savepath = HTURLPath_toFile(cp, TRUE);
+               FREE(cp);
+           } else {    /* Last resort, should never happen. */
+               savepath = HTURLPath_toFile(".", TRUE);
+           }
        } else {
-           cp = HTfullURL_toFile(cp);
-           StrAllocCopy(savepath, cp);
+           if (!strncmp(cp, "file://localhost", 16)) {
+               cp += 16;
+           } else if (!strncmp(cp, "file:", 5)) {
+               cp += 5;
+           }
+           savepath = HTURLPath_toFile(cp, TRUE);
        }
-       FREE(cp);
 
        if (!ok_stat(savepath, &dir_info)) {
            FREE(savepath);
@@ -556,8 +591,7 @@
             *  Move all tagged items to the target location.
             */
            while ((cp = (char *)HTList_nextObject(tag)) != NULL) {
-               cp = HTfullURL_toFile(cp);
-               StrAllocCopy(srcpath, cp);
+               srcpath = HTfullURL_toFile(cp);
 
                if (move_file(srcpath, savepath) < 0) {
                    FREE(cp);
@@ -565,7 +599,7 @@
                        count = -1;
                    break;
                }
-               FREE(cp);
+               FREE(srcpath);
                ++count;
            }
            clear_tags();
@@ -584,9 +618,9 @@
        char *,         testpath)
 {
     char *cp;
-    char tmpbuf[512];
-    char newpath[512];
-    char savepath[512];
+    char tmpbuf[DIRED_MAXBUF];
+    char newpath[DIRED_MAXBUF];
+    char savepath[DIRED_MAXBUF];
     struct stat dir_info;
 
     /*
@@ -642,8 +676,8 @@
     ino_t inode;
     uid_t owner;
     char tmpbuf[1024];
-    char newpath[512];
-    char savepath[512];
+    char newpath[DIRED_MAXBUF];
+    char savepath[DIRED_MAXBUF];
     struct stat dir_info;
 
     /*
@@ -725,15 +759,14 @@
 {
     int c, ans;
     char *cp;
-    char testpath[512]; /* a bit ridiculous */
+    char testpath[DIRED_MAXBUF]; /* a bit ridiculous */
     int count;
 
     if (!HTList_isEmpty(tagged)) {
        cp = HTpartURL_toFile(doc->address);
-       strcpy(testpath, cp);
-       FREE(cp);
 
-       count = modify_tagged(testpath);
+       count = modify_tagged(cp);
+       FREE(cp);
 
        if (doc->link > (nlinks-count - 1))
            doc->link = (nlinks-count - 1);
@@ -762,6 +795,10 @@
 
     if (strchr("NLP", ans) != NULL) {
        cp = HTfullURL_toFile(links[doc->link].lname);
+       if (strlen(cp) >= DIRED_MAXBUF) {
+           FREE(cp);
+           return 0;
+       }
        strcpy(testpath, cp);
        FREE(cp);
 
@@ -794,8 +831,8 @@
        char *,         current_location)
 {
     int code = FALSE;
-    char tmpbuf[512];
-    char testpath[512];
+    char tmpbuf[DIRED_MAXBUF];
+    char testpath[DIRED_MAXBUF];
     char *args[5];
     char *bad_chars = ".~/";
 
@@ -842,8 +879,8 @@
        char *,         current_location)
 {
     int code = FALSE;
-    char tmpbuf[512];
-    char testpath[512];
+    char tmpbuf[DIRED_MAXBUF];
+    char testpath[DIRED_MAXBUF];
     char *args[5];
     char *bad_chars = ".~/";
 
@@ -888,16 +925,20 @@
 {
     int c, ans;
     char *cp;
-    char testpath[512];
-
-    _statusline(gettext("Create file or directory (f or d): "));
-    c = LYgetch();
-    ans = TOUPPER(c);
+    char testpath[DIRED_MAXBUF];
 
     cp = HTfullURL_toFile(doc->address);
+    if (strlen(cp) >= DIRED_MAXBUF) {
+       FREE(cp);
+       return 0;
+    }
     strcpy(testpath,cp);
     FREE(cp);
 
+    _statusline(gettext("Create file or directory (f or d): "));
+    c = LYgetch();
+    ans = TOUPPER(c);
+
     if (ans == 'F') {
        return(create_file(testpath));
     } else if (ans == 'D') {
@@ -980,7 +1021,7 @@
        document *,     doc)
 {
     char *cp, *tp;
-    char testpath[512];
+    char testpath[DIRED_MAXBUF];
     int count, i;
 
     if (!HTList_isEmpty(tagged)) {
@@ -996,6 +1037,10 @@
     cp = links[doc->link].lname;
     if (is_url(cp) == FILE_URL_TYPE) {
        tp = HTfullURL_toFile(cp);
+       if (strlen(tp) >= DIRED_MAXBUF) {
+           FREE(tp);
+           return 0;
+       }
        strcpy(testpath, tp);
        FREE(tp);
 
@@ -1058,22 +1103,19 @@
         *  Create form.
         */
        FILE *fp0;
-       char local_src[LY_MAXPATH];
        char * user_filename;
        char * group_name;
 
-       cp = HTfullURL_toFile(strip_trailing_slash(srcpath));
-       strcpy(local_src, cp);
-       FREE(cp);
+       srcpath = strip_trailing_slash(srcpath);
 
        /*
         *  A couple of sanity tests.
         */
-       if (!ok_lstat(local_src, &dir_info)
+       if (!ok_lstat(srcpath, &dir_info)
         || !ok_file_or_dir(&dir_info))
            return 0;
 
-       user_filename = LYPathLeaf(local_src);
+       user_filename = LYPathLeaf(srcpath);
 
        LYRemoveTemp(tempfile);
        if ((fp0 = LYOpenTemp(tempfile, HTML_SUFFIX, "w")) == NULL) {
@@ -1089,7 +1131,7 @@
 
        group_name = HTAA_GidToName (dir_info.st_gid);
        LYstrncpy(LYValidPermitFile,
-                 local_src,
+                 srcpath,
                  (sizeof(LYValidPermitFile) - 1));
 
        fprintf(fp0, "<Html><Head>\n<Title>%s</Title>\n</Head>\n<Body>\n",
@@ -1194,10 +1236,14 @@
        *cp++ = '\0';   /* Null terminate file name and
                           start working on the masks. */
 
-       if ((destpath = HTfullURL_toFile(destpath)) == 0)
+       /* Will now operate only on filename part. */
+       if ((destpath = HTURLPath_toFile(destpath, TRUE)) == 0)
                return(0);
-
-       strcpy(tmpdst, destpath);       /* operate only on filename */
+       if (strlen(destpath) >= LY_MAXPATH) {
+           FREE(destpath);
+           return(0);
+       }
+       strcpy(tmpdst, destpath);
        FREE(destpath);
        destpath = tmpdst;
 
@@ -1428,15 +1474,19 @@
     } else if (!strncmp(line, "LYNXDIRED://NEW_FOLDER", 22)) {
        if (create_directory(&line[22]) > 0)
            LYforce_no_cache = TRUE;
+#ifdef OK_INSTALL
     } else if (!strncmp(line, "LYNXDIRED://INSTALL_SRC", 23)) {
        local_install(NULL, &line[23], &tp);
-       StrAllocCopy(doc->address, tp);
-       FREE(tp);
+       if (tp) {
+           FREE(doc->address);
+           doc->address = tp;
+       }
        FREE(line);
        return 0;
     } else if (!strncmp(line, "LYNXDIRED://INSTALL_DEST", 24)) {
        local_install(&line[24], NULL, &tp);
        LYpop(doc);
+#endif /* OK_INSTALL */
     } else if (!strncmp(line, "LYNXDIRED://MODIFY_NAME", 23)) {
        if (modify_name(&line[23]) > 0)
        LYforce_no_cache = TRUE;
@@ -1449,13 +1499,14 @@
 #ifdef OK_PERMIT
     } else if (!strncmp(line, "LYNXDIRED://PERMIT_SRC", 22)) {
        permit_location(NULL, &line[22], &tp);
-       if (tp)
+       if (tp) {
            /*
             *  One of the checks may have failed.
             */
-           StrAllocCopy(doc->address, tp);
+           FREE(doc->address);
+           doc->address = tp;
+       }
        FREE(line);
-       FREE(tp);
        return 0;
     } else if (!strncmp(line, "LYNXDIRED://PERMIT_LOCATION", 27)) {
        permit_location(&line_url[27], NULL, &tp);
@@ -1646,11 +1697,11 @@
        char **,        newfile)
 {
     static char tempfile[LY_MAXPATH];
-    char path[512], dir[512]; /* much too large */
+    char *path;
+    char *dir;
     lynx_html_item_type *nxt;
     struct stat dir_info;
     FILE *fp0;
-    char *cp = NULL;
     char *dir_url;
     char *path_url;
     BOOLEAN nothing_tagged;
@@ -1670,26 +1721,23 @@
     LYLocalFileToURL(newfile, tempfile);
     strcpy(LYDiredFileURL, *newfile);
 
-    cp = HTpartURL_toFile(doc->address);
-    strcpy(dir, cp);
-    LYTrimPathSep(dir);
-    FREE(cp);
-
     if (doc->link > -1 && doc->link < (nlinks+1)) {
-       cp = HTfullURL_toFile(links[doc->link].lname);
-       strcpy(path, cp);
+       path = HTfullURL_toFile(links[doc->link].lname);
        LYTrimPathSep(path);
-       FREE(cp);
 
        if (!ok_lstat(path, &dir_info)) {
            LYCloseTempFP(fp0);
+           FREE(path);
            return 0;
        }
 
     } else {
-       path[0] = '\0';
+       StrAllocCopy(path, "");
     }
 
+    dir = HTfullURL_toFile(doc->address);
+    LYTrimPathSep(dir);
+
     nothing_tagged = (HTList_isEmpty(tagged));
 
     BeginInternalPage(fp0, DIRED_MENU_TITLE, DIRED_MENU_HELP);
@@ -1778,6 +1826,7 @@
        FREE(dir_url);
        FREE(path_url);
     }
+    FREE(path);
 
     if (uploaders != NULL) {
        fprintf(fp0, "<p>Upload to current directory:<p>\n");
@@ -1789,6 +1838,7 @@
                    count, dir, nxt->name);
        }
     }
+    FREE(dir);
 
     EndInternalPage(fp0);
     LYCloseTempFP(fp0);
@@ -1831,6 +1881,72 @@
     return buf;
 }
 
+#ifdef OK_INSTALL
+
+#define LYEXECV_MAX_ARGC 15
+/* these are quasi-constant once they have been allocated: */
+static char ** install_argp = NULL;    /* args for execv install */
+static char * install_path = NULL;     /* auxiliary */
+#ifdef LY_FIND_LEAKS
+PRIVATE void clear_install_path NOARGS
+{
+    FREE(install_argp);
+    FREE(install_path);
+}
+#endif /* LY_FIND_LEAKS */
+/*
+ *  Fill in args array for execv (or execvp etc.) call, after first
+ *  allocating it if necessary.  No fancy parsing, cmd_args is just
+ *  split at spaces.  Leave room for reserve additional args to be
+ *  added by caller.
+ *  On success *argvp points to new args vector, *pathp is auxiliary.
+ *  On success returns index of next argument, else -1.
+ *  This is generic enough that it could be used for other calls than
+ *  install, except the atexit call.  Go through this trouble for install
+ *  because INSTALL_ARGS may be significant, and someone may configure it
+ *  with more than one significant flags. - kw
+ */
+PRIVATE int fill_argv_for_execv ARGS5(
+    char ***,          argvp,
+    char **,           pathp,
+    char *,            cmd_path,
+    CONST char *,      cmd_args,
+    int,               reserve)
+{
+    int n = 0;
+
+    char **args;
+    char *cp;
+    if (*argvp == NULL) {
+       *argvp = (char **)calloc(LYEXECV_MAX_ARGC+1, sizeof(char *));
+       if (!*argvp)
+           return(-1);
+#ifdef LY_FIND_LEAKS
+       atexit(clear_install_path);
+#endif
+    }
+    args = *argvp;
+    args[n++] = cmd_path;
+    if (cmd_args) {
+       StrAllocCopy(*pathp, cmd_args);
+       cp = strtok(*pathp, " ");
+       if (cp) {
+           while (cp && (n < LYEXECV_MAX_ARGC - reserve)) {
+               args[n++] = cp;
+               cp = strtok(NULL, " ");
+           }
+           if (cp && (n >= LYEXECV_MAX_ARGC - reserve)) {
+               CTRACE(tfp, "Too many args for '%s' in '%s'!\n",
+                      cmd_path ? cmd_path : "<null>" , cmd_args);
+               return(-1);
+           }
+       } else {
+           args[n++] = *pathp;
+       }
+    }
+    args[n] = (char *)0;
+    return(n);
+}
 /*
  *  Install the specified file or directory.
  */
@@ -1840,71 +1956,173 @@
        char **,        newpath)
 {
     char *tmpbuf = NULL;
-    char savepath[512]; /* This will be the link that is to be installed. */
+    static char savepath[DIRED_MAXBUF]; /* This will be the link that
+                                          is to be installed. */
     struct stat dir_info;
-    char *args[6];
+    char **args;
     HTList *tag;
+    char *cp = NULL;
+    char *tmpdest = NULL;
     int count = 0;
-    int n = 0, src;    /* indices into 'args[]' */
+    int n = 0;         /* indices into 'args[]' */
+    static int src = -1;
 
     /*
      * Determine the status of the selected item.
      */
     if (srcpath) {
-       if (!ok_localname(savepath, srcpath))
+       srcpath = strip_trailing_slash(srcpath);
+       if (is_url(srcpath)) {
+           char *local_src = HTfullURL_toFile(srcpath);
+           if (!ok_localname(savepath, local_src)) {
+               FREE(local_src);
+               return 0;
+           }
+           FREE(local_src);
+       } else if (!HTList_isEmpty(tagged) &&
+                  srcpath[0] == '\0') {
+           savepath[0] = '\0'; /* will always use tagged list - kw */
+       } else if (!ok_localname(savepath, srcpath)) {
            return 0;
-
+       }
        LYforce_no_cache = TRUE;
        LYLocalFileToURL(newpath, Home_Dir());
-       StrAllocCat(*newpath, "/.installdirs.html");
+       LYAddHtmlSep(newpath);
+       StrAllocCat(*newpath, INSTALLDIRS_FILE);
+       LYstrncpy(LYInstallFileURL,
+                 *newpath,
+                 (sizeof(LYInstallFileURL) - 1));
        return 0;
     }
 
+    /* deal with ~/ or /~/ at the beginning - kw */
+    if (destpath[0] == '~' &&
+       (destpath[1] == '/' || destpath[1] == '\0')) {
+       cp = &destpath[1];
+    } else if (destpath[0] == '/' && destpath[1] == '~' &&
+              (destpath[2] == '/' || destpath[2] == '\0')) {
+       cp = &destpath[2];
+    }
+    if (cp) {
+       /* If found, allocate new string, make destpath point to it - kw */
+       StrAllocCopy(tmpdest, Home_Dir());
+       if (cp[0] && cp[1]) {
+           LYAddPathSep(&tmpdest);
+           StrAllocCat(tmpdest, cp + 1);
+       }
+       destpath = tmpdest;
+    }
+
     destpath = strip_trailing_slash(destpath);
 
     if (!ok_stat(destpath, &dir_info)) {
+       FREE(tmpdest);
        return 0;
     } else if (!S_ISDIR(dir_info.st_mode)) {
        HTAlert(gettext("The selected item is not a directory!  Request 
ignored."));
+       FREE(tmpdest);
        return 0;
     } else if (0 /*directory not writable*/) {
        HTAlert(gettext("Install in the selected directory not permitted."));
+       FREE(tmpdest);
        return 0;
     }
 
     statusline(gettext("Just a moment, ..."));
-    args[n++] = "install";
+
+    /* fill in the fixed args, if not already done - kw */
+    if (src > 0 && install_argp) {
+       n = src;
+       n++;
+    } else {
+       n = fill_argv_for_execv(&install_argp, &install_path,
+                               "install",
 #ifdef INSTALL_ARGS
-    args[n++] = INSTALL_ARGS;
+                               INSTALL_ARGS,
+#else
+                               NULL,
 #endif /* INSTALL_ARGS */
-    src = n++;
+                               2);
+       if (n <= 0) {
+           src = 0;
+           HTAlert(gettext("Error buiding install args"));
+           FREE(tmpdest);
+           return 0;
+       }
+       src = n++;
+    }
+    args = install_argp;
+
     args[n++] = destpath;
     args[n] = (char *)0;
-    HTSprintf(&tmpbuf, "install %s", destpath);
     tag = tagged;
 
     if (HTList_isEmpty(tagged)) {
+       /* simplistic detection of identical src and dest - kw */
+       if (!strcmp(savepath, destpath)) {
+           HTUserMsg2(gettext("Source and target are the same: %s"),
+                      savepath);
+           FREE(tmpdest);
+           return(-1);         /* don't do it */
+       } else if (!strncmp(savepath, destpath, strlen(destpath)) &&
+                  LYIsPathSep(savepath[strlen(destpath)]) &&
+#ifdef DOSPATH
+                  !strchr(savepath + strlen(destpath) + 1, '\\') &&
+#endif
+                  !strchr(savepath + strlen(destpath) + 1, '/')) {
+           HTUserMsg2(gettext("Already in target directory: %s"),
+                      savepath);
+           FREE(tmpdest);
+           return 0;           /* don't do it */
+       }
        args[src] = savepath;
-       if (LYExecv(INSTALL_PATH, args, tmpbuf) <= 0)
+       HTSprintf(&tmpbuf, "install %s in %s", savepath, destpath);
+       if (LYExecv(INSTALL_PATH, args, tmpbuf) <= 0) {
+           FREE(tmpbuf);
+           FREE(tmpdest);
            return (-1);
+       }
        count++;
     } else {
        char *name;
+       HTSprintf(&tmpbuf, "install in %s", destpath);
        while ((name = (char *)HTList_nextObject(tag))) {
            int err;
            args[src] = HTfullURL_toFile(name);
+
+           /* simplistic detection of identical src and dest - kw */
+           if (!strcmp(args[src], destpath)) {
+               HTUserMsg2(gettext("Source and target are the same: %s"),
+                          args[src]);
+               FREE(args[src]);
+               continue;       /* skip this source file */
+           } else if (!strncmp(args[src], destpath, strlen(destpath)) &&
+                      LYIsPathSep(args[src][strlen(destpath)]) &&
+#ifdef DOSPATH
+                      !strchr(args[src] + strlen(destpath) + 1, '\\') &&
+#endif
+                      !strchr(args[src] + strlen(destpath) + 1, '/')) {
+               HTUserMsg2(gettext("Already in target directory: %s"),
+                          args[src]);
+               FREE(args[src]);
+               continue;       /* skip this source file */
+           }
            err = (LYExecv(INSTALL_PATH, args, tmpbuf) <= 0);
            FREE(args[src]);
-           if (err)
+           if (err) {
+               FREE(tmpdest);
                return ((count == 0) ? -1 : count);
+           }
            count++;
        }
        clear_tags();
     }
     FREE(tmpbuf);
+    FREE(tmpdest);
     HTInfoMsg(gettext("Installation complete"));
     return count;
 }
+#endif /* OK_INSTALL */
 
 /*
  *  Clear DIRED tags.
@@ -1990,13 +2208,13 @@
  */
 PRIVATE char * render_item ARGS6(
        CONST char *,   s,
-       char *,         path,
-       char *,         dir,
+       CONST char *,   path,
+       CONST char *,   dir,
        char *,         buf,
        int,            bufsize,
        BOOLEAN,        url_syntax)
 {
-    char *cp;
+    CONST char *cp;
     char *bp;
     char overrun = '\0';
     char *taglist = NULL;
@@ -2081,6 +2299,7 @@
     *bp = '\0';
     return buf;
 }
+
 #endif /* DIRED_SUPPORT */
 
 /*
Index: lynx2-8-3/src/LYMainLoop.c
--- lynx2-8-3.old/src/LYMainLoop.c Mon, 21 Jun 1999 00:31:29 -0500
+++ lynx2-8-3/src/LYMainLoop.c Mon, 21 Jun 1999 01:14:04 -0500
@@ -3329,6 +3329,9 @@
                         (strcmp(curdoc.address, LYPermitFileURL) ||
                          strcmp((curdoc.title ? curdoc.title : ""),
                                PERMIT_OPTIONS_TITLE)) &&
+#ifdef OK_INSTALL
+                        strcmp(curdoc.address, LYInstallFileURL) &&
+#endif /* OK_INSTALL */
                         (strcmp(curdoc.address, LYUploadFileURL) ||
                          strcmp((curdoc.title ? curdoc.title : ""),
                                UPLOAD_OPTIONS_TITLE))) ||
@@ -3509,7 +3512,9 @@
                           *  unescaping of other chars. - KW
                           */
                          HTUnEscapeSome(newdoc.address,"/");
-                         strip_trailing_slash(newdoc.address);
+                         /* avoid stripping final slash for root dir - kw */
+                         if (strcasecomp(newdoc.address, "file://localhost/"))
+                             strip_trailing_slash(newdoc.address);
                    }
 #endif /* DIRED_SUPPORT  && !__DJGPP__ */
                    if (!strncmp(curdoc.address, "LYNXCOOKIE:", 11)) {
@@ -4738,12 +4743,12 @@
            }
            break;
 
-#ifdef DIRED_SUPPORT
+#if defined(DIRED_SUPPORT) && defined(OK_INSTALL)
        case LYK_INSTALL:  /* install a file into system area */
            if (lynx_edit_mode && nlinks > 0 && !no_dired_support)
                local_install(NULL, links[curdoc.link].lname, &newdoc.address);
            break;
-#endif /* DIRED_SUPPORT */
+#endif /* DIRED_SUPPORT && OK_INSTALL */
 
        case LYK_INFO:  /* show document info */
            /*
Index: lynx2-8-3/src/LYLocal.h
--- lynx2-8-3.old/src/LYLocal.h Thu, 03 Jun 1999 19:24:44 -0500
+++ lynx2-8-3/src/LYLocal.h Mon, 21 Jun 1999 01:14:52 -0500
@@ -35,11 +35,16 @@
 extern char LYPermitFileURL[];
 extern char LYDiredFileURL[];
 extern char LYUploadFileURL[];
+#ifdef OK_INSTALL
+extern char LYInstallFileURL[];
+#endif
 
 extern BOOLEAN local_create PARAMS((document *doc));
 extern BOOLEAN local_modify PARAMS((document *doc, char **newpath));
 extern BOOLEAN local_remove PARAMS((document *doc));
+#ifdef OK_INSTALL
 extern BOOLEAN local_install PARAMS((char *destpath, char *srcpath, char 
**newpath));
+#endif
 
 /* MainLoop needs to know about this one for atexit cleanup */
 extern void clear_tags NOPARAMS;
Index: lynx2-8-3/configure.in
--- lynx2-8-3.old/configure.in Mon, 21 Jun 1999 00:31:29 -0500
+++ lynx2-8-3/configure.in Mon, 21 Jun 1999 01:15:05 -0500
@@ -224,7 +224,9 @@
        AC_DEFINE_UNQUOTED(INSTALL_PATH,"install")
        ;;
 *) # (vi
-       AC_DEFINE_UNQUOTED(INSTALL_PATH,"$INSTALL")
+       cf_save_INSTALL="$INSTALL"
+       CF_PATH_PROG(INSTALL,   install)
+       INSTALL="$cf_save_INSTALL"
        ;;
 esac
 
Index: lynx2-8-3/lynx.cfg
--- lynx2-8-3.old/lynx.cfg Mon, 21 Jun 1999 00:31:29 -0500
+++ lynx2-8-3/lynx.cfg Mon, 21 Jun 1999 01:15:34 -0500
@@ -1642,7 +1642,7 @@
 # Other codes not listed above may be available for additional keys,
 # depending on operating system and libraries used to compile Lynx.
 # On some systems, if compiled with recent versions of slang or ncurses
-# if macro USE_KEYMAPS was in effect during compilation), an additional
+# (if macro USE_KEYMAPS was in effect during compilation), an additional
 # level of key mapping is supported via an external ".lynx-keymaps" file.
 # This file, if found in the home directory at startup, will always be
 # used under those conditions; see lynx-keymaps distributed in the samples
@@ -1741,6 +1741,8 @@
 #KEYMAP:???:EDITTEXTAREA   # use external editor to edit a form textarea
 #KEYMAP:???:GROWTEXTAREA   # Add some blank lines to bottom of textarea
 #KEYMAP:???:INSERTFILE     # Insert file into a textarea (just above cursor)
+#*** Only useful with dired support and OK_INSTALL: ***
+#KEYMAP:???:INSTALL        # install (i.e. copy) local files to new location
 
 # If TOGGLE_HELP is mapped, in novice mode the second help menu line
 # can be toggled among NOVICE_LINE_TWO_A, _B, and _C, as defined in
@@ -1863,8 +1865,10 @@
 #DIRED_MENU:::New File:(in current directory):LYNXDIRED://NEW_FILE%d
 #DIRED_MENU:::New Directory:(in current directory):LYNXDIRED://NEW_FOLDER%d
 
-#DIRED_MENU:FILE::Install:(of current selection):LYNXDIRED://INSTALL_SRC%p
-#DIRED_MENU:DIR::Install:(of current selection):LYNXDIRED://INSTALL_SRC%p
+# Following depends on OK_INSTALL
+#DIRED_MENU:FILE::Install:selected file to new 
location:LYNXDIRED://INSTALL_SRC%p
+#DIRED_MENU:DIR::Install:selected directory to new 
location:LYNXDIRED://INSTALL_SRC%p
+
 #DIRED_MENU:FILE::Modify File Name:(of current 
selection):LYNXDIRED://MODIFY_NAME%p
 #DIRED_MENU:DIR::Modify Directory Name:(of current 
selection):LYNXDIRED://MODIFY_NAME%p
 #DIRED_MENU:LINK::Modify Name:(of selected symbolic 
link):LYNXDIRED://MODIFY_NAME%p
@@ -1920,6 +1924,10 @@
 #DIRED_MENU:FILE::Compress:(using zip):LYNXDIRED://ZIP%p
 
 #DIRED_MENU:TAG::Move all tagged items to another 
location.::LYNXDIRED://MOVE_TAGGED%d
+
+# Following depends on OK_INSTALL
+#DIRED_MENU:TAG::Install tagged files into another 
directory.::LYNXDIRED://INSTALL_SRC%00
+
 #DIRED_MENU:TAG::Remove all tagged files and 
directories.::LYNXDIRED://REMOVE_TAGGED
 #DIRED_MENU:TAG::Untag all tagged items.::LYNXDIRED://CLEAR_TAGGED
 
Index: lynx2-8-3/docs/README.defines
--- lynx2-8-3.old/docs/README.defines Tue, 08 Jun 1999 10:55:11 -0500
+++ lynx2-8-3/docs/README.defines Mon, 21 Jun 1999 01:16:05 -0500
@@ -59,6 +59,7 @@
 # -DOK_TAR         (see INSTALLATION, Section II-1c)
 # -DOK_UUDECODE    (see INSTALLATION, Section II-1c)
 # -DOK_ZIP         (see INSTALLATION, Section II-1c)
+# -DOK_INSTALL     to enable dired menu "Install" function
 # -DARCHIVE_ONLY   (see INSTALLATION, Section II-1c)
 # -DNO_CHANGE_EXECUTE_PERMS (see INSTALLATION, Section II-1c)
 # -DCANT_EDIT_UNWRITABLE_FILES (see LYEdit.c - always in effect for VMS)
Index: lynx2-8-3/samples/installdirs.html
--- /dev/null Mon, 21 Jun 1999 02:38:37 -0500
+++ lynx2-8-3/samples/installdirs.html Mon, 21 Jun 1999 01:16:09 -0500
@@ -0,0 +1,18 @@
+<HTML>
+<TITLE>File Management Install Targets</TITLE>
+<!-- This is an example file for the Lynx dired "install" functionality.
+     Lynx needs to be compiled with dired support and OK_INSTALL defined.
+     For the dired "install" function to work, this file has to exist
+     in the HOME directory under the name ".installdirs.html" or (for
+     8+3, i.e. DOS-like, filesystems) "instdirs.htm".
+  -->
+<BODY>
+<H1>Install Target directories</H1>
+<UL>
+<LH>Choose destination:</LH>
+<LI><A HREF="LYNXDIRED://INSTALL_DEST/~/">install in Home directory</A>
+<LI><A HREF="LYNXDIRED://INSTALL_DEST/~/bin">install in ~/bin</A>
+<LI><A HREF="LYNXDIRED://INSTALL_DEST/tmp">install in /tmp</A>
+</UL>
+</BODY>
+</HTML>


reply via email to

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