?? ftp.c
字號:
/* * Copyright (c) 1985, 1989, 1993, 1994 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char sccsid[] = "@(#)ftp.c 8.6 (Berkeley) 10/27/94";#endif /* not lint */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <sys/param.h>#include <sys/stat.h>#include <sys/ioctl.h>#include <sys/socket.h>#ifdef TIME_WITH_SYS_TIME# include <sys/time.h># include <time.h>#else# ifdef HAVE_SYS_TIME_H# include <sys/time.h># else# include <time.h># endif#endif#include <sys/file.h>#include <netinet/in.h>#ifdef HAVE_NETINET_IN_SYSTM_H#include <netinet/in_systm.h>#endif#ifdef HAVE_NETINET_IP_H#include <netinet/ip.h>#endif#include <arpa/inet.h>#include <arpa/ftp.h>#include <arpa/telnet.h>#include <ctype.h>#include <error.h>#include <errno.h>#include <fcntl.h>#include <netdb.h>#include <pwd.h>#include <signal.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__#include <stdarg.h>#else#include <varargs.h>#endif#ifdef HAVE_SYS_SELECT_H#include <sys/select.h>#endif#include "ftp_var.h"#if !HAVE_DECL_FCLOSE/* Some systems don't declare fclose in <stdio.h>, so do it ourselves. */extern int fclose (FILE *);#endif#if !HAVE_DECL_PCLOSE/* Some systems don't declare pclose in <stdio.h>, so do it ourselves. */extern int pclose (FILE *);#endifextern int h_errno;struct sockaddr_in hisctladdr;struct sockaddr_in data_addr;int data = -1;int abrtflag = 0;jmp_buf ptabort;int ptabflg;int ptflag = 0;struct sockaddr_in myctladdr;off_t restart_point = 0;FILE *cin, *cout;char *hookup(host, port) char *host; int port;{ struct hostent *hp = 0; int s, len, tos; static char hostnamebuf[80]; memset((char *)&hisctladdr, 0, sizeof (hisctladdr)); hisctladdr.sin_addr.s_addr = inet_addr(host); if (hisctladdr.sin_addr.s_addr != -1) { hisctladdr.sin_family = AF_INET; strncpy(hostnamebuf, host, sizeof(hostnamebuf)); } else { hp = gethostbyname(host); if (hp == NULL) {#ifdef HAVE_HSTRERROR error (0, 0, "%s: %s", host, hstrerror(h_errno));#else extern char *program_name; char *pfx = malloc (strlen (program_name) + 2 + strlen (host) + 1); sprintf (pfx, "%s: %s", program_name, host); herror (pfx);#endif code = -1; return ((char *) 0); } hisctladdr.sin_family = hp->h_addrtype; memmove((caddr_t)&hisctladdr.sin_addr,#ifdef HAVE_STRUCT_HOSTENT_H_ADDR_LIST hp->h_addr_list[0],#else hp->h_addr,#endif hp->h_length); strncpy(hostnamebuf, hp->h_name, sizeof(hostnamebuf)); } hostname = hostnamebuf; s = socket(hisctladdr.sin_family, SOCK_STREAM, 0); if (s < 0) { error (0, errno, "socket"); code = -1; return (0); } hisctladdr.sin_port = port; while (connect(s, (struct sockaddr *)&hisctladdr, sizeof (hisctladdr)) < 0) {#ifdef HAVE_STRUCT_HOSTENT_H_ADDR_LIST if (hp && hp->h_addr_list[1]) { int oerrno = errno; char *ia; ia = inet_ntoa(hisctladdr.sin_addr); error (0, oerrno, "connect to address %s", ia); hp->h_addr_list++; memmove((caddr_t)&hisctladdr.sin_addr, hp->h_addr_list[0], hp->h_length); fprintf(stdout, "Trying %s...\n", inet_ntoa(hisctladdr.sin_addr)); close(s); s = socket(hisctladdr.sin_family, SOCK_STREAM, 0); if (s < 0) { error (0, errno, "socket"); code = -1; return (0); } continue; }#endif error (0, errno, "connect"); code = -1; goto bad; } len = sizeof (myctladdr); if (getsockname(s, (struct sockaddr *)&myctladdr, &len) < 0) { error (0, errno, "getsockname"); code = -1; goto bad; }#if defined (IP_TOS) && defined (IPPROTO_IP) && defined (IPTOS_LOWDELAY) tos = IPTOS_LOWDELAY; if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0) error (0, errno, "setsockopt TOS (ignored)");#endif cin = fdopen(s, "r"); /* dup(s) is for sake of stdio implementations who do not allow two fdopen's on the same file-descriptor */ cout = fdopen(dup(s), "w"); if (cin == NULL || cout == NULL) { error (0, 0, "fdopen failed."); if (cin) fclose(cin); if (cout) fclose(cout); code = -1; goto bad; } if (verbose) printf("Connected to %s.\n", hostname); if (getreply(0) > 2) { /* read startup message from server */ if (cin) fclose(cin); if (cout) fclose(cout); code = -1; goto bad; }#ifdef SO_OOBINLINE { int on = 1; if (setsockopt(s, SOL_SOCKET, SO_OOBINLINE, (char *)&on, sizeof(on)) < 0 && debug) { error (0, errno, "setsockopt"); } }#endif /* SO_OOBINLINE */ return (hostname);bad: close(s); return NULL;}intlogin(host) char *host;{ char tmp[80]; char *user, *pass, *acct; int n, aflag = 0; user = pass = acct = 0; if (ruserpass(host, &user, &pass, &acct) < 0) { code = -1; return (0); } while (user == NULL) { char *myname = getlogin(); if (myname == NULL) { struct passwd *pp = getpwuid(getuid()); if (pp != NULL) myname = pp->pw_name; } if (myname) printf("Name (%s:%s): ", host, myname); else printf("Name (%s): ", host); if (fgets(tmp, sizeof(tmp) - 1, stdin)) { /* If they press Ctrl-d immediately, it's empty. */ tmp[strlen(tmp) - 1] = '\0'; } else *tmp = '\0'; if (*tmp == '\0') user = myname; else user = tmp; } n = command("USER %s", user); if (n == CONTINUE) { if (pass == NULL) pass = getpass("Password:"); n = command("PASS %s", pass); } if (n == CONTINUE) { aflag++; acct = getpass("Account:"); n = command("ACCT %s", acct); } if (n != COMPLETE) { error (0, 0, "Login failed."); return (0); } if (!aflag && acct != NULL) command("ACCT %s", acct); if (proxy) return (1); for (n = 0; n < macnum; ++n) { if (!strcmp("init", macros[n].mac_name)) {#if HAVE_LIBREADLINE if (line) free (line); line = calloc (200, sizeof (*line)); if (!line) quit (0, 0);#endif strcpy(line, "$init"); makeargv(); domacro(margc, margv); break; } } return (1);}RETSIGTYPEcmdabort(int sig ARG_UNUSED){ printf("\n"); fflush(stdout); abrtflag++; if (ptflag) longjmp(ptabort,1);}/*VARARGS*/int#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__command (const char *fmt, ...)#elsecommand(va_alist)va_dcl#endif{ va_list ap;#if !(defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__) const char *fmt;#endif int r; sig_t oldintr; abrtflag = 0; if (debug) { printf("---> ");#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__ va_start (ap, fmt);#else va_start(ap); fmt = va_arg(ap, char *);#endif if (strncmp("PASS ", fmt, 5) == 0) printf("PASS XXXX"); else vfprintf(stdout, fmt, ap); va_end(ap); printf("\n"); fflush(stdout); } if (cout == NULL) { error (0, 0, "No control connection for command"); code = -1; return (0); } oldintr = signal(SIGINT, cmdabort);#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__ va_start (ap, fmt);#else va_start(ap); fmt = va_arg(ap, char *);#endif vfprintf(cout, fmt, ap); va_end(ap); fprintf(cout, "\r\n"); fflush(cout); cpend = 1; r = getreply(!strcmp(fmt, "QUIT")); if (abrtflag && oldintr != SIG_IGN) (*oldintr)(SIGINT); signal(SIGINT, oldintr); return (r);}char reply_string[BUFSIZ]; /* last line of previous reply */intgetreply(expecteof) int expecteof;{ int c, n; int dig; int originalcode = 0, continuation = 0; sig_t oldintr; int pflag = 0; char *cp, *pt = pasv; oldintr = signal(SIGINT, cmdabort); for (;;) { dig = n = code = 0; cp = reply_string; while ((c = getc(cin)) != '\n') { if (c == IAC) { /* handle telnet commands */ switch (c = getc(cin)) { case WILL: case WONT: c = getc(cin); fprintf(cout, "%c%c%c", IAC, DONT, c); fflush(cout); break; case DO: case DONT: c = getc(cin); fprintf(cout, "%c%c%c", IAC, WONT, c); fflush(cout); break; default: break; } continue; } dig++; if (c == EOF) { if (expecteof) { signal(SIGINT,oldintr); code = 221; return (0); } lostpeer(); if (verbose) { printf("421 Service not available, remote server has closed connection\n"); fflush(stdout); } code = 421; return (4); } if (c != '\r' && (verbose > 0 || (verbose > -1 && n == '5' && dig > 4))) { if (proxflag && (dig == 1 || dig == 5 && verbose == 0)) printf("%s:",hostname); putchar(c); } if (dig < 4 && isdigit(c)) code = code * 10 + (c - '0'); if (!pflag && code == 227) pflag = 1; if (dig > 4 && pflag == 1 && isdigit(c)) pflag = 2; if (pflag == 2) { if (c != '\r' && c != ')') *pt++ = c; else { *pt = '\0'; pflag = 3; } } if (dig == 4 && c == '-') { if (continuation) code = 0; continuation++; } if (n == 0) n = c; if (cp < &reply_string[sizeof(reply_string) - 1]) *cp++ = c; } if (verbose > 0 || verbose > -1 && n == '5') { putchar(c); fflush (stdout); } if (continuation && code != originalcode) { if (originalcode == 0) originalcode = code; continue; } *cp = '\0'; if (n != '1') cpend = 0; signal(SIGINT,oldintr); if (code == 421 || originalcode == 421) lostpeer(); if (abrtflag && oldintr != cmdabort && oldintr != SIG_IGN) (*oldintr)(SIGINT); return (n - '0'); }}intempty(mask, sec) fd_set *mask; int sec;{ struct timeval t; t.tv_sec = (long) sec; t.tv_usec = 0; return (select(32, mask, (fd_set *) 0, (fd_set *) 0, &t));}jmp_buf sendabort;voidabortsend(sig) int sig;{ mflag = 0; abrtflag = 0; printf("\nsend aborted\nwaiting for remote to finish abort\n"); fflush(stdout); longjmp(sendabort, 1);}voidsendrequest(cmd, local, remote, printnames) char *cmd, *local, *remote; int printnames;{ struct stat st; struct timeval start, stop; int c, d; FILE *fin, *dout = 0, *popen(); int (*closefunc) (FILE *); sig_t oldintr, oldintp; long bytes = 0, local_hashbytes=hashbytes; char *lmode, buf[BUFSIZ], *bufp; if (verbose && printnames) { if (local && *local != '-') printf("local: %s ", local); if (remote) printf("remote: %s\n", remote);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -