📄 ftp.c
字号:
(void) putchar('#'); (void) putchar('\n'); (void) fflush(stdout); } if (ferror(din)) { if (errno != EPIPE) perror("netin"); bytes = -1; } if (ferror(fout)) fprintf(stderr, "local: %s: %s\n", local, strerror(errno)); break; } if (closefunc != NULL) (*closefunc)(fout); (void) signal(SIGINT, oldintr); if (oldintp) (void) signal(SIGPIPE, oldintp); (void) gettimeofday(&stop, (struct timezone *)0); (void) fclose(din); (void) getreply(0); if (bytes > 0 && is_retr) {#ifdef FASCIST syslog(LOG_NOTICE, "Received remote file %s as %s -- %d bytes", remote, local, bytes);#endif ptransfer("received", bytes, &start, &stop); } return;abort:/* abort using RFC959 recommended IP,SYNC sequence */ (void) gettimeofday(&stop, (struct timezone *)0); if (oldintp) (void) signal(SIGPIPE, oldintr); (void) signal(SIGINT, SIG_IGN); if (!cpend) { code = -1; (void) signal(SIGINT, oldintr); return; } abort_remote(din); code = -1; if (data >= 0) { (void) close(data); data = -1; } if (closefunc != NULL && fout != NULL) (*closefunc)(fout); if (din) (void) fclose(din); if (bytes > 0) {#ifdef FASCIST syslog(LOG_NOTICE, "Received remote file %s as %s -- %d bytes", remote, local, bytes);#endif ptransfer("received", bytes, &start, &stop); } (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. */initconn(){ register char *p, *a; int result, len, tmpno = 0; int on = 1;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) sendport = 1; return (1); } if (!sendport) if (setsockopt(data, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof (on)) < 0) { perror("ftp: setsockopt (reuse address)"); goto bad; } if (bind(data, (struct sockaddr *)&data_addr, sizeof(data_addr)) < 0) { perror("ftp: bind"); goto bad; } if (options & SO_DEBUG && setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof (on)) < 0) perror("ftp: setsockopt (ignored)"); len = sizeof (data_addr); if (getsockname(data, (struct sockaddr *)&data_addr, &len) < 0) { perror("ftp: getsockname"); goto bad; } if (listen(data, 1) < 0) perror("ftp: listen"); if (sendport) { a = (char *)&data_addr.sin_addr; p = (char *)&data_addr.sin_port;#define UC(b) (((int)b)&0xff) result = command("PORT %d,%d,%d,%d,%d,%d", UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]), UC(p[0]), UC(p[1])); if (result == ERROR && sendport == -1) { sendport = 0; tmpno = 1; goto noport; } return (result != COMPLETE); } if (tmpno) sendport = 1;#if defined(IP_TOS) && defined(IPTOS_THROUGHPUT) on = IPTOS_THROUGHPUT; if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0) perror("ftp: setsockopt TOS (ignored)");#endif return (0);bad: (void) close(data), data = -1; if (tmpno) sendport = 1; return (1);}FILE *dataconn(lmode) char *lmode;{ struct sockaddr_in from; int s, fromlen = sizeof (from), tos; s = accept(data, (struct sockaddr *) &from, &fromlen); if (s < 0) { perror("ftp: accept"); (void) close(data), data = -1; return (NULL); } (void) close(data); data = s;#if defined(IP_TOS) && defined(IPTOS_THROUGHPUT) tos = IPTOS_THROUGHPUT; if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0) perror("ftp: setsockopt TOS (ignored)");#endif return (fdopen(data, lmode));}ptransfer(direction, bytes, t0, t1) char *direction; long bytes; struct timeval *t0, *t1;{ struct timeval td; float s, bs; if (verbose) { tvsub(&td, t1, t0); s = td.tv_sec + (td.tv_usec / 1000000.);#define nz(x) ((x) == 0 ? 1 : (x)) bs = bytes / nz(s); printf("%ld bytes %s in %.2g seconds (%.2g Kbytes/s)\n", bytes, direction, s, bs / 1024.); }}/*tvadd(tsum, t0) struct timeval *tsum, *t0;{ tsum->tv_sec += t0->tv_sec; tsum->tv_usec += t0->tv_usec; if (tsum->tv_usec > 1000000) tsum->tv_sec++, tsum->tv_usec -= 1000000;} */tvsub(tdiff, t1, t0) struct timeval *tdiff, *t1, *t0;{ tdiff->tv_sec = t1->tv_sec - t0->tv_sec; tdiff->tv_usec = t1->tv_usec - t0->tv_usec; if (tdiff->tv_usec < 0) tdiff->tv_sec--, tdiff->tv_usec += 1000000;}voidpsabort(){ extern int abrtflag; abrtflag++;}pswitch(flag) int flag;{ extern int proxy, abrtflag; sig_t oldintr; static struct comvars { int connect; char name[MAXHOSTNAMELEN]; struct sockaddr_in mctl; struct sockaddr_in hctl; FILE *in; FILE *out; int tpe; int curtpe; int cpnd; int sunqe; int runqe; int mcse; int ntflg; char nti[17]; char nto[17]; int mapflg; char mi[MAXPATHLEN]; char mo[MAXPATHLEN]; } proxstruct, tmpstruct; struct comvars *ip, *op; abrtflag = 0; oldintr = signal(SIGINT, psabort); if (flag) { if (proxy) return; ip = &tmpstruct; op = &proxstruct; proxy++; } else { if (!proxy) return; ip = &proxstruct; op = &tmpstruct; proxy = 0; } ip->connect = connected; connected = op->connect; if (hostname) { (void) strncpy(ip->name, hostname, sizeof(ip->name) - 1); ip->name[strlen(ip->name)] = '\0'; } else ip->name[0] = 0; hostname = op->name; ip->hctl = hisctladdr; hisctladdr = op->hctl; ip->mctl = myctladdr; myctladdr = op->mctl; ip->in = cin; cin = op->in; ip->out = cout; cout = op->out; ip->tpe = type; type = op->tpe; ip->curtpe = curtype; curtype = op->curtpe; ip->cpnd = cpend; cpend = op->cpnd; ip->sunqe = sunique; sunique = op->sunqe; ip->runqe = runique; runique = op->runqe; ip->mcse = mcase; mcase = op->mcse; ip->ntflg = ntflag; ntflag = op->ntflg; (void) strncpy(ip->nti, ntin, 16); (ip->nti)[strlen(ip->nti)] = '\0'; (void) strcpy(ntin, op->nti); (void) strncpy(ip->nto, ntout, 16); (ip->nto)[strlen(ip->nto)] = '\0'; (void) strcpy(ntout, op->nto); ip->mapflg = mapflag; mapflag = op->mapflg; (void) strncpy(ip->mi, mapin, MAXPATHLEN - 1); (ip->mi)[strlen(ip->mi)] = '\0'; (void) strcpy(mapin, op->mi); (void) strncpy(ip->mo, mapout, MAXPATHLEN - 1); (ip->mo)[strlen(ip->mo)] = '\0'; (void) strcpy(mapout, op->mo); (void) signal(SIGINT, oldintr); if (abrtflag) { abrtflag = 0; (*oldintr)(SIGINT); }}jmp_buf ptabort;int ptabflg;voidabortpt(){ printf("\n"); (void) fflush(stdout); ptabflg++; mflag = 0; abrtflag = 0; longjmp(ptabort, 1);}proxtrans(cmd, local, remote) char *cmd, *local, *remote;{ sig_t oldintr; int secndflag = 0, prox_type, nfnd; extern jmp_buf ptabort; char *cmd2; struct fd_set mask; void abortpt(); if (strcmp(cmd, "RETR")) cmd2 = "RETR"; else cmd2 = runique ? "STOU" : "STOR"; if ((prox_type = type) == 0) { if (unix_server && unix_proxy) prox_type = TYPE_I; else prox_type = TYPE_A; } if (curtype != prox_type) changetype(prox_type, 1); if (command("PASV") != COMPLETE) { printf("proxy server does not support third party transfers.\n"); return; } pswitch(0); if (!connected) { printf("No primary connection\n"); pswitch(1); code = -1; return; } if (curtype != prox_type) changetype(prox_type, 1); if (command("PORT %s", pasv) != COMPLETE) { pswitch(1); return; } if (setjmp(ptabort)) goto abort; oldintr = signal(SIGINT, abortpt); if (command("%s %s", cmd, remote) != PRELIM) { (void) signal(SIGINT, oldintr); pswitch(1); return; } sleep(2); pswitch(1); secndflag++; if (command("%s %s", cmd2, local) != PRELIM) goto abort; ptflag++; (void) getreply(0); pswitch(0); (void) getreply(0); (void) signal(SIGINT, oldintr); pswitch(1); ptflag = 0; printf("local: %s remote: %s\n", local, remote); return;abort: (void) signal(SIGINT, SIG_IGN); ptflag = 0; if (strcmp(cmd, "RETR") && !proxy) pswitch(1); else if (!strcmp(cmd, "RETR") && proxy) pswitch(0); if (!cpend && !secndflag) { /* only here if cmd = "STOR" (proxy=1) */ if (command("%s %s", cmd2, local) != PRELIM) { pswitch(0); if (cpend) abort_remote((FILE *) NULL); } pswitch(1); if (ptabflg) code = -1; (void) signal(SIGINT, oldintr); return; } if (cpend) abort_remote((FILE *) NULL); pswitch(!proxy); if (!cpend && !secndflag) { /* only if cmd = "RETR" (proxy=1) */ if (command("%s %s", cmd2, local) != PRELIM) { pswitch(0); if (cpend) abort_remote((FILE *) NULL); pswitch(1); if (ptabflg) code = -1; (void) signal(SIGINT, oldintr); return; } } if (cpend) abort_remote((FILE *) NULL); pswitch(!proxy); if (cpend) { FD_ZERO(&mask); FD_SET(fileno(cin), &mask); if ((nfnd = empty(&mask, 10)) <= 0) { if (nfnd < 0) { perror("abort"); } if (ptabflg) code = -1; lostpeer(); } (void) getreply(0); (void) getreply(0); } if (proxy) pswitch(0); pswitch(1); if (ptabflg) code = -1; (void) signal(SIGINT, oldintr);}reset(){ struct fd_set mask; int nfnd = 1; FD_ZERO(&mask); while (nfnd > 0) { FD_SET(fileno(cin), &mask); if ((nfnd = empty(&mask,0)) < 0) { perror("reset"); code = -1; lostpeer(); } else if (nfnd) { (void) getreply(0); } }}char *gunique(local) char *local;{ static char new[MAXPATHLEN]; char *cp = rindex(local, '/'); int d, count=0; char ext = '1'; if (cp) *cp = '\0'; d = access(cp ? local : ".", 2); if (cp) *cp = '/'; if (d < 0) { fprintf(stderr, "local: %s: %s\n", local, strerror(errno)); return((char *) 0); } (void) strcpy(new, local); cp = new + strlen(new); *cp++ = '.'; while (!d) { if (++count == 100) { printf("runique: can't find unique file name.\n"); return((char *) 0); } *cp++ = ext; *cp = '\0'; if (ext == '9') ext = '0'; else ext++; if ((d = access(new, 0)) < 0) break; if (ext != '0') cp--; else if (*(cp - 2) == '.') *(cp - 1) = '1'; else { *(cp - 2) = *(cp - 2) + 1; cp--; } } return(new);}abort_remote(din)FILE *din;{ char buf[BUFSIZ]; int nfnd; struct fd_set mask; /* * send IAC in urgent mode instead of DM because 4.3BSD places oob mark * after urgent byte rather than before as is protocol now */ sprintf(buf, "%c%c%c", IAC, IP, IAC); if (send(fileno(cout), buf, 3, MSG_OOB) != 3) perror("abort"); fprintf(cout,"%cABOR\r\n", DM); (void) fflush(cout); FD_ZERO(&mask); FD_SET(fileno(cin), &mask); if (din) { FD_SET(fileno(din), &mask); } if ((nfnd = empty(&mask, 10)) <= 0) { if (nfnd < 0) { perror("abort"); } if (ptabflg) code = -1; lostpeer(); } if (din && FD_ISSET(fileno(din), &mask)) { while (read(fileno(din), buf, BUFSIZ) > 0) /* LOOP */; } if (getreply(0) == ERROR && code == 552) { /* 552 needed for nic style abort */ (void) getreply(0); } (void) getreply(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -