home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume39 / ncftp / part03 < prev    next >
Encoding:
Text File  |  1993-08-25  |  61.2 KB  |  2,512 lines

  1. Newsgroups: comp.sources.misc
  2. From: mgleason@cse.unl.edu (Mike Gleason)
  3. Subject: v39i055:  ncftp - Alternative User Interface for FTP, v1.5.0, Part03/05
  4. Message-ID: <1993Aug26.000516.24358@sparky.sterling.com>
  5. X-Md4-Signature: 5b940d30cc00bfd5d08ecf78481a517d
  6. Sender: kent@sparky.sterling.com (Kent Landfield)
  7. Organization: NCEMRSoft
  8. Date: Thu, 26 Aug 1993 00:05:16 GMT
  9. Approved: kent@sparky.sterling.com
  10.  
  11. Submitted-by: mgleason@cse.unl.edu (Mike Gleason)
  12. Posting-number: Volume 39, Issue 55
  13. Archive-name: ncftp/part03
  14. Environment: UNIX, ANSI-C, !SVR4
  15. Supersedes: ncftp: Volume 35, Issue 4-7
  16.  
  17. #! /bin/sh
  18. # This is a shell archive.  Remove anything before this line, then feed it
  19. # into a shell via "sh file" or similar.  To overwrite existing files,
  20. # type "sh file -c".
  21. # Contents:  copyright.h main.c ncftp.1
  22. # Wrapped by kent@sparky on Wed Aug 25 18:59:17 1993
  23. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  24. echo If this archive is complete, you will see the following message:
  25. echo '          "shar: End of archive 3 (of 5)."'
  26. if test -f 'copyright.h' -a "${1}" != "-c" ; then 
  27.   echo shar: Will not clobber existing file \"'copyright.h'\"
  28. else
  29.   echo shar: Extracting \"'copyright.h'\" \(1048 characters\)
  30.   sed "s/^X//" >'copyright.h' <<'END_OF_FILE'
  31. X/* Copyright.h */
  32. X
  33. X/*  $RCSfile: copyright.h,v $
  34. X *  $Revision: 14020.12 $
  35. X *  $Date: 93/06/02 13:43:03 $
  36. X */
  37. X
  38. X/*
  39. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  40. X * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  41. X * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  42. X *
  43. X * Copyright (c) 1992, 1993 Mike Gleason, NCEMRSoft.
  44. X * Copyright (c) 1985, 1989 Regents of the University of California.
  45. X * All rights reserved.
  46. X *
  47. X * Redistribution and use in source and binary forms are permitted provided
  48. X * that: (1) source distributions retain this entire copyright notice and
  49. X * comment, and (2) distributions may not be sold for profit on physicaical
  50. X * media such as disks, tapes, and CD-ROMS, without expressed written
  51. X * permission.
  52. X */
  53. X
  54. X#ifdef _main_c_
  55. X#ifndef lint
  56. Xstatic char copyright[] = "@(#) Copyright (c) 1992, 1993 by NCEMRSoft and Copyright (c) 1985, 1989 Regents of the University of California.\n All rights reserved.\n";
  57. X#endif /* not lint */
  58. X#endif /* _main_c_ */
  59. X
  60. X/* eof copyright.h */
  61. END_OF_FILE
  62.   if test 1048 -ne `wc -c <'copyright.h'`; then
  63.     echo shar: \"'copyright.h'\" unpacked with wrong size!
  64.   fi
  65.   # end of 'copyright.h'
  66. fi
  67. if test -f 'main.c' -a "${1}" != "-c" ; then 
  68.   echo shar: Will not clobber existing file \"'main.c'\"
  69. else
  70.   echo shar: Extracting \"'main.c'\" \(23284 characters\)
  71.   sed "s/^X//" >'main.c' <<'END_OF_FILE'
  72. X/* main.c */
  73. X
  74. X/*  $RCSfile: main.c,v $
  75. X *  $Revision: 14020.15 $
  76. X *  $Date: 93/07/09 11:50:12 $
  77. X */
  78. X
  79. X#define _main_c_
  80. X
  81. X#define FTP_VERSION \
  82. X"NcFTP 1.5.0 (Aug 22, 1993) by Mike Gleason, NCEMRSoft."
  83. X
  84. X/* #define BETA 1 */ /* If defined, it prints a little warning message. */
  85. X
  86. X#include "sys.h"
  87. X#include <sys/types.h>
  88. X#include <sys/param.h>
  89. X#include <sys/socket.h>
  90. X#include <sys/stat.h>
  91. X#include <sys/time.h>
  92. X#include <arpa/ftp.h>
  93. X#include <setjmp.h>
  94. X#include <signal.h>
  95. X#include <string.h>
  96. X#include <errno.h>
  97. X#include <ctype.h>
  98. X#include <netdb.h>
  99. X#include <pwd.h>
  100. X
  101. X#ifdef SYSLOG
  102. X#    include <syslog.h>
  103. X#endif
  104. X
  105. X#ifndef NO_UNISTDH
  106. X#    include <unistd.h>
  107. X#endif
  108. X
  109. X#ifdef CURSES
  110. X#    undef HZ        /* Collides with HaZeltine ! */
  111. X#    include <curses.h>
  112. X#endif    /* CURSES */
  113. X
  114. X#include "util.h"
  115. X#include "cmds.h"
  116. X#include "main.h"
  117. X#include "ftp.h"
  118. X#include "ftprc.h"
  119. X#include "open.h"
  120. X#include "set.h"
  121. X#include "defaults.h"
  122. X#include "copyright.h"
  123. X
  124. X/* main.c globals */
  125. Xint                    slrflag;
  126. Xint                    fromatty;            /* input is from a terminal */
  127. Xint                    toatty;                /* output is to a terminal */
  128. Xint                    doing_script;        /* is a file being <redirected to me? */
  129. Xchar                *altarg;            /* argv[1] with no shell-like preprocessing  */
  130. Xstruct servent        serv;                /* service spec for tcp/ftp */
  131. Xjmp_buf                toplevel;            /* non-local goto stuff for cmd scanner */
  132. Xchar                *line;                /* input line buffer */
  133. Xchar                *stringbase;        /* current scan point in line buffer */
  134. Xchar                *argbuf;            /* argument storage buffer */
  135. Xchar                *argbase;            /* current storage point in arg buffer */
  136. Xint                    margc;                /* count of arguments on input line */
  137. Xchar                *margv[20];            /* args parsed from input line */
  138. Xstruct userinfo        uinfo;                /* a copy of their pwent really */
  139. Xint                    ansi_escapes;        /* for fancy graphics */
  140. Xint                             startup_msg = 1;        /* TAR: display message on startup? */
  141. Xint                    ignore_rc;            /* are we supposed to ignore the netrc */
  142. Xstring                progname;            /* simple filename */
  143. Xstring                prompt, prompt2;    /* shell prompt string */
  144. Xstring                anon_password;        /* most likely your email address */
  145. Xstring                pager;                /* program to browse text files */
  146. Xstring                version = FTP_VERSION;
  147. Xlong                eventnumber;        /* number of commands we've done */
  148. XFILE                *logf = NULL;        /* log user activity */
  149. Xlongstring            logfname;            /* name of the logfile */
  150. Xlong                logsize = 4096L;    /* max log size. 0 == no limit */
  151. Xint                    percent_flags;        /* "%" in prompt string? */
  152. Xint                    at_flags;            /* "@" in prompt string? */
  153. Xstring                 mail_path;            /* your mailbox */
  154. Xtime_t                mbox_time;            /* last modified time of mbox */
  155. Xsize_t                epromptlen;            /* length of the last line of the
  156. X                                         * prompt as it will appear on screen,
  157. X                                         * (i.e. no invis escape codes).
  158. X                                         */
  159. Xchar                *tcap_normal = "\033[0m";    /* Default ANSI escapes */
  160. Xchar                *tcap_boldface = "\033[1m";
  161. Xchar                *tcap_underline = "\033[4m";
  162. Xchar                *tcap_reverse = "\033[7m";
  163. Xsize_t                tcl_normal = 4,        /* lengths of the above strings. */
  164. X                    tcl_bold = 4,
  165. X                    tcl_uline = 4,
  166. X                    tcl_rev = 4;
  167. X
  168. X#ifdef CURSES
  169. Xstatic char            tcbuf[2048];
  170. X#endif
  171. X
  172. X/* main.c externs */
  173. Xextern int            debug, verbose, mprompt;
  174. Xextern int            options, cpend, data, connected, logged_in;
  175. Xextern int            curtype, macnum, remote_is_unix;
  176. Xextern FILE            *cout;
  177. Xextern struct cmd    cmdtab[];
  178. Xextern str32        curtypename;
  179. Xextern char            *macbuf;
  180. Xextern char            *reply_string;
  181. Xextern char            *short_verbose_msgs[4];
  182. Xextern string        vstr;
  183. Xextern Hostname        hostname;
  184. Xextern longstring    cwd, lcwd, recent_file;
  185. Xextern int            Optind;
  186. Xextern char            *Optarg;
  187. X#ifdef GATEWAY
  188. Xextern string        gate_login;
  189. X#endif
  190. X
  191. Xvoid main(int argc, char **argv)
  192. X{
  193. X    register char        *cp;
  194. X    int                    top, opt, openopts = 0;
  195. X    string                tmp, oline;
  196. X    struct servent        *sptr;
  197. X
  198. X    if ((cp = rindex(argv[0], '/'))) cp++;
  199. X    else cp = argv[0];
  200. X    (void) Strncpy(progname, cp);
  201. X    
  202. X    sptr = getservbyname("ftp", "tcp");
  203. X    if (sptr == 0) fatal("ftp/tcp: unknown service");
  204. X    serv = *sptr;
  205. X
  206. X    if (init_arrays())            /* Reserve large blocks of memory now */
  207. X        fatal("could not reserve large amounts of memory.");
  208. X
  209. X    /*
  210. X     * Set up defaults for FTP.
  211. X     */
  212. X    mprompt = dMPROMPT;
  213. X    debug = dDEBUG;
  214. X    verbose = dVERBOSE;
  215. X    (void) Strncpy(vstr, short_verbose_msgs[verbose+1]);
  216. X
  217. X    (void) Strncpy(curtypename, dTYPESTR);
  218. X    curtype = dTYPE;
  219. X    (void) Strncpy(prompt, dPROMPT);
  220. X#ifdef GATEWAY
  221. X    (void) Strncpy(gate_login, dGATEWAY_LOGIN);
  222. X#endif
  223. X
  224. X#ifdef SOCKS
  225. X    SOCKSinit("ncftp");
  226. X#endif
  227. X    
  228. X    /*    Setup our pager variable, before we run through the rc,
  229. X        which may change it. */
  230. X    set_pager(getenv("PAGER"), 0);
  231. X#ifdef CURSES
  232. X    ansi_escapes = 1;
  233. X    termcap_init();
  234. X#else
  235. X    ansi_escapes = 0;
  236. X    if ((cp = getenv("TERM")) != NULL) {
  237. X        if ((*cp == 'v' && cp[1] == 't')        /* vt100, vt102, ... */
  238. X            || (strcmp(cp, "xterm") == 0))
  239. X            ansi_escapes = 1;
  240. X    }
  241. X#endif
  242. X    (void) getuserinfo();
  243. X
  244. X    /* Init the mailbox checking code. */
  245. X    (void) time(&mbox_time);
  246. X
  247. X    (void) Strncpy(anon_password, uinfo.username);
  248. X    if (getlocalhostname(uinfo.hostname, sizeof(uinfo.hostname)) == 0) {
  249. X        (void) Strncat(anon_password, "@");
  250. X        (void) Strncat(anon_password, uinfo.hostname);
  251. X    }
  252. X#if dLOGGING
  253. X    (void) Strncpy(logfname, dLOGNAME);
  254. X    (void) LocalDotPath(logfname);
  255. X#else
  256. X    *logfname = 0;
  257. X#endif
  258. X    (void) Strncpy(recent_file, dRECENTF);
  259. X    (void) LocalDotPath(recent_file);
  260. X
  261. X    (void) get_cwd(lcwd, (int) sizeof(lcwd));
  262. X
  263. X#ifdef SYSLOG
  264. X#    ifdef LOG_LOCAL3
  265. X    openlog ("NcFTP", LOG_PID, LOG_LOCAL3);
  266. X#    else
  267. X    openlog ("NcFTP", LOG_PID);
  268. X#    endif
  269. X#endif                /* SYSLOG */
  270. X
  271. X
  272. X    ignore_rc = 0;
  273. X    (void) strcpy(oline, "open ");
  274. X    while ((opt = Getopt(argc, argv, "D:V:INRHaicmup:rd:g:")) >= 0) {
  275. X        switch(opt) {
  276. X            case 'a':
  277. X            case 'c':
  278. X            case 'i':
  279. X            case 'm':
  280. X            case 'u':
  281. X            case 'r':
  282. X                (void) sprintf(tmp, "-%c ", opt);
  283. X                goto cattmp;
  284. X
  285. X            case 'p':
  286. X            case 'd':
  287. X            case 'g':
  288. X                (void) sprintf(tmp, "-%c %s ", opt, Optarg);
  289. X            cattmp:
  290. X                (void) strcat(oline, tmp);
  291. X                openopts++;
  292. X                break;
  293. X
  294. X            case 'D':
  295. X                debug = atoi(Optarg);
  296. X                break;
  297. X            
  298. X            case 'V':
  299. X                set_verbose(Optarg, 0);
  300. X                break;
  301. X
  302. X            case 'I':
  303. X                mprompt = !mprompt;
  304. X                break;
  305. X
  306. X            case 'N':
  307. X                ++ignore_rc;
  308. X                break;
  309. X
  310. X            case 'H':
  311. X                (void) show_version(0, NULL);
  312. X                exit (0);
  313. X
  314. X            default:
  315. X            usage:
  316. X                (void) fprintf(stderr, "Usage: %s [program options] [[open options] site.to.open[:path]]\n\
  317. XProgram Options:\n\
  318. X    -D x   : Set debugging level to x (a number).\n\
  319. X    -H     : Show version and compilation information.\n\
  320. X    -I     : Toggle interactive (mprompt) mode.\n\
  321. X    -N     : Toggle reading of the .netrc/.ncftprc.\n\
  322. X    -V x   : Set verbosity to level x (-1,0,1,2).\n\
  323. XOpen Options:\n\
  324. X    -a     : Open anonymously (this is the default).\n\
  325. X    -u     : Open, specify user/password.\n\
  326. X    -i     : Ignore machine entry in your .netrc.\n\
  327. X    -p N   : Use port #N for connection.\n\
  328. X    -r     : \"Redial\" until connected.\n\
  329. X    -d N   : Redial, pausing N seconds between tries.\n\
  330. X    -g N   : Redial, giving up after N tries.\n\
  331. X    :path  : ``Colon-mode:'' If \"path\" is a file, it opens site, retrieves\n\
  332. X             file \"path,\" then exits; if \"path\" is a remote directory,\n\
  333. X             it opens site then starts you in that directory..\n\
  334. X    -c     : If you're using colon-mode with a file path, this will cat the\n\
  335. X             file to stdout instead of storing on disk.\n\
  336. X    -m     : Just like -c, only it pipes the file to your $PAGER.\n\
  337. XExamples:\n\
  338. X    ncftp ftp.unl.edu:/pub/README (just fetches README then quits)\n\
  339. X    ncftp  (just enters ncftp command shell)\n\
  340. X    ncftp -V -u ftp.unl.edu\n\
  341. X    ncftp -c ftp.unl.edu:/pub/README (cats README to stdout then quits)\n\
  342. X    ncftp -D -r -d 120 -g 10 ftp.unl.edu\n", progname);
  343. X            exit(1);
  344. X        }
  345. X    }
  346. X
  347. X    cp = argv[Optind];  /* the site to open. */
  348. X    if (cp == NULL) {
  349. X        if (openopts)
  350. X            goto usage;
  351. X    } else
  352. X        (void) strcat(oline, cp);
  353. X
  354. X    if (ignore_rc <= 0)
  355. X        (void) thrash_rc();
  356. X    if (ignore_rc <= 1)
  357. X        ReadRecentSitesFile();
  358. X
  359. X    (void) fix_options();    /* adjust "options" according to "debug"  */
  360. X    
  361. X    fromatty = doing_script = isatty(0);
  362. X    toatty = isatty(1);
  363. X    (void) UserLoggedIn();    /* Init parent-death detection. */
  364. X    cpend = 0;  /* no pending replies */
  365. X    
  366. X    if (*logfname)
  367. X        logf = fopen (logfname, "a");
  368. X
  369. X
  370. X    /* The user specified a host, maybe in 'colon-mode', on the command
  371. X     * line.  Open it now...
  372. X     */
  373. X    if (argc > 1 && cp) {
  374. X        if (setjmp(toplevel))
  375. X            exit(0);
  376. X        (void) Signal(SIGINT, intr);
  377. X        (void) Signal(SIGPIPE, lostpeer);
  378. X        (void) strcpy(line, oline);
  379. X        makeargv();
  380. X        /* setpeer uses this to tell if it was called from the cmd-line. */
  381. X        eventnumber = 0L;
  382. X        (void) cmdOpen(margc, margv);
  383. X    }
  384. X    eventnumber = 1L;
  385. X
  386. X    (void) init_prompt();
  387. X
  388. X    if (startup_msg) {  /* TAR */
  389. X        if (ansi_escapes) {
  390. X#ifdef BETA
  391. X#    define BETA_MSG "\n\
  392. XFor testing purposes only.  Do not re-distribute or subject to novice users."
  393. X#else
  394. X#    define BETA_MSG ""
  395. X#endif
  396. X
  397. X#ifndef CURSES
  398. X        (void) printf("%s%s%s%s\n", 
  399. X                tcap_boldface, FTP_VERSION, BETA_MSG, tcap_normal);
  400. X#else
  401. X        string vis;
  402. X        (void) sprintf(vis, "%s%s%s%s\n", 
  403. X                tcap_boldface, FTP_VERSION, BETA_MSG, tcap_normal);
  404. X        tcap_put(vis);
  405. X#endif /* !CURSES */
  406. X        }
  407. X        else
  408. X        (void) printf("%s%s\n", FTP_VERSION, BETA_MSG);
  409. X    }  /* TAR */
  410. X    if (NOT_VQUIET)
  411. X        PrintTip();
  412. X    top = setjmp(toplevel) == 0;
  413. X    if (top) {
  414. X        (void) Signal(SIGINT, intr);
  415. X        (void) Signal(SIGPIPE, lostpeer);
  416. X    }
  417. X    for (;;) {
  418. X        (void) cmdscanner(top);
  419. X        top = 1;
  420. X    }
  421. X}    /* main */
  422. X
  423. X
  424. X
  425. X/*ARGSUSED*/
  426. Xvoid intr SIG_PARAMS
  427. X{
  428. X    dbprintf("intr()\n");
  429. X    (void) Signal(SIGINT, intr);
  430. X    (void) longjmp(toplevel, 1);
  431. X}    /* intr */
  432. X
  433. X
  434. X
  435. Xint getuserinfo(void)
  436. X{
  437. X    register char            *cp;
  438. X    struct passwd            *pw;
  439. X    string                    str;
  440. X    extern char                *home;    /* for glob.c */
  441. X    
  442. X    pw = getpwuid(getuid());
  443. X    if (pw != NULL) {
  444. X        (void) Strncpy(uinfo.username, pw->pw_name);
  445. X        (void) Strncpy(uinfo.shell, pw->pw_shell);
  446. X        (void) Strncpy(uinfo.homedir, pw->pw_dir);
  447. X        uinfo.uid = pw->pw_uid;
  448. X        home = uinfo.homedir;    /* for glob.c */
  449. X        cp = getenv("MAIL");
  450. X        if (cp == NULL)
  451. X            cp = getenv("mail");
  452. X        if (cp == NULL)
  453. X            (void) sprintf(str, "/usr/spool/mail/%s", uinfo.username);
  454. X        else
  455. X            (void) Strncpy(str, cp);
  456. X        cp = str;
  457. X
  458. X        /*
  459. X         * mbox variable may be like MAIL=(28 /usr/mail/me /usr/mail/you),
  460. X         * so try to find the first mail path.
  461. X         */
  462. X        while ((*cp != '/') && (*cp != 0))
  463. X            cp++;
  464. X        (void) Strncpy(mail_path, cp);
  465. X        if ((cp = index(mail_path, ' ')) != NULL)
  466. X            *cp = '\0';
  467. X        return (0);
  468. X    } else {
  469. X        (void) Strncpy(uinfo.username, "unknown");
  470. X        (void) Strncpy(uinfo.shell, "/bin/sh");
  471. X        (void) Strncpy(uinfo.homedir, ".");    /* current directory */
  472. X        uinfo.uid = 999;
  473. X        return (-1);
  474. X    }
  475. X}    /* getuserinfo */
  476. X
  477. X
  478. X
  479. X
  480. Xint init_arrays(void)
  481. X{
  482. X    if ((macbuf = (char *) malloc((size_t)(MACBUFLEN))) == NULL)
  483. X        goto barf;
  484. X    if ((line = (char *) malloc((size_t)(CMDLINELEN))) == NULL)
  485. X        goto barf;
  486. X    if ((argbuf = (char *) malloc((size_t)(CMDLINELEN))) == NULL)
  487. X        goto barf;
  488. X    if ((reply_string = (char *) malloc((size_t)(RECEIVEDLINELEN))) == NULL)
  489. X        goto barf;
  490. X    
  491. X    *macbuf = '\0';
  492. X    init_transfer_buffer();
  493. X    return (0);
  494. Xbarf:
  495. X    return (-1);
  496. X}    /* init_arrays */
  497. X
  498. X
  499. X
  500. X#ifndef BUFSIZ
  501. X#define BUFSIZ 512
  502. X#endif
  503. X
  504. Xvoid init_transfer_buffer(void)
  505. X{
  506. X    extern char *xferbuf;
  507. X    extern size_t xferbufsize;
  508. X    
  509. X    /* Make sure we use a multiple of BUFSIZ for efficiency. */
  510. X    xferbufsize = (MAX_XFER_BUFSIZE / BUFSIZ) * BUFSIZ;
  511. X    while (1) {
  512. X        xferbuf = (char *) malloc (xferbufsize);
  513. X        if (xferbuf != NULL || xferbufsize < 1024)
  514. X            break;
  515. X        xferbufsize >>= 2;
  516. X    }
  517. X    
  518. X    if (xferbuf != NULL) return;
  519. X    fatal("out of memory for transfer buffer.");
  520. X}    /* init_transfer_buffer */
  521. X
  522. X
  523. X
  524. X
  525. Xvoid init_prompt(void)
  526. X{
  527. X    register char *cp;
  528. X    
  529. X    percent_flags = at_flags = 0;
  530. X    for (cp = prompt; *cp; cp++) {
  531. X        if (*cp == '%') percent_flags = 1;
  532. X        else if (*cp == '@') at_flags = 1;
  533. X    }
  534. X}    /* init_prompt */
  535. X
  536. X
  537. X
  538. X/*ARGSUSED*/
  539. Xvoid lostpeer SIG_PARAMS
  540. X{
  541. X    if (connected) {
  542. X        close_streams(1);
  543. X        if (data >= 0) {
  544. X            (void) shutdown(data, 1+1);
  545. X            (void) close(data);
  546. X            data = -1;
  547. X        }
  548. X        connected = 0;
  549. X    }
  550. X    if (connected) {
  551. X        close_streams(1);
  552. X        connected = 0;
  553. X    }
  554. X    hostname[0] = cwd[0] = 0;
  555. X    logged_in = macnum = 0;
  556. X}    /* lostpeer */
  557. X
  558. X
  559. X/*
  560. X * Command parser.
  561. X */
  562. Xvoid cmdscanner(int top)
  563. X{
  564. X    register struct cmd *c;
  565. X#ifdef CURSES
  566. X    string vis, *vp;
  567. X#endif
  568. X
  569. X    if (!top)
  570. X        (void) putchar('\n');
  571. X    for (;;) {
  572. X        if (!doing_script && !UserLoggedIn())
  573. X            (void) quit(0, NULL);
  574. X        if (Gets(strprompt(), line, (size_t)CMDLINELEN) == NULL) {
  575. X            (void) quit(0, NULL);    /* control-d */
  576. X        }
  577. X        eventnumber++;
  578. X        dbprintf("\"%s\"\n", line);
  579. X        (void) makeargv();
  580. X        if (margc == 0) {
  581. X            continue;    /* blank line... */
  582. X        }
  583. X        c = getcmd(margv[0]);
  584. X        if (c == (struct cmd *) -1) {
  585. X            (void) printf("?Ambiguous command\n");
  586. X            continue;
  587. X        }
  588. X        if (c == 0) {
  589. X            if (!implicit_cd(margv[0]))
  590. X                (void) printf("?Invalid command\n");
  591. X            continue;
  592. X        }
  593. X        if (c->c_conn && !connected) {
  594. X            (void) printf ("Not connected.\n");
  595. X            continue;
  596. X        }
  597. X        if ((*c->c_handler)(margc, margv) == USAGE)
  598. X            cmd_usage(c);
  599. X        if (c->c_handler != help)
  600. X            break;
  601. X    }
  602. X    (void) Signal(SIGINT, intr);
  603. X    (void) Signal(SIGPIPE, lostpeer);
  604. X}    /* cmdscanner */
  605. X
  606. X
  607. X
  608. X
  609. Xchar *strprompt(void)
  610. X{
  611. X    time_t                    tyme;
  612. X    char                    eventstr[8];
  613. X    char                    *dname, *lastlinestart;
  614. X    register char            *p, *q;
  615. X    string                    str;
  616. X    int                        flag;
  617. X
  618. X    if (at_flags == 0 && percent_flags == 0) {
  619. X        epromptlen = strlen(prompt);
  620. X        return (prompt);    /* But don't overwrite it! */
  621. X    }
  622. X    epromptlen = 0;
  623. X    lastlinestart = prompt2;
  624. X    if (at_flags) {
  625. X        for (p = prompt, q = prompt2, *q = 0; (*p); p++) {
  626. X            if (*p == '@') switch (flag = *++p) {
  627. X                case '\0':
  628. X                    --p;
  629. X                    break;
  630. X                case 'M':
  631. X                    if (CheckNewMail() > 0)
  632. X                        q = Strpcpy(q, "(Mail) ");
  633. X                    break;
  634. X                case 'N':
  635. X                    q = Strpcpy(q, "\n");
  636. X                    lastlinestart = q;
  637. X                    epromptlen = 0;
  638. X                    break;
  639. X                case 'P':    /* reset to no bold, no uline, no inverse, etc. */
  640. X                    if (ansi_escapes) {
  641. X                        q = Strpcpy(q, tcap_normal);
  642. X                        epromptlen += tcl_normal;
  643. X                    }
  644. X                    break;
  645. X                case 'B':    /* toggle boldface */
  646. X                    if (ansi_escapes) {
  647. X                        q = Strpcpy(q, tcap_boldface);
  648. X                        epromptlen += tcl_bold;
  649. X                    }
  650. X                    break;
  651. X                case 'U':    /* toggle underline */
  652. X                    if (ansi_escapes) {
  653. X                        q = Strpcpy(q, tcap_underline);
  654. X                        epromptlen += tcl_uline;
  655. X                    }
  656. X                    break;
  657. X                case 'R':
  658. X                case 'I':    /* toggle inverse (reverse) video */
  659. X                    if (ansi_escapes) {
  660. X                        q = Strpcpy(q, tcap_reverse);
  661. X                        epromptlen += tcl_rev;
  662. X                    }
  663. X                    break;
  664. X                case 'D':    /* insert current directory */
  665. X                case 'J':
  666. X                    if ((flag == 'J') && (remote_is_unix)) {
  667. X                        /* Not the whole path, just the dir name. */
  668. X                        dname = rindex(cwd, '/');
  669. X                        if (dname == NULL)
  670. X                            dname = cwd;
  671. X                        else if ((dname != cwd) && (dname[1]))
  672. X                            ++dname;
  673. X                    } else
  674. X                        dname = cwd;
  675. X                    if (dname[0]) {
  676. X                        q = Strpcpy(q, dname);
  677. X                        q = Strpcpy(q, " ");
  678. X                    }
  679. X                    break;
  680. X                case 'H':    /* insert name of connected host */
  681. X                    if (logged_in) {
  682. X                        (void) sprintf(str, "%s ", hostname);
  683. X                        q = Strpcpy(q, str);
  684. X                    }
  685. X                    break;
  686. X                case 'C':  /* Insert host:path (colon-mode format. */
  687. X                    if (logged_in) {
  688. X                        (void) sprintf(str, "%s:%s ", hostname, cwd);
  689. X                        q = Strpcpy(q, str);
  690. X                    } else
  691. X                        q = Strpcpy(q, "(not connected)");
  692. X                    break;
  693. X                case 'c':
  694. X                    if (logged_in) {
  695. X                        (void) sprintf(str, "%s:%s\n", hostname, cwd);
  696. X                        q = Strpcpy(q, str);
  697. X                        lastlinestart = q;    /* there is a \n at the end. */
  698. X                        epromptlen = 0;
  699. X                    }
  700. X                    break;
  701. X                case '!':
  702. X                case 'E':    /* insert event number */
  703. X                    (void) sprintf(eventstr, "%ld", eventnumber);
  704. X                    q = Strpcpy(q, eventstr);
  705. X                    break;
  706. X                default:
  707. X                    *q++ = *p;    /* just copy it; unknown switch */
  708. X            } else
  709. X                *q++ = *p;
  710. X        }
  711. X        *q = '\0';
  712. X    } else 
  713. X        (void) strcpy(prompt2, prompt);
  714. X    
  715. X    if (percent_flags) {
  716. X        /*    only strftime if the user requested it (with a %something),
  717. X            otherwise don't waste time doing nothing. */
  718. X        (void) time(&tyme);
  719. X        (void) Strncpy(str, prompt2);
  720. X        (void) strftime(prompt2, sizeof(str), str, localtime(&tyme));
  721. X    }
  722. X    epromptlen = (size_t) ((long) strlen(lastlinestart) - (long) epromptlen);
  723. X    return (prompt2);
  724. X}    /* strprompt */
  725. X
  726. X
  727. X/*
  728. X * Slice a string up into argc/argv.
  729. X */
  730. X
  731. Xvoid makeargv(void)
  732. X{
  733. X    char **argp;
  734. X
  735. X    margc = 0;
  736. X    argp = margv;
  737. X    stringbase = line;        /* scan from first of buffer */
  738. X    argbase = argbuf;        /* store from first of buffer */
  739. X    slrflag = 0;
  740. X    while (*argp++ = slurpstring())
  741. X        margc++;
  742. X}    /* makeargv */
  743. X
  744. X
  745. X
  746. X
  747. X/*
  748. X * Parse string into argbuf;
  749. X * implemented with FSM to
  750. X * handle quoting and strings
  751. X */
  752. Xchar *slurpstring(void)
  753. X{
  754. X    int got_one = 0;
  755. X    register char *sb = stringbase;
  756. X    register char *ap = argbase;
  757. X    char *tmp = argbase;        /* will return this if token found */
  758. X
  759. X    if (*sb == '!' || *sb == '$') {    /* recognize ! as a token for shell */
  760. X        switch (slrflag) {    /* and $ as token for macro invoke */
  761. X            case 0:
  762. X                slrflag++;
  763. X                stringbase++;
  764. X                return ((*sb == '!') ? "!" : "$");
  765. X                /* NOTREACHED */
  766. X            case 1:
  767. X                slrflag++;
  768. X                altarg = stringbase;
  769. X                break;
  770. X            default:
  771. X                break;
  772. X        }
  773. X    }
  774. X
  775. XS0:
  776. X    switch (*sb) {
  777. X
  778. X    case '\0':
  779. X        goto OUT;
  780. X
  781. X    case ' ':
  782. X    case '\t':
  783. X    case '\n':
  784. X    case '=':
  785. X        sb++; goto S0;
  786. X
  787. X    default:
  788. X        switch (slrflag) {
  789. X            case 0:
  790. X                slrflag++;
  791. X                break;
  792. X            case 1:
  793. X                slrflag++;
  794. X                altarg = sb;
  795. X                break;
  796. X            default:
  797. X                break;
  798. X        }
  799. X        goto S1;
  800. X    }
  801. X
  802. XS1:
  803. X    switch (*sb) {
  804. X
  805. X    case ' ':
  806. X    case '\t':
  807. X    case '\n':
  808. X    case '=':
  809. X    case '\0':
  810. X        goto OUT;    /* end of token */
  811. X
  812. X    case '\\':
  813. X        sb++; goto S2;    /* slurp next character */
  814. X
  815. X    case '"':
  816. X        sb++; goto S3;    /* slurp quoted string */
  817. X
  818. X    default:
  819. X        *ap++ = *sb++;    /* add character to token */
  820. X        got_one = 1;
  821. X        goto S1;
  822. X    }
  823. X
  824. XS2:
  825. X    switch (*sb) {
  826. X
  827. X    case '\0':
  828. X        goto OUT;
  829. X
  830. X    default:
  831. X        *ap++ = *sb++;
  832. X        got_one = 1;
  833. X        goto S1;
  834. X    }
  835. X
  836. XS3:
  837. X    switch (*sb) {
  838. X
  839. X    case '\0':
  840. X        goto OUT;
  841. X
  842. X    case '"':
  843. X        sb++; goto S1;
  844. X
  845. X    default:
  846. X        *ap++ = *sb++;
  847. X        got_one = 1;
  848. X        goto S3;
  849. X    }
  850. X
  851. XOUT:
  852. X    if (got_one)
  853. X        *ap++ = '\0';
  854. X    argbase = ap;            /* update storage pointer */
  855. X    stringbase = sb;        /* update scan pointer */
  856. X    if (got_one) {
  857. X        return(tmp);
  858. X    }
  859. X    switch (slrflag) {
  860. X        case 0:
  861. X            slrflag++;
  862. X            break;
  863. X        case 1:
  864. X            slrflag++;
  865. X            altarg = (char *) 0;
  866. X            break;
  867. X        default:
  868. X            break;
  869. X    }
  870. X    return((char *)0);
  871. X}    /* slurpstring */
  872. X
  873. X/*
  874. X * Help command.
  875. X * Call each command handler with argc == 0 and argv[0] == name.
  876. X */
  877. Xint
  878. Xhelp(int argc, char **argv)
  879. X{
  880. X    register struct cmd        *c;
  881. X    int                        showall = 0, helpall = 0;
  882. X    char                    *arg;
  883. X    int                        i, j, k;
  884. X    int                     nRows, nCols;
  885. X    int                     nCmds2Print;
  886. X    int                     screenColumns;
  887. X    int                     len, widestName;
  888. X    char                     *cp, **cmdnames, spec[16];
  889. X
  890. X    if (argc == 2) {
  891. X        showall = (strcmp(argv[1], "showall") == 0);
  892. X        helpall = (strcmp(argv[1], "helpall") == 0);
  893. X    }
  894. X    if (argc == 1 || showall)  {
  895. X        (void) printf("\
  896. XCommands may be abbreviated.  'help showall' shows aliases, invisible and\n\
  897. Xunsupported commands.  'help <command>' gives a brief description of <command>.\n\n");
  898. X
  899. X        for (c = cmdtab, nCmds2Print=0; c->c_name != NULL; c++) 
  900. X            if (!c->c_hidden || showall)
  901. X                nCmds2Print++;
  902. X
  903. X        if ((cmdnames = (char **) malloc(sizeof(char *) * nCmds2Print)) == NULL)
  904. X            fatal("out of memory!");
  905. X
  906. X        for (c = cmdtab, i=0, widestName=0; c->c_name != NULL; c++) {
  907. X            if (!c->c_hidden || showall) {
  908. X                cmdnames[i++] = c->c_name;
  909. X                len = (int) strlen(c->c_name);
  910. X                if (len > widestName)
  911. X                    widestName = len;
  912. X            }
  913. X        }
  914. X
  915. X        if ((cp = getenv("COLUMNS")) == NULL)
  916. X            screenColumns = 80;
  917. X        else
  918. X            screenColumns = atoi(cp);
  919. X
  920. X        widestName += 2;    /* leave room for white-space in between cols. */
  921. X        nCols = screenColumns / widestName;
  922. X        /* if ((screenColumns % widestName) > 0) nCols++; */
  923. X        nRows = nCmds2Print / nCols;
  924. X        if ((nCmds2Print % nCols) > 0)
  925. X            nRows++;
  926. X
  927. X        (void) sprintf(spec, "%%-%ds", widestName);
  928. X        for (i=0; i<nRows; i++) {
  929. X            for (j=0; j<nCols; j++) {
  930. X                k = nRows*j + i;
  931. X                if (k < nCmds2Print)
  932. X                    (void) printf(spec, cmdnames[k]);
  933. X            }
  934. X            (void) printf("\n");
  935. X        }
  936. X        free(cmdnames);
  937. X    } else if (helpall) {
  938. X        /* Really intended to debug the help strings. */
  939. X        for (c = cmdtab; c->c_name != NULL; c++) {
  940. X            cmd_help(c);
  941. X            cmd_usage(c);
  942. X        }
  943. X    } else while (--argc > 0) {
  944. X        arg = *++argv;
  945. X        c = getcmd(arg);
  946. X        if (c == (struct cmd *)-1)
  947. X            (void) printf("?Ambiguous help command %s\n", arg);
  948. X        else if (c == (struct cmd *)0)
  949. X            (void) printf("?Invalid help command %s\n", arg);
  950. X        else {
  951. X            cmd_help(c);
  952. X            cmd_usage(c);
  953. X        }
  954. X    }
  955. X    return NOERR;
  956. X}    /* help */
  957. X
  958. X
  959. X/*
  960. X * If the user wants to, s/he can specify the maximum size of the log
  961. X * file, so it doesn't waste too much disk space.  If the log is too
  962. X * fat, trim the older lines (at the top) until we're under the limit.
  963. X */
  964. Xvoid trim_log(void)
  965. X{
  966. X    FILE                *new, *old;
  967. X    struct stat            st;
  968. X    long                fat;
  969. X    string                tmplogname, str;
  970. X
  971. X    if (logsize <= 0 || *logfname == 0 || stat(logfname, &st) ||
  972. X        (old = fopen(logfname, "r")) == NULL)
  973. X        return;    /* never trim, or no log */
  974. X    fat = st.st_size - logsize;
  975. X    if (fat <= 0L) return;    /* log too small yet */
  976. X    while (fat > 0L) {
  977. X        if (FGets(str, old) == NULL) return;
  978. X        fat -= (long) strlen(str);
  979. X    }
  980. X    /* skip lines until a new site was opened */
  981. X    while (1) {
  982. X        if (FGets(str, old) == NULL) {
  983. X            (void) fclose(old);
  984. X            (void) unlink(logfname);
  985. X            return;    /* nothing left, start anew */
  986. X        }
  987. X        if (*str != '\t') break;
  988. X    }
  989. X    
  990. X    /* copy the remaining lines in "old" to "new" */
  991. X    (void) Strncpy(tmplogname, logfname);
  992. X    tmplogname[strlen(tmplogname) - 1] = 'T';
  993. X    if ((new = fopen(tmplogname, "w")) == NULL) {
  994. X        (void) PERROR("trim_log", tmplogname);
  995. X        return;
  996. X    }
  997. X    (void) fputs(str, new);
  998. X    while (FGets(str, old))
  999. X        (void) fputs(str, new);
  1000. X    (void) fclose(old); (void) fclose(new);
  1001. X    if (unlink(logfname) < 0)
  1002. X        PERROR("trim_log", logfname);
  1003. X    if (rename(tmplogname, logfname) < 0)
  1004. X        PERROR("trim_log", tmplogname);
  1005. X}    /* trim_log */
  1006. X
  1007. X
  1008. X
  1009. X
  1010. Xint CheckNewMail(void)
  1011. X{
  1012. X    struct stat stbuf;
  1013. X
  1014. X    if (*mail_path == '\0') return 0;
  1015. X    if (stat(mail_path, &stbuf) < 0) {    /* cant find mail_path so we'll */
  1016. X        *mail_path = '\0';                /* never check it again */
  1017. X        return 0;
  1018. X    }
  1019. X
  1020. X    /*
  1021. X     * Check if the size is non-zero and the access time is less than
  1022. X     * the modify time -- this indicates unread mail.
  1023. X     */
  1024. X    if ((stbuf.st_size != 0) && (stbuf.st_atime <= stbuf.st_mtime)) {
  1025. X        if (stbuf.st_mtime > mbox_time) {
  1026. X            (void) printf("%s\n", NEWMAILMESSAGE);
  1027. X            mbox_time = stbuf.st_mtime;
  1028. X        }
  1029. X        return 1;
  1030. X    }
  1031. X
  1032. X    return 0;
  1033. X}    /* CheckNewMail */
  1034. X
  1035. X
  1036. X
  1037. X#ifdef CURSES
  1038. Xvoid termcap_get(char *dest, char *attr)
  1039. X{
  1040. X    static char area[1024];
  1041. X    static char *s = area;
  1042. X    char buf[32];
  1043. X    int foo;
  1044. X
  1045. X    (void) Strncpy(buf, tgetstr(attr, &s));
  1046. X    if (buf[0]) {
  1047. X         for (foo = 0; (buf[foo] <= '9') && (buf[foo] >= '0'); foo++); 
  1048. X         if ((dest = (char *)malloc(strlen(&(buf[foo])) + 1)) == NULL) 
  1049. X             *dest = 0;
  1050. X         else 
  1051. X             (void) strcpy(dest, &(buf[foo]));
  1052. X     } else 
  1053. X         *dest = 0;
  1054. X}    /* termcap_get */
  1055. X
  1056. X
  1057. X  
  1058. Xvoid termcap_init(void)
  1059. X{
  1060. X    static char area[1024];
  1061. X    static char *s = area;
  1062. X    char *term;
  1063. X
  1064. X    if ((term = getenv("TERM")) == NULL) {
  1065. X        term = "dumb";  /* TAR */
  1066. X        ansi_escapes = 0;
  1067. X    }
  1068. X    if (tgetent(tcbuf,term) != 1) {
  1069. X        (void) fprintf(stderr,"Can't get termcap entry for terminal [%s]\n", term);
  1070. X    } else {
  1071. X        termcap_get(tcap_normal, "me");
  1072. X        termcap_get(tcap_boldface, "md");
  1073. X        termcap_get(tcap_underline, "us");
  1074. X        termcap_get(tcap_reverse, "so");
  1075. X        tcl_normal = strlen(tcap_normal);
  1076. X        tcl_bold = strlen(tcap_boldface);
  1077. X        tcl_uline = strlen(tcap_underline);
  1078. X        tcl_rev = strlen(tcap_reverse);
  1079. X    }
  1080. X}    /* termcap_init */
  1081. X
  1082. X
  1083. X
  1084. Xstatic int c_output(int c)
  1085. X{
  1086. X    putchar(c);
  1087. X}    /* c_output */
  1088. X
  1089. X
  1090. X
  1091. X
  1092. Xvoid tcap_put(char *cap)
  1093. X{
  1094. X    tputs(cap, 0, c_output);
  1095. X}    /* tcap_put */
  1096. X
  1097. X#endif /* CURSES */
  1098. X
  1099. X/* eof main.c */
  1100. END_OF_FILE
  1101.   if test 23284 -ne `wc -c <'main.c'`; then
  1102.     echo shar: \"'main.c'\" unpacked with wrong size!
  1103.   fi
  1104.   # end of 'main.c'
  1105. fi
  1106. if test -f 'ncftp.1' -a "${1}" != "-c" ; then 
  1107.   echo shar: Will not clobber existing file \"'ncftp.1'\"
  1108. else
  1109.   echo shar: Extracting \"'ncftp.1'\" \(33324 characters\)
  1110.   sed "s/^X//" >'ncftp.1' <<'END_OF_FILE'
  1111. X.\"-------
  1112. X.\" Man page portability notes
  1113. X.\"
  1114. X.\" These are some notes on conventions to maintain for greatest
  1115. X.\" portability of this man page to various other versions of
  1116. X.\" nroff.
  1117. X.\"
  1118. X.\" When you want a \ to appear in the output, use \e in the man page.
  1119. X.\" (NOTE this comes up in the rc grammar, where to print out '\n' the
  1120. X.\" man page must contain '\en'.)
  1121. X.\"
  1122. X.\" Evidently not all versions of nroff allow the omission of the
  1123. X.\" terminal " on a macro argument.  Thus what could be written
  1124. X.\"
  1125. X.\" .Cr "exec >[2] err.out
  1126. X.\"
  1127. X.\" in true nroffs must be written
  1128. X.\"
  1129. X.\" .Cr "exec >[2] err.out"
  1130. X.\"
  1131. X.\" instead.
  1132. X.\"
  1133. X.\" Use symbolic font names (e.g. R, I, B) instead of the standard
  1134. X.\" font positions 1, 2, 3.  Note that for Xf to work the standard
  1135. X.\" font names must be single characters.
  1136. X.\"
  1137. X.\" Note that sentences should end at the end of a line.  nroff and
  1138. X.\" troff will supply the correct intersentence spacing, but only if
  1139. X.\" the sentences end at the end of a line.  Explicit spaces, if given,
  1140. X.\" are apparently honored and the normal intersentence spacing is
  1141. X.\" supressed.
  1142. X.\"
  1143. X.\" DaviD W. Sanderson
  1144. X.\"-------
  1145. X.\" Dd    distance to space vertically before a "display"
  1146. X.\" These are what n/troff use for interparagraph distance
  1147. X.\"-------
  1148. X.if t .nr Dd .4v
  1149. X.if n .nr Dd 1v
  1150. X.\"-------
  1151. X.\" Sp    space down the interparagraph distance
  1152. X.\"-------
  1153. X.de Sp
  1154. X.sp \\n(Ddu
  1155. X..
  1156. X.\"-------
  1157. X.\" Ds    begin a display, indented .5 inches from the surrounding text.
  1158. X.\"
  1159. X.\" Note that uses of Ds and De may NOT be nested.
  1160. X.\"-------
  1161. X.de Ds
  1162. X.Sp
  1163. X.in +0.5i
  1164. X.nf
  1165. X..
  1166. X.\"-------
  1167. X.\" De    end a display (no trailing vertical spacing)
  1168. X.\"-------
  1169. X.de De
  1170. X.fi
  1171. X.in
  1172. X..
  1173. X.TH NcFTP 1 "" NCEMRSoft
  1174. X.\"-------
  1175. X.SH "NAME"
  1176. X.\"-------
  1177. XNcFTP \(em Internet file transfer program
  1178. X.\"-------
  1179. X.SH "SYNOPSIS"
  1180. X.\"-------
  1181. X.B ncftp
  1182. X.RI [ "program options" ]
  1183. X.RI [[ "open options" ]
  1184. X.IR hostname [\c
  1185. X.B :\c
  1186. X.IR pathname ]]
  1187. X.\"-------
  1188. X.SH "DESCRIPTION"
  1189. X.\"-------
  1190. X.I NcFTP
  1191. Xis a user interface to the Internet standard
  1192. X.IR "File Transfer Protocol" .
  1193. XThis program allows a user to transfer files to and from a remote network
  1194. Xsite, and offers additional features that are not found in the standard
  1195. Xinterface,
  1196. X.IR ftp .
  1197. X.\"-------
  1198. X.SH "FEATURES"
  1199. X.\"-------
  1200. XProgram options will be explained later in this document.
  1201. XLet's get down to business and go over the features
  1202. Xthat make this program worthwhile.
  1203. X.PP
  1204. XHere is the list of section headers; I have my $MANPAGER environment
  1205. Xvariable set to use
  1206. X.RB `` "less \-i" ''
  1207. Xso that I can skip to the section I
  1208. Xwant (otherwise,
  1209. X.BI / regex
  1210. Xcommands to the pager won't match the section
  1211. Xheaders because of the formatting codes;
  1212. Xthe
  1213. X.RB `` \-i ''
  1214. Xcan search through the formatting codes)
  1215. X.Ds
  1216. XEstablishing the remote connection
  1217. XFormat of the RC file
  1218. XThe Recent-sites file
  1219. XRedialing a busy remote site
  1220. XSupplying a sitename from your shell's command line
  1221. XUsing Colon-mode
  1222. XUsing FTP-cat and FTP-more mode
  1223. XSupplying a port number with the open command
  1224. XDisplaying and changing program variables
  1225. XProgram variables
  1226. XListing a remote directory
  1227. XViewing a remote directory with your pager
  1228. XRedisplaying the last directory listing
  1229. XFetching files from the remote host
  1230. XViewing a remote file with your pager
  1231. XCreating a message file on the remote host
  1232. XLooking up site names and addresses
  1233. XChecking the configuration of the program
  1234. XUsing the command shell
  1235. XCustomizing the prompt
  1236. XKeeping a log of your file transfers
  1237. XProgram options
  1238. XA sample RC file
  1239. X.De
  1240. X.\"-------
  1241. X.SH "Establishing the remote connection"
  1242. X.\"-------
  1243. XJust opening a connection to a remote server was inconvenient enough in the
  1244. Xstock
  1245. X.I ftp
  1246. Xprogram to justify writing this program.
  1247. XHere at
  1248. X.IR NCEMRSoft ,
  1249. Xwe want to do our business as quickly and painlessly as possible.
  1250. XWe'd
  1251. Xrather save time and wear and tear on our metacarpals than bother typing
  1252. Xentire site names, usernames, and email addresses masquerading as passwords,
  1253. Xand setting binary mode.
  1254. X.PP
  1255. XWe made all connections anonymous by default, and we automatically send our
  1256. Xemail address for the password on those connections.
  1257. XWe allowed for site
  1258. Xnames to be abbreviated.
  1259. X.PP
  1260. XFor each commonly accessed site, you can put an entry in your program
  1261. Xpreferences file (let's call it the ``ncftprc file.''or ``RC file.''for short).
  1262. XTo open the site, from the command shell all you do is type:
  1263. X.Ds
  1264. Xopen wuarchive.wustl.edu
  1265. X.De
  1266. X.PP
  1267. Xor
  1268. X.Ds
  1269. Xo wuarchive.wustl.edu
  1270. X.De
  1271. X.PP
  1272. XAs promised, you can abbreviate that further.
  1273. XJust use any abbreviation that
  1274. Xwould match only the site you had in mind.
  1275. XFor the previous example, you
  1276. Xcould try:
  1277. X.Ds
  1278. Xo wuarc
  1279. Xo wustl
  1280. Xo stl
  1281. Xo wu
  1282. X.De
  1283. X.PP
  1284. XAny of those abbreviations would open wuarchive.wustl.edu anonymously,
  1285. Xsending your anon-password (usually set to your email address) as the
  1286. Xpassword.
  1287. XKeep in mind that the program tries opening the first site
  1288. Xthat matches the abbreviation you supplied.
  1289. XSo:
  1290. X.Ds
  1291. Xo w
  1292. X.De
  1293. X.PP
  1294. Xmight match a site named bowser.nintendo.jp if that site appeared before
  1295. Xyour entry for wuarchive.wustl.edu.
  1296. X.PP
  1297. XMost of the time we open remote sites anonymously, but
  1298. Xthere are times where you need to specifically open a site with an actual
  1299. Xusername and password.
  1300. XLet's say my partner, Phil Dietz, wants to FTP
  1301. Xsomething out of my account.
  1302. XPerhaps he wants to fetch the latest version
  1303. Xof the source code to
  1304. X.I NcFTP
  1305. Xso he can optimize something or add a new feature behind my back.
  1306. XSince the
  1307. Xprogram opens remote sites anonymously by default (actually, you can change
  1308. Xthis behavior; more on that later), he would have to specify a flag to the
  1309. X.I open
  1310. Xcommand so he can supply my username and password.
  1311. XHe would try:
  1312. X.Ds
  1313. Xo \-u sphygmomanometer.unl.edu
  1314. X.De
  1315. X.PP
  1316. Xor, more likely:
  1317. X.Ds
  1318. Xo \-u sph
  1319. X.De
  1320. X.PP
  1321. XThen the program would prompt him for a username (login, whatever) and a
  1322. Xpassword:
  1323. X.Ds
  1324. XLogin Name (pdietz): mgleason
  1325. XPassword: ********
  1326. X.De
  1327. X.PP
  1328. XIf he got it right, he could raid my stuff.
  1329. XIf not, he'd probably drop
  1330. Xme an email asking me to quit changing my password so often.
  1331. X.PP
  1332. XThere are even times where you want to FTP from your own account, like if
  1333. Xyou are debugging an FTP client you wrote.
  1334. XAt this prompt:
  1335. X.Ds
  1336. XLogin Name (mgleason):
  1337. X.De
  1338. X.PP
  1339. XI could just hit return to tell the program that I want ``mgleason.''as my
  1340. Xusername, then I would enter my password.
  1341. X.\"-------
  1342. X.SH "Format of the RC file"
  1343. X.\"-------
  1344. XThis release of the program is somewhat compatible with the stock
  1345. X.I ftp
  1346. Xprogram's
  1347. X.B ".netrc"
  1348. Xfile.
  1349. XHowever, I can promise you that in the near future the program will
  1350. Xuse a new format, so don't invest too much time in it.
  1351. X.PP
  1352. XThe RC file can be named
  1353. X.RB `` ncftprc ,''
  1354. X.RB `` netrc ,''
  1355. Xor
  1356. X.RB `` .ncftprc ,''
  1357. Xbut it is usually named
  1358. X.RB `` .netrc ''
  1359. Xso it can be used with the stock
  1360. X.I ftp
  1361. Xprogram.
  1362. X.I NcFTP
  1363. Xlooks in the current working directory for any of those files, and then in
  1364. Xyour home directory, and after that it gives up (which is OK, because RC
  1365. Xfiles aren't mandatory).
  1366. X.PP
  1367. XThe file usually starts with
  1368. X.I #set
  1369. Xand
  1370. X.I #unset
  1371. Xcommands that do things
  1372. Xto the programs variables.
  1373. XThe reason for the ``#.''is so the stock
  1374. X.I ftp
  1375. Xprogram will think they are comments.
  1376. XYou might have this appearing as
  1377. Xthe first few lines in your RC file (I'll explain later):
  1378. X.Ds
  1379. X#set debug 1
  1380. X#set pager "less \-EMi"
  1381. X#unset startup\-msg
  1382. X.De
  1383. X.PP
  1384. XAfter those, you put in machine entries for each of your favorite sites.
  1385. XLet's put in an entry for wuarchive.wustl.edu.
  1386. XFirst you would put:
  1387. X.Ds
  1388. Xmachine wuarchive.wustl.edu
  1389. X.De
  1390. X.PP
  1391. XThen you could put in your username, password, and account if you like:
  1392. X.Ds
  1393. Xuser anonymous
  1394. Xpassword \-mgleason@cse.unl.edu
  1395. Xaccount wuarc.does.not.use.accounts
  1396. X.De
  1397. X.PP
  1398. XFollowing that, you would add the startup macro that is run
  1399. Xeach time you connect to wuarchive.
  1400. XYou must start it with this line:
  1401. X.Ds
  1402. Xmacdef init
  1403. X.De
  1404. X.PP
  1405. XThen put in the commands you want to do:
  1406. X.Ds
  1407. Xcd /graphics/gif
  1408. Xls \-lt
  1409. X.De
  1410. X.PP
  1411. XAfter that, you end the macro with a blank line (important!).
  1412. XThe finished machine entry would look like the following.
  1413. XTo make the transition to the impending new format less painful,
  1414. XI recommend you adhere to this format:
  1415. X.ta 6m +6m
  1416. X.Ds
  1417. Xmachine wuarchive.wustl.edu
  1418. X    user anonymous
  1419. X    password \-mgleason@cse.unl.edu
  1420. X    account wuarc.does.not.use.accounts
  1421. X    macdef init
  1422. X        cd /graphics/gif
  1423. X        ls \-lt
  1424. X.RI \t( "mandatory blank line to end the macro" )
  1425. X.De
  1426. X.PP
  1427. XOf course, if all you want to do is open wuarchive anonymously, you
  1428. Xneedn't bother with the ``user,.''``password,.''and ``account.''lines.
  1429. XYou may want to put them in if you plan on using the stock
  1430. X.I ftp
  1431. Xprogram, though.
  1432. XTry something like this:
  1433. X.ta 6m +6m
  1434. X.Ds
  1435. Xmachine wuarchive.wustl.edu
  1436. X    macdef init
  1437. X        cd /graphics/gif
  1438. X        ls \-lt
  1439. X.RI \t( "mandatory blank line to end the macro" )
  1440. X.De
  1441. X.PP
  1442. XYou can tell the program to not run the startup macro if you supply
  1443. X.B "\-i"
  1444. Xto the
  1445. X.I open
  1446. Xcommand.
  1447. X.PP
  1448. XReally, you should only bother adding entries for sites that you want to
  1449. Xrun startup macros upon connection.
  1450. XThe next section explains why.
  1451. X.\"-------
  1452. X.SH "The Recent-sites file"
  1453. X.\"-------
  1454. XEach time you open a site, the program saves the name of the site and the
  1455. Xlast directory you were in to the
  1456. X.I recent-sites file
  1457. Xwhich is named
  1458. X.B ".ncrecent"
  1459. Xand placed in your home directory.
  1460. XThe program saves a
  1461. Xpredetermined number of these sites in the file, and when it reaches the
  1462. Xlimit, it discards the oldest entry so it can add a new one.
  1463. X.PP
  1464. XYou can just go ahead and use the name of the site you want with the
  1465. X.I open
  1466. Xcommand if you know it is in the
  1467. X.I recent\-file
  1468. X(and you can abbreviate the
  1469. Xname, just like those in the RC file).
  1470. XBut if you cannot remember what the
  1471. Xname of the site you want, all you do is run the
  1472. X.I open
  1473. Xcommand with
  1474. Xno site parameter:
  1475. X.Ds
  1476. Xopen
  1477. X.De
  1478. X.PP
  1479. XThis will pop up a list of the sites in the
  1480. X.IR "recent-file" ,
  1481. Xand sites in your RC file.
  1482. XAt the open prompt, just type the name (or an
  1483. Xabbreviation of that name) or the number preceding the site name to open
  1484. Xthat site.
  1485. XAfter opening the site you wanted, the program sets the remote
  1486. Xworking directory to the same one you left in the last time you called.
  1487. X.PP
  1488. XIf you don't like the idea of having the sites you called stored on disk,
  1489. Xyou can turn this feature off using an
  1490. X.I unset
  1491. Xcommand, explained later.
  1492. X.\"-------
  1493. X.SH "Redialing a busy remote site"
  1494. X.\"-------
  1495. XSome remote sites limit the number of leeches, er, anonymous connections
  1496. Xat a time to reduce the load on the host computer.
  1497. XYou can use the
  1498. X.I open
  1499. Xcommand's redial feature to keep attempting connections until you get on,
  1500. Xalthough that is not a very polite thing to do.
  1501. XThe simplest way to do
  1502. Xthis would be to just supply the
  1503. X.B \-r
  1504. Xoption:
  1505. X.Ds
  1506. Xopen \-r wuarc
  1507. X.De
  1508. X.PP
  1509. XThere are also options you can use to tweak redial.
  1510. XThe
  1511. X.B \-d
  1512. Xflag sets
  1513. Xthe delay between dials, and the
  1514. X.B \-g
  1515. Xflag sets a limit on how many dials
  1516. Xshould be attempting before giving up.
  1517. XIf you don't supply
  1518. X.B \-g
  1519. Xthe program will dial a day and forever (which my Number Theory professor,
  1520. XDr. Mientka, says is longer than forever and a day)
  1521. Xuntil it connects successfully, or until you get sick of waiting and hit the
  1522. Xinterrupt key (usually ^C).
  1523. X.PP
  1524. XThis example dials wuarchive every ten minutes, giving up after twenty
  1525. Xattempts.
  1526. XNote that the redial delay is specified in seconds:
  1527. X.Ds
  1528. Xopen \-r \-d 600 \-g 20 wuarc
  1529. X.De
  1530. X.PP
  1531. XPlease be considerate when you use redialing, so you won't tax the network.
  1532. XSite administrators can and do get angry when they get flooded with
  1533. Xconnections.
  1534. X.\"-------
  1535. X.SH "Supplying a sitename from your shell's command line"
  1536. X.\"-------
  1537. XWhen you run the program:
  1538. X.Ds
  1539. Xncftp
  1540. X.De
  1541. X.PP
  1542. Xby itself does nothing and waits for you to type commands to the program's
  1543. Xown shell.
  1544. XJust like the stock
  1545. X.I ftp
  1546. Xprogram, you can supply a site name
  1547. Xon the command line:
  1548. X.Ds
  1549. Xncftp wuarchive.wustl.edu
  1550. X.De
  1551. X.PP
  1552. XYou can also use abbreviations as usual:
  1553. X.Ds
  1554. Xncftp wuarc
  1555. X.De
  1556. X.PP
  1557. XThis is equivalent to running the program, then issuing an
  1558. X.I open
  1559. Xcommand to open wuarchive.
  1560. X.\"-------
  1561. X.SH "Using Colon-mode"
  1562. X.\"-------
  1563. XThe
  1564. X.I open
  1565. Xcommand is not a one-trick pony.
  1566. XAnother option is what I call
  1567. X.IR "colon-mode" .
  1568. XThis feature is used (most of the time) from your shell's
  1569. Xcommand line.
  1570. X.PP
  1571. XIn ancient times, way back during the Disco era, you could use a program
  1572. Xcalled
  1573. X.I tftp
  1574. Xto fetch a file using the Internet standard
  1575. X.I Trivial File Transfer Protocol.
  1576. XYou could use that program to do something like this
  1577. Xfrom within its shell:
  1578. X.Ds
  1579. Xget wuarchive.wustl.edu:/graphics/gif/README
  1580. X.De
  1581. X.PP
  1582. Xand that would call wuarchive and fetch the
  1583. X.B README
  1584. Xfile.
  1585. X.PP
  1586. XYou can use this program to do the same thing from your shell's command
  1587. Xline:
  1588. X.Ds
  1589. Xcsh> ncftp wuarchive.wustl.edu:/graphics/gif/README
  1590. Xcsh> head README
  1591. X.De
  1592. X.PP
  1593. XThis tells your shell, in this case the ``c-shell.''to run
  1594. X.IR NcFTP ,
  1595. Xwhich
  1596. Xwould open wuarchive, fetch
  1597. X.B /pub/README
  1598. Xand write the file
  1599. X.B ./README
  1600. Xin the your current working directory, and then exits.
  1601. XThis is nice if you don't
  1602. Xwant to browse around the remote site, and you know exactly want you want.
  1603. XIt would also come in handy in shell scripts, where you don't want to
  1604. Xenter the command shell, and might not want the program to spew output.
  1605. X.PP
  1606. XYou can use
  1607. X.I colon-mode
  1608. Xto set the starting remote working directory also:
  1609. X.Ds
  1610. Xcsh> ncftp wuarchive.wustl.edu:/graphics/gif
  1611. X.De
  1612. X.PP
  1613. XThis would run the program, open wuarchive, and
  1614. X.I cd
  1615. Xto the gif directory, then run the program's command shell so you can
  1616. Xbrowse.
  1617. X.PP
  1618. X.I Colon-mode
  1619. Xis also available from within the program's command shell.
  1620. XAt a prompt you can do stuff like this:
  1621. X.Ds
  1622. Xncftp> open wuarchive.wustl.edu:/graphics/gif/README
  1623. Xncftp> o wuarc:/graphics/gif
  1624. X.De
  1625. X.\"-------
  1626. X.SH "Using FTP-cat and FTP-more mode"
  1627. X.\"-------
  1628. XThere are times where you might not want the program to write a
  1629. X.I colon-mode
  1630. Xfile in the current working directory, or perhaps you want to pipe the
  1631. Xoutput of a remote file into something else.
  1632. X.I Colon-mode
  1633. Xhas options to
  1634. Xdo this.
  1635. XIt was inspired by the guy who wrote the
  1636. X.I ftpcat
  1637. Xperl script.
  1638. XThe
  1639. X.B \-c
  1640. Xoption tells the program to write on the standard
  1641. Xoutput stream.
  1642. XThe
  1643. X.B \-m
  1644. Xoption pipes the file into your pager (like
  1645. X.IR more ")"
  1646. XOf course this won't work if the thing you give
  1647. X.I colon-mode
  1648. Xis a directory!  This example just dumps a remote file to stdout:
  1649. X.Ds
  1650. Xcsh> ncftp \-c wuarc:/graphics/gif/README
  1651. X\&...
  1652. Xcsh>
  1653. X.De
  1654. X.PP
  1655. XThis example redirects a remote file into a different
  1656. Xlocation:
  1657. X.Ds
  1658. Xcsh> ncftp \-c wu:/README > ~pdietz/thesis.tex
  1659. X.De
  1660. X.PP
  1661. XThis one shows how to use a pipeline:
  1662. X.Ds
  1663. Xcsh> ncftp \-c wuarc:/README | tail | wc \-l
  1664. X10
  1665. Xcsh>
  1666. X.De
  1667. X.PP
  1668. XThis shows how to page a remote file:
  1669. X.Ds
  1670. Xcsh> ncftp \-m wuarc:/graphics/gif/README
  1671. X\&...
  1672. Xcsh>
  1673. X.De
  1674. X.\"-------
  1675. X.SH "Supplying a port number with the open command"
  1676. X.\"-------
  1677. XThis option just didn't fit anywhere else, so to finish out the open command,
  1678. X.B \-p
  1679. Xlets you supply a port number if you have to
  1680. X.I ftp
  1681. Xto a site using an nonstandard port number.
  1682. XPersonally, I have yet to use feature, but its
  1683. Xthere for compatibility with the stock
  1684. X.I ftp
  1685. Xprogram.
  1686. X.\"-------
  1687. X.SH "Displaying and changing program variables"
  1688. X.\"-------
  1689. XNow I'll explain the commands unique to
  1690. X.IR NcFTP .
  1691. XThe others should perform the
  1692. Xsame as they would in the stock
  1693. X.I ftp
  1694. Xprogram;
  1695. Xconsult the man page for it if you want those explained,
  1696. Xor use the
  1697. X.I help
  1698. Xcommand for a brief blurb.
  1699. X.PP
  1700. XThe
  1701. X.I show
  1702. Xcommand is used to display program variables and their values.
  1703. X.Ds
  1704. Xshow all
  1705. X.De
  1706. X.PP
  1707. Xor
  1708. X.Ds
  1709. Xshow
  1710. X.De
  1711. X.PP
  1712. Xwould display all the variables with their values.
  1713. X.Ds
  1714. X.RI show " var1 var2 ... varN"
  1715. X.De
  1716. X.PP
  1717. Xwould display each specified variable and its value.
  1718. X.PP
  1719. XThe
  1720. X.I set
  1721. Xcommand changes the value of a program variable.
  1722. XIts syntax is:
  1723. X.Ds
  1724. X.RI set " varname value"
  1725. X.De
  1726. X.PP
  1727. XFor Boolean or Integer variables,
  1728. X.Ds
  1729. X.RI set " varname"
  1730. X.De
  1731. X.PP
  1732. Xwould set the value of the variable
  1733. X.I varname
  1734. Xto
  1735. X.B 1
  1736. X.RB ( true ).
  1737. X.PP
  1738. XThe
  1739. X.I unset
  1740. Xcommand can be used to set the variable to its default value,
  1741. Xor for Boolean and Integer variables, set the value of the variable to
  1742. X.B 0
  1743. X.RB ( false ).
  1744. XFor String variables, you can use this to set the value to an
  1745. Xempty string.
  1746. X.PP
  1747. XYou can use any of those three commands in both the command shell,
  1748. Xor in the RC file with a ``#.''prepended.
  1749. X.\"-------
  1750. X.SH "Program variables"
  1751. X.\"-------
  1752. XEach variable can be one of the following types:
  1753. X.TP
  1754. XBoolean:
  1755. XCan be
  1756. X.RB `` on ''
  1757. Xor
  1758. X.RB `` off ''
  1759. X(you can also use
  1760. X.RB `` 1 ''
  1761. Xor
  1762. X.RB `` 0 .''.
  1763. X.TP
  1764. XInteger:
  1765. XCan be any positive or negative number, or
  1766. X.BR 0 .
  1767. X.TP
  1768. XString:
  1769. XIs a string of characters.
  1770. XIf the string needs to have a space
  1771. Xin it, make sure you surround the whole string with double quotes in a
  1772. X.I set
  1773. Xcommand.
  1774. X.PP
  1775. XVariables follow.
  1776. XSome variables are explained later in the relevant sections.
  1777. X.TP
  1778. X.IR anon\-open " (Boolean)"
  1779. XTells whether the default login mode is anonymous if
  1780. Xon, or if off, will prompt for a username/password.
  1781. XYou can always override this by using either
  1782. X.B \-a
  1783. Xor
  1784. X.B \-u
  1785. Xwith the
  1786. X.I open
  1787. Xcommand.
  1788. X.TP
  1789. X.IR anon\-password " (String)"
  1790. XSends this as the password when you login anonymously.
  1791. XBy default this is your email address.
  1792. X.TP
  1793. X.IR ansi\-escapes " (Boolean)"
  1794. XIf on, the program can use boldface, underline,
  1795. Xand inverse text.
  1796. X.TP
  1797. X.IR auto\-binary " (Boolean)"
  1798. XIf on, sets the transfer type to binary mode
  1799. Ximmediately after connection.
  1800. X.TP
  1801. X.IR debug " (Integer)"
  1802. XSets the debugging level.
  1803. X.TP
  1804. X.IR gateway\-login " (String)"
  1805. XTells which username to use when logging in to
  1806. Xyour firewall gateway host.
  1807. X.TP
  1808. X.IR gateway\-host " (String)"
  1809. XThe site which is acting as your firewall gateway,
  1810. Xor empty if you aren't using one.
  1811. X.TP
  1812. X.IR local\-dir " (String)"
  1813. XThe current local working directory.
  1814. XI like to set this from my RC file,
  1815. Xso all my files go into my download directory.
  1816. X.TP
  1817. X.IR logfile " (String)"
  1818. XThe name of your personal transfer log, or empty
  1819. Xif you aren't using a transfer log.
  1820. X.TP
  1821. X.IR logsize " (Integer)"
  1822. XThe maximum ceiling of your log file, before the program
  1823. Xremoves old entries.
  1824. X.TP
  1825. X.IR mprompt " (Boolean)"
  1826. XIf on, prompts for each remote file expanded from a
  1827. Xwildcard globbing expression.
  1828. X.TP
  1829. X.IR netrc " (String, Read-only)"
  1830. XTells you the name of the RC file in use.
  1831. X.TP
  1832. X.IR pager " (String)"
  1833. XThe pathname and flags of the program used to display
  1834. Xoutput one screenful at a time.
  1835. XThe default is the value of your $PAGER
  1836. Xenvironment variable.
  1837. X.TP
  1838. X.IR prompt " (String)"
  1839. XThe prompt specification that expands into the prompt.
  1840. X.TP
  1841. X.IR progress\-reports " (Integer)"
  1842. XWhich progress meter to use, or 0 if you
  1843. Xdon't want progress reports during file transfers.
  1844. X.TP
  1845. X.IR recent\-list " (Boolean)"
  1846. XIf on, uses and updates the
  1847. X.I recent\-file.
  1848. X.TP
  1849. X.IR remote\-is\-unix " (Boolean)"
  1850. XSet automatically by the program upon connection,
  1851. Xyou may need to use this in a startup macro if the program guessed
  1852. Xthat a remote site was UNIX when it really is not.
  1853. X.TP
  1854. X.IR startup\-msg " (Boolean)"
  1855. XIf on, prints the opening message and tip.
  1856. X.TP
  1857. X.IR tips " (Boolean)"
  1858. XIf on, prints a tip on how to use the program better each
  1859. Xtime you run the program.
  1860. X.TP
  1861. X.IR type " (String)"
  1862. XThe name of the file transfer mode in use,
  1863. Xsuch as
  1864. X.RB `` binary ''
  1865. Xor
  1866. X.RB `` ascii .''
  1867. X.TP
  1868. X.IR verbose " (String/Integer)"
  1869. XControls the amount of output spewed by the program.
  1870. XYou can supply either the first character of the name of the
  1871. Xverbosity level, or its number:
  1872. X.RS
  1873. X.TP
  1874. X.IR "Q" "uiet (\-1)"
  1875. XWon't print any output at all, even if an error occurs.
  1876. X.TP
  1877. X.IR "E" "rrors Only (0)"
  1878. XNo output, except when errors occur.
  1879. X.TP
  1880. X.IR "T" "erse (1)"
  1881. XPrints errors, and useful output from the remote host.
  1882. X.TP
  1883. X.IR "V" "erbose (2)"
  1884. XPrints everything, even junk output from the remote end.
  1885. X.RE
  1886. X.\"-------
  1887. X.SH "Listing a remote directory"
  1888. X.\"-------
  1889. XThe
  1890. X.I ls
  1891. Xand
  1892. X.I dir
  1893. Xcommands perform in a similar manner to those of the
  1894. Xstock
  1895. X.I ftp
  1896. Xprogram.
  1897. X.PP
  1898. XThe
  1899. X.I ls
  1900. Xcommand sends the FTP command ``NLST.''for you.
  1901. XThis command has been set so that it defaults
  1902. Xto always listing files in columns (this is the
  1903. X.B \-C
  1904. Xoption given to the UNIX
  1905. X.I ls
  1906. Xcommand) and appending
  1907. Xmetacharacters to each item name (this is the
  1908. X.B \-F
  1909. Xoption), so you can
  1910. Xsee which items are directories, files, links, etcetera.
  1911. XIf you don't want
  1912. Xyour items columnized, you can try using the
  1913. X.B \-1
  1914. Xoption with
  1915. X.I ls
  1916. Xto print one item per line.
  1917. X.PP
  1918. XThe
  1919. X.I dir
  1920. Xcommand sends the FTP command ``LIST.''for you, which instead
  1921. Xof printing just item names, it prints item sizes, owners, dates, and
  1922. Xpermissions as well.
  1923. XThis command is equivalent to
  1924. X.RB `` "ls \-l" ''
  1925. Xon most remote systems.
  1926. X.PP
  1927. XThe usage for both commands is the same.
  1928. XHere is the one for
  1929. X.IR ls :
  1930. X.PP
  1931. X.RS
  1932. X.B ls
  1933. X.RI [ \-flags ]
  1934. X.RI [ "directory and file names" ]
  1935. X.RI [ redirection ]
  1936. X.RE
  1937. X.PP
  1938. XNote that in this program, you can supply both flags and items to list in
  1939. Xthe same command.
  1940. XThe stock version of
  1941. X.I ftp
  1942. Xdoesn't let you do this:
  1943. X.Ds
  1944. Xls \-lrt /info\-mac/help
  1945. X.De
  1946. X.PP
  1947. XAnother thing that the program does which the others should have done is
  1948. Xlet you supply more than one item:
  1949. X.Ds
  1950. Xls \-lrt /info\-mac/help /pub /info\-mac/README
  1951. X.De
  1952. X.PP
  1953. XYou can also redirect the output into a file, or pipe it into something.
  1954. XThis example shows how to list the contents of the current remote directory,
  1955. Xand save the output into a file in the current local directory:
  1956. X.Ds
  1957. Xls \-t >ls.out
  1958. X.De
  1959. X.PP
  1960. XNote that for this to work, there must be no whitespace between the ``>''
  1961. Xand the filename, unlike your shell command line which allows for extra
  1962. Xwhitespace.
  1963. XThis will be (actually, is) fixed in a future version of the
  1964. Xprogram.
  1965. X.PP
  1966. XThese examples show how to use a pipe:
  1967. X.Ds
  1968. Xls \-t |tail
  1969. Xdir \-t "|less \-CM"
  1970. Xls \-t "|tail | wc"
  1971. X.De
  1972. X.PP
  1973. XLike the redirection example, there must be no whitespace between the first
  1974. Xpipe character and the rest of the stuff.
  1975. XThe trick is that it has to
  1976. Xappear as one argument to the commands.
  1977. XThe second and third examples
  1978. Xillustrate the use of double quotes to squeeze extra parameters in.
  1979. XThe second example can be done without all that typing.
  1980. XSee the descriptions of the
  1981. X.I pdir
  1982. Xand
  1983. X.I pls
  1984. Xcommands below.
  1985. X.\"-------
  1986. X.SH "Viewing a remote directory with your pager"
  1987. X.\"-------
  1988. XDidn't you hate it when you listed a remote directory, only to have most of
  1989. Xthe stuff scrolled off your terminal before you could read it?
  1990. XThe
  1991. X.I pls
  1992. Xand
  1993. X.I pdir
  1994. Xcommands take care of this for you.
  1995. XAs you might have guessed,
  1996. Xthey perform exactly like their regular counterparts,
  1997. Xonly you view them with your pager.
  1998. XThe pager to use is controlled by the
  1999. X.I pager
  2000. Xprogram variable.
  2001. X.\"-------
  2002. X.SH "Redisplaying the last directory listing"
  2003. X.\"-------
  2004. XThe program saves the listing into a local buffer,
  2005. Xso if you need to see it again (probably forgot about
  2006. X.IR pdir )
  2007. Xyou can use the
  2008. X.I redir
  2009. Xand
  2010. X.I predir
  2011. Xcommands for this.
  2012. X.\"-------
  2013. X.SH "Fetching files from the remote host"
  2014. X.\"-------
  2015. XThe
  2016. X.I get
  2017. Xand
  2018. X.I mget
  2019. Xretrieve remote files for you.
  2020. XThe usage for
  2021. X.I get
  2022. Xis:
  2023. X.Ds
  2024. Xget remote\-file [local\-file or redirection]
  2025. X.De
  2026. X.PP
  2027. XTo fetch
  2028. X.B /pub/README
  2029. Xand write it as a file named
  2030. X.BR ./junk/readme ,
  2031. Xtry:
  2032. X.Ds
  2033. Xget /pub/README ./junk/readme
  2034. X.De
  2035. X.PP
  2036. XTo fetch
  2037. X.B /pub/README
  2038. Xand write it as
  2039. X.BR ./README ,
  2040. Xjust do:
  2041. X.Ds
  2042. Xget /pub/README
  2043. X.De
  2044. X.PP
  2045. XThis lets you fetch a file using its whole pathname, and write a copy of
  2046. Xit in the current directory, without having to bother with typing a local
  2047. Xfilename.
  2048. XIn the unlikely event that you have write permission to a
  2049. Xdirectory called
  2050. X.B /pub
  2051. Xon your local machine, it would write
  2052. X.RB `` README ''
  2053. Xin that directory.
  2054. X.PP
  2055. XMost of the time the file you want will be in the current remote directory,
  2056. Xso you can just do these:
  2057. X.Ds
  2058. Xget README
  2059. Xget README ./junk/readme
  2060. X.De
  2061. X.PP
  2062. XYou can also use a redirection for
  2063. X.IR get ,
  2064. Xjust like you can with the
  2065. X.IR ls ", " dir ", and " redir
  2066. Xcommands.
  2067. XAs described earlier, you have
  2068. Xto conform to the format below for this release of the program:
  2069. X.Ds
  2070. Xget README >/dev/null
  2071. Xget README |head
  2072. Xget README "|head \-8"
  2073. Xget README "|less \-EMi"
  2074. X.De
  2075. X.PP
  2076. XThe last example is facilitated by the
  2077. X.I page
  2078. Xcommand described later.
  2079. X.PP
  2080. XThe
  2081. X.I get
  2082. Xcommand can also use a wildcard expression in an attempt to
  2083. Xmatch exactly one remote file.
  2084. XI call it ``Poor Man's File Completion.''
  2085. XIf you've done a remote listing, and you decide you want to download a
  2086. Xfile by the name of
  2087. X.RB `` obnoxiouslylongpackagename.tar.Z ,''
  2088. Xyou can use
  2089. X``PMFC.''to save some keystrokes.
  2090. XChoose an expression that will only
  2091. Xmatch that one file, then use it with
  2092. X.IR get :
  2093. X.Ds
  2094. Xget obn*.Z a.tar.Z
  2095. X.De
  2096. X.PP
  2097. XIf your pattern was unique,
  2098. X.I get
  2099. Xwill fetch that file only.
  2100. XIf the pattern matched more than one file, the program will bitch and moan.
  2101. X.PP
  2102. XThe
  2103. X.I mget
  2104. Xcommand is used to fetch many files at a time.
  2105. XThe difference between
  2106. X.I get
  2107. Xand
  2108. X.I mget
  2109. Xis that
  2110. X.I get
  2111. Xlets you write only one file,
  2112. Xbut you can put it in a different directory, while
  2113. X.I mget
  2114. Xfetches many files,
  2115. Xalways writing them in the current local directory.
  2116. XThis example fetches several remote files at once:
  2117. X.Ds
  2118. Xmget a.file.Z b.file.Z c.tar d.tar.Z
  2119. X.De
  2120. X.PP
  2121. XThe
  2122. X.I mget
  2123. Xcommand, and its ugly sisters,
  2124. X.I mput
  2125. Xand
  2126. X.I mdelete
  2127. Xlet you use wildcard expressions.
  2128. XI could have done the previous example as:
  2129. X.Ds
  2130. Xmget *.Z c.tar
  2131. X.De
  2132. X.PP
  2133. Xinstead.
  2134. XThe ``m.''commands will verify each file,
  2135. Xif you have the program variable
  2136. X.I mprompt
  2137. Xset.
  2138. X.\"-------
  2139. X.SH "Viewing a remote file with your pager"
  2140. X.\"-------
  2141. XIf you would like to read a file on the remote host without saving a copy
  2142. Xof it on your machine, you can use the
  2143. X.I page
  2144. X(or
  2145. X.I more
  2146. Xif you wish) command:
  2147. X.Ds
  2148. Xpage README
  2149. Xpage obn*README
  2150. Xpage README.Z
  2151. X.De
  2152. X.PP
  2153. XThe second example show that you can use ``PMFC.''like you can for
  2154. X.IR get.
  2155. XThe third example will work also, because if the program knows how to
  2156. Xdecompress the file, it will do so before feeding it to your pager.
  2157. XAs stated earlier,
  2158. Xyou can change the program to use to page by setting the program variable
  2159. X.IR pager.
  2160. X.\"-------
  2161. X.SH "Creating a message file on the remote host"
  2162. X.\"-------
  2163. XUse the
  2164. X.I create
  2165. Xan empty file on the remote site.
  2166. XSometimes it is necessary to leave a note if you can't get in touch
  2167. Xwith the remote site's administrator.
  2168. XFor example if a file is corrupted, you could try:
  2169. X.Ds
  2170. Xcreate Foo.tar_is_corrupt
  2171. X.De
  2172. X.PP
  2173. Xin hopes that the original uploader will replace it.
  2174. X.\"-------
  2175. X.SH "Looking up site names and addresses"
  2176. X.\"-------
  2177. XYou can use the program's builtin
  2178. X.RI mini- nslookup
  2179. Xfacility.
  2180. XIf you wanted to know the site's IP number, but only knew the name you
  2181. Xcould do:
  2182. X.Ds
  2183. Xlookup cse.unl.edu
  2184. X.De
  2185. X.PP
  2186. XThis would spit out IP number for that site, in this case ``129.93.1.12.''
  2187. XIf you needed to know what a site's name was, but only knew the IP number,
  2188. Xtry:
  2189. X.Ds
  2190. Xlookup 129.93.1.12
  2191. X.De
  2192. X.PP
  2193. XThis would spit out the name for that site, in this case ``cse.unl.edu.''
  2194. X.\"-------
  2195. X.SH "Checking the configuration of the program"
  2196. X.\"-------
  2197. XUse the
  2198. X.I version
  2199. Xcommand to print version and compilation information about the program.
  2200. XThis will also tell you which optional features are
  2201. Xcompiled into the program, such as logging to the system log and which
  2202. Xcommand line editor (if any) has been installed.
  2203. X.PP
  2204. XThe author's email address is listed, and if you need to report something,
  2205. Xsend the output of this command along with your message.
  2206. X.\"-------
  2207. X.SH "Using the command shell"
  2208. X.\"-------
  2209. XJust like the stock
  2210. X.I ftp
  2211. Xprogram, you type commands to it until you get
  2212. Xbored and hit either ^D or type the
  2213. X.I quit
  2214. Xcommand.
  2215. X.PP
  2216. XThe program supports links to popular command line editing libraries.
  2217. XIf the person who compiled it went to the effort, you will be able to
  2218. Xedit the command line with arrow keys and other editing commands, and also
  2219. Xscroll up and down in the command line history, usually with the up and
  2220. Xdown arrows.
  2221. XYou can check the
  2222. X.I version
  2223. Xcommand to see if either
  2224. X``GETLINE.''or ``READLINE.''are installed.
  2225. X.\"-------
  2226. X.SH "Customizing the prompt"
  2227. X.\"-------
  2228. XYou can set the shell's prompt string to whatever you like.
  2229. XYou can use several metacharacters that expand into something each prompt.
  2230. XThe
  2231. X.RB `` % ''
  2232. Xflags are passed to
  2233. X.IR strftime (3),
  2234. Xso you can put the date or time in the prompt formatted as you like it:
  2235. X.Ds
  2236. Xset prompt "%I:%M ncftp>"
  2237. X.De
  2238. X.PP
  2239. XThat would the current time in the prompt.
  2240. X.PP
  2241. XThe
  2242. X.RB `` @ ''
  2243. Xflags are expanded by the program itself.
  2244. XHere's the list of them.
  2245. X.PP
  2246. XIf you have an ANSI-compatible terminal, or you have the program variable
  2247. X.I ansi\-escapes
  2248. Xset, you can use
  2249. X.BR @B ,
  2250. X.BR @I ,
  2251. Xand
  2252. X.B @U
  2253. Xto turn on boldface,
  2254. Xinverse, and underline text respectively (otherwise they won't insert
  2255. Xanything).
  2256. XYou can also use
  2257. X.B @R
  2258. Xto turn on inverse (reverse) text.
  2259. X.B @P
  2260. Xsets the text back to plain text.
  2261. X.PP
  2262. X.B @D
  2263. XInserts the full path of the current remote directory.
  2264. XThe
  2265. X.B @J
  2266. Xflag is similar except it inserts only the directory name.
  2267. X.PP
  2268. X.B @H
  2269. XInserts the name of the remote host.
  2270. X.B @C
  2271. Xinserts the host and current
  2272. Xdirectory path in
  2273. X.I "colon-mode"
  2274. Xformat, such as
  2275. X``cse.unl.edu:/pub/mgleason,.''or ``(not connected).''
  2276. XThe
  2277. X.B @c
  2278. Xflag is similar, only it will insert ``cse.unl.edu:/pub/mgleason.''and a
  2279. Xnewline if connected, otherwise it prints nothing.
  2280. XThe default prompt uses
  2281. Xthis flag to print a two line prompt when connected and a one line prompt
  2282. Xwhen not connected.
  2283. X.PP
  2284. X.BR @E " or " @!
  2285. Xinserts the event number (how many commands you've typed).
  2286. X.PP
  2287. X.B @M
  2288. Xinserts ``(Mail)\0.''if mail has arrived since running the program.
  2289. X.PP
  2290. X.B @N
  2291. Xinserts a newline character.
  2292. X.\"-------
  2293. X.SH "Keeping a log of your file transfers"
  2294. X.\"-------
  2295. XYou can have the program keep a personal log file.
  2296. XI find it is useful so I can see where I got a certain file,
  2297. Xor what the name of that site was I called two weeks ago.
  2298. X.PP
  2299. XTo use a log, add:
  2300. X.Ds
  2301. X#set logfile ~/.ftplog
  2302. X.De
  2303. X.PP
  2304. X(or whatever you want to name the log) to your RC file.
  2305. XI don't want my log growing too large and using up all my disk space,
  2306. Xso I also have:
  2307. X.Ds
  2308. X#set logsize 10240
  2309. X.De
  2310. X.PP
  2311. Xin my RC file.
  2312. XIf you set the limit on the maximum log size, the program will
  2313. Xkeep the log file at or below that size, discarding old entries.
  2314. X.PP
  2315. XNote that this is different from having SYSLOG appear in the
  2316. X.I version
  2317. Xcommand's output.
  2318. XWhen this is on, your actions are recorded to the system
  2319. Xlog, so your system administrator can make sure you aren't doing anything
  2320. X``bad.''
  2321. X.\"-------
  2322. X.SH "Program options"
  2323. X.\"-------
  2324. XRemember that you can treat the command line like an
  2325. X.I open
  2326. Xcommand,
  2327. Xso all lowercase options are passed to the
  2328. X.I open
  2329. Xcommand, and the
  2330. Xuppercase options are handled by the main program.
  2331. XThe uppercase options
  2332. Xare described below; refer to the
  2333. X.I open
  2334. Xcommand for descriptions of its options.
  2335. X.TP
  2336. X.BI \-D " x"
  2337. Xsets the debugging level to
  2338. X.IR x .
  2339. X.TP
  2340. X.B \-H
  2341. Xruns the
  2342. X.I version
  2343. Xcommand and exits, so you can save the output of
  2344. Xit to use when you need to mail me something.
  2345. X.TP
  2346. X.B \-I
  2347. Xtoggles the mprompt variable; this is provided for compatibility with
  2348. X.RB `` "ftp \-i" .''
  2349. X.TP
  2350. X.B \-N
  2351. Xdisables reading of the RC file;
  2352. Xthis is provided for compatibility with
  2353. X.RB `` "ftp \-n" .''
  2354. X.TP
  2355. X.BI \-V " x"
  2356. Xsets verbosity to level
  2357. X.I x
  2358. X.RB ( \-1 ,
  2359. X.BR 0 ,
  2360. X.BR 1 ,
  2361. X.BR 2 )
  2362. Xor
  2363. X.RB ( quiet ,
  2364. X.BR errs ,
  2365. X.BR terse ,
  2366. X.BR verbose ).
  2367. XSee the description of the
  2368. X.I verbose
  2369. Xprogram variable for more information.
  2370. X.PP
  2371. XHere are some example command lines.
  2372. XAgain, see the description of the
  2373. X.I open
  2374. Xcommand (especially
  2375. X.IR "colon-mode" " and " "FTP\-cat mode" ")"
  2376. Xand all its functions for more information.
  2377. X.PP
  2378. XThis just enters the
  2379. X.I NcFTP
  2380. Xcommand shell:
  2381. X.Ds
  2382. Xcsh> ncftp
  2383. X.De
  2384. X.PP
  2385. XThis fetches
  2386. X.B README
  2387. Xand then quits:
  2388. X.Ds
  2389. Xcsh> ncftp ftp.unl.edu:/pub/README
  2390. X.De
  2391. X.PP
  2392. XSome others examples, with open options and main program options mixed in:
  2393. X.Ds
  2394. Xcsh> ncftp \-V quiet \-u ftp.unl.edu
  2395. Xcsh> ncftp \-c ftp.unl.edu:/pub/README
  2396. Xcsh> ncftp \-D 2 \-r \-d 120 \-g 10 \-N ftp.unl.edu
  2397. X.De
  2398. X.\"-------
  2399. X.SH "A sample RC file"
  2400. X.\"-------
  2401. XHere is a sample RC file:
  2402. X.ta 6m +6m
  2403. X.Ds
  2404. X#set logfile ~/.ftplog
  2405. X#set progress\-reports 2
  2406. X#set local\-dir /usr/tmp/zz
  2407. X#set prompt "@B@E @UNcFTP@P @B@M@D@P \->"
  2408. X.sp
  2409. Xmachine sumex\-aim.stanford.edu
  2410. X    macdef init
  2411. X        cd /info\-mac
  2412. X        get ./help/recent\-files.txt "|grep \-v '.abs' > sumex
  2413. X        !less sumex
  2414. X        pwd
  2415. X.sp
  2416. X# This site is in here just so I can use ``apple''
  2417. X# as an abbreviation.
  2418. Xmachine ftp.apple.com
  2419. X.sp
  2420. X# NcFTP will only ask for your password:
  2421. Xmachine cse.unl.edu
  2422. X    login mgleason
  2423. X.sp
  2424. X# You can supply a login and a password:
  2425. Xmachine fake.machine.unl.edu
  2426. X    login mgleason
  2427. X    password mypass
  2428. X    macdef init
  2429. X    cd ./foo/bar
  2430. X.sp
  2431. X# If an antiquated non-UNIX machine doesn't use
  2432. X# the "SYST" command, you may need to unset
  2433. X# remote\-is\-unix, if the remote host complains
  2434. X# about ``ls \-CF.''
  2435. Xmachine some.vms.unl.edu
  2436. X    macdef init
  2437. X    unset remote\-is\-unix
  2438. X.sp
  2439. X.De
  2440. X.\"-------
  2441. X.SH "AUTHORS"
  2442. X.\"-------
  2443. X.I NcFTP
  2444. Xwas written by Mike Gleason,
  2445. X.I NCEMRSoft
  2446. X(mgleason@cse.unl.edu), and based on code by the authors of the
  2447. X.I ftp
  2448. Xfrom the BSD 4.3 distribution.
  2449. X.I NcFTP
  2450. Xis copyrighted 1992, 1993 by NCEMRSoft
  2451. Xand 1985, 1989 by the Regents of California.
  2452. X.PP
  2453. XIdeas and some code contributed by Phil Dietz,
  2454. X.I NCEMRSoft
  2455. X(pdietz@cse.unl.edu).
  2456. XTesting and debugging done by Phil and
  2457. XKok Hon Yin (hkok@cse.unl.edu).
  2458. X.PP
  2459. XExtensive man page formatting work
  2460. Xby DaviD W. Sanderson (dws@ssec.wisc.edu).
  2461. X.\"-------
  2462. X.SH "BUGS"
  2463. X.\"-------
  2464. XCorrect execution of many commands depends upon proper behavior
  2465. Xby the remote server.
  2466. X.PP
  2467. XThe remote server may drop the connection if you take a long time to
  2468. Xpage remote files.
  2469. X.PP
  2470. XTermcap padding is not correctly displayed.
  2471. X.PP
  2472. XThere are no such sites named
  2473. X.I bowser.nintendo.jp
  2474. Xor
  2475. X.IR sphygmomanometer.unl.edu .
  2476. X.\"-------
  2477. X.SH "SEE ALSO"
  2478. X.\"-------
  2479. X.IR strftime (3),
  2480. X.IR ftpd (8),
  2481. X.IR ftp (1),
  2482. X.IR nslookup (1),
  2483. X.IR compress (1),
  2484. X.IR gzip (1),
  2485. X.IR zcat (1),
  2486. X.IR fsp (1),
  2487. X.IR archie (1),
  2488. X.IR tftp (1).
  2489. END_OF_FILE
  2490.   if test 33324 -ne `wc -c <'ncftp.1'`; then
  2491.     echo shar: \"'ncftp.1'\" unpacked with wrong size!
  2492.   fi
  2493.   # end of 'ncftp.1'
  2494. fi
  2495. echo shar: End of archive 3 \(of 5\).
  2496. cp /dev/null ark3isdone
  2497. MISSING=""
  2498. for I in 1 2 3 4 5 ; do
  2499.     if test ! -f ark${I}isdone ; then
  2500.     MISSING="${MISSING} ${I}"
  2501.     fi
  2502. done
  2503. if test "${MISSING}" = "" ; then
  2504.     echo You have unpacked all 5 archives.
  2505.     rm -f ark[1-9]isdone
  2506. else
  2507.     echo You still must unpack the following archives:
  2508.     echo "        " ${MISSING}
  2509. fi
  2510. exit 0
  2511. exit 0 # Just in case...
  2512.