home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume42 / ncftp / patch01 next >
Encoding:
Internet Message Format  |  1994-03-29  |  75.0 KB

  1. From: mgleason@cse.unl.edu (Mike Gleason)
  2. Newsgroups: comp.sources.misc
  3. Subject: v42i018:  ncftp - Alternative User Interface for FTP, Patch01
  4. Date: 29 Mar 1994 14:59:05 -0600
  5. Organization: NCEMRSoft
  6. Sender: kent@sparky.sterling.com
  7. Approved: kent@sparky.sterling.com
  8. Message-ID: <2na4qp$3c1@sparky.sterling.com>
  9. X-Md4-Signature: c5834125dc32c0ed11e7c6b0816f9e53
  10.  
  11. Submitted-by: mgleason@cse.unl.edu (Mike Gleason)
  12. Posting-number: Volume 42, Issue 18
  13. Archive-name: ncftp/patch01
  14. Environment: UNIX, ANSI-C, !SVR4
  15. Patch-To: ncftp: Volume 40, Issue 76-81
  16.  
  17. This is the first official patch to ncftp 1.6.  This patch is a low
  18. priority patch, unless you use the syslog()'ing.  There was a bug which
  19. could cause some transfers not to be logged.  There are a bunch of
  20. minor fixes, and a couple of medium-sized bugs that were fixed; really,
  21. you could probably live without upgrading if you don't feel like going
  22. to the trouble.
  23.  
  24. You need to have the ncftp 1.6.0 sources to apply this patch.
  25. NOTE: this patch includes all the unofficial patches, i.e. everything
  26. between 1.6.1 and 1.6.9.  So after applying this patch you will get
  27. 1.7.0, and NOT 1.6 PL 1, nor 1.6.1.  As a result, this patch won't work
  28. if you try to patch one of the unofficial versions.  In that case, just
  29. ftp the whole 1.7.0 package.
  30.  
  31. There are supposed to be tabs in this patch. Make sure your newsreader isn't
  32. converting them to spaces; if you have problems you may want to check to see
  33. if your 'patch' program can handle munged tabs (like patch -l, perhaps).
  34.  
  35. I'll put up the whole 1.7.0 distribution up for ftp as:
  36.   cse.unl.edu:/pub/mgleason/ncftp/ncftp.tgz
  37. PLEASE don't ftp it during business hours, though.
  38.  
  39.  * v1.6.1 - November 5, 1993.
  40.  *  Checking if we have permission to write over a file to fetch.
  41.  *  A few very minor changes.  BSD no longer trying to use strchr :-)
  42.  *
  43.  * v1.6.2 - December 10, 1993.
  44.  *  Term hack no longer depends on the PASV command (!).  The BROKEN_MEMCPY
  45.  *  problem worked-around.  More wary of symbolic-link recursion.
  46.  *  Fixed local path expander.  Fixed inadvertant flushing of the typeahead
  47.  *  buffer.  Debug mode won't print your password.  Progress meters
  48.  *  no longer goof up when the file is huge.  Added time-remaining to the
  49.  *  Philbar.
  50.  *
  51.  * v1.6.3 - December 28, 1993.  Added a new diagnostic command, memchk,
  52.  *  to print stats from a special malloc library if you used one.
  53.  *  Using SIZE and MDTM when the remote site supports it.  Using a new
  54.  *  set of routines for term (again).
  55.  *
  56.  * v1.6.4 - December 30, 1993.  Fixed rare problem with GetDateAndTime.
  57.  *  confirm() will return true if you're running the init macro. 
  58.  *
  59.  * v1.6.5 - January 6, 1994.  Fixed error with an #ifndef/#endif block having
  60.  *  whitespace before the #.  No longer confirming "ls >file" actions.
  61.  *  Changed echo() to Echo().  AIX 3 uses TERMIOS.
  62.  *
  63.  * v1.6.6 - February 15, 1994.  Prevented scenario of fclosing a NULL FILE *.
  64.  *  Edited term ftp's hookup() a little.  More defs for linux in sys.h.
  65.  *  Not updating a recent entry unless you were fully logged in.
  66.  *
  67.  * v1.6.7 - February 20, 1994.  Using getpwnam() instead of getpwuid().
  68.  *  Supporting WWW paths (i.e. ftp://host.name/path/name).
  69.  *
  70.  * v1.6.8 - March 4, 1994.  Ensuring that tmp files are not public.
  71.  *  Trying harder to get the real hostname, and fixed problem with
  72.  *  disappearing progress meters (both due to T. Lindgren).
  73.  *
  74.  * v1.6.9 - March 11, 1994.  Added DOMAIN_NAME and Solaris CPP symbols.
  75.  *  Better handling of getting the domain name, specifically with SunOS.
  76.  *  BSDi support added.
  77.  *
  78.  * v1.7.0 - March 14, 1994.  More verbose when logging to the system log,
  79.  *  and making sure that syslog() itself is called with a total of 5
  80.  *  or less parameters.  Official patch posted which incorporates all
  81.  *  the fixes to 1.6.0 (i.e. 1.6.1, 1.6.2, ... 1.6.9).
  82.  */
  83. diff -c ./Blurb ../ncftp170/Blurb
  84. *** ./Blurb    Wed Mar 16 18:24:56 1994
  85. --- ../ncftp170/Blurb    Wed Mar 16 19:16:03 1994
  86. ***************
  87. *** 14,24 ****
  88.   man page.
  89.   
  90.   1.6.0 is an "evolutionary" upgrade, which consolidates all the previous
  91. ! patches and adds a little.  1.6, like 1.5 are "interim" versions between
  92.   2.0 which has been suspended indefinitely due to time constraints.
  93.   
  94.   Major changes since 1.5.6:
  95. - -------------------------
  96.   
  97.   * Built-in support for the "term" package, used by Linux, etc.
  98.   
  99. --- 14,23 ----
  100.   man page.
  101.   
  102.   1.6.0 is an "evolutionary" upgrade, which consolidates all the previous
  103. ! patches and adds a little.  1.6 and 1.5 are "interim" versions between
  104.   2.0 which has been suspended indefinitely due to time constraints.
  105.   
  106.   Major changes since 1.5.6:
  107.   
  108.   * Built-in support for the "term" package, used by Linux, etc.
  109.   
  110. ***************
  111. *** 30,36 ****
  112.   
  113.   
  114.   Major changes since 1.0.2:
  115. - -------------------------
  116.   
  117.   * Supports the Getline (input-edit) and GNU Readline command-line
  118.     editing and history libraries.
  119. --- 29,34 ----
  120. diff -c ./README ../ncftp170/README
  121. *** ./README    Wed Mar 16 18:24:47 1994
  122. --- ../ncftp170/README    Wed Mar 16 20:29:09 1994
  123. ***************
  124. *** 78,88 ****
  125.   'make' (but proceed to part C):
  126.   
  127.      Silicon Graphics IRIX
  128. !    AIX
  129.      SINIX
  130. !    Ultrix
  131.      NeXT
  132.      Pyramid OSx
  133.   
  134.   Otherwise you will have to configure ncftp manually.
  135.   
  136. --- 78,89 ----
  137.   'make' (but proceed to part C):
  138.   
  139.      Silicon Graphics IRIX
  140. !    IBM's AIX
  141.      SINIX
  142. !    DEC's Ultrix (well, might need to use -lcursesX instead of -lcurses)
  143.      NeXT
  144.      Pyramid OSx
  145. +    Berkley Software Design, Inc.'s BSDi
  146.   
  147.   Otherwise you will have to configure ncftp manually.
  148.   
  149. ***************
  150. *** 104,110 ****
  151.         The regular 'cc' is not an ANSI compiler.  You could also run
  152.         something like 'ansi2knr' on the sources and hope it works.
  153.         You will probably need to link both the curses and termcap
  154. !       libraries if you use -DCURSES (see below).
  155.   
  156.       Hewlett-Packard HP-UX:  If you have 7.0, you'll need to find
  157.         a copy of <ftp.h> from somewhere (8.0 has it though). Then
  158. --- 105,113 ----
  159.         The regular 'cc' is not an ANSI compiler.  You could also run
  160.         something like 'ansi2knr' on the sources and hope it works.
  161.         You will probably need to link both the curses and termcap
  162. !       libraries if you use -DCURSES (see below).  If you're running
  163. !       Solaris (SunOS 5.x or greater) add -DSolaris to SDEFS.
  164. !       I also needed to add -lnsl -lsocket to LIBS.
  165.   
  166.       Hewlett-Packard HP-UX:  If you have 7.0, you'll need to find
  167.         a copy of <ftp.h> from somewhere (8.0 has it though). Then
  168. ***************
  169. *** 117,124 ****
  170.   
  171.       Linux:  For 'term' support, from what I can tell just add
  172.         the path of 'client.a' to LIBS, and add -DTERM_FTP to SDEFS,
  173. !       to turn on the term specific ftp code.  srivasta@pilgrim.umass.edu
  174. !       supplied the term patch.
  175.         
  176.       SCO Unix:  Add -DSCO324 or -DSCO322 (as appropriate) to SDEFS,
  177.         and -lsocket to LIBS.
  178. --- 120,127 ----
  179.   
  180.       Linux:  For 'term' support, from what I can tell just add
  181.         the path of 'client.a' to LIBS, and add -DTERM_FTP to SDEFS,
  182. !       to turn on the term specific ftp code.  May need to link
  183. !       -lcurses and -ltermcap.
  184.         
  185.       SCO Unix:  Add -DSCO324 or -DSCO322 (as appropriate) to SDEFS,
  186.         and -lsocket to LIBS.
  187. ***************
  188. *** 230,237 ****
  189.   re-compile it with HOSTNAME set to your machine's address, in the
  190.   form of 'machine.xxx.yyy.'
  191.   
  192.   *  (Optional) Add -DSTRICT_PROTOS if your compiler wants function prototypes
  193. ! for all functions, not just non-int-returning ones.
  194.   
  195.   
  196.   Part C.  Program Options:
  197. --- 233,253 ----
  198.   re-compile it with HOSTNAME set to your machine's address, in the
  199.   form of 'machine.xxx.yyy.'
  200.   
  201. + *  (Optional) Add -DHAS_DOMAINNAME if you have the getdomainname()
  202. +    function.
  203. + *  (Optional) If you're having problems with your hostname not being
  204. + full (i.e you have 'yourlogin@machine') all is not lost.  First of all,
  205. + define HAS_DOMAINNAME if you can.  But sometimes getdomainname() doesn't
  206. + work -- instead of giving you the domain name, it returns an empty
  207. + string.  So you can hardcode the domain name by defining DOMAIN_NAME to
  208. + be the domain (i.e. add -DDOMAIN_NAME=\"domain.nam\").  That way, if
  209. + getdomainname doesn't work, the program will have something to fall back
  210. + on.  This problem is common on SunOS/Solaris.
  211.   *  (Optional) Add -DSTRICT_PROTOS if your compiler wants function prototypes
  212. ! for all functions, not just non-int-returning ones.  This is really just
  213. ! handy for debugging during development, so this is not recommended.
  214.   
  215.   
  216.   Part C.  Program Options:
  217. diff -c ./cmds.c ../ncftp170/cmds.c
  218. *** ./cmds.c    Wed Mar 16 18:24:47 1994
  219. --- ../ncftp170/cmds.c    Wed Mar 16 19:16:02 1994
  220. ***************
  221. *** 48,53 ****
  222. --- 48,54 ----
  223.   int                    creating = 0;
  224.   struct macel        macros[MAXMACROS];
  225.   char                *macbuf;            /* holds ALL macros */
  226. + int                    doingInitMacro = 0;    /* TRUE if executing "init" macro. */
  227.   jmp_buf                jabort;
  228.   char                *mname;                /* name of current m* command */
  229.   int                    activemcmd;            /* flag: if != 0, then active multi command */
  230. ***************
  231. *** 77,82 ****
  232. --- 78,84 ----
  233.   extern char                    *altarg, *line, *margv[];
  234.   extern char                    *globchars;
  235.   extern Hostname                hostname;
  236. + extern RemoteSiteInfo        gRmtInfo;
  237.   extern string                progname, pager, anon_password;
  238.   extern string                prompt, version, indataline;
  239.   extern longstring            logfname;
  240. ***************
  241. *** 107,121 ****
  242.   
  243.   
  244.   
  245. ! long GetDateAndSize(char *fName, unsigned long *mod_time)
  246.   {
  247.       char *cp, *np;
  248.       string lsline;
  249. !     long size = 0L;
  250.       int n, v;
  251.       struct lslist *savedh, *savedt;
  252. !     
  253. !     *mod_time = 0;
  254.       v = verbose; verbose = V_QUIET;
  255.       is_ls = 1;
  256.       buffer_only = 1;
  257. --- 109,125 ----
  258.   
  259.   
  260.   
  261. ! long GetDateSizeFromLSLine(char *fName, unsigned long *mod_time)
  262.   {
  263.       char *cp, *np;
  264.       string lsline;
  265. !     long size = SIZE_UNKNOWN;
  266.       int n, v;
  267.       struct lslist *savedh, *savedt;
  268. !     static int depth = 0;
  269. !     depth++;    /* Try to prevent infinite recursion. */
  270. !     *mod_time = MDTM_UNKNOWN;
  271.       v = verbose; verbose = V_QUIET;
  272.       is_ls = 1;
  273.       buffer_only = 1;
  274. ***************
  275. *** 173,189 ****
  276.               /* May be the size of a link to the file, instead of the file. */
  277.               if ((cp = strstr(lsline, " -> ")) != NULL) {
  278.                   /* Yes, it was a link. */
  279. !                 size = GetDateAndSize(cp + 4, mod_time); /* Try the file. */
  280.               }
  281.           }
  282.       }    
  283.   aa:
  284.       return (size);
  285.   }    /* GetDateAndSize */
  286.   
  287.   
  288.   
  289.   
  290.   int _settype(char *typename)
  291.   {
  292.       register struct types    *p;
  293. --- 177,272 ----
  294.               /* May be the size of a link to the file, instead of the file. */
  295.               if ((cp = strstr(lsline, " -> ")) != NULL) {
  296.                   /* Yes, it was a link. */
  297. !                 size = (depth>4) ? SIZE_UNKNOWN :
  298. !                     GetDateAndSize(cp + 4, mod_time);
  299. !                 /* Try the file. */
  300.               }
  301.           }
  302.       }    
  303.   aa:
  304. +     --depth;
  305.       return (size);
  306. + }    /* GetDateSizeFromLSLine */
  307. + /* The caller wanted to know the modification date and size of the remote
  308. +  * file given to us.  We try to get this information by using the SIZE
  309. +  * and MDTM ftp commands, and if that didn't work we try sending the site
  310. +  * a "ls -l <fName>" and try to get that information from the line it
  311. +  * sends us back.  It is possible that we won't be able to determine
  312. +  * either of these, though.
  313. +  */
  314. + long GetDateAndSize(char *fName, unsigned long *mod_time)
  315. + {
  316. +     unsigned long mdtm, ls_mdtm;
  317. +     long size, ls_size;
  318. +     int have_mdtm, have_size;
  319. +     string cmd;
  320. +     size = SIZE_UNKNOWN;
  321. +     mdtm = MDTM_UNKNOWN;
  322. +     if (fName != NULL) {
  323. +         have_mdtm = have_size = 0;
  324. +         if (gRmtInfo.hasSIZE) {
  325. +             (void) Strncpy(cmd, "SIZE ");
  326. +             (void) Strncat(cmd, fName);
  327. +             if (quiet_command(cmd) == 2) {
  328. +                 if (sscanf(reply_string, "%*d %ld", &size) == 1)
  329. +                     have_size = 1;
  330. +             } else if (strncmp(reply_string, "550", (size_t)3) != 0)
  331. +                 gRmtInfo.hasSIZE = 0;
  332. +         }
  333. + #ifndef NO_MKTIME
  334. +         /* We'll need mktime() to un-mangle this. */
  335. +         if (gRmtInfo.hasMDTM) {
  336. +             (void) Strncpy(cmd, "MDTM ");
  337. +             (void) Strncat(cmd, fName);
  338. +             if (quiet_command(cmd) == 2) {
  339. +                 /* Result should look like "213 19930602204445\n" */
  340. +                 mdtm = UnSIZEDate(reply_string);
  341. +                 if (mdtm != MDTM_UNKNOWN)
  342. +                     have_mdtm = 1;
  343. +             } else if (strncmp(reply_string, "550", (size_t)3) != 0)
  344. +                 gRmtInfo.hasMDTM = 0;
  345. +         }
  346. + #endif /* NO_MKTIME */
  347. +         if (!have_mdtm || !have_size)
  348. +             ls_size = GetDateSizeFromLSLine(fName, &ls_mdtm);
  349. +         /* Try to use the information from the real SIZE/MDTM commands if
  350. +          * we could, since some maverick ftp server may be using a non-standard
  351. +          * ls command, and we could parse it wrong.
  352. +          */
  353. +         
  354. +         if (!have_mdtm)
  355. +             mdtm = ls_mdtm;
  356. +         if (!have_size)
  357. +             size = ls_size;
  358. +         dbprintf("Used SIZE: %s;  Used MDTM: %s\n",
  359. +             have_size ? "yes" : "no",
  360. +             have_mdtm ? "yes" : "no"
  361. +         );
  362. +         if (debug > 0) {
  363. +             if (size != SIZE_UNKNOWN)
  364. +                 dbprintf("Size: %ld\n", size);
  365. +             if (mdtm != MDTM_UNKNOWN)
  366. +                 dbprintf("Mdtm: %s\n", ctime((time_t *) &mdtm));
  367. +         }
  368. +     }
  369. +     *mod_time = mdtm;
  370. +     return size;
  371.   }    /* GetDateAndSize */
  372.   
  373.   
  374.   
  375.   
  376.   int _settype(char *typename)
  377.   {
  378.       register struct types    *p;
  379. ***************
  380. *** 225,231 ****
  381.           case TYPE_L: c = 't';
  382.       }
  383.       *tp = c;
  384. !     return (_settype(tp));
  385.   }    /* SetTypeByNumber */
  386.   
  387.   
  388. --- 308,314 ----
  389.           case TYPE_L: c = 't';
  390.       }
  391.       *tp = c;
  392. !     return (c == 0 ? -1 : _settype(tp));
  393.   }    /* SetTypeByNumber */
  394.   
  395.   
  396. ***************
  397. *** 368,373 ****
  398. --- 451,457 ----
  399.       (void) recvrequest ("NLST", tname, pattern, "w");
  400.       verbose = oldverbose;
  401.       ftemp = fopen(tname, "r");
  402. +     (void) chmod(tname, 0600);
  403.       if (ftemp == NULL || FGets(str, ftemp) == NULL) {
  404.           if (NOT_VQUIET)
  405.               (void) printf("%s: no match.\n", pattern);
  406. ***************
  407. *** 563,568 ****
  408. --- 647,654 ----
  409.           errs = 0;
  410.           for (mode = "w", i=1; argv[i] != NULL; i++, mode = "a") {
  411.               result = recvrequest ("NLST", tmpname, argv[i], mode);
  412. +             if (i == 1)
  413. +                 (void) chmod(tmpname, 0600);
  414.               if (result < 0) {
  415.                   fprintf(stderr, "%s: %s.\n",
  416.                       argv[i],
  417. ***************
  418. *** 572,583 ****
  419.                   errs++;
  420.               }
  421.           }
  422.           if (errs == (i - 1)) {
  423.               /* Every pattern was in error, so we can't try anything. */
  424.               (void) unlink(tmpname);        /* Shouldn't be there anyway. */
  425.               return NULL;
  426.           }
  427. -         verbose = oldverbose;
  428.           ftemp = fopen(tmpname, "r");
  429.           if (ftemp == NULL) {
  430.               PERROR("remglob", tmpname);
  431. --- 658,669 ----
  432.                   errs++;
  433.               }
  434.           }
  435. +               verbose = oldverbose;
  436.           if (errs == (i - 1)) {
  437.               /* Every pattern was in error, so we can't try anything. */
  438.               (void) unlink(tmpname);        /* Shouldn't be there anyway. */
  439.               return NULL;
  440.           }
  441.           ftemp = fopen(tmpname, "r");
  442.           if (ftemp == NULL) {
  443.               PERROR("remglob", tmpname);
  444. ***************
  445. *** 736,748 ****
  446.    */
  447.   int lcd(int argc, char **argv)
  448.   {
  449.       if (argc < 2)
  450.           argc++, argv[1] = home;
  451.       if (argc != 2) {
  452.           return USAGE;
  453.       }
  454. !     if (chdir(LocalDotPath(argv[1])) < 0) {
  455. !         PERROR("lcd", argv[1]);
  456.           return CMDERR;
  457.       }
  458.       (void) get_cwd(lcwd, (int) sizeof(lcwd));
  459. --- 822,837 ----
  460.    */
  461.   int lcd(int argc, char **argv)
  462.   {
  463. +     longstring ldir;
  464.       if (argc < 2)
  465.           argc++, argv[1] = home;
  466.       if (argc != 2) {
  467.           return USAGE;
  468.       }
  469. !     (void) Strncpy(ldir, argv[1]);
  470. !     if (chdir(LocalDotPath(ldir)) < 0) {
  471. !         PERROR("lcd", ldir);
  472.           return CMDERR;
  473.       }
  474.       (void) get_cwd(lcwd, (int) sizeof(lcwd));
  475. ***************
  476. *** 952,961 ****
  477.           }
  478.       }
  479.   
  480. ! aa:    if ((strcmp(local, "-") != 0) && (local[0] != '|')) {
  481. !         if (!confirm("Output to local-file: ", local))
  482. !             return CMDERR;
  483. !     }
  484.       is_ls = 1; /* tells getreply() to start saving input to a buffer. */
  485.       (void) Strncpy(str, remote);
  486.       if (lsflags[0] && remote[0])
  487. --- 1041,1047 ----
  488.           }
  489.       }
  490.   
  491. ! aa:
  492.       is_ls = 1; /* tells getreply() to start saving input to a buffer. */
  493.       (void) Strncpy(str, remote);
  494.       if (lsflags[0] && remote[0])
  495. ***************
  496. *** 987,992 ****
  497. --- 1073,1081 ----
  498.   
  499.       old1 = signal (SIGINT, SIG_IGN);
  500.       old2 = signal (SIGQUIT, SIG_IGN);
  501. +     /* This will prevent <defunct> zombie processes. */
  502. +     /* (void) signal(SIGCHLD, SIG_IGN); */
  503.       if ((pid = fork()) == 0) {
  504.           for (pid = 3; pid < 20; pid++)
  505.               (void) close(pid);
  506. ***************
  507. *** 1224,1230 ****
  508.   
  509.       (void) command("QUIT");
  510.       close_streams(0);
  511. !     UpdateRecentSitesList(hostname, cwd);
  512.       hostname[0] = cwd[0] = 0;
  513.       logged_in = connected = 0;
  514.       data = -1;
  515. --- 1313,1320 ----
  516.   
  517.       (void) command("QUIT");
  518.       close_streams(0);
  519. !     if (logged_in)
  520. !         UpdateRecentSitesList(hostname, cwd);
  521.       hostname[0] = cwd[0] = 0;
  522.       logged_in = connected = 0;
  523.       data = -1;
  524. ***************
  525. *** 1437,1442 ****
  526. --- 1527,1533 ----
  527.           (void) printf("'%s' macro not found.\n", argv[1]);
  528.           return USAGE;
  529.       }
  530. +     doingInitMacro = (strcmp(macros[i].mac_name, "init") == 0);
  531.       (void) Strncpy(str, line);
  532.   TOP:
  533.       cp1 = macros[i].mac_start;
  534. ***************
  535. *** 1507,1512 ****
  536. --- 1598,1604 ----
  537.       if (loopflg && ++count < argc) {
  538.           goto TOP;
  539.       }
  540. +     doingInitMacro = 0;
  541.       return NOERR;
  542.   }    /* domacro */
  543.   
  544. ***************
  545. *** 1554,1561 ****
  546.           (void) sprintf(str, "MDTM %s", argv[1]);
  547.           if (command(str) == COMPLETE) {
  548.               int yy, mo, day, hour, min, sec;
  549. !             (void) sscanf(reply_string, "%*s %04d%02d%02d%02d%02d%02d", &yy, &mo,
  550. !                 &day, &hour, &min, &sec);
  551.               /* might want to print this in local time */
  552.               (void) printf("%s\t%02d/%02d/%04d %02d:%02d:%02d GMT\n", argv[1],
  553.                   mo, day, yy, hour, min, sec);
  554. --- 1646,1653 ----
  555.           (void) sprintf(str, "MDTM %s", argv[1]);
  556.           if (command(str) == COMPLETE) {
  557.               int yy, mo, day, hour, min, sec;
  558. !             (void) sscanf(reply_string, "%*s %04d%02d%02d%02d%02d%02d",
  559. !                 &yy, &mo, &day, &hour, &min, &sec);
  560.               /* might want to print this in local time */
  561.               (void) printf("%s\t%02d/%02d/%04d %02d:%02d:%02d GMT\n", argv[1],
  562.                   mo, day, yy, hour, min, sec);
  563. ***************
  564. *** 1623,1628 ****
  565. --- 1715,1726 ----
  566.            } else {
  567.                if (*host->h_name)
  568.                    (void) Strncpy(lasthostname, host->h_name);
  569. +             for (j=0; host->h_aliases[j] != NULL; j++) {
  570. +                 if (strlen(host->h_aliases[j]) >
  571. +                     strlen(host->h_name) &&
  572. +                     strstr(host->h_aliases[j],host->h_name) != NULL)
  573. +                         (void) Strncpy(lasthostname,host->h_aliases[j]);
  574. +             }
  575.               if (NOT_VQUIET) {
  576.                   (void) printf("%-32s  ", *host->h_name ? host->h_name : "???");
  577.                   if (*host->h_addr_list) {
  578. ***************
  579. *** 1649,1664 ****
  580.   {
  581.       int oldv, r;
  582.       char *argv[2];
  583. - #ifdef HAS_DOMAINNAME
  584.       char domain[64];
  585. - #endif
  586.   
  587.   #ifdef HOSTNAME
  588.       (void) strncpy(host, HOSTNAME, size);
  589.       return NOERR;
  590.   #else
  591. !     *host = 0;
  592.       if ((r = gethostname(host, size)) == 0) {
  593.           oldv = verbose;
  594.           verbose = V_QUIET;
  595.           argv[0] = "lookup";
  596. --- 1747,1766 ----
  597.   {
  598.       int oldv, r;
  599.       char *argv[2];
  600.       char domain[64];
  601.   
  602.   #ifdef HOSTNAME
  603.       (void) strncpy(host, HOSTNAME, size);
  604.       return NOERR;
  605.   #else
  606. !     host[0] = '\0';
  607.       if ((r = gethostname(host, size)) == 0) {
  608. +         if (host[0] == '\0') {
  609. +             (void) fprintf(stderr,
  610. + "Could not determine the hostname. Re-compile with HOSTNAME defined\n\
  611. + to be the full name of your hostname.\n");
  612. +             exit(1);
  613. +         }
  614.           oldv = verbose;
  615.           verbose = V_QUIET;
  616.           argv[0] = "lookup";
  617. ***************
  618. *** 1666,1679 ****
  619.           (void) makeargv();
  620.           if (lookup(margc, margv) == 0 && lasthostname[0]) {
  621.               (void) _Strncpy(host, lasthostname, size);
  622.   #ifdef HAS_DOMAINNAME
  623.               if (index(host, '.') == NULL) {
  624. !                 if (getdomainname(domain + 1, sizeof(domain) - 1) == 0) {
  625. !                     domain[0] = '.';
  626.                       (void) _Strncat(host, domain, size);
  627.                   }
  628.               }
  629. - #endif
  630.           }
  631.           verbose = oldv;
  632.       }
  633. --- 1768,1807 ----
  634.           (void) makeargv();
  635.           if (lookup(margc, margv) == 0 && lasthostname[0]) {
  636.               (void) _Strncpy(host, lasthostname, size);
  637. +             domain[0] = '\0';
  638.   #ifdef HAS_DOMAINNAME
  639. +             /* getdomainname() returns just the domain name, without a
  640. +              * preceding period.  For example, on "cse.unl.edu", it would
  641. +              * return "unl.edu".
  642. +              *
  643. +              * SunOS note: getdomainname will return an empty string if
  644. +              * this machine isn't on NIS.
  645. +              */
  646. +             (void) getdomainname(domain, sizeof(domain) - 1);
  647. + #endif
  648. + #ifdef DOMAIN_NAME
  649. +             if (domain[0] == '\0')
  650. +                 (void) Strncpy(domain, DOMAIN_NAME);
  651. + #endif
  652.               if (index(host, '.') == NULL) {
  653. !                 /* If the hostname has periods we'll assume that the
  654. !                  * it includes the domain name already.  Some gethostname()s
  655. !                  * return the whole host name, others just the machine name.
  656. !                  * If we have just the machine name and we successfully
  657. !                  * found out the domain name (from above), we'll append
  658. !                  * the domain to the machine to get a full hostname.
  659. !                  */
  660. !                 if (domain[0]) {
  661. !                     (void) _Strncat(host, ".", size);
  662.                       (void) _Strncat(host, domain, size);
  663. +                 } else {
  664. +                     fprintf(stderr,
  665. + "WARNING: could not determine full host name (have: '%s').\n\
  666. + The program should be re-compiled with DOMAIN_NAME defined to be the\n\
  667. + domain name, i.e. -DDOMAIN_NAME=\\\"unl.edu\\\"\n\n",
  668. +                         host);
  669.                   }
  670.               }
  671.           }
  672.           verbose = oldv;
  673.       }
  674. ***************
  675. *** 1797,1802 ****
  676. --- 1925,1936 ----
  677.   #ifdef HAS_DOMAINNAME
  678.       DStrs[nDStrs++] = "HAS_DOMAINNAME";
  679.   #endif
  680. + #ifdef DOMAIN_NAME
  681. +     DStrs[nDStrs++] = "DOMAIN_NAME";
  682. + #endif
  683. + #ifdef Solaris
  684. +     DStrs[nDStrs++] = "Solaris";
  685. + #endif
  686.   #ifdef HOSTNAME
  687.       DStrs[nDStrs++] = "HOSTNAME";
  688.   #endif
  689. ***************
  690. *** 1985,1990 ****
  691. --- 2119,2172 ----
  692.           (void) Signal(SIGPIPE, oldintp);
  693.       return NOERR;
  694.   }    /* ShowLineBuffer */
  695. + #if LIBMALLOC != LIBC_MALLOC
  696. + /*ARGSUSED*/
  697. + int MallocStatusCmd(int argc, char **argv)
  698. + {
  699. + #if (LIBMALLOC == FAST_MALLOC)
  700. +     struct mallinfo mi;
  701. +     mi = mallinfo();
  702. +     printf("\
  703. + total space in arena:               %d\n\
  704. + number of ordinary blocks:          %d\n\
  705. + number of small blocks:             %d\n\
  706. + number of holding blocks:           %d\n\
  707. + space in holding block headers:     %d\n\
  708. + space in small blocks in use:       %d\n\
  709. + space in free small blocks:         %d\n\
  710. + space in ordinary blocks in use:    %d\n\
  711. + space in free ordinary blocks:      %d\n\
  712. + cost of enabling keep option:       %d\n",
  713. +         mi.arena,
  714. +         mi.ordblks,
  715. +         mi.smblks,
  716. +         mi.hblks,
  717. +         mi.hblkhd,
  718. +         mi.usmblks,
  719. +         mi.fsmblks,
  720. +         mi.uordblks,
  721. +         mi.fordblks,
  722. +         mi.keepcost
  723. +     );
  724. + #else
  725. + #if (LIBMALLOC == DEBUG_MALLOC)
  726. +     printf("malloc_chain_check: %d\n\n", malloc_chain_check(0));
  727. +     if (argc > 1)
  728. +         malloc_dump(1);
  729. +     printf("malloc_inuse: %lu\n", malloc_inuse(NULL));
  730. + #else
  731. +     printf("Nothing to report.\n");
  732. + #endif    /* (LIBMALLOC == DEBUG_MALLOC) */
  733. + #endif    /* (LIBMALLOC == FAST_MALLOC) */
  734. +     return (0);
  735. + }    /* MallocStatusCmd */
  736. + #endif    /* LIBMALLOC */
  737.   
  738.   
  739.   
  740. diff -c ./cmds.h ../ncftp170/cmds.h
  741. *** ./cmds.h    Wed Mar 16 18:24:56 1994
  742. --- ../ncftp170/cmds.h    Wed Mar 16 19:16:02 1994
  743. ***************
  744. *** 26,31 ****
  745. --- 26,35 ----
  746.   
  747.   #define LS_FLAGS_AND_FILE '\1'
  748.   
  749. + /* Possible values returned by GetDateAndTime. */
  750. + #define SIZE_UNKNOWN (-1L)
  751. + #define MDTM_UNKNOWN (0L)
  752.   /* Command result codes. */
  753.   #define USAGE (88)
  754.   #define NOERR (0)
  755. ***************
  756. *** 112,118 ****
  757. --- 116,124 ----
  758.   int show_version(int argc, char **argv);
  759.   void PurgeLineBuffer(void);
  760.   int ShowLineBuffer(int argc, char **argv);
  761. + int MallocStatusCmd(int argc, char **argv);
  762.   int unimpl(int argc, char **argv);
  763. + long GetDateSizeFromLSLine(char *fName, unsigned long *mod_time);
  764.   long GetDateAndSize(char *fName, unsigned long *mod_time);
  765.   int SetTypeByNumber(int i);
  766.   
  767. diff -c ./cmdtab.c ../ncftp170/cmdtab.c
  768. *** ./cmdtab.c    Wed Mar 16 18:24:57 1994
  769. --- ../ncftp170/cmdtab.c    Wed Mar 16 19:16:02 1994
  770. ***************
  771. *** 84,90 ****
  772.       -r     : \"Redial\" until connected.\n\
  773.       -d N   : Redial, pausing N seconds between tries.\n\
  774.       -g N   : Redial, giving up after N tries.\n\
  775. !     :path  : Open site, then retrieve file \"path.\""
  776.   
  777.   #define PAGEHELP "view a file on the remote host with your $PAGER"
  778.   #define PAGEUSAGE REMOTEFILE
  779. --- 84,91 ----
  780.       -r     : \"Redial\" until connected.\n\
  781.       -d N   : Redial, pausing N seconds between tries.\n\
  782.       -g N   : Redial, giving up after N tries.\n\
  783. !     :path  : Open site, then retrieve file \"path.\"  WWW-style paths are\n\
  784. !              also acceptable, i.e. 'ftp://cse.unl.edu/mgleason/README.'"
  785.   
  786.   #define PAGEHELP "view a file on the remote host with your $PAGER"
  787.   #define PAGEUSAGE REMOTEFILE
  788. ***************
  789. *** 161,166 ****
  790. --- 162,171 ----
  791.       { "mdelete",          1,  0,  mdelete,
  792.           "deletes multiple files on the remote host", REMOTEFILES  },
  793.       { "mdir",             1,  1,  ls, LSHELP, LSUSAGE },
  794. + #if LIBMALLOC != LIBC_MALLOC
  795. +     { "memchk",        0,  0,  MallocStatusCmd,
  796. +         "show debugging information about memory usage.", EMPTYSTR },
  797. + #endif
  798.       { "mget",             1,  0,  mget,
  799.           "fetches multiple files from the remote host", REMOTEFILES },
  800.       { "mkdir",            1,  0,  makedir,
  801. diff -c ./ftp.c ../ncftp170/ftp.c
  802. *** ./ftp.c    Wed Mar 16 18:24:49 1994
  803. --- ../ncftp170/ftp.c    Wed Mar 16 19:16:02 1994
  804. ***************
  805. *** 54,63 ****
  806.   #include "defaults.h"
  807.   #include "copyright.h"
  808.   
  809. - #ifdef TERM_FTP
  810. - extern int compress_toggle;
  811. - #endif
  812.   /* ftp.c globals */
  813.   struct                sockaddr_in hisctladdr;
  814.   struct                sockaddr_in data_addr;
  815. --- 54,59 ----
  816. ***************
  817. *** 87,93 ****
  818.   
  819.   /* ftp.c externs */
  820.   extern FILE                    *logf;
  821. ! extern string                cwd, anon_password;
  822.   extern Hostname                hostname;
  823.   extern int                    verbose, debug, macnum, margc;
  824.   extern int                    curtype, creating, toatty;
  825. --- 83,90 ----
  826.   
  827.   /* ftp.c externs */
  828.   extern FILE                    *logf;
  829. ! extern string                anon_password;
  830. ! extern longstring            cwd, lcwd;
  831.   extern Hostname                hostname;
  832.   extern int                    verbose, debug, macnum, margc;
  833.   extern int                    curtype, creating, toatty;
  834. ***************
  835. *** 107,115 ****
  836.   #endif
  837.   
  838.   #ifdef TERM_FTP
  839. ! #include "client.h"
  840.   extern int lcompression, rcompression;
  841.   int compress_toggle = 0;
  842.   #endif
  843.   
  844.   
  845. --- 104,113 ----
  846.   #endif
  847.   
  848.   #ifdef TERM_FTP
  849. ! #include <term/client.h>
  850.   extern int lcompression, rcompression;
  851.   int compress_toggle = 0;
  852. + extern int compress_toggle;
  853.   #endif
  854.   
  855.   
  856. ***************
  857. *** 117,162 ****
  858.   
  859.   int hookup(char *host, unsigned int port)
  860.   {
  861. !       int s;
  862.   
  863. !       lcompression = rcompression = compress_toggle;
  864.   
  865. !       if ((s = connect_server(0)) < 0) {
  866. !           perror("ftp: connect to term server");
  867. !           return -1;
  868. !       }
  869. !       send_command(s, C_PORT, 0, "%s:%d", host, ntohs(port));
  870. !       send_command(s, C_DUMB, 1, 0);
  871.   
  872. !       cin = fdopen(s, "r");
  873. !       cout = fdopen(s, "w");
  874. !       if (cin == NULL || cout == NULL) {
  875. !               fprintf(stderr, "ftp: fdopen failed.\n");
  876. !               if (cin)
  877. !                       fclose(cin);
  878. !               if (cout)
  879. !                       fclose(cout);
  880. !               code = -1;
  881. !               goto bad;
  882. !       }
  883. !       Strncpy(hostname, host);
  884. !       if (verbose)
  885. !               printf("Connected to %s.\n", hostname);
  886. !       if (getreply(0) > 2) {  /* read startup message from server */
  887. !               if (cin)
  888. !                       fclose(cin);
  889. !               if (cout)
  890. !                       fclose(cout);
  891. !               code = -1;
  892. !               goto bad;
  893. !       }
  894. !       return 0;
  895.   bad:
  896. !       (void) close(s);
  897. !       return code;
  898. ! }
  899. ! #else
  900.   
  901.   int hookup(char *host, unsigned int port)
  902.   {
  903.       register struct hostent *hp = 0;
  904. --- 115,160 ----
  905.   
  906.   int hookup(char *host, unsigned int port)
  907.   {
  908. !     int s;
  909. !     int result = -1;
  910.   
  911. !     lcompression = rcompression = compress_toggle;
  912.   
  913. !     if ((s = connect_server(0)) < 0) {
  914. !         perror("ftp: connect to term server");
  915. !         goto ret;
  916. !     }
  917. !     send_command(s, C_PORT, 0, "%s:%d", host, ntohs(port));
  918. !     send_command(s, C_DUMB, 1, 0);
  919.   
  920. !     cin = fdopen(s, "r");
  921. !     cout = fdopen(dup(s), "w");
  922. !     if (cin == NULL || cout == NULL) {
  923. !         fprintf(stderr, "ftp: fdopen failed.\n");
  924. !         goto bad;
  925. !     }
  926. !     Strncpy(hostname, host);
  927. !     if (verbose)
  928. !         printf("Connected to %s.\n", hostname);
  929. !     if (getreply(0) > 2) {               /* read startup message from server */
  930. !         goto bad;
  931. !     }
  932. !     result = 0;
  933. !     goto ret;
  934.   bad:
  935. !     (void) close(s);
  936. !     if (cin != NULL)
  937. !         (void) fclose(cin);
  938. !     if (cout != NULL)
  939. !         (void) fclose(cout);
  940. !     cin = cout = NULL;
  941.   
  942. + ret:
  943. +     return (result);
  944. + }                                       /* hookup_term */
  945. + #else    /* Not TERM_FTP, i.e. most of us. */
  946.   int hookup(char *host, unsigned int port)
  947.   {
  948.       register struct hostent *hp = 0;
  949. ***************
  950. *** 238,244 ****
  951.           goto bad;
  952.       }
  953.       cin = fdopen(s, "r");
  954. !     cout = fdopen(s, "w");
  955.       if (cin == NULL || cout == NULL) {
  956.           (void) fprintf(stderr, "ftp: fdopen failed.\n");
  957.           close_streams(0);
  958. --- 236,242 ----
  959.           goto bad;
  960.       }
  961.       cin = fdopen(s, "r");
  962. !     cout = fdopen(dup(s), "w");
  963.       if (cin == NULL || cout == NULL) {
  964.           (void) fprintf(stderr, "ftp: fdopen failed.\n");
  965.           close_streams(0);
  966. ***************
  967. *** 268,273 ****
  968. --- 266,275 ----
  969.   
  970.   bad:
  971.       (void) close(s);
  972. +     if (cin != NULL)
  973. +         (void) fclose(cin);
  974. +     if (cout != NULL)
  975. +         (void) fclose(cout);
  976.   done:
  977.       return (hErr);
  978.   }    /* hookup */
  979. ***************
  980. *** 430,437 ****
  981.       Sig_t oldintr;
  982.       string str;
  983.   
  984.       abrtflag = 0;
  985. !     dbprintf("cmd: \"%s\" (length %d)\n", cmd, (int) strlen(cmd));
  986.       if (cout == NULL) {
  987.           (void) sprintf(str, "%s: No control connection for command", cmd);
  988.           PERROR("command", str);
  989. --- 432,449 ----
  990.       Sig_t oldintr;
  991.       string str;
  992.   
  993. +     if (cmd == NULL) {
  994. +         /* Should never happen; bug if it does. */
  995. +         PERROR("command", "NULL command");
  996. +         return (-1);
  997. +     }
  998.       abrtflag = 0;
  999. !     if (debug) {
  1000. !         if (strncmp(cmd, "PASS", (size_t)4) == 0)
  1001. !             dbprintf("cmd: \"PASS ********\"\n");
  1002. !         else
  1003. !             dbprintf("cmd: \"%s\" (length %d)\n", cmd, (int) strlen(cmd));
  1004. !     }
  1005.       if (cout == NULL) {
  1006.           (void) sprintf(str, "%s: No control connection for command", cmd);
  1007.           PERROR("command", str);
  1008. ***************
  1009. *** 438,460 ****
  1010.           return (0);
  1011.       }
  1012.       oldintr = Signal(SIGINT, /* cmdabort */ SIG_IGN);
  1013. ! #ifndef BROKEN_MEMCPY
  1014.       if (cout != NULL)
  1015.           (void) fprintf(cout, "%s\r\n", cmd);
  1016. - #else
  1017. -     {
  1018. -         /*
  1019. -          * The fprintf() above gives me a core-dump in memcpy()...
  1020. -          * This does the trick though...
  1021. -          */
  1022.   
  1023. -         char *p = cmd;
  1024. -         while (*p)
  1025. -             fputc(*p++, cout);
  1026. -         fputc('\r', cout);
  1027. -         fputc('\n', cout);
  1028. -     }
  1029. - #endif /* !SCO324 */
  1030.       (void) fflush(cout);
  1031.       cpend = 1;
  1032.       r = (flags == WAIT_FOR_REPLY) ?
  1033. --- 450,460 ----
  1034.           return (0);
  1035.       }
  1036.       oldintr = Signal(SIGINT, /* cmdabort */ SIG_IGN);
  1037. !     /* Used to have BROKEN_MEMCPY tested here. */
  1038.       if (cout != NULL)
  1039.           (void) fprintf(cout, "%s\r\n", cmd);
  1040.   
  1041.       (void) fflush(cout);
  1042.       cpend = 1;
  1043.       r = (flags == WAIT_FOR_REPLY) ?
  1044. ***************
  1045. *** 490,496 ****
  1046.       register int oldverbose, result;
  1047.       
  1048.       oldverbose = verbose;
  1049. !     verbose = V_QUIET;
  1050.       result = command(cmd);
  1051.       verbose = oldverbose;
  1052.       return (result);
  1053. --- 490,496 ----
  1054.       register int oldverbose, result;
  1055.       
  1056.       oldverbose = verbose;
  1057. !     verbose = debug ? V_VERBOSE : V_QUIET;
  1058.       result = command(cmd);
  1059.       verbose = oldverbose;
  1060.       return (result);
  1061. ***************
  1062. *** 694,700 ****
  1063.   int start_progress(int sending, char *local)
  1064.   {
  1065.       long s;
  1066. !     str32 spec;
  1067.   
  1068.       cur_progress_meter = toatty ? progress_meter : 0;
  1069.       if ((cur_progress_meter > pr_last) || (cur_progress_meter < 0))
  1070. --- 694,700 ----
  1071.   int start_progress(int sending, char *local)
  1072.   {
  1073.       long s;
  1074. !     char spec[64];
  1075.   
  1076.       cur_progress_meter = toatty ? progress_meter : 0;
  1077.       if ((cur_progress_meter > pr_last) || (cur_progress_meter < 0))
  1078. ***************
  1079. *** 723,731 ****
  1080.                   local,
  1081.                   tcap_normal
  1082.               );
  1083. !             barlen = 63;
  1084.               for (s = file_size; s > 0; s /= 10L) barlen--;
  1085. !             (void) sprintf(spec, "      0 %%%ds %%ld bytes.\r", barlen);
  1086.               (void) printf(spec, " ", file_size);
  1087.               goto zz;
  1088.           case pr_dots:
  1089. --- 723,732 ----
  1090.                   local,
  1091.                   tcap_normal
  1092.               );
  1093. !             barlen = 52;
  1094.               for (s = file_size; s > 0; s /= 10L) barlen--;
  1095. !             (void) sprintf(spec, "      0 %%%ds %%ld bytes. ETA: --:--\r",
  1096. !                 barlen);
  1097.               (void) printf(spec, " ", file_size);
  1098.               goto zz;
  1099.           case pr_dots:
  1100. ***************
  1101. *** 734,740 ****
  1102.               (void) printf("%s: ", local);
  1103.           zz:
  1104.               (void) fflush(stdout);
  1105. !             echo(stdin, 0);
  1106.       }    /* end switch */
  1107.       return (cur_progress_meter);
  1108.   }    /* start_progress */
  1109. --- 735,741 ----
  1110.               (void) printf("%s: ", local);
  1111.           zz:
  1112.               (void) fflush(stdout);
  1113. !             Echo(stdin, 0);
  1114.       }    /* end switch */
  1115.       return (cur_progress_meter);
  1116.   }    /* start_progress */
  1117. ***************
  1118. *** 745,752 ****
  1119.   int progress_report(int finish_up)
  1120.   {
  1121.       int size;
  1122. !     long perc;
  1123. !     str32 spec;
  1124.   
  1125.       next_report += xferbufsize;
  1126.       (void) Gettimeofday(&stop);
  1127. --- 746,757 ----
  1128.   int progress_report(int finish_up)
  1129.   {
  1130.       int size;
  1131. !     int perc;
  1132. !     float frac;
  1133. !     char spec[64];
  1134. !     float secsElap;
  1135. !     int secsLeft, minLeft;
  1136. !     struct timeval td;
  1137.   
  1138.       next_report += xferbufsize;
  1139.       (void) Gettimeofday(&stop);
  1140. ***************
  1141. *** 755,775 ****
  1142.               case pr_none:
  1143.                   break;
  1144.               case pr_percent:
  1145. !                 perc = 100L * bytes / file_size;
  1146. !                 if (perc > 100L) perc = 100L;
  1147. !                 (void) printf("\b\b\b\b%3ld%%", perc);
  1148.                   (void) fflush(stdout);
  1149.                   break;
  1150.               case pr_philbar:
  1151. !                 size = (int) ((float)barlen * ((float) (bytes > file_size ?
  1152. !                     file_size : bytes)/file_size));
  1153. !                 (void) sprintf(spec, "%%3ld%%%%  0 %%s%%%ds%%s\r", size);
  1154.                   (void) printf(
  1155.                       spec,
  1156. !                     100L * (bytes > file_size ? file_size : bytes) / file_size,
  1157.                       tcap_reverse,
  1158. !                     " ",
  1159. !                     tcap_normal
  1160.                   );
  1161.                   (void) fflush(stdout);
  1162.                   break;
  1163. --- 760,795 ----
  1164.               case pr_none:
  1165.                   break;
  1166.               case pr_percent:
  1167. !                 perc = (int) (100.0 * (float)bytes / (float)file_size);
  1168. !                 if (perc > 100) perc = 100;
  1169. !                 (void) printf("\b\b\b\b%3d%%", perc);
  1170.                   (void) fflush(stdout);
  1171.                   break;
  1172.               case pr_philbar:
  1173. !                 frac = (float)bytes / (float)file_size;
  1174. !                 if (frac > 1.0)
  1175. !                     frac = 1.0;
  1176. !                 size = (int) ((float)barlen * frac);
  1177. !                 (void) sprintf(spec,
  1178. !                     "%%3d%%%%  0 %%s%%%ds%%s%%%ds %%ld bytes. ETA:%%3d:%%02d\r",
  1179. !                     size, barlen - size);
  1180. !                 perc = (long) (100.0 * frac);
  1181. !                 tvsub(&td, &stop, &start);
  1182. !                 secsElap = td.tv_sec + (td.tv_usec / 1000000.0);
  1183. !                 secsLeft = (int) ((float)file_size / ((float)bytes/secsElap) -
  1184. !                     secsElap + 0.5);
  1185. !                 minLeft = secsLeft / 60;
  1186. !                 secsLeft = secsLeft - (minLeft * 60);
  1187.                   (void) printf(
  1188.                       spec,
  1189. !                     perc,
  1190.                       tcap_reverse,
  1191. !                     "",
  1192. !                     tcap_normal,
  1193. !                     "",
  1194. !                     file_size,
  1195. !                     minLeft,
  1196. !                     secsLeft
  1197.                   );
  1198.                   (void) fflush(stdout);
  1199.                   break;
  1200. ***************
  1201. *** 795,867 ****
  1202.   
  1203.   
  1204.   
  1205.   void end_progress(char *direction, char *local, char *remote)
  1206.   {
  1207. !     struct timeval            td;
  1208. !     float                    s, bs = 0.0;
  1209. !     char                    *cp, *bsstr;
  1210. !     string                    str;
  1211.   
  1212. !     if (bytes <= 0)
  1213. !         return;
  1214. !     (void) progress_report(1);        /* tell progress proc to cleanup. */
  1215.   
  1216. !     tvsub(&td, &stop, &start);
  1217. !     s = td.tv_sec + (td.tv_usec / 1000000.0);
  1218. !     if (s != 0.0)
  1219. !         bs = bytes / s;
  1220. !     if (bs > 1024.0) {
  1221. !         bs /= 1024.0;
  1222. !         bsstr = "K/s.\n";
  1223. !     } else
  1224. !         bsstr = "Bytes/s.\n";
  1225.   
  1226. !     if (NOT_VQUIET) switch(cur_progress_meter) {
  1227. !         case pr_none:
  1228. !         zz:
  1229. !             (void) printf("%s: %ld bytes %s in %.2f seconds, %.2f %s", local, bytes, direction, s, bs, bsstr);
  1230.               break;
  1231. !         case pr_kbytes:
  1232. !         case pr_percent:
  1233. !             (void) printf("%s%ld bytes %s in %.2f seconds, %.2f %s",
  1234. !             cur_progress_meter == pr_kbytes ? "\b\b\b\b\b\b" : "\b\b\b\b",
  1235. !             bytes, direction, s, bs, bsstr);
  1236. !             echo(stdin, 1);
  1237.               break;
  1238. !         case pr_philbar:
  1239. !             (void) printf("\n");
  1240. !             echo(stdin, 1);
  1241. !             goto zz;
  1242. !         case pr_dots:
  1243. !             for (; dots < 10; dots++)
  1244. !                 (void) fputc('.', stdout);
  1245. !             (void) fputc('\n', stdout);
  1246. !             echo(stdin, 1);
  1247. !             goto zz;
  1248.       }
  1249. !     
  1250. !     /* Save transfers to the logfile. */
  1251. !     /* if a simple path is given, try to log the full path */
  1252. !     if (rindex(remote, '/') == NULL && cwd != NULL) {
  1253. !         (void) sprintf(str, "%s/%s", cwd, remote);
  1254. !          cp = str;
  1255. !     } else
  1256. !         cp = remote;
  1257.       if (logf != NULL) {
  1258. !         (void) fprintf(logf, "\t-> \"%s\" %s, %.2f %s", cp, direction, bs, bsstr);
  1259. !     } 
  1260.   #ifdef SYSLOG
  1261. !     if (direction[0] == 'r')
  1262. !         syslog (LOG_INFO, "%s received %s as %s from %s (%ld bytes).",
  1263. !             uinfo.username, cp, local, hostname, bytes);
  1264. !     else
  1265. !         syslog (LOG_INFO, "%s sent %s as %s to %s (%ld bytes).",
  1266. !             uinfo.username, local, cp, hostname, bytes);
  1267. ! #endif
  1268. ! }   /* end_progress */
  1269.   
  1270.   
  1271.   
  1272.   void close_file(FILE **fin, int filetype)
  1273.   {
  1274.       if (*fin != NULL) {
  1275. --- 815,934 ----
  1276.   
  1277.   
  1278.   
  1279.   void end_progress(char *direction, char *local, char *remote)
  1280.   {
  1281. !     struct timeval          td;
  1282. !     float                   s, bs = 0.0;
  1283. !     str32                   bsstr;
  1284. !     int                     doLastReport;
  1285. !     int                        receiving;
  1286. !     longstring              fullRemote, fullLocal;
  1287.   
  1288. !     doLastReport = ((UserLoggedIn()) && (cur_progress_meter != pr_none) &&
  1289. !         (NOT_VQUIET) && (bytes > 0));
  1290.   
  1291. !     receiving = (direction[0] == 'r');
  1292.   
  1293. !     switch(FileType(local)) {
  1294. !         case IS_FILE:
  1295. !             (void) Strncpy(fullLocal, lcwd);
  1296. !             (void) Strncat(fullLocal, "/");
  1297. !             (void) Strncat(fullLocal, local);
  1298.               break;
  1299. !         case IS_PIPE:
  1300. !             doLastReport = 0;
  1301. !             local = Strncpy(fullLocal, local);
  1302.               break;
  1303. !         case IS_STREAM:
  1304. !         default:
  1305. !             doLastReport = 0;
  1306. !             local = Strncpy(fullLocal, receiving ? "stdout" : "stdin");
  1307.       }
  1308. !     if (doLastReport)
  1309. !         (void) progress_report(1);      /* tell progress proc to cleanup. */
  1310. !     tvsub(&td, &stop, &start);
  1311. !     s = td.tv_sec + (td.tv_usec / 1000000.0);
  1312. !     bsstr[0] = '\0';
  1313. !     if (s != 0.0) {
  1314. !         bs = (float)bytes / s;
  1315. !         if (bs > 1024.0)
  1316. !             sprintf(bsstr, "%.2f K/s", bs / 1024.0);
  1317. !         else
  1318. !             sprintf(bsstr, "%.2f Bytes/sec", bs / 1024.0);
  1319. !     }
  1320. !     if (doLastReport) switch(cur_progress_meter) {
  1321. !         case pr_none:
  1322. !         zz:
  1323. !             (void) printf("%s: %ld bytes %s in %.2f seconds, %s.\n",
  1324. !                 local, bytes, direction, s, bsstr);
  1325. !             break;
  1326. !         case pr_kbytes:
  1327. !         case pr_percent:
  1328. !             (void) printf("%s%ld bytes %s in %.2f seconds, %s.\n",
  1329. !             cur_progress_meter == pr_kbytes ? "\b\b\b\b\b\b" : "\b\b\b\b",
  1330. !             bytes, direction, s, bsstr);
  1331. !             Echo(stdin, 1);
  1332. !             break;
  1333. !         case pr_philbar:
  1334. !             (void) printf("\n");
  1335. !             Echo(stdin, 1);
  1336. !             goto zz;
  1337. !         case pr_dots:
  1338. !             for (; dots < 10; dots++)
  1339. !                 (void) fputc('.', stdout);
  1340. !             (void) fputc('\n', stdout);
  1341. !             Echo(stdin, 1);
  1342. !             goto zz;
  1343. !     }
  1344. !     /* Save transfers to the logfile. */
  1345. !     /* if a simple path is given, try to log the full path */
  1346. !     if (*remote != '/') {
  1347. !         (void) Strncpy(fullRemote, cwd);
  1348. !         (void) Strncat(fullRemote, "/");
  1349. !         (void) Strncat(fullRemote, remote);
  1350. !     } else
  1351. !         (void) Strncpy(fullRemote, remote);
  1352.       if (logf != NULL) {
  1353. !         (void) fprintf(logf, "\t-> \"%s\" %s, %s\n",
  1354. !             fullRemote, direction, bsstr);
  1355. !     }
  1356.   #ifdef SYSLOG
  1357. !     {
  1358. !         longstring infoPart1;
  1359.   
  1360. +         /* Some syslog()'s can't take an unlimited number of arguments,
  1361. +          * so shorten our call to syslog to 5 arguments total.
  1362. +          */
  1363. +         Strncpy(infoPart1, uinfo.username);
  1364. +         if (receiving) {
  1365. +             Strncat(infoPart1, " received ");
  1366. +             Strncpy(infoPart1, fullRemote);
  1367. +             Strncat(infoPart1, " as ");
  1368. +             Strncat(infoPart1, fullLocal);
  1369. +             Strncat(infoPart1, " from ");
  1370. +         } else {
  1371. +             Strncat(infoPart1, " sent ");
  1372. +             Strncat(infoPart1, fullLocal);
  1373. +             Strncat(infoPart1, " as ");
  1374. +             Strncat(infoPart1, fullRemote);
  1375. +             Strncat(infoPart1, " to ");
  1376. +         }
  1377. +         Strncat(infoPart1, hostname);
  1378. +         syslog (LOG_INFO, "%s (%ld bytes, %s).", infoPart1, bytes, bsstr);
  1379. +     }
  1380. + #endif  /* SYSLOG */
  1381. + }    /* end_progress */
  1382.   
  1383.   
  1384.   void close_file(FILE **fin, int filetype)
  1385.   {
  1386.       if (*fin != NULL) {
  1387. ***************
  1388. *** 884,890 ****
  1389.       activemcmd = 0;
  1390.       abrtflag = 0;
  1391.       (void) fprintf(stderr, "\nSend aborted.\n");
  1392. !     echo(stdin, 1);
  1393.       longjmp(sendabort, 1);
  1394.   }    /* abortsend */
  1395.   
  1396. --- 951,957 ----
  1397.       activemcmd = 0;
  1398.       abrtflag = 0;
  1399.       (void) fprintf(stderr, "\nSend aborted.\n");
  1400. !     Echo(stdin, 1);
  1401.       longjmp(sendabort, 1);
  1402.   }    /* abortsend */
  1403.   
  1404. ***************
  1405. *** 902,908 ****
  1406.       char                    *mode;
  1407.       register char            *bufp;
  1408.   
  1409. !     dbprintf("cmd: %s;  rmt: %s;  loc: %s.\n", cmd, remote, local);
  1410.       oldintr = NULL;
  1411.       oldintp = NULL;
  1412.       mode = "w";
  1413. --- 969,980 ----
  1414.       char                    *mode;
  1415.       register char            *bufp;
  1416.   
  1417. !     dbprintf("cmd: %s;  rmt: %s;  loc: %s.\n",
  1418. !         cmd,
  1419. !         remote == NULL ? "(null)" : remote,
  1420. !         local == NULL ? "(null)" : local
  1421. !     );
  1422.       oldintr = NULL;
  1423.       oldintp = NULL;
  1424.       mode = "w";
  1425. ***************
  1426. *** 1075,1082 ****
  1427.       (void) Signal(SIGINT, oldintr);
  1428.       if (oldintp)
  1429.           (void) Signal(SIGPIPE, oldintp);
  1430. !     if (do_reports)
  1431. !         end_progress("sent", local, remote);
  1432.   xx:
  1433.       return (result);
  1434.   Abort:
  1435. --- 1147,1153 ----
  1436.       (void) Signal(SIGINT, oldintr);
  1437.       if (oldintp)
  1438.           (void) Signal(SIGPIPE, oldintp);
  1439. !     end_progress("sent", local, remote);
  1440.   xx:
  1441.       return (result);
  1442.   Abort:
  1443. ***************
  1444. *** 1105,1111 ****
  1445.       "\nAborting, please wait...");
  1446.   #endif
  1447.       (void) fflush(stderr);
  1448. !     echo(stdin, 1);
  1449.       longjmp(recvabort, 1);
  1450.   }    /* abortrecv */
  1451.   
  1452. --- 1176,1182 ----
  1453.       "\nAborting, please wait...");
  1454.   #endif
  1455.       (void) fflush(stderr);
  1456. !     Echo(stdin, 1);
  1457.       longjmp(recvabort, 1);
  1458.   }    /* abortrecv */
  1459.   
  1460. ***************
  1461. *** 1141,1146 ****
  1462. --- 1212,1221 ----
  1463.   int AdjustLocalFileName(char *local)
  1464.   {
  1465.       char *dir;
  1466. +     
  1467. +     /* See if the file exists, and if we can overwrite it. */
  1468. +     if ((access(local, 0) == 0) && (access(local, 2) < 0))
  1469. +         goto noaccess;
  1470.   
  1471.       /*
  1472.        * Make sure we are writing to a valid local path.
  1473. ***************
  1474. *** 1473,1479 ****
  1475.   {
  1476.       FILE                        *fout = NULL, *din = NULL;
  1477.       Sig_t                        oldintr = NULL, oldintp = NULL;
  1478. !     int                            oldtype = 0, is_retr;
  1479.       int                            nfnd;
  1480.       char                        msg;
  1481.       struct fd_set                mask;
  1482. --- 1548,1554 ----
  1483.   {
  1484.       FILE                        *fout = NULL, *din = NULL;
  1485.       Sig_t                        oldintr = NULL, oldintp = NULL;
  1486. !     int                            oldtype = -1, is_retr;
  1487.       int                            nfnd;
  1488.       char                        msg;
  1489.       struct fd_set                mask;
  1490. ***************
  1491. *** 1483,1489 ****
  1492.       int                            result = -1;
  1493.   
  1494.       dbprintf("---> cmd: %s;  rmt: %s;  loc: %s;  mode: %s.\n",
  1495. !         cmd, remote, local, mode);
  1496.       is_retr = strcmp(cmd, "RETR") == 0;
  1497.   
  1498.       GetLSRemoteDir(remote, remote_dir);
  1499. --- 1558,1569 ----
  1500.       int                            result = -1;
  1501.   
  1502.       dbprintf("---> cmd: %s;  rmt: %s;  loc: %s;  mode: %s.\n",
  1503. !         cmd,
  1504. !         remote == NULL ? "(null)" : remote,
  1505. !         local == NULL ? "(null)" : local,
  1506. !         mode
  1507. !     );
  1508.       is_retr = strcmp(cmd, "RETR") == 0;
  1509.   
  1510.       GetLSRemoteDir(remote, remote_dir);
  1511. ***************
  1512. *** 1595,1601 ****
  1513.       dbprintf("outfile closed.\n");
  1514.       if (din)
  1515.           (void) fclose(din);
  1516. !     if (do_reports)
  1517.           end_progress("received", local, remote);
  1518.       if (oldintr)
  1519.           (void) Signal(SIGINT, oldintr);
  1520. --- 1675,1681 ----
  1521.       dbprintf("outfile closed.\n");
  1522.       if (din)
  1523.           (void) fclose(din);
  1524. !     if (is_retr)
  1525.           end_progress("received", local, remote);
  1526.       if (oldintr)
  1527.           (void) Signal(SIGINT, oldintr);
  1528. ***************
  1529. *** 1602,1608 ****
  1530.       if (oldintp)
  1531.           (void) Signal(SIGPIPE, oldintp);
  1532.       dbprintf("recvrequest result = %d.\n", result);
  1533. !     ResetOldType(oldtype);
  1534.       return (result);
  1535.   }    /* recvrequest */
  1536.   
  1537. --- 1682,1689 ----
  1538.       if (oldintp)
  1539.           (void) Signal(SIGPIPE, oldintp);
  1540.       dbprintf("recvrequest result = %d.\n", result);
  1541. !     if (oldtype >= 0)
  1542. !         ResetOldType(oldtype);
  1543.       return (result);
  1544.   }    /* recvrequest */
  1545.   
  1546. ***************
  1547. *** 1617,1666 ****
  1548.   
  1549.   #ifdef TERM_FTP
  1550.   
  1551.   /*
  1552. !  * Need to request that the server go into passive mode and
  1553. !  * then get the address and port for the term server to connect to.
  1554.    */
  1555.   int initconn(void)
  1556.   {
  1557. !       int result;
  1558. !       int n[6];
  1559. !       int s;
  1560.   
  1561. !       if (data != -1)
  1562. !               (void) close(data);
  1563. !       result = command("PASV");
  1564. !       if (result == COMPLETE) {
  1565. !               if (sscanf(reply_string, "%*[^(](%d,%d,%d,%d,%d,%d)",
  1566. !                       &n[0], &n[1], &n[2], &n[3], &n[4], &n[5]) != 6) {
  1567. !                       fprintf(stderr, "Cannot parse PASV response: %s\n",
  1568. !                                reply_string);
  1569. !                       return 1;
  1570. !               }
  1571. !               close(data);
  1572. !               lcompression = rcompression = compress_toggle;
  1573. !               if ((s = connect_server(0)) < 0) {
  1574. !                       perror("ftp: connect to term server");
  1575. !                       data = -1;
  1576. !                       return 1;
  1577. !               }
  1578. !               data = s;
  1579. !               send_command(s, C_PORT, 0, "%d.%d.%d.%d:%d",
  1580. !                       n[0], n[1], n[2], n[3], 256*n[4] + n[5]);
  1581. !               send_command(s, C_COMPRESS, 1, "n");
  1582. !               send_command(s, C_DUMB, 1, 0);
  1583. !               return 0;
  1584. !       }
  1585. !       return 1;
  1586. ! }
  1587.   
  1588. ! FILE *
  1589. ! dataconn(lmode)
  1590. !       char *lmode;
  1591.   {
  1592. !       return (fdopen(data, lmode));
  1593. ! }
  1594. ! #else /* TERM_FTP */
  1595.   
  1596.   
  1597.   int initconn(void)
  1598. --- 1698,1749 ----
  1599.   
  1600.   #ifdef TERM_FTP
  1601.   
  1602.   /*
  1603. !  * Need to request that the server go into passive mode and then get the
  1604. !  * address and port for the term server to connect to.
  1605.    */
  1606.   int initconn(void)
  1607.   {
  1608. !     int result;
  1609. !     int n[6];
  1610. !     int s;
  1611.   
  1612. !     if (data != -1)
  1613. !         (void) close(data);
  1614. !     result = command("PASV");
  1615. !     if (result == COMPLETE) {
  1616. !         if (sscanf(reply_string, "%*[^(](%d,%d,%d,%d,%d,%d)",
  1617. !                    &n[0], &n[1], &n[2], &n[3], &n[4], &n[5]) != 6) {
  1618. !             printf("Cannot parse PASV response: %s\n",
  1619. !                    reply_string);
  1620. !             return 1;
  1621. !         }
  1622. !         close(data);
  1623. !         lcompression = rcompression = compress_toggle;
  1624. !         if ((s = connect_server(0)) < 0) {
  1625. !             perror("ftp: connect to term server");
  1626. !             data = -1;
  1627. !             return 1;
  1628. !         }
  1629. !         data = s;
  1630. !         send_command(s, C_PORT, 0, "%d.%d.%d.%d:%d",
  1631. !                      n[0], n[1], n[2], n[3], 256 * n[4] + n[5]);
  1632. !         send_command(s, C_COMPRESS, 1, "n");
  1633. !         send_command(s, C_DUMB, 1, 0);
  1634. !         return 0;
  1635. !     }
  1636. !     return 1;
  1637. ! }                                       /* initconn_term */
  1638.   
  1639. ! FILE *dataconn(char *lmode)
  1640.   {
  1641. !     return (fdopen(data, lmode));
  1642. ! }                                       /* dataconn_term */
  1643. ! #else /* not TERM_FTP */
  1644.   
  1645.   
  1646.   int initconn(void)
  1647. diff -c ./ftprc.c ../ncftp170/ftprc.c
  1648. *** ./ftprc.c    Wed Mar 16 18:24:53 1994
  1649. --- ../ncftp170/ftprc.c    Wed Mar 16 19:16:02 1994
  1650. ***************
  1651. *** 155,164 ****
  1652.   static siteptr FindNetrcSite(char *host)
  1653.   {
  1654.       register siteptr s, s2;
  1655.   
  1656.       /* see if 'host' is in our list of favorite sites (in NETRC). */
  1657.       for (s = firstsite; s != NULL; s2=s->next, s=s2) {
  1658. !         if (strstr(s->name, host) != NULL) {
  1659.               return s;
  1660.           }
  1661.       }
  1662. --- 155,170 ----
  1663.   static siteptr FindNetrcSite(char *host)
  1664.   {
  1665.       register siteptr s, s2;
  1666. +     string str, host2;
  1667.   
  1668. +     (void) Strncpy(host2, host);
  1669. +     StrLCase(host2);
  1670. +     
  1671.       /* see if 'host' is in our list of favorite sites (in NETRC). */
  1672.       for (s = firstsite; s != NULL; s2=s->next, s=s2) {
  1673. !         (void) Strncpy(str, s->name);
  1674. !         StrLCase(str);
  1675. !         if (strstr(str, host2) != NULL) {
  1676.               return s;
  1677.           }
  1678.       }
  1679. ***************
  1680. *** 172,182 ****
  1681.   {
  1682.       register recentsite        *r;
  1683.       register int            i;
  1684.   
  1685.       /* see if 'host' is in our list of favorite sites (in recent-log). */
  1686.       for (i=0; i<nRecents; i++) {
  1687.           r = &recents[i];
  1688. !         if (strstr(r->name, host) != NULL) {
  1689.               return r;
  1690.           }
  1691.       }
  1692. --- 178,194 ----
  1693.   {
  1694.       register recentsite        *r;
  1695.       register int            i;
  1696. +     string                    str, host2;
  1697.   
  1698. +     (void) Strncpy(host2, host);
  1699. +     StrLCase(host2);
  1700.       /* see if 'host' is in our list of favorite sites (in recent-log). */
  1701.       for (i=0; i<nRecents; i++) {
  1702.           r = &recents[i];
  1703. !         (void) Strncpy(str, r->name);
  1704. !         StrLCase(str);
  1705. !         if (strstr(str, host2) != NULL) {
  1706.               return r;
  1707.           }
  1708.       }
  1709. ***************
  1710. *** 203,208 ****
  1711. --- 215,222 ----
  1712.                   if (FGets(str, rfp) == NULL)
  1713.                       break;
  1714.                   (void) RemoveTrailingNewline(str, NULL);
  1715. +                 name[0] = 0;
  1716. +                 offset = 45;
  1717.                   if (sscanf(str, "%s %lu %n",
  1718.                       name,
  1719.                       (unsigned long *) &r->lastcall,
  1720. ***************
  1721. *** 212,218 ****
  1722.                           r->dir = NewString(str + offset);
  1723.                           if (r->dir != NULL)
  1724.                               nRecents++;
  1725. !                         else free(r->name);
  1726.                       }
  1727.                   }
  1728.               }
  1729. --- 226,235 ----
  1730.                           r->dir = NewString(str + offset);
  1731.                           if (r->dir != NULL)
  1732.                               nRecents++;
  1733. !                         else {
  1734. !                             free(r->name);
  1735. !                             r->name = r->dir = NULL;
  1736. !                         }
  1737.                       }
  1738.                   }
  1739.               }
  1740. ***************
  1741. *** 474,480 ****
  1742.                       cp++;
  1743.               } else
  1744.                   continue;
  1745. -             /* if (strstr(cp, host) != NULL) { */
  1746.               if (strncmp(host, cp, strlen(host)) == 0) {
  1747.                   site_found = 1;
  1748.                   while (!isspace(*cp))
  1749. --- 491,496 ----
  1750. diff -c ./getpass.c ../ncftp170/getpass.c
  1751. *** ./getpass.c    Wed Mar 16 18:24:58 1994
  1752. --- ../ncftp170/getpass.c    Wed Mar 16 19:16:02 1994
  1753. ***************
  1754. *** 39,45 ****
  1755.   
  1756.   
  1757.   
  1758. ! void echo(FILE *fp, int on)
  1759.   {
  1760.   #ifndef GETPASS        /* Otherwise just do nothing which is ok. */
  1761.   
  1762. --- 39,45 ----
  1763.   
  1764.   
  1765.   
  1766. ! void Echo(FILE *fp, int on)
  1767.   {
  1768.   #ifndef GETPASS        /* Otherwise just do nothing which is ok. */
  1769.   
  1770. ***************
  1771. *** 91,97 ****
  1772.       }
  1773.       if (tp != NULL) {
  1774.   #ifdef TERMIOS
  1775. !         if (tcsetattr(fd, TCSAFLUSH, tp) < 0)
  1776.               PERROR("echo", "tcsetattr");
  1777.   #else
  1778.   #    ifdef SGTTYB
  1779. --- 91,97 ----
  1780.       }
  1781.       if (tp != NULL) {
  1782.   #ifdef TERMIOS
  1783. !         if (tcsetattr(fd, TCSANOW, tp) < 0)
  1784.               PERROR("echo", "tcsetattr");
  1785.   #else
  1786.   #    ifdef SGTTYB
  1787. ***************
  1788. *** 105,111 ****
  1789.       }
  1790.   
  1791.   #endif    /* GETPASS */
  1792. ! }    /* echo */
  1793.   
  1794.   
  1795.   
  1796. --- 105,111 ----
  1797.       }
  1798.   
  1799.   #endif    /* GETPASS */
  1800. ! }    /* Echo */
  1801.   
  1802.   
  1803.   
  1804. ***************
  1805. *** 136,142 ****
  1806.           outfp = stderr;
  1807.   #endif
  1808.       oldintr = Signal(SIGINT, SIG_IGN);
  1809. !     echo(fp, 0);        /* Turn echoing off. */
  1810.       (void) fputs(promptstr, outfp);
  1811.       (void) rewind(outfp);            /* implied flush */
  1812.       for (p = buf; (ch = getc(fp)) != EOF && ch != '\n';)
  1813. --- 136,142 ----
  1814.           outfp = stderr;
  1815.   #endif
  1816.       oldintr = Signal(SIGINT, SIG_IGN);
  1817. !     Echo(fp, 0);        /* Turn echoing off. */
  1818.       (void) fputs(promptstr, outfp);
  1819.       (void) rewind(outfp);            /* implied flush */
  1820.       for (p = buf; (ch = getc(fp)) != EOF && ch != '\n';)
  1821. ***************
  1822. *** 144,150 ****
  1823.               *p++ = ch;
  1824.       *p = '\0';
  1825.       (void)write(fileno(outfp), "\n", 1);
  1826. !     echo(fp, 1);
  1827.       (void) Signal(SIGINT, oldintr);
  1828.       if (fp != stdin)
  1829.           (void)fclose(fp);
  1830. --- 144,150 ----
  1831.               *p++ = ch;
  1832.       *p = '\0';
  1833.       (void)write(fileno(outfp), "\n", 1);
  1834. !     Echo(fp, 1);
  1835.       (void) Signal(SIGINT, oldintr);
  1836.       if (fp != stdin)
  1837.           (void)fclose(fp);
  1838. diff -c ./getpass.h ../ncftp170/getpass.h
  1839. *** ./getpass.h    Wed Mar 16 18:24:51 1994
  1840. --- ../ncftp170/getpass.h    Wed Mar 16 19:16:03 1994
  1841. ***************
  1842. *** 10,17 ****
  1843.   
  1844.   #define kMaxPassLen 127
  1845.   
  1846.   char *Getpass(char *prompt);
  1847. ! void echo(FILE *fp, int on);
  1848.   
  1849.   #endif    /* _getpass_h_ */
  1850.   
  1851. --- 10,22 ----
  1852.   
  1853.   #define kMaxPassLen 127
  1854.   
  1855. + #ifdef GETPASS
  1856. + extern char *getpass();    /* Use the system supplied getpass. */
  1857. + #else
  1858.   char *Getpass(char *prompt);
  1859. ! #endif
  1860. ! void Echo(FILE *fp, int on);
  1861.   
  1862.   #endif    /* _getpass_h_ */
  1863.   
  1864. diff -c ./main.c ../ncftp170/main.c
  1865. *** ./main.c    Wed Mar 16 18:24:54 1994
  1866. --- ../ncftp170/main.c    Wed Mar 16 19:16:02 1994
  1867. ***************
  1868. *** 7,13 ****
  1869.   
  1870.   #define _main_c_
  1871.   
  1872. ! #define FTP_VERSION "1.6.0 (October 31, 1993)"
  1873.   
  1874.   /* #define BETA 1 */ /* If defined, it prints a little warning message. */
  1875.   
  1876. --- 7,13 ----
  1877.   
  1878.   #define _main_c_
  1879.   
  1880. ! #define FTP_VERSION "1.7.0 (St. Patrick's Day, 1994)"
  1881.   
  1882.   /* #define BETA 1 */ /* If defined, it prints a little warning message. */
  1883.   
  1884. ***************
  1885. *** 404,414 ****
  1886.       extern char                *home;    /* for glob.c */
  1887.       
  1888.       home = uinfo.homedir;    /* for glob.c */
  1889. !     pw = getpwuid(uinfo.uid = getuid());
  1890.       if (pw != NULL) {
  1891.           (void) Strncpy(uinfo.username, pw->pw_name);
  1892.           (void) Strncpy(uinfo.shell, pw->pw_shell);
  1893. !         (void) Strncpy(uinfo.homedir, pw->pw_dir);
  1894.           cp = getenv("MAIL");
  1895.           if (cp == NULL)
  1896.               cp = getenv("mail");
  1897. --- 404,430 ----
  1898.       extern char                *home;    /* for glob.c */
  1899.       
  1900.       home = uinfo.homedir;    /* for glob.c */
  1901. !     pw = NULL;
  1902. ! #ifdef USE_GETPWUID
  1903. !     pw = getpwuid(getuid());
  1904. ! #else
  1905. !     cp = getlogin();
  1906. !     if (cp == NULL) {
  1907. !         cp = getenv("LOGNAME");
  1908. !         if (cp == NULL)
  1909. !             cp = getenv("USER");
  1910. !     }
  1911. !     if (cp != NULL)
  1912. !         pw = getpwnam(cp);
  1913. ! #endif
  1914.       if (pw != NULL) {
  1915. +         uinfo.uid = pw->pw_uid;
  1916.           (void) Strncpy(uinfo.username, pw->pw_name);
  1917.           (void) Strncpy(uinfo.shell, pw->pw_shell);
  1918. !         if ((cp = getenv("HOME")) != NULL)
  1919. !             (void) Strncpy(uinfo.homedir, cp);
  1920. !         else
  1921. !             (void) Strncpy(uinfo.homedir, pw->pw_dir);
  1922.           cp = getenv("MAIL");
  1923.           if (cp == NULL)
  1924.               cp = getenv("mail");
  1925. ***************
  1926. *** 432,437 ****
  1927. --- 448,454 ----
  1928.           PERROR("getuserinfo", "Could not get your passwd entry!");
  1929.           (void) Strncpy(uinfo.shell, "/bin/sh");
  1930.           (void) Strncpy(uinfo.homedir, ".");    /* current directory */
  1931. +         uinfo.uid = 999;
  1932.           if ((cp = getenv("HOME")) != NULL)
  1933.               (void) Strncpy(uinfo.homedir, cp);
  1934.           mail_path[0] = 0;
  1935. diff -c ./ncftp.1 ../ncftp170/ncftp.1
  1936. *** ./ncftp.1    Wed Mar 16 18:24:52 1994
  1937. --- ../ncftp170/ncftp.1    Wed Mar 16 19:16:03 1994
  1938. ***************
  1939. *** 181,187 ****
  1940.   o w
  1941.   .De
  1942.   .PP
  1943. ! might match a site named bowser.nintendo.jp if that site appeared before
  1944.   your entry for wuarchive.wustl.edu.
  1945.   .PP
  1946.   Most of the time we open remote sites anonymously, but
  1947. --- 181,187 ----
  1948.   o w
  1949.   .De
  1950.   .PP
  1951. ! might match a site named bowser.nintendo.co.jp if that site appeared before
  1952.   your entry for wuarchive.wustl.edu.
  1953.   .PP
  1954.   Most of the time we open remote sites anonymously, but
  1955. ***************
  1956. *** 1375,1381 ****
  1957.   Termcap padding is not correctly displayed.
  1958.   .PP
  1959.   There are no such sites named
  1960. ! .I bowser.nintendo.jp
  1961.   or
  1962.   .IR sphygmomanometer.unl.edu .
  1963.   .\"-------
  1964. --- 1375,1381 ----
  1965.   Termcap padding is not correctly displayed.
  1966.   .PP
  1967.   There are no such sites named
  1968. ! .I bowser.nintendo.co.jp
  1969.   or
  1970.   .IR sphygmomanometer.unl.edu .
  1971.   .\"-------
  1972. diff -c ./open.c ../ncftp170/open.c
  1973. *** ./open.c    Wed Mar 16 18:24:53 1994
  1974. --- ../ncftp170/open.c    Wed Mar 16 19:16:02 1994
  1975. ***************
  1976. *** 30,35 ****
  1977. --- 30,36 ----
  1978.   int                    connected = 0;        /* TRUE if connected to server */
  1979.                                           /* If TRUE, set binary each connection. */
  1980.   Hostname            hostname;            /* Name of current host */
  1981. + RemoteSiteInfo        gRmtInfo;
  1982.   #ifdef GATEWAY
  1983.   string                gateway;            /* node name of firewall gateway */
  1984.   string                gate_login;            /* login at firewall gateway */
  1985. ***************
  1986. *** 106,113 ****
  1987.   
  1988.   int GetOpenOptions(int argc, char **argv, OpenOptions *openopt)
  1989.   {
  1990. !     int                    opt;
  1991. !     char                *cp;
  1992.   
  1993.       /* First setup the openopt variables. */
  1994.       InitOpenOptions(openopt);
  1995. --- 107,114 ----
  1996.   
  1997.   int GetOpenOptions(int argc, char **argv, OpenOptions *openopt)
  1998.   {
  1999. !     int                    opt, www;
  2000. !     char                *cp, *hostp, *cpath;
  2001.   
  2002.       /* First setup the openopt variables. */
  2003.       InitOpenOptions(openopt);
  2004. ***************
  2005. *** 180,186 ****
  2006.   Try 'ncftp -m wuarchive.wustl.edu:/README'\n");
  2007.                       goto usage;
  2008.                   }
  2009. !                 break;
  2010.   
  2011.               case 'c':
  2012.                   /* ftpcat mode is only available from your shell command-line,
  2013. --- 181,187 ----
  2014.   Try 'ncftp -m wuarchive.wustl.edu:/README'\n");
  2015.                       goto usage;
  2016.                   }
  2017. !                 /* break; */
  2018.   
  2019.               case 'c':
  2020.                   /* ftpcat mode is only available from your shell command-line,
  2021. ***************
  2022. *** 198,204 ****
  2023.   Try 'ncftp -c wuarchive.wustl.edu:/README > file.'\n");
  2024.                       goto usage;
  2025.                   }
  2026. !                 break;
  2027.                   
  2028.               default:
  2029.               usage:
  2030. --- 199,205 ----
  2031.   Try 'ncftp -c wuarchive.wustl.edu:/README > file.'\n");
  2032.                       goto usage;
  2033.                   }
  2034. !                 /* break; */
  2035.                   
  2036.               default:
  2037.               usage:
  2038. ***************
  2039. *** 221,233 ****
  2040.           /* The user gave us a host to open.
  2041.            *
  2042.            * First, check to see if they gave us a colon-mode path
  2043. !          * along with the hostname.
  2044.            */
  2045. !         if ((cp = index(argv[Optind], ':')) != NULL) {
  2046. !             *cp++ = 0;
  2047. !             (void) Strncpy(openopt->colonmodepath, cp);
  2048.           }    
  2049. !         (void) Strncpy(openopt->hostname, argv[Optind]);
  2050.       }
  2051.       return NOERR;
  2052.   }    /* GetOpenOptions */
  2053. --- 222,267 ----
  2054.           /* The user gave us a host to open.
  2055.            *
  2056.            * First, check to see if they gave us a colon-mode path
  2057. !          * along with the hostname.  We also understand a WWW path,
  2058. !          * like "ftp://bang.nta.no/pub/fm2html.v.0.8.4.tar.Z".
  2059.            */
  2060. !         hostp = argv[Optind];
  2061. !         cpath = NULL;
  2062. !         if ((cp = index(hostp, ':')) != NULL) {
  2063. !             *cp++ = '\0';
  2064. !             cpath = cp;
  2065. !             www = 0;    /* Is 0 or 1, depending on the type of path. */
  2066. !             if ((*cp == '/') && (cp[1] == '/')) {
  2067. !                 /* First make sure the path was intended to be used
  2068. !                  * with ftp and not one of the other URLs.
  2069. !                  */
  2070. !                 if (strcmp(argv[Optind], "ftp")) {
  2071. !                     fprintf(
  2072. !                         stderr,
  2073. !                         "Bad URL '%s' -- WWW paths must be prefixed by 'ftp://'.\n",
  2074. !                         argv[Optind]
  2075. !                     );
  2076. !                     goto usage;
  2077. !                 }
  2078. !                 cp += 2;
  2079. !                 hostp = cp;
  2080. !                 cpath = NULL;    /* It could have been ftp://hostname only. */
  2081. !                 if ((cp = index(hostp, '/')) != NULL) {
  2082. !                     *cp++ = '\0';
  2083. !                     cpath = cp;
  2084. !                 }
  2085. !                 www = 1;
  2086. !             }
  2087. !             if (cpath != NULL) {
  2088. !                 (void) Strncpy(openopt->colonmodepath, www ? "/" : "");
  2089. !                 (void) Strncat(openopt->colonmodepath, cpath);
  2090. !                 dbprintf("Colon-Mode Path = '%s'\n", openopt->colonmodepath);
  2091. !             }
  2092.           }    
  2093. !         (void) Strncpy(openopt->hostname, hostp);
  2094. !         dbprintf("Host = '%s'\n", hostp);
  2095.       }
  2096.       return NOERR;
  2097.   }    /* GetOpenOptions */
  2098. ***************
  2099. *** 586,591 ****
  2100. --- 620,631 ----
  2101.           (void) printf("Closing %s...\n", hostname);
  2102.           (void) disconnect(0, NULL);
  2103.       }
  2104. +     /* Reset the remote info structure for the new site we want to open.
  2105. +      * Assume we have these properties until we discover otherwise.
  2106. +      */
  2107. +     gRmtInfo.hasSIZE = 1;
  2108. +     gRmtInfo.hasMDTM = 1;
  2109.   
  2110.       if ((GetOpenOptions(argc, argv, &openopt) == USAGE) ||
  2111.           (Open(&openopt) == USAGE))
  2112. diff -c ./open.h ../ncftp170/open.h
  2113. *** ./open.h    Wed Mar 16 18:25:04 1994
  2114. --- ../ncftp170/open.h    Wed Mar 16 19:16:03 1994
  2115. ***************
  2116. *** 16,21 ****
  2117. --- 16,26 ----
  2118.       longstring        colonmodepath;
  2119.   } OpenOptions;
  2120.   
  2121. + typedef struct RemoteSiteInfo {
  2122. +     int                hasSIZE;
  2123. +     int                hasMDTM;
  2124. + } RemoteSiteInfo;
  2125.   /* Open modes. */
  2126.   #define openImplicitAnon 1
  2127.   #define openImplicitUser 4
  2128. diff -c ./patchlevel.h ../ncftp170/patchlevel.h
  2129. *** ./patchlevel.h    Wed Mar 16 18:24:55 1994
  2130. --- ../ncftp170/patchlevel.h    Wed Mar 16 19:16:03 1994
  2131. ***************
  2132. *** 178,181 ****
  2133. --- 178,225 ----
  2134.    *  since it wasn't always stripping \n's.  Recent file can now read dir
  2135.    *  names with whitespace.  Opening msg uses a larger buffer, because of
  2136.    *  escape codes.  Philbar now prints K/sec stats.
  2137. +  *
  2138. +  * v1.6.1 - November 5, 1993.
  2139. +  *  Checking if we have permission to write over a file to fetch.
  2140. +  *  A few very minor changes.  BSD no longer trying to use strchr :-)
  2141. +  *
  2142. +  * v1.6.2 - December 10, 1993.
  2143. +  *  Term hack no longer depends on the PASV command (!).  The BROKEN_MEMCPY
  2144. +  *  problem worked-around.  More wary of symbolic-link recursion.
  2145. +  *  Fixed local path expander.  Fixed inadvertant flushing of the typeahead
  2146. +  *  buffer.  Debug mode won't print your password.  Progress meters
  2147. +  *  no longer goof up when the file is huge.  Added time-remaining to the
  2148. +  *  Philbar.
  2149. +  *
  2150. +  * v1.6.3 - December 28, 1993.  Added a new diagnostic command, memchk,
  2151. +  *  to print stats from a special malloc library if you used one.
  2152. +  *  Using SIZE and MDTM when the remote site supports it.  Using a new
  2153. +  *  set of routines for term (again).
  2154. +  *
  2155. +  * v1.6.4 - December 30, 1993.  Fixed rare problem with GetDateAndTime.
  2156. +  *  confirm() will return true if you're running the init macro. 
  2157. +  *
  2158. +  * v1.6.5 - January 6, 1994.  Fixed error with an #ifndef/#endif block having
  2159. +  *  whitespace before the #.  No longer confirming "ls >file" actions.
  2160. +  *  Changed echo() to Echo().  AIX 3 uses TERMIOS.
  2161. +  *
  2162. +  * v1.6.6 - February 15, 1994.  Prevented scenario of fclosing a NULL FILE *.
  2163. +  *  Edited term ftp's hookup() a little.  More defs for linux in sys.h.
  2164. +  *  Not updating a recent entry unless you were fully logged in.
  2165. +  *
  2166. +  * v1.6.7 - February 20, 1994.  Using getpwnam() instead of getpwuid().
  2167. +  *  Supporting WWW paths (i.e. ftp://host.name/path/name).
  2168. +  *
  2169. +  * v1.6.8 - March 4, 1994.  Ensuring that tmp files are not public.
  2170. +  *  Trying harder to get the real hostname, and fixed problem with
  2171. +  *  disappearing progress meters (both due to T. Lindgren).
  2172. +  *
  2173. +  * v1.6.9 - March 11, 1994.  Added DOMAIN_NAME and Solaris CPP symbols.
  2174. +  *  Better handling of getting the domain name, specifically with SunOS.
  2175. +  *  BSDi support added.
  2176. +  *
  2177. +  * v1.7.0 - March 14, 1994.  More verbose when logging to the system log,
  2178. +  *  and making sure that syslog() itself is called with a total of 5
  2179. +  *  or less parameters.  Official patch posted which incorporates all
  2180. +  *  the fixes to 1.6.0 (i.e. 1.6.1, 1.6.2, ... 1.6.9).
  2181.    */
  2182. diff -c ./sys.h ../ncftp170/sys.h
  2183. *** ./sys.h    Wed Mar 16 18:24:59 1994
  2184. --- ../ncftp170/sys.h    Wed Mar 16 19:16:03 1994
  2185. ***************
  2186. *** 32,41 ****
  2187.   #    if !defined(__GNUC__) && !defined(__STDC__) && !defined(SunOverride)
  2188.       ^^^ "You need to use an ANSI C compiler.  Try using gcc or acc." ^^^
  2189.   #    endif
  2190. ! #    define System "SunOS"
  2191. ! #    ifndef RINDEX
  2192. ! #        define RINDEX 1
  2193. ! #    endif
  2194.   #    ifndef TERMIOS
  2195.   #        define TERMIOS 1
  2196.   #    endif
  2197. --- 32,46 ----
  2198.   #    if !defined(__GNUC__) && !defined(__STDC__) && !defined(SunOverride)
  2199.       ^^^ "You need to use an ANSI C compiler.  Try using gcc or acc." ^^^
  2200.   #    endif
  2201. ! #    ifdef Solaris    /* not predefined. */
  2202. ! #        define SYSV 1
  2203. ! #        define System "Solaris"
  2204. ! #    else
  2205. ! #        define System "SunOS"
  2206. ! #        ifndef RINDEX
  2207. ! #            define RINDEX 1
  2208. ! #        endif
  2209. ! #    endif    /* not Solaris */
  2210.   #    ifndef TERMIOS
  2211.   #        define TERMIOS 1
  2212.   #    endif
  2213. ***************
  2214. *** 83,88 ****
  2215. --- 88,94 ----
  2216.   #ifdef _AIX
  2217.   #    define System "AIX 3.x"
  2218.   #    define SYSSELECTH 1
  2219. + #    define TERMIOS 1
  2220.   #endif    /* _AIX */
  2221.   
  2222.   #ifdef SCOXNX
  2223. ***************
  2224. *** 117,123 ****
  2225.   
  2226.   #ifdef linux
  2227.   #    define System "Linux"
  2228. ! /* Anyone want to fill the rest in? */
  2229.   #endif
  2230.   
  2231.   #ifdef ISC
  2232. --- 123,140 ----
  2233.   
  2234.   #ifdef linux
  2235.   #    define System "Linux"
  2236. ! #    ifndef HAS_DOMAINNAME
  2237. ! #        define HAS_DOMAINNAME 1
  2238. ! #    endif
  2239. ! #    ifndef TERMIOS
  2240. ! #        define TERMIOS 1
  2241. ! #    endif
  2242. ! #    ifndef TERMH
  2243. ! #        define TERMH 1
  2244. ! #    endif
  2245. ! #    ifndef SYSV
  2246. ! #        define SYSV 1
  2247. ! #    endif
  2248.   #endif
  2249.   
  2250.   #ifdef ISC
  2251. ***************
  2252. *** 173,179 ****
  2253.   extern int errno;
  2254.   #endif    /* pyr */
  2255.   
  2256. ! #ifdef DYNIXPTX
  2257.   #    define System "Dynix/PTX"
  2258.   #    ifndef SYSV
  2259.   #        define SYSV 1
  2260. --- 190,202 ----
  2261.   extern int errno;
  2262.   #endif    /* pyr */
  2263.   
  2264. ! #ifdef _SEQUENT_
  2265. ! #    if !defined(DYNIXPTX) && !defined(DYNIX)
  2266. ! #        define DYNIXPTX 1
  2267. ! #    endif
  2268. ! #endif
  2269. ! #if DYNIXPTX
  2270.   #    define System "Dynix/PTX"
  2271.   #    ifndef SYSV
  2272.   #        define SYSV 1
  2273. ***************
  2274. *** 321,331 ****
  2275.   #    endif
  2276.   #endif
  2277.   
  2278. ! #ifdef __386BSD__
  2279. ! #    define TERMIOS
  2280.   #    ifndef BSD
  2281. ! #        define BSD
  2282.   #    endif
  2283.   #endif
  2284.   
  2285.   #ifdef BSD
  2286. --- 344,368 ----
  2287.   #    endif
  2288.   #endif
  2289.   
  2290. ! #ifdef __bsdi__
  2291. ! #    define System "BSDi"
  2292.   #    ifndef BSD
  2293. ! #        define BSD 1
  2294.   #    endif
  2295. + #    ifndef SYSSELECTH
  2296. + #        define SYSSELECTH 1
  2297. + #    endif
  2298. + #    ifndef GETCWDSIZET
  2299. + #        define GETCWDSIZET 1
  2300. + #    endif
  2301. + #    ifndef HERROR
  2302. + #        define HERROR 1
  2303. + #    endif
  2304. + #endif    /* BSDi */
  2305. + #ifdef __386BSD__
  2306. + #    define TERMIOS 1
  2307. + #    define NO_CONST 1       /* avoid prototype conflict */
  2308.   #endif
  2309.   
  2310.   #ifdef BSD
  2311. ***************
  2312. *** 340,348 ****
  2313.   #    ifndef SGTTYB
  2314.   #        define SGTTYB
  2315.   #    endif
  2316. - #    ifndef RINDEX
  2317. - #        define RINDEX 1
  2318. - #    endif
  2319.   #endif
  2320.   
  2321.   /*
  2322. --- 377,382 ----
  2323. ***************
  2324. *** 507,511 ****
  2325. --- 541,560 ----
  2326.   extern    int     shutdown(int, int);
  2327.   extern    int     socket(int, int, int);
  2328.   #endif    /* NO_STD_PROTOS */
  2329. + /* This malloc stuff is mostly for our own use. */
  2330. + #define LIBC_MALLOC 0
  2331. + #define FAST_MALLOC 1
  2332. + #define DEBUG_MALLOC 2
  2333. + #ifdef LIBMALLOC
  2334. + #    if LIBMALLOC != LIBC_MALLOC
  2335. +         /* Make sure you use -I to use the malloc.h of choice. */
  2336. + #        include <malloc.h>
  2337. + #    endif
  2338. + #else
  2339. + #    define LIBMALLOC LIBC_MALLOC
  2340. + #endif
  2341. + /* End of personal malloc junk. */
  2342.   
  2343.   /* eof sys.h */
  2344. diff -c ./tips.c ../ncftp170/tips.c
  2345. *** ./tips.c    Wed Mar 16 18:25:00 1994
  2346. --- ../ncftp170/tips.c    Wed Mar 16 19:16:02 1994
  2347. ***************
  2348. *** 76,83 ****
  2349.   
  2350.       "This program is pronounced Nik-F-T-P.  NCEMRSoft is Nik'-mer-soft.",
  2351.   
  2352. -     "Never pick Nebraska to win a big game.",
  2353.   #ifdef GETLINE
  2354.       "NcFTP was compiled with the Getline command-line/history editor! (by\n\
  2355.        Chris Thewalt <thewalt@ce.berkeley.edu>).  To activate it, use the up\n\
  2356. --- 76,81 ----
  2357. ***************
  2358. *** 92,98 ****
  2359.   #endif
  2360.   
  2361.       "You can get the newest version of NcFTP from cse.unl.edu, in the\n\
  2362. !      /pub/mgleason directory.",
  2363.   
  2364.       "The type of progress-meter that will be used depends if the remote host\n\
  2365.        supports the SIZE command, and whether your terminal is capable of ANSI\n\
  2366. --- 90,96 ----
  2367.   #endif
  2368.   
  2369.       "You can get the newest version of NcFTP from cse.unl.edu, in the\n\
  2370. !      /pub/mgleason/ncftp directory, AFTER business hours.",
  2371.   
  2372.       "The type of progress-meter that will be used depends if the remote host\n\
  2373.        supports the SIZE command, and whether your terminal is capable of ANSI\n\
  2374. ***************
  2375. *** 105,110 ****
  2376. --- 103,112 ----
  2377.       "Don't put a site in your .ncftprc unless you want an 'init' macro.  The \n\
  2378.        recent-file saves sites with the last directory you were in, unlike \n\
  2379.        the rc file, while still letting you use sitename abbreviations.",
  2380. +     "You can use World Wide Web style paths instead of colon-mode paths.\n\
  2381. +      For example, if the colon-mode path was 'cse.unl.edu:pub/mgleason/ncftp,'\n\
  2382. +      the WWW-style path would be 'ftp://cse.unl.edu/pub/mgleason/ncftp.'",
  2383.   
  2384.       "Sick and tired of these tips?  Put '#unset tips' in your .ncftprc."
  2385.   };
  2386. diff -c ./util.c ../ncftp170/util.c
  2387. *** ./util.c    Wed Mar 16 18:24:50 1994
  2388. --- ../ncftp170/util.c    Wed Mar 16 19:16:02 1994
  2389. ***************
  2390. *** 40,46 ****
  2391.   
  2392.   /* Util.c externs */
  2393.   extern int            toatty, fromatty;
  2394. ! extern int            verbose;
  2395.   extern string        prompt2;
  2396.   extern char            *line, *margv[];
  2397.   extern int            margc;
  2398. --- 40,46 ----
  2399.   
  2400.   /* Util.c externs */
  2401.   extern int            toatty, fromatty;
  2402. ! extern int            verbose, doingInitMacro;
  2403.   extern string        prompt2;
  2404.   extern char            *line, *margv[];
  2405.   extern int            margc;
  2406. ***************
  2407. *** 50,55 ****
  2408. --- 50,56 ----
  2409.   extern struct userinfo uinfo;
  2410.   
  2411.   #ifndef NO_VARARGS
  2412. + /*VARARGS*/
  2413.   void dbprintf(char *fmt, ...)
  2414.   {
  2415.       va_list ap;
  2416. ***************
  2417. *** 143,149 ****
  2418. --- 144,164 ----
  2419.   
  2420.   
  2421.   
  2422. + /* Converts any uppercase characters in the string to lowercase.
  2423. +  * Never would have guessed that, huh?
  2424. +  */
  2425. + void StrLCase(char *dst)
  2426. + {
  2427. +     register char *cp;
  2428.   
  2429. +     for (cp=dst; *cp != '\0'; cp++)
  2430. +         if (isupper((int) *cp))
  2431. +             *cp = (char) tolower(*cp);
  2432. + }
  2433.   char *Strpcpy(char *dst, char *src)
  2434.   {
  2435.       while ((*dst++ = *src++) != '\0')
  2436. ***************
  2437. *** 229,234 ****
  2438. --- 244,250 ----
  2439.   
  2440.   
  2441.   
  2442.   /*
  2443.    * Converts an ls date, in either the "Feb  4  1992" or "Jan 16 13:42"
  2444.    * format to a time_t.
  2445. ***************
  2446. *** 236,246 ****
  2447.   unsigned long UnLSDate(char *dstr)
  2448.   {
  2449.   #ifdef NO_MKTIME
  2450. !     return (0);
  2451.   #else
  2452.       char *cp = dstr;
  2453. !     int long mon, day, year, hr, min;
  2454. !     time_t now;
  2455.       struct tm ut, *t;
  2456.   
  2457.       switch (*cp++) {
  2458. --- 252,263 ----
  2459.   unsigned long UnLSDate(char *dstr)
  2460.   {
  2461.   #ifdef NO_MKTIME
  2462. !     return (MDTM_UNKNOWN);
  2463.   #else
  2464.       char *cp = dstr;
  2465. !     int mon, day, year, hr, min;
  2466. !     time_t now, mt;
  2467. !     unsigned long result = MDTM_UNKNOWN;
  2468.       struct tm ut, *t;
  2469.   
  2470.       switch (*cp++) {
  2471. ***************
  2472. *** 286,292 ****
  2473.       if (*++cp != ' ') {
  2474.           /* It's a time, XX:YY, not a year. */
  2475.           cp[2] = ' ';
  2476. !         (void) sscanf(cp, "%ld %ld", &hr, &min);
  2477.           cp[2] = ':';
  2478.           year = t->tm_year;
  2479.           if (mon > t->tm_mon)
  2480. --- 303,309 ----
  2481.       if (*++cp != ' ') {
  2482.           /* It's a time, XX:YY, not a year. */
  2483.           cp[2] = ' ';
  2484. !         (void) sscanf(cp, "%d %d", &hr, &min);
  2485.           cp[2] = ':';
  2486.           year = t->tm_year;
  2487.           if (mon > t->tm_mon)
  2488. ***************
  2489. *** 293,299 ****
  2490.               --year;
  2491.       } else {
  2492.           hr = min = 0;
  2493. !         (void) sscanf(cp, "%ld", &year);
  2494.           year -= 1900;
  2495.       }
  2496.       ut.tm_sec = 1;
  2497. --- 310,316 ----
  2498.               --year;
  2499.       } else {
  2500.           hr = min = 0;
  2501. !         (void) sscanf(cp, "%d", &year);
  2502.           year -= 1900;
  2503.       }
  2504.       ut.tm_sec = 1;
  2505. ***************
  2506. *** 304,316 ****
  2507.       ut.tm_year = year;
  2508.       ut.tm_isdst = t->tm_isdst;
  2509.       ut.tm_wday = ut.tm_yday = 0;
  2510. !     return ((unsigned long) mktime(&ut));
  2511.   #endif    /* NO_MKTIME */
  2512.   }    /* UnLSDate */
  2513.   
  2514.   
  2515.   
  2516.   
  2517.   void Perror(
  2518.   #ifdef DB_ERRS
  2519.               char *fromProc
  2520. --- 321,371 ----
  2521.       ut.tm_year = year;
  2522.       ut.tm_isdst = t->tm_isdst;
  2523.       ut.tm_wday = ut.tm_yday = 0;
  2524. !     mt = mktime(&ut);
  2525. !     if (mt != (time_t) -1)
  2526. !         result = (unsigned long) mt;
  2527. !     return (result);
  2528.   #endif    /* NO_MKTIME */
  2529.   }    /* UnLSDate */
  2530.   
  2531.   
  2532.   
  2533. + /*
  2534. +  * Converts a SIZE date, like "213 19930602204445\n"
  2535. +  * format to a time_t.
  2536. +  */
  2537. + unsigned long UnSIZEDate(char *dstr)
  2538. + {
  2539. + #ifdef NO_MKTIME
  2540. +     return (MDTM_UNKNOWN);
  2541. + #else
  2542. +     struct tm ut;
  2543. +     time_t mt;
  2544. +     unsigned long result = MDTM_UNKNOWN;
  2545.   
  2546. +     if (sscanf(dstr, "%*s %04d%02d%02d%02d%02d%02d",
  2547. +         &ut.tm_year,
  2548. +         &ut.tm_mon,
  2549. +         &ut.tm_mday,
  2550. +         &ut.tm_hour,
  2551. +         &ut.tm_min,
  2552. +         &ut.tm_sec) == 6)
  2553. +     {    
  2554. +         --ut.tm_mon;
  2555. +         ut.tm_year -= 1900;
  2556. +         ut.tm_isdst = 0;    /* Hmmm.... */
  2557. +         ut.tm_wday = ut.tm_yday = 0;
  2558. +         mt = mktime(&ut);
  2559. +         if (mt != (time_t) -1)
  2560. +             result = (unsigned long) mt;
  2561. +     }
  2562. +     return result;
  2563. + #endif    /* NO_MKTIME */
  2564. + }    /* UnSIZEDate */
  2565.   void Perror(
  2566.   #ifdef DB_ERRS
  2567.               char *fromProc
  2568. ***************
  2569. *** 415,420 ****
  2570. --- 470,476 ----
  2571.   #endif
  2572.       }
  2573.       sline[0] = 0;
  2574. +     (void) fflush(stdout);    /* for svr4 */
  2575.       cp = fgets(sline, (int)(size - 2), stdin);
  2576.       (void) RemoveTrailingNewline(sline, NULL);
  2577.       return cp;
  2578. ***************
  2579. *** 597,603 ****
  2580.   {
  2581.       string str, pr;
  2582.   
  2583. !     if (!fromatty || (activemcmd && !mprompt))
  2584.           return 1;
  2585.       (void) sprintf(pr, "%s %s? ", cmd, file);
  2586.       (void) Gets(pr, str, sizeof(str));
  2587. --- 653,659 ----
  2588.   {
  2589.       string str, pr;
  2590.   
  2591. !     if (!fromatty || (activemcmd && !mprompt) || (doingInitMacro))
  2592.           return 1;
  2593.       (void) sprintf(pr, "%s %s? ", cmd, file);
  2594.       (void) Gets(pr, str, sizeof(str));
  2595. ***************
  2596. *** 702,734 ****
  2597.   {
  2598.       longstring orig;
  2599.       struct passwd *pw;
  2600. !     char *firstent = NULL;
  2601.       char *cp, *dp, *rest;
  2602.   
  2603.       (void) Strncpy(orig, path);
  2604. !     if (((cp = index(orig, '/')) != NULL) && (cp != orig)) {
  2605.           *cp = 0;
  2606.           rest = cp + 1;
  2607. !         if (orig[0] == '~') {
  2608. !             if (orig[1] == 0) {
  2609. !                 firstent = uinfo.homedir;
  2610. !             } else {
  2611. !                 pw = getpwnam(orig + 1);
  2612. !                 if (pw != NULL)
  2613. !                     firstent = pw->pw_dir;
  2614. !             }
  2615. !         } else if (orig[0] == '$') {
  2616. !             cp = orig + 1;
  2617. !             dp = orig + strlen(orig) - 1;
  2618. !             if ((*cp == '(' && *dp == ')') || (*cp == '{' && *dp == '}')) {
  2619. !                 cp++;
  2620. !                 *dp = 0;
  2621. !             }
  2622. !             firstent = getenv(cp);
  2623.           }
  2624. !         if (firstent != NULL)
  2625. !             (void) sprintf(path, "%s/%s", firstent, rest);
  2626.       }
  2627.       return (path);
  2628.   }    /* LocalPath */
  2629.   
  2630. --- 758,814 ----
  2631.   {
  2632.       longstring orig;
  2633.       struct passwd *pw;
  2634. !     char *firstent;
  2635.       char *cp, *dp, *rest;
  2636.   
  2637.       (void) Strncpy(orig, path);
  2638. !     firstent = orig;
  2639. !     if ((cp = index(orig, '/')) != NULL) {
  2640. !         if (cp == orig) {
  2641. !             /* If we got here, the path is actually a full path name,
  2642. !              * with the first character as a slash, so just leave it
  2643. !              * alone.
  2644. !              */
  2645. !             return (path);
  2646. !         }
  2647. !         /* Otherwise we can look at the first word of the path, and
  2648. !          * try to expand it, like $HOME/ or ~/, or it is a relative path, 
  2649. !          * which is okay since we won't really do anything with it.
  2650. !          */
  2651.           *cp = 0;
  2652.           rest = cp + 1;
  2653. !         /* 'firstent' now contains the first 'word' in the path. */
  2654. !     } else {
  2655. !         /* Path was just a single word, or it is a full path, like:
  2656. !          * /usr/tmp/zz, so firstent is just the entire given "path."
  2657. !          */
  2658. !         rest = NULL;
  2659. !     }
  2660. !     if (orig[0] == '~') {
  2661. !         if (orig[1] == 0) {
  2662. !             firstent = uinfo.homedir;
  2663. !         } else {
  2664. !             pw = getpwnam(orig + 1);
  2665. !             if (pw != NULL)
  2666. !                 firstent = pw->pw_dir;
  2667.           }
  2668. !     } else if (orig[0] == '$') {
  2669. !         cp = orig + 1;
  2670. !         dp = orig + strlen(orig) - 1;
  2671. !         if ((*cp == '(' && *dp == ')') || (*cp == '{' && *dp == '}')) {
  2672. !             cp++;
  2673. !             *dp = 0;
  2674. !         }
  2675. !         firstent = getenv(cp);
  2676. !         if (firstent == NULL) {
  2677. !             (void) fprintf(stderr, "%s: no such environment variable.\n", cp);
  2678. !             firstent = "badEnvVar";
  2679. !         }
  2680.       }
  2681. +     if (rest == NULL)
  2682. +         (void) strcpy(path, firstent);
  2683. +     else 
  2684. +         (void) sprintf(path, "%s/%s", firstent, rest);
  2685.       return (path);
  2686.   }    /* LocalPath */
  2687.   
  2688. diff -c ./util.h ../ncftp170/util.h
  2689. *** ./util.h    Wed Mar 16 18:25:00 1994
  2690. --- ../ncftp170/util.h    Wed Mar 16 19:16:03 1994
  2691. ***************
  2692. *** 72,77 ****
  2693. --- 72,78 ----
  2694.   /* Protos. */
  2695.   char *_Strncat(char *dst, char *src, register size_t n);
  2696.   char *_Strncpy(char *dst, char *src, register size_t n);
  2697. + void StrLCase(char *dst);
  2698.   char *NewString(char *oldstr);
  2699.   char **re_makeargv(char *promptstr, int *argc);
  2700.   char *onoff(int);
  2701. ***************
  2702. *** 85,90 ****
  2703. --- 86,92 ----
  2704.   char *Gets(char *promptstr, char *sline, size_t size);
  2705.   size_t RemoveTrailingNewline(char *cp, int *stripped);
  2706.   unsigned long UnLSDate(char *dstr);
  2707. + unsigned long UnSIZEDate(char *dstr);
  2708.   char *Strpcpy(char *dst, char *src);
  2709.   int UserLoggedIn(void);
  2710.   char *LocalPath(char *path);
  2711. diff -c ./v2_Note ../ncftp170/v2_Note
  2712. *** ./v2_Note    Wed Mar 16 18:25:01 1994
  2713. --- ../ncftp170/v2_Note    Wed Mar 16 19:16:03 1994
  2714. ***************
  2715. *** 1,10 ****
  2716. ! Version 1.6 of NcFTP is an interim release.  Version 2.0 is much cooler,
  2717. ! but it wasn't ready to go by my self-imposed deadline of September 1, 1993.
  2718. ! The reason for that deadline is that my senior year will be getting under
  2719. ! way, and I don't want to work on the program during that period.  Last year
  2720. ! I spent too much time on NcFTP and other projects, and not enough time on
  2721. ! studies.  As a result, my grades slipped a bit.  Therefore I will be
  2722. ! studying more and programming, reading news, and reading email less.  If
  2723.   you send me email, I _will_ read it, but it may take me awhile to get to it,
  2724.   and I may not answer.  Please don't be offended.  I really regret having
  2725.   to release code that is such a mess.  I should have wrote the code from
  2726. --- 1,7 ----
  2727. ! Versions numbered between 1.5.0 and 1.9.9 are interim releases.  No major
  2728. ! features are planned for these; only tweaks and fixes.
  2729. ! Version 2.0 is much cooler, but I haven't had time to work on it.  If
  2730.   you send me email, I _will_ read it, but it may take me awhile to get to it,
  2731.   and I may not answer.  Please don't be offended.  I really regret having
  2732.   to release code that is such a mess.  I should have wrote the code from
  2733. ***************
  2734. *** 11,26 ****
  2735.   scratch, rather than built it upon the original BSD code (which is a mess
  2736.   itself!).
  2737.   
  2738. - This version is based on 1.5, which in turn was based on the betas of 1.4.
  2739. - 1.4 was almost finished when I decided to add some significant features, and
  2740. - clean up the code so it is better organized and easier to read. That version
  2741. - is called 2.0, and isn't finished yet. The innards are totally different
  2742. - from the 1.4 family, so patches to 1.6 won't work at all on 2.0. During the
  2743. - process of adding stuff and cleaning up, a couple of bugs creeped in that
  2744. - will take time to resolve. Maybe I can work on it during Christmas break.
  2745.   I apologize in advance for bugs I fixed in 2.0 but forgot to re-fix
  2746. ! in 1.6 (I think I got'em all, though).
  2747.   
  2748.   Here is a list of things that are in the 2.0 code but not this version:
  2749.   
  2750. --- 8,15 ----
  2751.   scratch, rather than built it upon the original BSD code (which is a mess
  2752.   itself!).
  2753.   
  2754.   I apologize in advance for bugs I fixed in 2.0 but forgot to re-fix
  2755. ! in these interim releases (I think I got'em all, though).
  2756.   
  2757.   Here is a list of things that are in the 2.0 code but not this version:
  2758.   
  2759. ***************
  2760. *** 41,46 ****
  2761.   
  2762.   Keep that in mind if you want to make a feature enhancement.  I'm telling
  2763.   you this now so you don't spend your time programming something that is
  2764. ! already done for the 2.0 release.  Also note that patches for 1.6 will
  2765.   have to be re-coded for 2.0.  (The gist is that you should wait until
  2766.   2.0 is done before doing anything major).
  2767. --- 30,35 ----
  2768.   
  2769.   Keep that in mind if you want to make a feature enhancement.  I'm telling
  2770.   you this now so you don't spend your time programming something that is
  2771. ! already done for the 2.0 release.  Also note that patches would
  2772.   have to be re-coded for 2.0.  (The gist is that you should wait until
  2773.   2.0 is done before doing anything major).
  2774. --
  2775. --mg                                        Mike Gleason <mgleason@cse.unl.edu>
  2776.  
  2777. exit 0 # Just in case...
  2778.