diff --git a/usr.bin/ftp/cmds.c b/usr.bin/ftp/cmds.c index 7547af7652b1..e8664f6b4b1c 100644 --- a/usr.bin/ftp/cmds.c +++ b/usr.bin/ftp/cmds.c @@ -1,4 +1,4 @@ -/* $NetBSD: cmds.c,v 1.36 1998/05/20 00:52:29 christos Exp $ */ +/* $NetBSD: cmds.c,v 1.37 1998/06/04 08:28:35 lukem Exp $ */ /* * Copyright (c) 1985, 1989, 1993, 1994 @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)cmds.c 8.6 (Berkeley) 10/9/94"; #else -__RCSID("$NetBSD: cmds.c,v 1.36 1998/05/20 00:52:29 christos Exp $"); +__RCSID("$NetBSD: cmds.c,v 1.37 1998/06/04 08:28:35 lukem Exp $"); #endif #endif /* not lint */ @@ -97,18 +97,18 @@ settype(argc, argv) if (argc > 2) { char *sep; - printf("usage: %s [", argv[0]); + fprintf(ttyout, "usage: %s [", argv[0]); sep = " "; for (p = types; p->t_name; p++) { - printf("%s%s", sep, p->t_name); + fprintf(ttyout, "%s%s", sep, p->t_name); sep = " | "; } - puts(" ]"); + fputs(" ]\n", ttyout); code = -1; return; } if (argc < 2) { - printf("Using %s mode to transfer files.\n", typename); + fprintf(ttyout, "Using %s mode to transfer files.\n", typename); code = 0; return; } @@ -116,7 +116,7 @@ settype(argc, argv) if (strcmp(argv[1], p->t_name) == 0) break; if (p->t_name == 0) { - printf("%s: unknown mode.\n", argv[1]); + fprintf(ttyout, "%s: unknown mode.\n", argv[1]); code = -1; return; } @@ -222,7 +222,7 @@ setftmode(argc, argv) char *argv[]; { - printf("We only support %s mode, sorry.\n", modename); + fprintf(ttyout, "We only support %s mode, sorry.\n", modename); code = -1; } @@ -236,7 +236,7 @@ setform(argc, argv) char *argv[]; { - printf("We only support %s format, sorry.\n", formname); + fprintf(ttyout, "We only support %s format, sorry.\n", formname); code = -1; } @@ -250,7 +250,7 @@ setstruct(argc, argv) char *argv[]; { - printf("We only support %s structure, sorry.\n", structname); + fprintf(ttyout, "We only support %s structure, sorry.\n", structname); code = -1; } @@ -275,7 +275,8 @@ put(argc, argv) goto usage; if ((argc < 3 && !another(&argc, &argv, "remote-file")) || argc > 3) { usage: - printf("usage: %s local-file [ remote-file ]\n", argv[0]); + fprintf(ttyout, "usage: %s local-file [ remote-file ]\n", + argv[0]); code = -1; return; } @@ -319,7 +320,7 @@ mput(argc, argv) char *tp; if (argc < 2 && !another(&argc, &argv, "local-files")) { - printf("usage: %s local-files\n", argv[0]); + fprintf(ttyout, "usage: %s local-files\n", argv[0]); code = -1; return; } @@ -471,7 +472,8 @@ getit(argc, argv, restartit, mode) goto usage; if ((argc < 3 && !another(&argc, &argv, "local-file")) || argc > 3) { usage: - printf("usage: %s remote-file [ local-file ]\n", argv[0]); + fprintf(ttyout, "usage: %s remote-file [ local-file ]\n", + argv[0]); code = -1; return (0); } @@ -548,8 +550,8 @@ mabort(signo) int ointer, oconf; alarmtimer(0); - putchar('\n'); - (void)fflush(stdout); + putc('\n', ttyout); + (void)fflush(ttyout); if (mflag && fromatty) { ointer = interactive; oconf = confirmrest; @@ -580,7 +582,7 @@ mget(argc, argv) char *cp, *tp, *tp2, tmpbuf[MAXPATHLEN]; if (argc < 2 && !another(&argc, &argv, "remote-files")) { - printf("usage: %s remote-files\n", argv[0]); + fprintf(ttyout, "usage: %s remote-files\n", argv[0]); code = -1; return; } @@ -643,55 +645,56 @@ status(argc, argv) int i; if (connected) - printf("Connected %sto %s.\n", + fprintf(ttyout, "Connected %sto %s.\n", connected == -1 ? "and logged in" : "", hostname); else - puts("Not connected."); + fputs("Not connected.\n", ttyout); if (!proxy) { pswitch(1); if (connected) { - printf("Connected for proxy commands to %s.\n", + fprintf(ttyout, "Connected for proxy commands to %s.\n", hostname); } else { - puts("No proxy connection."); + fputs("No proxy connection.\n", ttyout); } pswitch(0); } - printf("Gate ftp: %s, server %s, port %d.\n", onoff(gatemode), + fprintf(ttyout, "Gate ftp: %s, server %s, port %d.\n", onoff(gatemode), *gateserver ? gateserver : "(none)", ntohs(gateport)); - printf("Passive mode: %s.\n", onoff(passivemode)); - printf("Mode: %s; Type: %s; Form: %s; Structure: %s.\n", - modename, typename, formname, structname); - printf("Verbose: %s; Bell: %s; Prompting: %s; Globbing: %s.\n", - onoff(verbose), onoff(bell), onoff(interactive), - onoff(doglob)); - printf("Store unique: %s; Receive unique: %s.\n", onoff(sunique), - onoff(runique)); - printf("Preserve modification times: %s.\n", onoff(preserve)); - printf("Case: %s; CR stripping: %s.\n", onoff(mcase), onoff(crflag)); + fprintf(ttyout, "Passive mode: %s.\n", onoff(passivemode)); + fprintf(ttyout, "Mode: %s; Type: %s; Form: %s; Structure: %s.\n", + modename, typename, formname, structname); + fprintf(ttyout, "Verbose: %s; Bell: %s; Prompting: %s; Globbing: %s.\n", + onoff(verbose), onoff(bell), onoff(interactive), onoff(doglob)); + fprintf(ttyout, "Store unique: %s; Receive unique: %s.\n", + onoff(sunique), onoff(runique)); + fprintf(ttyout, "Preserve modification times: %s.\n", onoff(preserve)); + fprintf(ttyout, "Case: %s; CR stripping: %s.\n", onoff(mcase), + onoff(crflag)); if (ntflag) { - printf("Ntrans: (in) %s (out) %s\n", ntin, ntout); + fprintf(ttyout, "Ntrans: (in) %s (out) %s\n", ntin, ntout); } else { - puts("Ntrans: off."); + fputs("Ntrans: off.\n", ttyout); } if (mapflag) { - printf("Nmap: (in) %s (out) %s\n", mapin, mapout); + fprintf(ttyout, "Nmap: (in) %s (out) %s\n", mapin, mapout); } else { - puts("Nmap: off."); + fputs("Nmap: off.\n", ttyout); } - printf("Hash mark printing: %s; Mark count: %d; Progress bar: %s.\n", + fprintf(ttyout, + "Hash mark printing: %s; Mark count: %d; Progress bar: %s.\n", onoff(hash), mark, onoff(progress)); - printf("Use of PORT cmds: %s.\n", onoff(sendport)); + fprintf(ttyout, "Use of PORT cmds: %s.\n", onoff(sendport)); #ifndef SMALL - printf("Command line editing: %s.\n", onoff(editing)); + fprintf(ttyout, "Command line editing: %s.\n", onoff(editing)); #endif /* !SMALL */ if (macnum > 0) { - puts("Macros:"); + fputs("Macros:\n", ttyout); for (i=0; i 3) { - printf("usage: %s [ on | off | gateserver [ port ] ]\n", - argv[0]); + fprintf(ttyout, + "usage: %s [ on | off | gateserver [ port ] ]\n", argv[0]); code = -1; return; } else if (argc < 2) { @@ -886,7 +891,8 @@ setgate(argc, argv) port = strtol(argv[2], &ep, 10); if (port < 0 || port > MAX_IN_PORT_T || *ep != '\0') { - printf("%s: bad gateport value.\n", + fprintf(ttyout, + "%s: bad gateport value.\n", argv[2]); code = -1; return; @@ -900,12 +906,13 @@ setgate(argc, argv) } } if (gatemode && (gateserver == NULL || *gateserver == '\0')) { - printf( + fprintf(ttyout, "Disabling gate-ftp mode - no gate-ftp server defined.\n"); gatemode = 0; } else { - printf("Gate ftp: %s, server %s, port %d.\n", onoff(gatemode), - *gateserver ? gateserver : "(none)", ntohs(gateport)); + fprintf(ttyout, "Gate ftp: %s, server %s, port %d.\n", + onoff(gatemode), *gateserver ? gateserver : "(none)", + ntohs(gateport)); } code = gatemode; } @@ -946,7 +953,8 @@ setdebug(argc, argv) char *argv[]; { if (argc > 2) { - printf("usage: %s [ on | off | debuglevel ]\n", argv[0]); + fprintf(ttyout, "usage: %s [ on | off | debuglevel ]\n", + argv[0]); code = -1; return; } else if (argc == 2) { @@ -960,7 +968,8 @@ setdebug(argc, argv) val = strtol(argv[1], &ep, 10); if (val < 0 || val > INT_MAX || *ep != '\0') { - printf("%s: bad debugging value.\n", argv[1]); + fprintf(ttyout, "%s: bad debugging value.\n", + argv[1]); code = -1; return; } @@ -972,7 +981,7 @@ setdebug(argc, argv) options |= SO_DEBUG; else options &= ~SO_DEBUG; - printf("Debugging %s (debug=%d).\n", onoff(debug), debug); + fprintf(ttyout, "Debugging %s (debug=%d).\n", onoff(debug), debug); code = debug > 0; } @@ -988,14 +997,15 @@ cd(argc, argv) if ((argc < 2 && !another(&argc, &argv, "remote-directory")) || argc > 2) { - printf("usage: %s remote-directory\n", argv[0]); + fprintf(ttyout, "usage: %s remote-directory\n", argv[0]); code = -1; return; } r = command("CWD %s", argv[1]); if (r == ERROR && code == 500) { if (verbose) - puts("CWD command not recognized, trying XCWD."); + fputs("CWD command not recognized, trying XCWD.\n", + ttyout); r = command("XCWD %s", argv[1]); } if (r == COMPLETE) @@ -1016,7 +1026,7 @@ lcd(argc, argv) if (argc < 2) argc++, argv[1] = home; if (argc != 2) { - printf("usage: %s local-directory\n", argv[0]); + fprintf(ttyout, "usage: %s local-directory\n", argv[0]); code = -1; return; } @@ -1030,7 +1040,7 @@ lcd(argc, argv) code = -1; } else { if (getcwd(buf, sizeof(buf)) != NULL) - printf("Local directory now %s\n", buf); + fprintf(ttyout, "Local directory now %s\n", buf); else warn("getcwd: %s", argv[1]); code = 0; @@ -1049,7 +1059,7 @@ delete(argc, argv) { if ((argc < 2 && !another(&argc, &argv, "remote-file")) || argc > 2) { - printf("usage: %s remote-file\n", argv[0]); + fprintf(ttyout, "usage: %s remote-file\n", argv[0]); code = -1; return; } @@ -1069,7 +1079,7 @@ mdelete(argc, argv) char *cp; if (argc < 2 && !another(&argc, &argv, "remote-files")) { - printf("usage: %s remote-files\n", argv[0]); + fprintf(ttyout, "usage: %s remote-files\n", argv[0]); code = -1; return; } @@ -1111,7 +1121,7 @@ renamefile(argc, argv) goto usage; if ((argc < 3 && !another(&argc, &argv, "to-name")) || argc > 3) { usage: - printf("usage: %s from-name to-name\n", argv[0]); + fprintf(ttyout, "usage: %s from-name to-name\n", argv[0]); code = -1; return; } @@ -1135,7 +1145,8 @@ ls(argc, argv) if (argc < 3) argc++, argv[2] = "-"; if (argc > 3) { - printf("usage: %s remote-directory local-file\n", argv[0]); + fprintf(ttyout, "usage: %s remote-directory local-file\n", + argv[0]); code = -1; return; } @@ -1155,7 +1166,7 @@ ls(argc, argv) recvrequest(cmd, argv[2], argv[1], "w", 0, 0); /* flush results in case commands are coming from a pipe */ - fflush(stdout); + fflush(ttyout); freels: if (argv[2] != globargv2) /* free up after globulize() */ free(argv[2]); @@ -1180,7 +1191,7 @@ mls(argc, argv) goto usage; if (argc < 3 && !another(&argc, &argv, "local-file")) { usage: - printf("usage: %s remote-files local-file\n", argv[0]); + fprintf(ttyout, "usage: %s remote-files local-file\n", argv[0]); code = -1; return; } @@ -1249,8 +1260,9 @@ shell(argc, argv) if (strcmp(namep, "sh") != 0) shellnam[0] = '+'; if (debug) { - puts(shell); - (void)fflush(stdout); + fputs(shell, ttyout); + putc('\n', ttyout); + (void)fflush(ttyout); } if (argc > 1) { execl(shell, shellnam, "-c", altarg, (char *)0); @@ -1290,7 +1302,8 @@ user(argc, argv) if (argc < 2) (void)another(&argc, &argv, "username"); if (argc < 2 || argc > 4) { - printf("usage: %s username [password] [account]\n", argv[0]); + fprintf(ttyout, "usage: %s username [password] [account]\n", + argv[0]); code = -1; return; } @@ -1302,8 +1315,8 @@ user(argc, argv) } if (n == CONTINUE) { if (argc < 4) { - (void)fputs("Account: ", stdout); - (void)fflush(stdout); + (void)fputs("Account: ", ttyout); + (void)fflush(ttyout); (void)fgets(acct, sizeof(acct) - 1, stdin); acct[strlen(acct) - 1] = '\0'; argv[3] = acct; argc++; @@ -1312,7 +1325,7 @@ user(argc, argv) aflag++; } if (n != COMPLETE) { - puts("Login failed."); + fputs("Login failed.\n", ttyout); return; } if (!aflag && argc == 4) { @@ -1337,7 +1350,7 @@ pwd(argc, argv) */ verbose = 1; if (command("PWD") == ERROR && code == 500) { - puts("PWD command not recognized, trying XPWD."); + fputs("PWD command not recognized, trying XPWD.\n", ttyout); (void)command("XPWD"); } verbose = oldverbose; @@ -1354,7 +1367,7 @@ lpwd(argc, argv) char buf[MAXPATHLEN]; if (getcwd(buf, sizeof(buf)) != NULL) - printf("Local directory %s\n", buf); + fprintf(ttyout, "Local directory %s\n", buf); else warn("getcwd"); code = 0; @@ -1371,13 +1384,14 @@ makedir(argc, argv) if ((argc < 2 && !another(&argc, &argv, "directory-name")) || argc > 2) { - printf("usage: %s directory-name\n", argv[0]); + fprintf(ttyout, "usage: %s directory-name\n", argv[0]); code = -1; return; } if (command("MKD %s", argv[1]) == ERROR && code == 500) { if (verbose) - puts("MKD command not recognized, trying XMKD."); + fputs("MKD command not recognized, trying XMKD.\n", + ttyout); (void)command("XMKD %s", argv[1]); } } @@ -1393,13 +1407,14 @@ removedir(argc, argv) if ((argc < 2 && !another(&argc, &argv, "directory-name")) || argc > 2) { - printf("usage: %s directory-name\n", argv[0]); + fprintf(ttyout, "usage: %s directory-name\n", argv[0]); code = -1; return; } if (command("RMD %s", argv[1]) == ERROR && code == 500) { if (verbose) - puts("RMD command not recognized, trying XRMD."); + fputs("RMD command not recognized, trying XRMD.\n", + ttyout); (void)command("XRMD %s", argv[1]); } } @@ -1414,7 +1429,7 @@ quote(argc, argv) { if (argc < 2 && !another(&argc, &argv, "command line to send")) { - printf("usage: %s line-to-send\n", argv[0]); + fprintf(ttyout, "usage: %s line-to-send\n", argv[0]); code = -1; return; } @@ -1433,7 +1448,7 @@ site(argc, argv) { if (argc < 2 && !another(&argc, &argv, "arguments to SITE command")) { - printf("usage: %s line-to-send\n", argv[0]); + fprintf(ttyout, "usage: %s line-to-send\n", argv[0]); code = -1; return; } @@ -1465,6 +1480,8 @@ quote1(initial, argc, argv) sizeof(buf) - len) - 1); } } + /* Ensure buf is NUL terminated */ + buf[sizeof(buf) - 1] = '\0'; if (command(buf) == PRELIM) { while (getreply(0) == PRELIM) continue; @@ -1481,7 +1498,7 @@ do_chmod(argc, argv) goto usage; if ((argc < 3 && !another(&argc, &argv, "file-name")) || argc > 3) { usage: - printf("usage: %s mode file-name\n", argv[0]); + fprintf(ttyout, "usage: %s mode file-name\n", argv[0]); code = -1; return; } @@ -1577,7 +1594,7 @@ account(argc, argv) char *ap; if (argc > 2) { - printf("usage: %s [password]\n", argv[0]); + fprintf(ttyout, "usage: %s [password]\n", argv[0]); code = -1; return; } @@ -1619,26 +1636,26 @@ doproxy(argc, argv) sig_t oldintr; if (argc < 2 && !another(&argc, &argv, "command")) { - printf("usage: %s command\n", argv[0]); + fprintf(ttyout, "usage: %s command\n", argv[0]); code = -1; return; } c = getcmd(argv[1]); if (c == (struct cmd *) -1) { - puts("?Ambiguous command."); - (void)fflush(stdout); + fputs("?Ambiguous command.\n", ttyout); + (void)fflush(ttyout); code = -1; return; } if (c == 0) { - puts("?Invalid command."); - (void)fflush(stdout); + fputs("?Invalid command.\n", ttyout); + (void)fflush(ttyout); code = -1; return; } if (!c->c_proxy) { - puts("?Invalid proxy command."); - (void)fflush(stdout); + fputs("?Invalid proxy command.\n", ttyout); + (void)fflush(ttyout); code = -1; return; } @@ -1649,8 +1666,8 @@ doproxy(argc, argv) oldintr = signal(SIGINT, proxabort); pswitch(1); if (c->c_conn && !connected) { - puts("Not connected."); - (void)fflush(stdout); + fputs("Not connected.\n", ttyout); + (void)fflush(ttyout); pswitch(0); (void)signal(SIGINT, oldintr); code = -1; @@ -1695,7 +1712,7 @@ setntrans(argc, argv) { if (argc == 1) { ntflag = 0; - puts("Ntrans off."); + fputs("Ntrans off.\n", ttyout); code = ntflag; return; } @@ -1749,12 +1766,12 @@ setnmap(argc, argv) if (argc == 1) { mapflag = 0; - puts("Nmap off."); + fputs("Nmap off.\n", ttyout); code = mapflag; return; } if ((argc < 3 && !another(&argc, &argv, "mapout")) || argc > 3) { - printf("usage: %s [mapin mapout]\n", argv[0]); + fprintf(ttyout, "usage: %s [mapin mapout]\n", argv[0]); code = -1; return; } @@ -1885,8 +1902,9 @@ LOOP: } } if (!*cp2) { - puts( -"nmap: unbalanced brackets."); + fputs( + "nmap: unbalanced brackets.\n", + ttyout); return (name); } match = 1; @@ -1899,8 +1917,9 @@ LOOP: } } if (!*cp2) { - puts( -"nmap: unbalanced brackets."); + fputs( + "nmap: unbalanced brackets.\n", + ttyout); return (name); } break; @@ -1986,7 +2005,8 @@ cdup(argc, argv) r = command("CDUP"); if (r == ERROR && code == 500) { if (verbose) - puts("CDUP command not recognized, trying XCUP."); + fputs("CDUP command not recognized, trying XCUP.\n", + ttyout); r = command("XCUP"); } if (r == COMPLETE) @@ -2003,7 +2023,7 @@ restart(argc, argv) { if (argc > 2) { - printf("usage: %s [restart_point]\n", argv[0]); + fprintf(ttyout, "usage: %s [restart_point]\n", argv[0]); code = -1; return; } @@ -2021,18 +2041,20 @@ restart(argc, argv) rp = strtol(argv[1], &ep, 10); #endif if (rp < 0 || *ep != '\0') - printf("restart: Invalid offset `%s'\n", argv[1]); + fprintf(ttyout, "restart: Invalid offset `%s'\n", + argv[1]); else restart_point = rp; } if (restart_point == 0) - puts("No restart point defined"); + fputs("No restart point defined.\n", ttyout); else + fprintf(ttyout, #ifndef NO_QUAD - printf("Restarting at %qd for next get, put or append\n", + "Restarting at %qd for next get, put or append\n", (long long)restart_point); #else - printf("Restarting at %ld for next get, put or append\n", + "Restarting at %ld for next get, put or append\n", (long)restart_point); #endif } @@ -2058,18 +2080,20 @@ macdef(argc, argv) int c; if (macnum == 16) { - puts("Limit of 16 macros have already been defined."); + fputs("Limit of 16 macros have already been defined.\n", + ttyout); code = -1; return; } if ((argc < 2 && !another(&argc, &argv, "macro name")) || argc > 2) { - printf("usage: %s macro_name\n", argv[0]); + fprintf(ttyout, "usage: %s macro_name\n", argv[0]); code = -1; return; } if (interactive) - puts( -"Enter macro line by line, terminating it with a null line."); + fputs( + "Enter macro line by line, terminating it with a null line.\n", + ttyout); (void)strncpy(macros[macnum].mac_name, argv[1], sizeof(macros[macnum].mac_name) - 1); macros[macnum].mac_name[sizeof(macros[macnum].mac_name) - 1] = '\0'; @@ -2080,7 +2104,7 @@ macdef(argc, argv) tmp = macros[macnum].mac_start; while (tmp != macbuf+4096) { if ((c = getchar()) == EOF) { - puts("macdef: end of file encountered."); + fputs("macdef: end of file encountered.\n", ttyout); code = -1; return; } @@ -2103,7 +2127,8 @@ macdef(argc, argv) while ((c = getchar()) != '\n' && c != EOF) /* LOOP */; if (c == EOF || getchar() == '\n') { - puts("Macro not defined - 4K buffer exceeded."); + fputs("Macro not defined - 4K buffer exceeded.\n", + ttyout); code = -1; return; } @@ -2121,16 +2146,17 @@ sizecmd(argc, argv) off_t size; if ((argc < 2 && !another(&argc, &argv, "filename")) || argc > 2) { - printf("usage: %s filename\n", argv[0]); + fprintf(ttyout, "usage: %s filename\n", argv[0]); code = -1; return; } size = remotesize(argv[1], 1); if (size != -1) + fprintf(ttyout, #ifndef NO_QUAD - printf("%s\t%qd\n", argv[1], (long long)size); + "%s\t%qd\n", argv[1], (long long)size); #else - printf("%s\t%ld\n", argv[1], (long)size); + "%s\t%ld\n", argv[1], (long)size); #endif code = size; } @@ -2146,13 +2172,13 @@ modtime(argc, argv) time_t mtime; if ((argc < 2 && !another(&argc, &argv, "filename")) || argc > 2) { - printf("usage: %s filename\n", argv[0]); + fprintf(ttyout, "usage: %s filename\n", argv[0]); code = -1; return; } mtime = remotemodtime(argv[1], 1); if (mtime != -1) - printf("%s\t%s", argv[1], asctime(localtime(&mtime))); + fprintf(ttyout, "%s\t%s", argv[1], asctime(localtime(&mtime))); code = mtime; } @@ -2178,8 +2204,9 @@ newer(argc, argv) { if (getit(argc, argv, -1, "w")) - printf("Local file \"%s\" is newer than remote file \"%s\".\n", - argv[2], argv[1]); + fprintf(ttyout, + "Local file \"%s\" is newer than remote file \"%s\".\n", + argv[2], argv[1]); } /* @@ -2190,11 +2217,11 @@ page(argc, argv) int argc; char *argv[]; { - int ohash, overbose; + int ohash, orestart_point, overbose; char *p, *pager, *oldargv1; if ((argc < 2 && !another(&argc, &argv, "filename")) || argc > 2) { - printf("usage: %s filename\n", argv[0]); + fprintf(ttyout, "usage: %s filename\n", argv[0]); code = -1; return; } @@ -2211,11 +2238,13 @@ page(argc, argv) (void)sprintf(pager, "|%s", p); ohash = hash; + orestart_point = restart_point; overbose = verbose; - hash = verbose = 0; + hash = restart_point = verbose = 0; recvrequest("RETR", pager, argv[1], "r+w", 1, 0); (void)free(pager); hash = ohash; + restart_point = orestart_point; verbose = overbose; if (oldargv1 != argv[1]) /* free up after globulize() */ free(argv[1]); diff --git a/usr.bin/ftp/complete.c b/usr.bin/ftp/complete.c index 69d87d750317..16ecbf0a1b3d 100644 --- a/usr.bin/ftp/complete.c +++ b/usr.bin/ftp/complete.c @@ -1,4 +1,4 @@ -/* $NetBSD: complete.c,v 1.13 1998/06/01 14:46:11 lukem Exp $ */ +/* $NetBSD: complete.c,v 1.14 1998/06/04 08:28:35 lukem Exp $ */ /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. @@ -40,7 +40,7 @@ #include #ifndef lint -__RCSID("$NetBSD: complete.c,v 1.13 1998/06/01 14:46:11 lukem Exp $"); +__RCSID("$NetBSD: complete.c,v 1.14 1998/06/04 08:28:35 lukem Exp $"); #endif /* not lint */ /* @@ -126,7 +126,7 @@ complete_ambiguous(word, list, words) } } - putchar('\n'); + putc('\n', ttyout); qsort(words->sl_str, words->sl_cur, sizeof(char *), comparstr); list_vertical(words); return (CC_REDISPLAY); @@ -303,7 +303,7 @@ complete_remote(word, list) sl_add(dirlist, tcp); } if (emesg != NULL) { - printf("\n%s\n", emesg); + fprintf(ttyout, "\n%s\n", emesg); return (CC_REDISPLAY); } (void)strcpy(lastdir, dir); @@ -385,7 +385,8 @@ complete(el, ch) case 'r': /* remote complete */ case 'R': if (connected != -1) { - puts("\nMust be logged in to complete."); + fputs("\nMust be logged in to complete.\n", + ttyout); return (CC_REDISPLAY); } return (complete_remote(word, dolist)); diff --git a/usr.bin/ftp/domacro.c b/usr.bin/ftp/domacro.c index 8db79363f714..8ebb8772eb3a 100644 --- a/usr.bin/ftp/domacro.c +++ b/usr.bin/ftp/domacro.c @@ -1,4 +1,4 @@ -/* $NetBSD: domacro.c,v 1.11 1998/05/20 00:54:26 christos Exp $ */ +/* $NetBSD: domacro.c,v 1.12 1998/06/04 08:28:35 lukem Exp $ */ /* * Copyright (c) 1985, 1993, 1994 @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)domacro.c 8.3 (Berkeley) 4/2/94"; #else -__RCSID("$NetBSD: domacro.c,v 1.11 1998/05/20 00:54:26 christos Exp $"); +__RCSID("$NetBSD: domacro.c,v 1.12 1998/06/04 08:28:35 lukem Exp $"); #endif #endif /* not lint */ @@ -59,7 +59,7 @@ domacro(argc, argv) struct cmd *c; if (argc < 2 && !another(&argc, &argv, "macro name")) { - printf("usage: %s macro_name\n", argv[0]); + fprintf(ttyout, "usage: %s macro_name\n", argv[0]); code = -1; return; } @@ -69,7 +69,7 @@ domacro(argc, argv) } } if (i == macnum) { - printf("'%s' macro not found.\n", argv[1]); + fprintf(ttyout, "'%s' macro not found.\n", argv[1]); code = -1; return; } @@ -121,23 +121,25 @@ TOP: makeargv(); c = getcmd(margv[0]); if (c == (struct cmd *)-1) { - puts("?Ambiguous command."); + fputs("?Ambiguous command.\n", ttyout); code = -1; } else if (c == 0) { - puts("?Invalid command."); + fputs("?Invalid command.\n", ttyout); code = -1; } else if (c->c_conn && !connected) { - puts("Not connected."); + fputs("Not connected.\n", ttyout); code = -1; } else { - if (verbose) - puts(line); + if (verbose) { + fputs(line, ttyout); + putc('\n', ttyout); + } (*c->c_handler)(margc, margv); if (bell && c->c_bell) { - (void)putchar('\007'); + (void)putc('\007', ttyout); } (void)strcpy(line, line2); makeargv(); diff --git a/usr.bin/ftp/extern.h b/usr.bin/ftp/extern.h index bdbf8923fe44..a09ceef97667 100644 --- a/usr.bin/ftp/extern.h +++ b/usr.bin/ftp/extern.h @@ -1,4 +1,4 @@ -/* $NetBSD: extern.h,v 1.19 1998/01/18 14:23:34 lukem Exp $ */ +/* $NetBSD: extern.h,v 1.20 1998/06/04 08:28:35 lukem Exp $ */ /*- * Copyright (c) 1994 The Regents of the University of California. @@ -44,7 +44,7 @@ void abortsend __P((int)); void account __P((int, char **)); void alarmtimer __P((int)); int another __P((int *, char ***, const char *)); -int auto_fetch __P((int, char **)); +int auto_fetch __P((int, char **, char *)); void blkfree __P((char **)); void cd __P((int, char **)); void cdup __P((int, char **)); @@ -67,6 +67,7 @@ char *domap __P((char *)); void doproxy __P((int, char **)); char *dotrans __P((char *)); int empty __P((struct fd_set *, int)); +int foregroundproc __P((void)); void get __P((int, char **)); struct cmd *getcmd __P((const char *)); int getit __P((int, char **, int, const char *)); diff --git a/usr.bin/ftp/fetch.c b/usr.bin/ftp/fetch.c index ee9e1bd964fe..44bd73bb1c1c 100644 --- a/usr.bin/ftp/fetch.c +++ b/usr.bin/ftp/fetch.c @@ -1,4 +1,4 @@ -/* $NetBSD: fetch.c,v 1.21 1998/06/03 15:50:34 tv Exp $ */ +/* $NetBSD: fetch.c,v 1.22 1998/06/04 08:28:35 lukem Exp $ */ /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. @@ -38,7 +38,7 @@ #include #ifndef lint -__RCSID("$NetBSD: fetch.c,v 1.21 1998/06/03 15:50:34 tv Exp $"); +__RCSID("$NetBSD: fetch.c,v 1.22 1998/06/04 08:28:35 lukem Exp $"); #endif /* not lint */ /* @@ -56,6 +56,7 @@ __RCSID("$NetBSD: fetch.c,v 1.21 1998/06/03 15:50:34 tv Exp $"); #include #include +#include #include #include #include @@ -66,7 +67,7 @@ __RCSID("$NetBSD: fetch.c,v 1.21 1998/06/03 15:50:34 tv Exp $"); #include "ftp_var.h" -static int url_get __P((const char *, const char *)); +static int url_get __P((const char *, const char *, const char *)); void aborthttp __P((int)); @@ -86,9 +87,10 @@ jmp_buf httpabort; * Returns -1 on failure, 0 on success */ static int -url_get(origline, proxyenv) +url_get(origline, proxyenv, outfile) const char *origline; const char *proxyenv; + const char *outfile; { struct sockaddr_in sin; int i, out, isftpurl; @@ -98,16 +100,23 @@ url_get(origline, proxyenv) char c, *cp, *ep, *portnum, *path, buf[4096]; const char *savefile; char *line, *proxy, *host; - volatile sig_t oldintr; + volatile sig_t oldintr, oldintp; off_t hashbytes; + struct hostent *hp = NULL; + int (*closefunc) __P((FILE *)); + FILE *fout; + closefunc = NULL; + fout = NULL; s = -1; proxy = NULL; isftpurl = 0; -#ifdef __GNUC__ /* XXX: to shut up gcc warnings */ - (void)&savefile; +#ifdef __GNUC__ /* to shut up gcc warnings */ + (void)&closefunc; + (void)&fout; (void)&proxy; + (void)&savefile; #endif line = strdup(origline); @@ -136,11 +145,15 @@ url_get(origline, proxyenv) goto cleanup_url_get; } - savefile = strrchr(path, '/'); /* find savefile */ - if (savefile != NULL) - savefile++; - else - savefile = path; + if (outfile) + savefile = outfile; + else { + savefile = strrchr(path, '/'); /* find savefile */ + if (savefile != NULL) + savefile++; + else + savefile = path; + } if (EMPTYSTRING(savefile)) { if (isftpurl) goto noftpautologin; @@ -176,7 +189,7 @@ url_get(origline, proxyenv) *portnum++ = '\0'; if (debug) - printf("host %s, port %s, path %s, save as %s.\n", + fprintf(ttyout, "host %s, port %s, path %s, save as %s.\n", host, portnum, path, savefile); memset(&sin, 0, sizeof(sin)); @@ -188,8 +201,6 @@ url_get(origline, proxyenv) goto cleanup_url_get; } } else { - struct hostent *hp; - hp = gethostbyname(host); if (hp == NULL) { warnx("%s: %s", host, hstrerror(h_errno)); @@ -222,7 +233,29 @@ url_get(origline, proxyenv) goto cleanup_url_get; } - if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) == -1) { + while (connect(s, (struct sockaddr *)&sin, sizeof(sin)) == -1) { + if (errno == EINTR) + continue; + if (hp && hp->h_addr_list[1]) { + int oerrno = errno; + char *ia; + + ia = inet_ntoa(sin.sin_addr); + errno = oerrno; + warn("connect to address %s", ia); + hp->h_addr_list++; + memcpy(&sin.sin_addr, hp->h_addr_list[0], + (size_t)hp->h_length); + fprintf(ttyout, "Trying %s...\n", + inet_ntoa(sin.sin_addr)); + (void)close(s); + s = socket(AF_INET, SOCK_STREAM, 0); + if (s < 0) { + warn("socket"); + goto cleanup_url_get; + } + continue; + } warn("Can't connect to %s", host); goto cleanup_url_get; } @@ -232,11 +265,11 @@ url_get(origline, proxyenv) * status of "200". Proxy requests don't want leading /. */ if (!proxy) { - printf("Requesting %s\n", origline); + fprintf(ttyout, "Requesting %s\n", origline); len = snprintf(buf, sizeof(buf), "GET /%s HTTP/1.1\r\nHost: %s\r\n\r\n", path, host); } else { - printf("Requesting %s (via %s)\n", origline, proxyenv); + fprintf(ttyout, "Requesting %s (via %s)\n", origline, proxyenv); len = snprintf(buf, sizeof(buf), "GET %s HTTP/1.0\r\n\r\n", path); } @@ -265,9 +298,7 @@ url_get(origline, proxyenv) goto cleanup_url_get; } - /* - * Read the rest of the header. - */ + /* Read the rest of the header. */ memset(buf, 0, sizeof(buf)); c = '\0'; for (cp = buf; cp < buf + sizeof(buf); ) { @@ -282,9 +313,7 @@ url_get(origline, proxyenv) } buf[sizeof(buf) - 1] = '\0'; /* sanity */ - /* - * Look for the "Content-length: " header. - */ + /* Look for the "Content-length: " header. */ #define CONTENTLEN "Content-Length: " for (cp = buf; *cp != '\0'; cp++) { if (tolower(*cp) == 'c' && @@ -304,18 +333,34 @@ url_get(origline, proxyenv) } else filesize = -1; - /* Open the output file. */ - out = open(savefile, O_CREAT | O_WRONLY | O_TRUNC, 0666); - if (out < 0) { - warn("Can't open %s", savefile); - goto cleanup_url_get; + oldintr = oldintp = NULL; + + /* Open the output file. */ + if (strcmp(savefile, "-") == 0) { + fout = stdout; + } else if (*savefile == '|') { + oldintp = signal(SIGPIPE, SIG_IGN); + fout = popen(savefile + 1, "w"); + if (fout == NULL) { + warn("Can't run %s", savefile + 1); + goto cleanup_url_get; + } + closefunc = pclose; + } else { + fout = fopen(savefile, "w"); + if (fout == NULL) { + warn("Can't open %s", savefile); + goto cleanup_url_get; + } + closefunc = fclose; } - /* Trap signals */ - oldintr = NULL; + /* Trap signals */ if (setjmp(httpabort)) { if (oldintr) (void)signal(SIGINT, oldintr); + if (oldintp) + (void)signal(SIGPIPE, oldintp); goto cleanup_url_get; } oldintr = signal(SIGINT, aborthttp); @@ -326,6 +371,7 @@ url_get(origline, proxyenv) /* Finally, suck down the file. */ i = 0; + out = fileno(fout); while ((len = read(s, buf, sizeof(buf))) > 0) { bytes += len; for (cp = buf; len > 0; len -= i, cp += i) { @@ -338,17 +384,17 @@ url_get(origline, proxyenv) } if (hash && !progress) { while (bytes >= hashbytes) { - (void)putchar('#'); + (void)putc('#', ttyout); hashbytes += mark; } - (void)fflush(stdout); + (void)fflush(ttyout); } } if (hash && !progress && bytes > 0) { if (bytes < mark) - (void)putchar('#'); - (void)putchar('\n'); - (void)fflush(stdout); + (void)putc('#', ttyout); + (void)putc('\n', ttyout); + (void)fflush(ttyout); } if (len != 0) { warn("Reading from socket"); @@ -356,11 +402,14 @@ url_get(origline, proxyenv) } progressmeter(1); if (verbose) - puts("Successfully retrieved file."); + fputs("Successfully retrieved file.\n", ttyout); (void)signal(SIGINT, oldintr); + if (oldintp) + (void)signal(SIGPIPE, oldintp); close(s); - close(out); + if (closefunc != NULL) + (*closefunc)(fout); if (proxy) free(proxy); free(line); @@ -377,6 +426,8 @@ improper: cleanup_url_get: if (s != -1) close(s); + if (closefunc != NULL && fout != NULL) + (*closefunc)(fout); if (proxy) free(proxy); free(line); @@ -392,8 +443,8 @@ aborthttp(notused) { alarmtimer(0); - puts("\nhttp fetch aborted."); - (void)fflush(stdout); + fputs("\nhttp fetch aborted.\n", ttyout); + (void)fflush(ttyout); longjmp(httpabort, 1); } @@ -412,9 +463,10 @@ aborthttp(notused) * Otherwise, 0 is returned if all files retrieved successfully. */ int -auto_fetch(argc, argv) +auto_fetch(argc, argv, outfile) int argc; char *argv[]; + char *outfile; { static char lasthost[MAXHOSTNAMELEN]; char *xargv[5]; @@ -426,6 +478,10 @@ auto_fetch(argc, argv) int dirhasglob, filehasglob; char rempath[MAXPATHLEN]; +#ifdef __GNUC__ /* to shut up gcc warnings */ + (void)&outfile; +#endif + argpos = 0; if (setjmp(toplevel)) { @@ -458,7 +514,7 @@ auto_fetch(argc, argv) * Try HTTP URL-style arguments first. */ if (strncasecmp(line, HTTP_URL, sizeof(HTTP_URL) - 1) == 0) { - if (url_get(line, httpproxy) == -1) + if (url_get(line, httpproxy, outfile) == -1) rval = argpos + 1; continue; } @@ -471,7 +527,7 @@ auto_fetch(argc, argv) host = line; if (strncasecmp(line, FTP_URL, sizeof(FTP_URL) - 1) == 0) { if (ftpproxy) { - if (url_get(line, ftpproxy) == -1) + if (url_get(line, ftpproxy, outfile) == -1) rval = argpos + 1; continue; } @@ -537,7 +593,8 @@ parsed_url: } } if (debug) - printf("user %s:%s host %s port %s dir %s file %s\n", + fprintf(ttyout, + "user %s:%s host %s port %s dir %s file %s\n", user, pass, host, portnum, dir, file); /* @@ -612,7 +669,8 @@ parsed_url: } if (!verbose) - printf("Retrieving %s/%s\n", dir ? dir : "", file); + fprintf(ttyout, "Retrieving %s/%s\n", dir ? dir : "", + file); if (dirhasglob) { snprintf(rempath, sizeof(rempath), "%s/%s", dir, file); @@ -620,6 +678,7 @@ parsed_url: } /* Fetch the file(s). */ + xargc = 2; xargv[0] = "get"; xargv[1] = file; xargv[2] = NULL; @@ -629,10 +688,19 @@ parsed_url: ointeractive = interactive; interactive = 0; xargv[0] = "mget"; - mget(2, xargv); + mget(xargc, xargv); interactive = ointeractive; - } else - get(2, xargv); + } else { + if (outfile != NULL) { + xargv[2] = outfile; + xargv[3] = NULL; + xargc++; + } + get(xargc, xargv); + if (outfile != NULL && strcmp(outfile, "-") != 0 + && outfile[0] != '|') + outfile = NULL; + } if ((code / 100) != COMPLETE) rval = argpos + 1; diff --git a/usr.bin/ftp/ftp.1 b/usr.bin/ftp/ftp.1 index 903724109c61..5e5a364081ad 100644 --- a/usr.bin/ftp/ftp.1 +++ b/usr.bin/ftp/ftp.1 @@ -1,4 +1,4 @@ -.\" $NetBSD: ftp.1,v 1.24 1998/05/20 00:38:46 msaitoh Exp $ +.\" $NetBSD: ftp.1,v 1.25 1998/06/04 08:28:36 lukem Exp $ .\" .\" Copyright (c) 1985, 1989, 1990, 1993 .\" The Regents of the University of California. All rights reserved. @@ -43,6 +43,7 @@ file transfer program .Sh SYNOPSIS .Nm +.Op Fl A .Op Fl a .Op Fl d .Op Fl e @@ -51,15 +52,19 @@ file transfer program .Op Fl n .Op Fl p .Op Fl P Ar port +.Op Fl r Ar seconds .Op Fl t .Op Fl v .Op Fl V .Op Ar host Op Ar port .Nm ftp +.Op Fl o Ar output ftp://[\fIuser\fR:\fIpassword\fR@]\fIhost\fR[:\fIport\fR]/\fIfile\fR[/] .Nm ftp +.Op Fl o Ar output http://\fIhost\fR[:\fIport\fR]/\fIfile\fR .Nm ftp +.Op Fl o Ar output \fIhost\fR:[/\fIpath\fR/]\fIfile\fR[/] .Sh DESCRIPTION .Nm @@ -78,7 +83,18 @@ below for more information. .Pp Options may be specified at the command line, or to the command interpreter. -.Bl -tag -width "port " +.Bl -tag -width "port " +.It Fl A +Force active mode ftp. +By default, +.Nm +will try to use passive mode ftp and fall back to active mode +if passive is not supported by the server. +This option causes +.Nm +to always use an active connection. +It is only useful for connecting to very old servers that do not +implement passive mode properly. .It Fl a Causes .Nm @@ -87,6 +103,7 @@ to bypass normal login procedure, and use an anonymous login instead. Enables debugging. .It Fl e Disables command line editing. +This is useful for Emacs ange-ftp mode. .It Fl g Disables file name globbing. .It Fl i @@ -109,11 +126,36 @@ If no entry exists, will prompt for the remote machine login name (default is the user identity on the local machine), and, if necessary, prompt for a password and an account with which to login. +.It Fl o Ar output +When auto-fetching files, save the contents in +.Ar output . +.Ar output +is parsed according to the +.Sx FILE NAMING CONVENTIONS +below. +If +.Ar output +is not +.Sq - +or doesn't start with +.Sq \&| , +then only the first file specified will be retrieved into +.Ar output ; +all other files will be retreived into the basename of their +remote name. .It Fl p Enable passive mode operation for use behind connection filtering firewalls. +This option has been deprecated as +.Nm +now tries to use passive mode by default, falling back to active mode +if the server does not support passive connections. .It Fl P Ar port Sets the port number to .Ar port . +.It Fl r Ar wait +Retry the connection attempt if it failed, pausing for +.Ar wait +seconds. .It Fl t Enables packet tracing. .It Fl v @@ -1329,6 +1371,19 @@ By default, this is bound to the TAB key. .Nm utilizes the following environment variables. .Bl -tag -width "FTPSERVERPORT" +.It Ev FTPMODE +Overrides the default operation mode. +Support values are: +.Bl -tag -width "passive" +.It active +active mode ftp only +.It auto +automatic determination of passive or active (this is the default) +.It gate +gate-ftp mode +.It passive +passive mode ftp only +.El .It Ev FTPSERVER Host to use as gate-ftp server when .Ic gate diff --git a/usr.bin/ftp/ftp.c b/usr.bin/ftp/ftp.c index 8ccc2f244dfc..a248b52caa17 100644 --- a/usr.bin/ftp/ftp.c +++ b/usr.bin/ftp/ftp.c @@ -1,4 +1,4 @@ -/* $NetBSD: ftp.c,v 1.34 1998/05/20 09:43:41 pk Exp $ */ +/* $NetBSD: ftp.c,v 1.35 1998/06/04 08:28:36 lukem Exp $ */ /* * Copyright (c) 1985, 1989, 1993, 1994 @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)ftp.c 8.6 (Berkeley) 10/27/94"; #else -__RCSID("$NetBSD: ftp.c,v 1.34 1998/05/20 09:43:41 pk Exp $"); +__RCSID("$NetBSD: ftp.c,v 1.35 1998/06/04 08:28:36 lukem Exp $"); #endif #endif /* not lint */ @@ -120,6 +120,8 @@ hookup(host, port) hisctladdr.sin_port = port; while (connect(s, (struct sockaddr *)&hisctladdr, sizeof(hisctladdr)) < 0) { + if (errno == EINTR) + continue; if (hp && hp->h_addr_list[1]) { int oerrno = errno; char *ia; @@ -129,7 +131,7 @@ hookup(host, port) warn("connect to address %s", ia); hp->h_addr_list++; memcpy(&hisctladdr.sin_addr, hp->h_addr, hp->h_length); - printf("Trying %s...\n", + fprintf(ttyout, "Trying %s...\n", inet_ntoa(hisctladdr.sin_addr)); (void)close(s); s = socket(hisctladdr.sin_family, SOCK_STREAM, 0); @@ -167,7 +169,7 @@ hookup(host, port) goto bad; } if (verbose) - printf("Connected to %s.\n", hostname); + fprintf(ttyout, "Connected to %s.\n", hostname); if (getreply(0) > 2) { /* read startup message from server */ if (cin) (void)fclose(cin); @@ -199,8 +201,8 @@ cmdabort(notused) { alarmtimer(0); - putchar('\n'); - (void)fflush(stdout); + putc('\n', ttyout); + (void)fflush(ttyout); abrtflag++; if (ptflag) longjmp(ptabort, 1); @@ -224,7 +226,7 @@ command(va_alist) abrtflag = 0; if (debug) { - fputs("---> ", stdout); + fputs("---> ", ttyout); #ifdef __STDC__ va_start(ap, fmt); #else @@ -232,14 +234,14 @@ command(va_alist) fmt = va_arg(ap, const char *); #endif if (strncmp("PASS ", fmt, 5) == 0) - fputs("PASS XXXX", stdout); + fputs("PASS XXXX", ttyout); else if (strncmp("ACCT ", fmt, 5) == 0) - fputs("ACCT XXXX", stdout); + fputs("ACCT XXXX", ttyout); else - vprintf(fmt, ap); + vfprintf(ttyout, fmt, ap); va_end(ap); - putchar('\n'); - (void)fflush(stdout); + putc('\n', ttyout); + (void)fflush(ttyout); } if (cout == NULL) { warnx("No control connection for command."); @@ -312,19 +314,22 @@ getreply(expecteof) } lostpeer(); if (verbose) { - puts( -"421 Service not available, remote server has closed connection."); - (void)fflush(stdout); + fputs( + "421 Service not available, remote server has closed connection.\n", + ttyout); + (void)fflush(ttyout); } code = 421; return (4); } if (c != '\r' && (verbose > 0 || - (verbose > -1 && n == '5' && dig > 4))) { + ((verbose > -1 && n == '5' && dig > 4) && + (((!n && c < '5') || (n && n < '5')) + || !retry_connect)))) { if (proxflag && (dig == 1 || (dig == 5 && verbose == 0))) - printf("%s:", hostname); - (void)putchar(c); + fprintf(ttyout, "%s:", hostname); + (void)putc(c, ttyout); } if (dig < 4 && isdigit(c)) code = code * 10 + (c - '0'); @@ -350,9 +355,10 @@ getreply(expecteof) if (cp < ¤t_line[sizeof(current_line) - 1]) *cp++ = c; } - if (verbose > 0 || (verbose > -1 && n == '5')) { - (void)putchar(c); - (void)fflush (stdout); + if (verbose > 0 || ((verbose > -1 && n == '5') && + (n < '5' || !retry_connect))) { + (void)putc(c, ttyout); + (void)fflush (ttyout); } if (line == 0) { size_t len = cp - current_line; @@ -402,8 +408,8 @@ abortsend(notused) alarmtimer(0); mflag = 0; abrtflag = 0; - puts("\nsend aborted\nwaiting for remote to finish abort."); - (void)fflush(stdout); + fputs("\nsend aborted\nwaiting for remote to finish abort.\n", ttyout); + (void)fflush(ttyout); longjmp(sendabort, 1); } @@ -421,7 +427,7 @@ sendrequest(cmd, local, remote, printnames) char *lmode, buf[BUFSIZ], *bufp; int oprogress; -#ifdef __GNUC__ /* XXX: to shut up gcc warnings */ +#ifdef __GNUC__ /* to shut up gcc warnings */ (void)&fin; (void)&dout; (void)&closefunc; @@ -439,9 +445,9 @@ sendrequest(cmd, local, remote, printnames) oprogress = progress; if (verbose && printnames) { if (local && *local != '-') - printf("local: %s ", local); + fprintf(ttyout, "local: %s ", local); if (remote) - printf("remote: %s\n", remote); + fprintf(ttyout, "remote: %s\n", remote); } if (proxy) { proxtrans(cmd, local, remote); @@ -500,7 +506,7 @@ sendrequest(cmd, local, remote, printnames) } closefunc = fclose; if (fstat(fileno(fin), &st) < 0 || !S_ISREG(st.st_mode)) { - printf("%s: not a plain file.\n", local); + fprintf(ttyout, "%s: not a plain file.\n", local); (void)signal(SIGINT, oldintr); (void)signal(SIGINFO, oldinti); fclose(fin); @@ -591,17 +597,17 @@ sendrequest(cmd, local, remote, printnames) break; if (hash && (!progress || filesize < 0) ) { while (bytes >= hashbytes) { - (void)putchar('#'); + (void)putc('#', ttyout); hashbytes += mark; } - (void)fflush(stdout); + (void)fflush(ttyout); } } if (hash && (!progress || filesize < 0) && bytes > 0) { if (bytes < mark) - (void)putchar('#'); - (void)putchar('\n'); - (void)fflush(stdout); + (void)putc('#', ttyout); + (void)putc('\n', ttyout); + (void)fflush(ttyout); } if (c < 0) warn("local: %s", local); @@ -617,8 +623,8 @@ sendrequest(cmd, local, remote, printnames) if (c == '\n') { while (hash && (!progress || filesize < 0) && (bytes >= hashbytes)) { - (void)putchar('#'); - (void)fflush(stdout); + (void)putc('#', ttyout); + (void)fflush(ttyout); hashbytes += mark; } if (ferror(dout)) @@ -637,9 +643,9 @@ sendrequest(cmd, local, remote, printnames) } if (hash && (!progress || filesize < 0)) { if (bytes < hashbytes) - (void)putchar('#'); - (void)putchar('\n'); - (void)fflush(stdout); + (void)putc('#', ttyout); + (void)putc('\n', ttyout); + (void)fflush(ttyout); } if (ferror(fin)) warn("local: %s", local); @@ -698,8 +704,9 @@ abortrecv(notused) alarmtimer(0); mflag = 0; abrtflag = 0; - puts("\nreceive aborted\nwaiting for remote to finish abort."); - (void)fflush(stdout); + fputs("\nreceive aborted\nwaiting for remote to finish abort.\n", + ttyout); + (void)fflush(ttyout); longjmp(recvabort, 1); } @@ -722,7 +729,7 @@ recvrequest(cmd, local, remote, lmode, printnames, ignorespecial) int oprogress; int opreserve; -#ifdef __GNUC__ /* XXX: to shut up gcc warnings */ +#ifdef __GNUC__ /* to shut up gcc warnings */ (void)&local; (void)&fout; (void)&din; @@ -745,9 +752,9 @@ recvrequest(cmd, local, remote, lmode, printnames, ignorespecial) is_retr = (strcmp(cmd, "RETR") == 0); if (is_retr && verbose && printnames) { if (local && (ignorespecial || *local != '-')) - printf("local: %s ", local); + fprintf(ttyout, "local: %s ", local); if (remote) - printf("remote: %s\n", remote); + fprintf(ttyout, "remote: %s\n", remote); } if (proxy && is_retr) { proxtrans(cmd, local, remote); @@ -800,7 +807,7 @@ recvrequest(cmd, local, remote, lmode, printnames, ignorespecial) return; } if (!runique && errno == EACCES && - chmod(local, 0600) < 0) { + chmod(local, (S_IRUSR|S_IWUSR)) < 0) { warn("local: %s", local); (void)signal(SIGINT, oldintr); (void)signal(SIGINFO, oldinti); @@ -921,17 +928,17 @@ recvrequest(cmd, local, remote, lmode, printnames, ignorespecial) bytes += c; if (hash && (!progress || filesize < 0)) { while (bytes >= hashbytes) { - (void)putchar('#'); + (void)putc('#', ttyout); hashbytes += mark; } - (void)fflush(stdout); + (void)fflush(ttyout); } } if (hash && (!progress || filesize < 0) && bytes > 0) { if (bytes < mark) - (void)putchar('#'); - (void)putchar('\n'); - (void)fflush(stdout); + (void)putc('#', ttyout); + (void)putc('\n', ttyout); + (void)fflush(ttyout); } if (c < 0) { if (errno != EPIPE) @@ -976,8 +983,8 @@ done: while (c == '\r') { while (hash && (!progress || filesize < 0) && (bytes >= hashbytes)) { - (void)putchar('#'); - (void)fflush(stdout); + (void)putc('#', ttyout); + (void)fflush(ttyout); hashbytes += mark; } bytes++; @@ -999,15 +1006,17 @@ done: } break2: if (bare_lfs) { - printf( -"WARNING! %d bare linefeeds received in ASCII mode.\n", bare_lfs); - puts("File may not have transferred correctly."); + fprintf(ttyout, + "WARNING! %d bare linefeeds received in ASCII mode.\n", + bare_lfs); + fputs("File may not have transferred correctly.\n", + ttyout); } if (hash && (!progress || filesize < 0)) { if (bytes < hashbytes) - (void)putchar('#'); - (void)putchar('\n'); - (void)fflush(stdout); + (void)putc('#', ttyout); + (void)putc('\n', ttyout); + (void)fflush(ttyout); } if (ferror(din)) { if (errno != EPIPE) @@ -1037,7 +1046,7 @@ break2: tval[1].tv_sec = mtime; tval[1].tv_usec = 0; if (utimes(local, tval) == -1) { - printf( + fprintf(ttyout, "Can't change modification time on %s to %s", local, asctime(localtime(&mtime))); } @@ -1092,6 +1101,7 @@ initconn() int on = 1; int a0, a1, a2, a3, p0, p1; +reinit: if (passivemode) { data = socket(AF_INET, SOCK_STREAM, 0); if (data < 0) { @@ -1103,7 +1113,14 @@ initconn() sizeof(on)) < 0) warn("setsockopt (ignored)"); if (command("PASV") != COMPLETE) { - puts("Passive mode refused."); + if (activefallback) { + (void)close(data); + data = -1; + passivemode = 0; + activefallback = 0; + goto reinit; + } + fputs("Passive mode refused.\n", ttyout); goto bad; } @@ -1117,8 +1134,9 @@ initconn() if (sscanf(pasv, "%d,%d,%d,%d,%d,%d", &a0, &a1, &a2, &a3, &p0, &p1) != 6) { - puts( -"Passive mode address scan failure. Shouldn't happen!"); + fputs( + "Passive mode address scan failure. Shouldn't happen!\n", + ttyout); goto bad; } @@ -1133,8 +1151,10 @@ initconn() p[0] = p0 & 0xff; p[1] = p1 & 0xff; - if (connect(data, (struct sockaddr *)&data_addr, + while (connect(data, (struct sockaddr *)&data_addr, sizeof(data_addr)) < 0) { + if (errno == EINTR) + continue; warn("connect"); goto bad; } @@ -1356,8 +1376,8 @@ abortpt(notused) { alarmtimer(0); - putchar('\n'); - (void)fflush(stdout); + putc('\n', ttyout); + (void)fflush(ttyout); ptabflg++; mflag = 0; abrtflag = 0; @@ -1374,7 +1394,7 @@ proxtrans(cmd, local, remote) char *cmd2; struct fd_set mask; -#ifdef __GNUC__ /* XXX: to shut up gcc warnings */ +#ifdef __GNUC__ /* to shut up gcc warnings */ (void)&oldintr; (void)&cmd2; #endif @@ -1394,12 +1414,13 @@ proxtrans(cmd, local, remote) if (curtype != prox_type) changetype(prox_type, 1); if (command("PASV") != COMPLETE) { - puts("proxy server does not support third party transfers."); + fputs("proxy server does not support third party transfers.\n", + ttyout); return; } pswitch(0); if (!connected) { - puts("No primary connection."); + fputs("No primary connection.\n", ttyout); pswitch(1); code = -1; return; @@ -1430,7 +1451,7 @@ proxtrans(cmd, local, remote) (void)signal(SIGINT, oldintr); pswitch(1); ptflag = 0; - printf("local: %s remote: %s\n", local, remote); + fprintf(ttyout, "local: %s remote: %s\n", local, remote); return; abort: (void)signal(SIGINT, SIG_IGN); @@ -1536,7 +1557,8 @@ gunique(local) *cp++ = '.'; while (!d) { if (++count == 100) { - puts("runique: can't find unique file name."); + fputs("runique: can't find unique file name.\n", + ttyout); return (NULL); } *cp++ = ext; diff --git a/usr.bin/ftp/ftp_var.h b/usr.bin/ftp/ftp_var.h index ed4d3f8f854d..1fa45ab1fcc9 100644 --- a/usr.bin/ftp/ftp_var.h +++ b/usr.bin/ftp/ftp_var.h @@ -1,4 +1,4 @@ -/* $NetBSD: ftp_var.h,v 1.23 1998/01/18 22:09:41 lukem Exp $ */ +/* $NetBSD: ftp_var.h,v 1.24 1998/06/04 08:28:36 lukem Exp $ */ /* * Copyright (c) 1985, 1989, 1993, 1994 @@ -97,6 +97,7 @@ int code; /* return/reply code for ftp command */ int crflag; /* if 1, strip car. rets. on ascii gets */ char pasv[64]; /* passive port for proxy data connection */ int passivemode; /* passive mode enabled */ +int activefallback; /* fall back to active mode if passive fails */ char *altarg; /* argv[1] with no shell-like preprocessing */ char ntin[17]; /* input translation table */ char ntout[17]; /* output translation table */ @@ -115,8 +116,10 @@ char bytename[32]; /* local byte size in ascii */ int bytesize; /* local byte size in binary */ int anonftp; /* automatic anonymous login */ int dirchange; /* remote directory changed by cd command */ +int retry_connect; /* seconds between retrying connection */ int ttywidth; /* width of tty */ char *tmpdir; /* temporary directory */ +FILE *ttyout; /* stdout, or stderr if retrieving to stdout */ #ifndef SMALL int editing; /* command line editing enabled */ @@ -175,6 +178,6 @@ struct macel { char *mac_end; /* end of macro in macbuf */ }; -int macnum; /* number of defined macros */ +int macnum; /* number of defined macros */ struct macel macros[16]; -char macbuf[4096]; +char macbuf[4096]; diff --git a/usr.bin/ftp/main.c b/usr.bin/ftp/main.c index 7c5508eae5e9..b515401ac208 100644 --- a/usr.bin/ftp/main.c +++ b/usr.bin/ftp/main.c @@ -1,4 +1,4 @@ -/* $NetBSD: main.c,v 1.30 1998/01/21 11:14:34 lukem Exp $ */ +/* $NetBSD: main.c,v 1.31 1998/06/04 08:28:36 lukem Exp $ */ /* * Copyright (c) 1985, 1989, 1993, 1994 @@ -43,7 +43,7 @@ __COPYRIGHT("@(#) Copyright (c) 1985, 1989, 1993, 1994\n\ #if 0 static char sccsid[] = "@(#)main.c 8.6 (Berkeley) 10/9/94"; #else -__RCSID("$NetBSD: main.c,v 1.30 1998/01/21 11:14:34 lukem Exp $"); +__RCSID("$NetBSD: main.c,v 1.31 1998/06/04 08:28:36 lukem Exp $"); #endif #endif /* not lint */ @@ -76,6 +76,7 @@ main(argc, argv) long port; struct passwd *pw = NULL; char *cp, *ep, homedir[MAXPATHLEN]; + char *outfile = NULL; int dumbterm; sp = getservbyname("ftp", "tcp"); @@ -93,7 +94,7 @@ main(argc, argv) if (cp != NULL) { port = strtol(cp, &ep, 10); if (port < 1 || port > MAX_IN_PORT_T || *ep != '\0') - warnx("bad FTPSERVERPORT port number: %s (ignored)", + warnx("bad $FTPSERVERPORT port number: %s (ignored)", cp); else gateport = htons(port); @@ -108,7 +109,8 @@ main(argc, argv) doglob = 1; interactive = 1; autologin = 1; - passivemode = 0; + passivemode = 1; + activefallback = 1; preserve = 1; verbose = 0; progress = 0; @@ -123,11 +125,29 @@ main(argc, argv) if ((tmpdir = getenv("TMPDIR")) == NULL) tmpdir = _PATH_TMP; + /* Set default operation mode based on FTPMODE environment variable */ + if ((cp = getenv("FTPMODE")) != NULL) { + if (strcmp(cp, "passive") == 0) { + passivemode = 1; + activefallback = 0; + } else if (strcmp(cp, "active") == 0) { + passivemode = 0; + activefallback = 0; + } else if (strcmp(cp, "gate") == 0) { + gatemode = 1; + } else if (strcmp(cp, "auto") == 0) { + passivemode = 1; + activefallback = 1; + } else + warnx("unknown $FTPMODE '%s'; using defaults", cp); + } + cp = strrchr(argv[0], '/'); cp = (cp == NULL) ? argv[0] : cp + 1; - if (strcmp(cp, "pftp") == 0) + if (strcmp(cp, "pftp") == 0) { passivemode = 1; - else if (strcmp(cp, "gate-ftp") == 0) + activefallback = 0; + } else if (strcmp(cp, "gate-ftp") == 0) gatemode = 1; gateserver = getenv("FTPSERVER"); @@ -136,7 +156,7 @@ main(argc, argv) if (gatemode) { if (*gateserver == '\0') { warnx( -"Neither $FTPSERVER nor GATE_SERVER is defined; disabling gate-ftp"); +"Neither $FTPSERVER nor $GATE_SERVER is defined; disabling gate-ftp"); gatemode = 0; } } @@ -154,13 +174,19 @@ main(argc, argv) editing = 1; /* editing mode on if tty is usable */ #endif } + ttyout = stdout; #ifndef SMALL - if (isatty(fileno(stdout)) && !dumbterm) + if (isatty(fileno(ttyout)) && !dumbterm && foregroundproc()) progress = 1; /* progress bar on if tty is usable */ #endif - while ((ch = getopt(argc, argv, "adeginpP:tvV")) != -1) { + while ((ch = getopt(argc, argv, "Aadegino:pP:r:tvV")) != -1) { switch (ch) { + case 'A': + activefallback = 0; + passivemode = 0; + break; + case 'a': anonftp = 1; break; @@ -188,8 +214,15 @@ main(argc, argv) autologin = 0; break; + case 'o': + outfile = optarg; + if (strcmp(outfile, "-") == 0) + ttyout = stderr; + break; + case 'p': passivemode = 1; + activefallback = 0; break; case 'P': @@ -200,6 +233,13 @@ main(argc, argv) ftpport = htons((in_port_t)port); break; + case 'r': + retry_connect = strtol(optarg, &ep, 10); + if (retry_connect < 1 || retry_connect > MAX_IN_PORT_T + || *ep != '\0') + errx(1, "bad retry value: %s", optarg); + break; + case 't': trace = 1; break; @@ -240,7 +280,7 @@ main(argc, argv) setttywidth(0); (void)signal(SIGWINCH, setttywidth); -#ifdef __GNUC__ /* XXX: to shut up gcc warnings */ +#ifdef __GNUC__ /* to shut up gcc warnings */ (void)&argc; (void)&argv; #endif @@ -248,7 +288,7 @@ main(argc, argv) if (argc > 0) { if (strchr(argv[0], ':') != NULL) { anonftp = 1; /* Handle "automatic" transfers. */ - rval = auto_fetch(argc, argv); + rval = auto_fetch(argc, argv, outfile); if (rval >= 0) /* -1 == connected and cd-ed */ exit(rval); } else { @@ -263,7 +303,19 @@ main(argc, argv) xargv[2] = argv[1]; xargv[3] = argv[2]; xargv[4] = NULL; - setpeer(argc+1, xargv); + do { + setpeer(argc+1, xargv); + if (!retry_connect) + break; + if (!connected) { + macnum = 0; + fprintf(ttyout, + "Retrying in %d seconds...\n", + retry_connect); + sleep(retry_connect); + } + } while (!connected); + retry_connect = 0; /* connected, stop hiding msgs */ } } #ifndef SMALL @@ -343,14 +395,14 @@ cmdscanner(top) && !editing #endif /* !SMALL */ ) - (void)putchar('\n'); + (void)putc('\n', ttyout); for (;;) { #ifndef SMALL if (!editing) { #endif /* !SMALL */ if (fromatty) { - fputs(prompt(), stdout); - (void)fflush(stdout); + fputs(prompt(), ttyout); + (void)fflush(ttyout); } if (fgets(line, sizeof(line), stdin) == NULL) quit(0, 0); @@ -362,7 +414,7 @@ cmdscanner(top) break; line[num] = '\0'; } else if (num == sizeof(line) - 2) { - puts("sorry, input line too long."); + fputs("sorry, input line too long.\n", ttyout); while ((num = getchar()) != '\n' && num != EOF) /* void */; break; @@ -379,7 +431,7 @@ cmdscanner(top) if (num == 0) break; } else if (num >= sizeof(line)) { - puts("sorry, input line too long."); + fputs("sorry, input line too long.\n", ttyout); break; } memcpy(line, buf, num); @@ -393,7 +445,7 @@ cmdscanner(top) continue; c = getcmd(margv[0]); if (c == (struct cmd *)-1) { - puts("?Ambiguous command."); + fputs("?Ambiguous command.\n", ttyout); continue; } if (c == NULL) { @@ -408,17 +460,17 @@ cmdscanner(top) if (strchr(margv[0], ':') != NULL || el_parse(el, margc, margv) != 0) #endif /* !SMALL */ - puts("?Invalid command."); + fputs("?Invalid command.\n", ttyout); continue; } if (c->c_conn && !connected) { - puts("Not connected."); + fputs("Not connected.\n", ttyout); continue; } confirmrest = 0; (*c->c_handler)(margc, margv); if (bell && c->c_bell) - (void)putchar('\007'); + (void)putc('\007', ttyout); if (c->c_handler != help) break; } @@ -650,7 +702,8 @@ help(argc, argv) StringList *buf; buf = sl_init(); - printf("%sommands may be abbreviated. Commands are:\n\n", + fprintf(ttyout, + "%sommands may be abbreviated. Commands are:\n\n", proxy ? "Proxy c" : "C"); for (c = cmdtab; c < &cmdtab[NCMDS]; c++) if (c->c_name && (!proxy || c->c_proxy)) @@ -668,11 +721,11 @@ help(argc, argv) arg = *++argv; c = getcmd(arg); if (c == (struct cmd *)-1) - printf("?Ambiguous help command %s\n", arg); + fprintf(ttyout, "?Ambiguous help command %s\n", arg); else if (c == NULL) - printf("?Invalid help command %s\n", arg); + fprintf(ttyout, "?Invalid help command %s\n", arg); else - printf("%-*s\t%s\n", HELPINDENT, + fprintf(ttyout, "%-*s\t%s\n", HELPINDENT, c->c_name, c->c_help); } } @@ -681,10 +734,10 @@ void usage() { (void)fprintf(stderr, - "usage: %s [-adeginptvV] [host [port]]\n" - " %s host:path[/]\n" - " %s ftp://host[:port]/path[/]\n" - " %s http://host[:port]/file\n", + "usage: %s [-AadeginptvV] [-r retry] [-P port] [host [port]]\n" + " %s [-o outfile] host:path[/]\n" + " %s [-o outfile] ftp://host[:port]/path[/]\n" + " %s [-o outfile] http://host[:port]/file\n", __progname, __progname, __progname, __progname); exit(1); } diff --git a/usr.bin/ftp/ruserpass.c b/usr.bin/ftp/ruserpass.c index 9c873bfeaf6b..7bc412e7cf71 100644 --- a/usr.bin/ftp/ruserpass.c +++ b/usr.bin/ftp/ruserpass.c @@ -1,4 +1,4 @@ -/* $NetBSD: ruserpass.c,v 1.16 1998/05/20 00:55:16 christos Exp $ */ +/* $NetBSD: ruserpass.c,v 1.17 1998/06/04 08:28:36 lukem Exp $ */ /* * Copyright (c) 1985, 1993, 1994 @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)ruserpass.c 8.4 (Berkeley) 4/27/95"; #else -__RCSID("$NetBSD: ruserpass.c,v 1.16 1998/05/20 00:55:16 christos Exp $"); +__RCSID("$NetBSD: ruserpass.c,v 1.17 1998/06/04 08:28:36 lukem Exp $"); #endif #endif /* not lint */ @@ -71,7 +71,7 @@ static char tokval[100]; static struct toktab { char *tokstr; int tval; -} toktab[]= { +} toktab[] = { { "default", DEFAULT }, { "login", LOGIN }, { "password", PASSWD }, @@ -96,7 +96,7 @@ ruserpass(host, aname, apass, aacct) if (hdir == NULL) hdir = "."; if (strlen(hdir) + sizeof(".netrc") < sizeof(buf)) { - (void)snprintf(buf, sizeof buf, "%s/.netrc", hdir); + (void)snprintf(buf, sizeof(buf), "%s/.netrc", hdir); } else { warnx("%s/.netrc: %s", hdir, strerror(ENAMETOOLONG)); return (0); @@ -190,36 +190,40 @@ next: (void)fclose(cfile); return (0); } - while ((c=getc(cfile)) != EOF) + while ((c = getc(cfile)) != EOF) if (c != ' ' && c != '\t') break; if (c == EOF || c == '\n') { - puts("Missing macdef name argument."); + fputs("Missing macdef name argument.\n", + ttyout); goto bad; } if (macnum == 16) { - puts( -"Limit of 16 macros have already been defined."); + fputs( + "Limit of 16 macros have already been defined.\n", + ttyout); goto bad; } tmp = macros[macnum].mac_name; *tmp++ = c; - for (i=0; i < 8 && (c=getc(cfile)) != EOF && + for (i = 0; i < 8 && (c = getc(cfile)) != EOF && !isspace(c); ++i) { *tmp++ = c; } if (c == EOF) { - puts( -"Macro definition missing null line terminator."); + fputs( + "Macro definition missing null line terminator.\n", + ttyout); goto bad; } *tmp = '\0'; if (c != '\n') { - while ((c=getc(cfile)) != EOF && c != '\n'); + while ((c = getc(cfile)) != EOF && c != '\n'); } if (c == EOF) { - puts( -"Macro definition missing null line terminator."); + fputs( + "Macro definition missing null line terminator.\n", + ttyout); goto bad; } if (macnum == 0) { @@ -231,9 +235,10 @@ next: } tmp = macros[macnum].mac_start; while (tmp != macbuf + 4096) { - if ((c=getc(cfile)) == EOF) { - puts( -"Macro definition missing null line terminator."); + if ((c = getc(cfile)) == EOF) { + fputs( + "Macro definition missing null line terminator.\n", + ttyout); goto bad; } *tmp = c; @@ -247,7 +252,8 @@ next: tmp++; } if (tmp == macbuf + 4096) { - puts("4K macro buffer exceeded."); + fputs("4K macro buffer exceeded.\n", + ttyout); goto bad; } break; diff --git a/usr.bin/ftp/util.c b/usr.bin/ftp/util.c index 9cfb27704575..1272261b8472 100644 --- a/usr.bin/ftp/util.c +++ b/usr.bin/ftp/util.c @@ -1,4 +1,4 @@ -/* $NetBSD: util.c,v 1.23 1998/05/20 00:55:52 christos Exp $ */ +/* $NetBSD: util.c,v 1.24 1998/06/04 08:28:36 lukem Exp $ */ /* * Copyright (c) 1985, 1989, 1993, 1994 @@ -35,7 +35,7 @@ #include #ifndef lint -__RCSID("$NetBSD: util.c,v 1.23 1998/05/20 00:55:52 christos Exp $"); +__RCSID("$NetBSD: util.c,v 1.24 1998/06/04 08:28:36 lukem Exp $"); #endif /* not lint */ /* @@ -76,7 +76,7 @@ setpeer(argc, argv) in_port_t port; if (connected) { - printf("Already connected to %s, use close first.\n", + fprintf(ttyout, "Already connected to %s, use close first.\n", hostname); code = -1; return; @@ -84,7 +84,7 @@ setpeer(argc, argv) if (argc < 2) (void)another(&argc, &argv, "to"); if (argc < 2 || argc > 3) { - printf("usage: %s host-name [port]\n", argv[0]); + fprintf(ttyout, "usage: %s host-name [port]\n", argv[0]); code = -1; return; } @@ -98,8 +98,10 @@ setpeer(argc, argv) nport = strtol(argv[2], &ep, 10); if (nport < 1 || nport > MAX_IN_PORT_T || *ep != '\0') { - printf("%s: bad port number '%s'.\n", argv[1], argv[2]); - printf("usage: %s host-name [port]\n", argv[0]); + fprintf(ttyout, "%s: bad port number '%s'.\n", + argv[1], argv[2]); + fprintf(ttyout, "usage: %s host-name [port]\n", + argv[0]); code = -1; return; } @@ -120,7 +122,8 @@ setpeer(argc, argv) if (command("PASSERVE %s", argv[1]) != COMPLETE) return; if (verbose) - printf("Connected via pass-through server %s\n", + fprintf(ttyout, + "Connected via pass-through server %s\n", gateserver); } @@ -143,9 +146,9 @@ setpeer(argc, argv) if (command("SYST") == COMPLETE && overbose) { char *cp, c; c = 0; - cp = strchr(reply_string+4, ' '); + cp = strchr(reply_string + 4, ' '); if (cp == NULL) - cp = strchr(reply_string+4, '\r'); + cp = strchr(reply_string + 4, '\r'); if (cp) { if (cp[-1] == '.') cp--; @@ -153,7 +156,8 @@ setpeer(argc, argv) *cp = '\0'; } - printf("Remote system type is %s.\n", reply_string + 4); + fprintf(ttyout, "Remote system type is %s.\n", + reply_string + 4); if (cp) *cp = c; } @@ -171,7 +175,8 @@ setpeer(argc, argv) type = 0; (void)strcpy(typename, "binary"); if (overbose) - printf("Using %s mode to transfer files.\n", + fprintf(ttyout, + "Using %s mode to transfer files.\n", typename); } else { if (proxy) @@ -180,14 +185,14 @@ setpeer(argc, argv) unix_server = 0; if (overbose && !strncmp(reply_string, "215 TOPS20", 10)) - puts( -"Remember to set tenex mode when transferring binary files from this machine."); + fputs( +"Remember to set tenex mode when transferring binary files from this machine.\n", + ttyout); } verbose = overbose; } } - /* * login to remote host, using given username & password if supplied */ @@ -252,9 +257,9 @@ login(host, user, pass) if (myname == NULL && (pw = getpwuid(getuid())) != NULL) myname = pw->pw_name; if (myname) - printf("Name (%s:%s): ", host, myname); + fprintf(ttyout, "Name (%s:%s): ", host, myname); else - printf("Name (%s): ", host); + fprintf(ttyout, "Name (%s): ", host); *tmp = '\0'; (void)fgets(tmp, sizeof(tmp) - 1, stdin); tmp[strlen(tmp) - 1] = '\0'; @@ -309,10 +314,10 @@ another(pargc, pargv, prompt) int len = strlen(line), ret; if (len >= sizeof(line) - 3) { - puts("sorry, arguments too long."); + fputs("sorry, arguments too long.\n", ttyout); intr(); } - printf("(%s) ", prompt); + fprintf(ttyout, "(%s) ", prompt); line[len++] = ' '; if (fgets(&line[len], sizeof(line) - len, stdin) == NULL) intr(); @@ -389,7 +394,9 @@ remglob(argv, doswitch, errbuf) (void)unlink(temp); if (ftemp == NULL) { if (errbuf == NULL) - puts("can't find list of remote files, oops."); + fputs( + "can't find list of remote files, oops.\n", + ttyout); else *errbuf = "can't find list of remote files, oops."; @@ -414,8 +421,8 @@ confirm(cmd, file) if (!interactive || confirmrest) return (1); - printf("%s %s? ", cmd, file); - (void)fflush(stdout); + fprintf(ttyout, "%s %s? ", cmd, file); + (void)fflush(ttyout); if (fgets(line, sizeof(line), stdin) == NULL) return (0); switch (tolower(*line)) { @@ -423,11 +430,12 @@ confirm(cmd, file) return (0); case 'p': interactive = 0; - puts("Interactive mode: off."); + fputs("Interactive mode: off.\n", ttyout); break; case 'a': confirmrest = 1; - printf("Prompting off for duration of %s.\n", cmd); + fprintf(ttyout, "Prompting off for duration of %s.\n", + cmd); break; } return (1); @@ -494,8 +502,10 @@ remotesize(file, noisy) if (*ep != '\0' && !isspace((unsigned char)*ep)) size = -1; } - } else if (noisy && debug == 0) - puts(reply_string); + } else if (noisy && debug == 0) { + fputs(reply_string, ttyout); + putc('\n', ttyout); + } verbose = overbose; return (size); } @@ -532,15 +542,18 @@ remotemodtime(file, noisy) timebuf.tm_isdst = -1; rtime = mktime(&timebuf); if (rtime == -1 && (noisy || debug != 0)) - printf("Can't convert %s to a time.\n", reply_string); + fprintf(ttyout, "Can't convert %s to a time.\n", + reply_string); else #ifndef __SVR4 rtime += timebuf.tm_gmtoff; /* conv. local -> GMT */ #else rtime -= timezone; #endif - } else if (noisy && debug == 0) - puts(reply_string); + } else if (noisy && debug == 0) { + fputs(reply_string, ttyout); + putc('\n', ttyout); + } verbose = overbose; if (rtime == -1) code = ocode; @@ -548,11 +561,12 @@ remotemodtime(file, noisy) } #ifndef SMALL -static void updateprogressmeter __P((int)); -void -updateprogressmeter(dummy) - int dummy; +/* + * return non-zero if we're the current foreground process + */ +int +foregroundproc() { static pid_t pgrp = -1; int ctty_pgrp; @@ -560,11 +574,22 @@ updateprogressmeter(dummy) if (pgrp == -1) pgrp = getpgrp(); + return ((ioctl(fileno(ttyout), TIOCGPGRP, &ctty_pgrp) != -1 && + ctty_pgrp == (int)pgrp)); +} + + +static void updateprogressmeter __P((int)); + +static void +updateprogressmeter(dummy) + int dummy; +{ + /* * print progress bar only if we are foreground process. */ - if (ioctl(STDOUT_FILENO, TIOCGPGRP, &ctty_pgrp) != -1 && - ctty_pgrp == (int)pgrp) + if (foregroundproc()) progressmeter(0); } #endif /* SMALL */ @@ -676,16 +701,16 @@ progressmeter(flag) "%02d:%02d ETA", i / 60, i % 60); } } - (void)write(STDOUT_FILENO, buf, len); + (void)write(fileno(ttyout), buf, len); if (flag == -1) { (void)signal(SIGALRM, updateprogressmeter); alarmtimer(1); /* set alarm timer for 1 Hz */ } else if (flag == 1) { alarmtimer(0); - (void)putchar('\n'); + (void)putc('\n', ttyout); } - fflush(stdout); + fflush(ttyout); #endif /* SMALL */ } @@ -694,8 +719,8 @@ progressmeter(flag) * Requires start to be initialised by progressmeter(-1), * direction to be defined by xfer routines, and filesize and bytes * to be updated by xfer routines - * If siginfo is nonzero, an ETA is displayed, and the output goes to STDERR - * instead of STDOUT. + * If siginfo is nonzero, an ETA is displayed, and the output goes to stderr + * instead of ttyout. */ void ptransfer(siginfo) @@ -762,7 +787,7 @@ ptransfer(siginfo) " (stalled)"); } len += snprintf(buf + len, sizeof(buf) - len, "\n"); - (void)write(siginfo ? STDERR_FILENO : STDOUT_FILENO, buf, len); + (void)write(siginfo ? STDERR_FILENO : fileno(ttyout), buf, len); #endif /* SMALL */ } @@ -794,15 +819,15 @@ list_vertical(sl) for (j = 0; j < columns; j++) { p = sl->sl_str[j * lines + i]; if (p) - fputs(p, stdout); + fputs(p, ttyout); if (j * lines + i + lines >= sl->sl_cur) { - putchar('\n'); + putc('\n', ttyout); break; } w = strlen(p); while (w < width) { w = (w + 8) &~ 7; - (void)putchar('\t'); + (void)putc('\t', ttyout); } } } @@ -817,7 +842,7 @@ setttywidth(a) { struct winsize winsize; - if (ioctl(fileno(stdout), TIOCGWINSZ, &winsize) != -1) + if (ioctl(fileno(ttyout), TIOCGWINSZ, &winsize) != -1) ttywidth = winsize.ws_col; else ttywidth = 80; @@ -848,7 +873,7 @@ controlediting() if (editing && el == NULL && hist == NULL) { HistEvent ev; - el = el_init(__progname, stdin, stdout, stderr); + el = el_init(__progname, stdin, ttyout, stderr); /* init editline */ hist = history_init(); /* init the builtin history */ history(hist, &ev, H_SETSIZE, 100);/* remember 100 events */