📄 ftp.c
字号:
if (hash && bytes > 0) {
if (bytes < HASHBYTES)
(void) putchar('#');
(void) putchar('\n');
(void) fflush(stdout);
}
if (c < 0)
perror(local);
if (d <= 0) {
if (d == 0)
fprintf(stderr, "netout: write returned 0?\n");
else if (errno != EPIPE)
perror("netout");
bytes = -1;
}
break;
case TYPE_A:
{
char buf[1024];
static int bufsize = 1024;
int ipos=0;
while ((c = getc(fin)) != EOF) {
if (c == '\n') {
while (hash && (bytes >= hashbytes)) {
(void) putchar('#');
(void) fflush(stdout);
hashbytes += HASHBYTES;
}
// Szurgot: The following code is unncessary on Win32.
// (void) fputcSocket(dout, '\r');
// bytes++;
}
if (ipos >= bufsize) {
fputSocket(dout,buf,ipos);
if(!hash) (void) putchar('.');
ipos=0;
}
buf[ipos]=c; ++ipos;
bytes++;
}
if (ipos) {
fputSocket(dout,buf,ipos);
ipos=0;
}
if (hash) {
if (bytes < hashbytes)
(void) putchar('#');
(void) putchar('\n');
(void) fflush(stdout);
}
else {
(void) putchar('.');
(void) putchar('\n');
(void) fflush(stdout);
}
if (ferror(fin))
perror(local);
// if (ferror(dout)) {
// if (errno != EPIPE)
// perror("netout");
// bytes = -1;
// }
break;
}
}
(void) gettimeofday(&stop, (struct timezone *)0);
if (closefunc != NULL)
(*closefunc)(fin);
if(closesocket(dout)) {
int iret=WSAGetLastError ();
fprintf(stdout,"Error closing socket(%d)\n",iret);
(void) fflush(stdout);
}
(void) getreply(0);
null();// (void) signal(SIGINT, oldintr);
if (oldintp)
null();// (void) signal(SIGPIPE, oldintp);
if (bytes > 0)
ptransfer("sent", bytes, &start, &stop);
return;
abort:
(void) gettimeofday(&stop, (struct timezone *)0);
null();// (void) signal(SIGINT, oldintr);
if (oldintp)
null();// (void) signal(SIGPIPE, oldintp);
if (!cpend) {
code = -1;
return;
}
if (data >= 0) {
(void) close(data);
data = -1;
}
if (dout)
if(closesocket(dout)) {
int iret=WSAGetLastError ();
fprintf(stdout,"Error closing socket(%d)\n",iret);
(void) fflush(stdout);
}
(void) getreply(0);
code = -1;
if (closefunc != NULL && fin != NULL)
(*closefunc)(fin);
if (bytes > 0)
ptransfer("sent", bytes, &start, &stop);
}
jmp_buf recvabort;
#if 0
void abortrecv()
{
mflag = 0;
abrtflag = 0;
printf("\n");
(void) fflush(stdout);
longjmp(recvabort, 1);
}
#endif
void recvrequest(const char *cmd, const char *local, const char *remote, const char *mode,
int printnames)
{
FILE *fout = stdout;
int din = 0;
int (*closefunc)(), _pclose(), fclose();
void (*oldintr)(int), (*oldintp)(int);
int oldverbose = 0, oldtype = 0, is_retr, tcrflag, nfnd, bare_lfs = 0;
char msg;
// static char *buf; // Szurgot: Shouldn't this go SOMEWHERE?
char buf[1024];
static int bufsize = 1024;
long bytes = 0, hashbytes = HASHBYTES;
// struct
fd_set mask;
register int c, d;
struct timeval start, stop;
// struct stat st;
extern void *malloc();
is_retr = strcmp(cmd, "RETR") == 0;
if (is_retr && verbose && printnames) {
if (local && *local != '-')
printf("local: %s ", local);
if (remote)
printf("remote: %s\n", remote);
(void) fflush(stdout);
}
if (proxy && is_retr) {
proxtrans(cmd, local, remote);
return;
}
closefunc = NULL;
oldintr = NULL;
oldintp = NULL;
tcrflag = !crflag && is_retr;
if (setjmp(recvabort)) {
while (cpend) {
(void) getreply(0);
}
if (data >= 0) {
(void) close(data);
data = -1;
}
if (oldintr)
null();// (void) signal(SIGINT, oldintr);
code = -1;
return;
}
null();// oldintr = signal(SIGINT, abortrecv);
if (strcmp(local, "-") && *local != '|') {
#ifndef _WIN32
// This whole thing is a problem... access Won't work on non-existent files
if (access(local, 2) < 0) {
char *dir = rindex(local, '/');
if (errno != ENOENT && errno != EACCES) {
perror(local);
(void) signal(SIGINT, oldintr);
code = -1;
return;
}
if (dir != NULL)
*dir = 0;
d = access(dir ? local : ".", 2);
if (dir != NULL)
*dir = '/';
if (d < 0) {
perror(local);
(void) signal(SIGINT, oldintr);
code = -1;
return;
}
if (!runique && errno == EACCES &&
chmod(local, 0600) < 0) {
perror(local);
(void) signal(SIGINT, oldintr);
code = -1;
return;
}
if (runique && errno == EACCES &&
(local = gunique(local)) == NULL) {
(void) signal(SIGINT, oldintr);
code = -1;
return;
}
}
else if (runique && (local = gunique(local)) == NULL) {
(void) signal(SIGINT, oldintr);
code = -1;
return;
}
#endif
}
if (initconn()) {
null();// (void) signal(SIGINT, oldintr);
code = -1;
return;
}
if (setjmp(recvabort))
goto abort;
if (!is_retr) {
if (type != TYPE_A && (allbinary == 0 || type != TYPE_I)) {
oldtype = type;
oldverbose = verbose;
if (!debug)
verbose = 0;
setascii();
verbose = oldverbose;
}
} else if (restart_point) {
if (command("REST %ld", (long) restart_point) != CONTINUE)
return;
}
if (remote) {
if (command("%s %s", cmd, remote) != PRELIM) {
null();// (void) signal(SIGINT, oldintr);
if (oldtype) {
if (!debug)
verbose = 0;
switch (oldtype) {
case TYPE_I:
setbinary();
break;
case TYPE_E:
setebcdic();
break;
case TYPE_L:
settenex();
break;
}
verbose = oldverbose;
}
return;
}
} else {
if (command("%s", cmd) != PRELIM) {
null();// (void) signal(SIGINT, oldintr);
if (oldtype) {
if (!debug)
verbose = 0;
switch (oldtype) {
case TYPE_I:
setbinary();
break;
case TYPE_E:
setebcdic();
break;
case TYPE_L:
settenex();
break;
}
verbose = oldverbose;
}
return;
}
}
din = dataconn("r");
if (din == (int)NULL)
goto abort;
if (strcmp(local, "-") == 0)
fout = stdout;
else if (*local == '|') {
null();// oldintp = signal(SIGPIPE, SIG_IGN);
fout = _popen(local + 1, "w");
if (fout == NULL) {
perror(local+1);
goto abort;
}
closefunc = _pclose;
} else {
fout = fopen(local, mode);
if (fout == NULL) {
perror(local);
goto abort;
}
closefunc = fclose;
}
(void) gettimeofday(&start, (struct timezone *)0);
switch (type) {
case TYPE_I:
case TYPE_L:
if (restart_point &&
lseek(fileno(fout), (long) restart_point, L_SET) < 0) {
perror(local);
if (closefunc != NULL)
(*closefunc)(fout);
return;
}
errno = d = 0;
// while ((c = recv(din, buf, bufsize, 1)) > 0) {
// if ((d = write(fileno(fout), buf, c)) != c)
// if ((d = write(fileno(fout), buf, c)) != c)
// break;
while ((c = recv(din, buf, bufsize, 0)) > 0) {
write(fileno(fout), buf, c);
bytes += c;
if (hash) {
while (bytes >= hashbytes) {
(void) putchar('#');
hashbytes += HASHBYTES;
}
(void) fflush(stdout);
}
}
if (hash && bytes > 0) {
if (bytes < HASHBYTES)
(void) putchar('#');
(void) putchar('\n');
(void) fflush(stdout);
}
// if (c < 0) {
// if (errno != EPIPE)
// perror("netin");
// bytes = -1;
// }
// if (d < c) {
// if (d < 0)
// perror(local);
// else
// fprintf(stderr, "%s: short write\n", local);
// }
break;
case TYPE_A:
if (restart_point) {
register int i, n, c;
if (fseek(fout, 0L, L_SET) < 0)
goto done;
n = restart_point;
i = 0;
while (i++ < n) {
if ((c=getc(fout)) == EOF)
goto done;
if (c == '\n')
i++;
}
if (fseek(fout, 0L, L_INCR) < 0) {
done:
perror(local);
if (closefunc != NULL)
(*closefunc)(fout);
return;
}
}
while ((c = fgetcSocket(din)) != EOF) {
if (c == '\n')
bare_lfs++;
while (c == '\r') {
while (hash && (bytes >= hashbytes)) {
(void) putchar('#');
(void) fflush(stdout);
hashbytes += HASHBYTES;
}
bytes++;
if ((c = fgetcSocket(din)) != '\n' || tcrflag) {
if (ferror(fout))
goto break2;
(void) putc('\r', fout);
if (c == '\0') {
bytes++;
goto contin2;
}
if (c == EOF)
goto contin2;
}
}
(void) putc(c, fout);
bytes++;
contin2: ;
}
break2:
if (bare_lfs) {
printf("WARNING! %d bare linefeeds received in ASCII mode\n", bare_lfs);
printf("File may not have transferred correctly.\n");
(void) fflush(stdout);
}
if (hash) {
if (bytes < hashbytes)
(void) putchar('#');
(void) putchar('\n');
(void) fflush(stdout);
}
// if (ferror(din)) {
// if (errno != EPIPE)
// perror("netin");
// bytes = -1;
// }
if (ferror(fout))
perror(local);
break;
}
if (closefunc != NULL)
(*closefunc)(fout);
null();// (void) signal(SIGINT, oldintr);
if (oldintp)
null();// (void) signal(SIGPIPE, oldintp);
(void) gettimeofday(&stop, (struct timezone *)0);
if(closesocket(din)) {
int iret=WSAGetLastError ();
fprintf(stdout,"Error closing socket(%d)\n",iret);
(void) fflush(stdout);
}
(void) getreply(0);
if (bytes > 0 && is_retr)
ptransfer("received", bytes, &start, &stop);
if (oldtype) {
if (!debug)
verbose = 0;
switch (oldtype) {
case TYPE_I:
setbinary();
break;
case TYPE_E:
setebcdic();
break;
case TYPE_L:
settenex();
break;
}
verbose = oldverbose;
}
return;
abort:
/* abort using RFC959 recommended IP,SYNC sequence */
(void) gettimeofday(&stop, (struct timezone *)0);
if (oldintp)
null();// (void) signal(SIGPIPE, oldintr);
null();// (void) signal(SIGINT,SIG_IGN);
if (oldtype) {
if (!debug)
verbose = 0;
switch (oldtype) {
case TYPE_I:
setbinary();
break;
case TYPE_E:
setebcdic();
break;
case TYPE_L:
settenex();
break;
}
verbose = oldverbose;
}
if (!cpend) {
code = -1;
null();// (void) signal(SIGINT,oldintr);
return;
}
fprintfSocket(cout,"%c%c",IAC,IP);
msg = (char)IAC;
/* send IAC in urgent mode instead of DM because UNIX places oob mark */
/* after urgent byte rather than before as now is protocol */
if (send(cout,&msg,1,MSG_OOB) != 1) {
perror("abort");
}
fprintfSocket(cout,"%cABOR\r\n",DM);
FD_ZERO(&mask);
FD_SET(cin, &mask); // Need to correct this
if (din) {
FD_SET(din, &mask); // Need to correct this
}
if ((nfnd = empty(&mask,10)) <= 0) {
if (nfnd < 0) {
perror("abort");
}
code = -1;
lostpeer();
}
if (din && FD_ISSET(din, &mask)) {
while ((c = recv(din, buf, bufsize, 0)) > 0)
;
}
if ((c = getreply(0)) == ERROR && code == 552) { /* needed for nic style abort */
if (data >= 0) {
(void) close(data);
data = -1;
}
(void) getreply(0);
}
(void) getreply(0);
code = -1;
if (data >= 0) {
(void) close(data);
data = -1;
}
if (closefunc != NULL && fout != NULL)
(*closefunc)(fout);
if (din)
if(closesocket(din)) {
int iret=WSAGetLastError ();
fprintf(stdout,"Error closing socket(%d)\n",iret);
(void) fflush(stdout);
}
if (bytes > 0)
ptransfer("received", bytes, &start, &stop);
null();// (void) signal(SIGINT,oldintr);
}
/*
* Need to start a listen on the data channel
* before we send the command, otherwise the
* server's connect may fail.
*/
int sendport = -1;
int
initconn()
{
register char *p, *a;
int result, len, tmpno = 0;
int on = 1;
int a0, a1, a2, a3, p0, p1;
if (passivemode) {
data = socket(AF_INET, SOCK_STREAM, 0);
if (data < 0) {
perror("ftp: socket");
return(1);
}
if ((options & SO_DEBUG) &&
setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on,
sizeof (on)) < 0)
perror("ftp: setsockopt (ignored)");
if (command("PASV") != COMPLETE) {
printf("Passive mode refused.\n");
goto bad;
}
/*
* What we've got at this point is a string of comma
* separated one-byte unsigned integer values.
* The first four are the an IP address. The fifth is
* the MSB of the port number, the sixth is the LSB.
* From that we'll prepare a sockaddr_in.
*/
if (sscanf(pasv,"%d,%d,%d,%d,%d,%d",
&a0, &a1, &a2, &a3, &p0, &p1) != 6) {
printf("Passive mode address scan failure. Shouldn't happen!\n");
goto bad;
}
bzero(&data_addr, sizeof(data_addr));
data_addr.sin_family = AF_INET;
a = (char *)&data_addr.sin_addr.s_addr;
a[0] = a0 & 0xff;
a[1] = a1 & 0xff;
a[2] = a2 & 0xff;
a[3] = a3 & 0xff;
p = (char *)&data_addr.sin_port;
p[0] = p0 & 0xff;
p[1] = p1 & 0xff;
if (connect(data, (struct sockaddr *)&data_addr,
sizeof(data_addr)) < 0) {
perror("ftp: connect");
goto bad;
}
return(0);
}
noport:
data_addr = myctladdr;
if (sendport)
data_addr.sin_port = 0; /* let system pick one */
if (data != -1)
(void) close (data);
data = socket(AF_INET, SOCK_STREAM, 0);
if (data < 0) {
perror("ftp: socket");
if (tmpno)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -