/** * list files in dirname. * When verbose == 1, means "ls -l". * When verbose == 0, means "ls" * * @param dirname Directory or filename to list * @param verbose 1: LIST * 0: NLIST */ void cmd_list(const char *dirname, int verbose) { FILE *datastream = NULL; int recursive = 0; int error; if (dirname[0] != '\0') { /* skip arguments */ if (dirname[0] == '-') { while ((dirname[0] != ' ') && (dirname[0] != '\0')) { // For ffftp. It send "nlist -l" to do file list. if ( (verbose == 0) && (dirname[0] == 'l') ) { verbose = 1; } // This is for ffftp, too. When it delete files, it use // nlist -alLR to recursive enlist all files recursive. // and then delete them. if ( (recursive == 0) && (dirname[0] == 'R')) { recursive = 1; } dirname++; } if (dirname[0] != '\0') dirname++; } } datastream = dataconn("file list", -1, "w"); if (datastream == NULL) { reply(550, "Data connection: %s", strerror(errno)); dataconnclose(datastream); return; } STARTXFER; if (dirname[0] == '\0') { error = smbftpd_dir_list(".", datastream, verbose, recursive); } else { error = smbftpd_dir_list(dirname, datastream, verbose, recursive); } ENDXFER; if (error == 0) { reply_noformat(226, "Transfer complete."); } dataconnclose(datastream); }
void recvrequest(const char *cmd, char *volatile local, char *remote, const char *lmode, int printnames) { FILE *volatile fout, *volatile din = 0; int (*volatile closefunc)(FILE *); void (*volatile oldintp)(int); void (*volatile oldintr)(int); volatile int is_retr, tcrflag, bare_lfs = 0; static unsigned bufsize; static char *buf; volatile long bytes = 0, hashbytes = HASHBYTES; register int c, d; struct timeval start, stop; struct stat st; #if 0 printf("%s(%d): recvrequest(cmd=%s,local=%s,remote=%s)\n", __FILE__, __LINE__, cmd, local, remote); #endif is_retr = strcmp(cmd, "RETR") == 0; if (is_retr && ftpverbose && printnames) { if (local && *local != '-') printf("local: %s ", local); if (remote) printf("remote: %s\n", remote); } #if 0 if (proxy && is_retr) { proxtrans(cmd, local, remote); return; } #endif closefunc = NULL; oldintr = NULL; oldintp = NULL; tcrflag = !crflag && is_retr; if (sigsetjmp(recvabort, 1)) { while (cpend) { (void) getreply(0); } if (data >= 0) { (void) close(data); data = -1; } if (oldintr) (void) signal(SIGINT, oldintr); code = -1; return; } oldintr = signal(SIGINT, abortrecv); #if 0 if (strcmp(local, "-") && *local != '|') { if (access(local, W_OK) < 0) { char *dir = rindex(local, '/'); if (errno != ENOENT && errno != EACCES) { fprintf(stderr, "local: %s: %s\n", local, strerror(errno)); (void) signal(SIGINT, oldintr); code = -1; return; } if (dir != NULL) *dir = 0; d = access(dir ? local : ".", W_OK); if (dir != NULL) *dir = '/'; if (d < 0) { fprintf(stderr, "local: %s: %s\n", local, strerror(errno)); (void) signal(SIGINT, oldintr); code = -1; return; } if (!runique && errno == EACCES && chmod(local, 0600) < 0) { fprintf(stderr, "local: %s: %s\n", local, strerror(errno)); /* * Believe it or not, this was actually * repeated in the original source. */ (void) signal(SIGINT, oldintr); /*(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 (!is_retr) { if (curtype != TYPE_A) changetype(TYPE_A, 0); } else if (curtype != type) { changetype(type, 0); } if (initconn()) { (void) signal(SIGINT, oldintr); code = -1; return; } if (sigsetjmp(recvabort, 1)) goto abort; if (is_retr && restart_point && command("REST %ld", (long) restart_point) != CONTINUE) return; if (remote) { if (command("%s %s", cmd, remote) != PRELIM) { (void) signal(SIGINT, oldintr); return; } } else { if (command("%s", cmd) != PRELIM) { (void) signal(SIGINT, oldintr); return; } } din = dataconn("r"); if (din == NULL) goto abort; if (strcmp(local, "-") == 0) fout = stdout; else if (*local == '|') { oldintp = signal(SIGPIPE, SIG_IGN); fout = popen(local + 1, "w"); if (fout == NULL) { perror(local+1); goto abort; } closefunc = pclose; } else { extern int local_fclose(); fout = local_fopen(local, lmode); if (fout == NULL) { fprintf(stderr, "local: %s: %s\n", local, strerror(errno)); goto abort; } closefunc = local_fclose; } if (fstat(fileno(fout), &st) < 0 || st.st_blksize == 0) st.st_blksize = BUFSIZ; if (st.st_blksize > bufsize) { if (buf) (void) free(buf); buf = malloc((unsigned)st.st_blksize); if (buf == NULL) { perror("malloc"); bufsize = 0; goto abort; } bufsize = st.st_blksize; } (void) gettimeofday(&start, (struct timezone *)0); switch (curtype) { case TYPE_I: case TYPE_L: if (restart_point && lseek(fileno(fout), (long) restart_point, L_SET) < 0) { fprintf(stderr, "local: %s: %s\n", local, strerror(errno)); if (closefunc != NULL) (*closefunc)(fout); return; } errno = d = 0; while ((c = read(fileno(din), buf, bufsize)) > 0) { if ((d = local_write(fileno(fout), buf, c)) != c) break; bytes += c; if (hash && is_retr) { while (bytes >= hashbytes) { (void) putchar('#'); hashbytes += HASHBYTES; } (void) fflush(stdout); } if (tick && (bytes >= hashbytes) && is_retr) { (void) printf("\rBytes transferred: %ld", bytes); (void) fflush(stdout); while (bytes >= hashbytes) hashbytes += TICKBYTES; } } if (hash && bytes > 0) { if (bytes < HASHBYTES) (void) putchar('#'); (void) putchar('\n'); (void) fflush(stdout); } if (tick && is_retr) { (void) printf("\rBytes transferred: %ld\n", bytes); (void) fflush(stdout); } if (c < 0) { if (errno != EPIPE) perror("netin"); bytes = -1; } if (d < c) { if (d < 0) fprintf(stderr, "local: %s: %s\n", local, strerror(errno)); else fprintf(stderr, "%s: short write\n", local); } break; case TYPE_A: #if 0 /* ascii mode not supported for netflash */ if (restart_point) { register int i, n, ch; if (fseek(fout, 0L, L_SET) < 0) goto done; n = restart_point; for (i = 0; i++ < n;) { if ((ch = getc(fout)) == EOF) goto done; if (ch == '\n') i++; } if (fseek(fout, 0L, L_INCR) < 0) { done: fprintf(stderr, "local: %s: %s\n", local, strerror(errno)); if (closefunc != NULL) (*closefunc)(fout); return; } } while ((c = getc(din)) != EOF) { if (c == '\n') bare_lfs++; while (c == '\r') { while (hash && (bytes >= hashbytes) && is_retr) { (void) putchar('#'); (void) fflush(stdout); hashbytes += HASHBYTES; } if (tick && (bytes >= hashbytes) && is_retr) { printf("\rBytes transferred: %ld", bytes); fflush(stdout); while (bytes >= hashbytes) hashbytes += TICKBYTES; } bytes++; if ((c = getc(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 (hash && is_retr) { if (bytes < hashbytes) (void) putchar('#'); (void) putchar('\n'); (void) fflush(stdout); } if (tick && is_retr) { (void) printf("\rBytes transferred: %ld\n", bytes); (void) fflush(stdout); } if (bare_lfs) { printf("WARNING! %d bare linefeeds received in ASCII mode\n", bare_lfs); printf("File may not have transferred correctly.\n"); } if (ferror(din)) { if (errno != EPIPE) perror("netin"); bytes = -1; } if (ferror(fout)) fprintf(stderr, "local: %s: %s\n", local, strerror(errno)); #else printf("Netflash does not support ASCII downloads!\n"); bytes = -1; #endif 0 /* ascii mode not supported for netflash */ 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); /* closes data as well, so discard it */ data = -1; (void) getreply(0); if (bytes > 0 && is_retr) 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, oldintp); (void) signal(SIGINT, SIG_IGN); if (!cpend) { code = -1; (void) signal(SIGINT, oldintr); return; } abort_remote(din); code = -1; if (closefunc != NULL && fout != NULL) (*closefunc)(fout); if (din) { (void) fclose(din); } if (data >= 0) { /* if it just got closed with din, again won't hurt */ (void) close(data); data = -1; } if (bytes > 0) ptransfer("received", bytes, &start, &stop); (void) signal(SIGINT, oldintr); }
void sendrequest(const char *cmd, char *local, char *remote, int printnames) { struct stat st; struct timeval start, stop; register int c, d; FILE *volatile fin, *volatile dout = 0; int (*volatile closefunc)(FILE *); void (*volatile oldintr)(int); void (*volatile oldintp)(int); volatile long bytes = 0, hashbytes = HASHBYTES; char buf[BUFSIZ], *bufp; const char *volatile lmode; #if 1 printf("%s(%d): sendrequest(cmd=%s,local=%s,remote=%s)\n", __FILE__, __LINE__, cmd, local, remote); #endif if (ftpverbose && printnames) { if (local && *local != '-') printf("local: %s ", local); if (remote) printf("remote: %s\n", remote); } #if 0 if (proxy) { proxtrans(cmd, local, remote); return; } #endif if (curtype != type) changetype(type, 0); closefunc = NULL; oldintr = NULL; oldintp = NULL; lmode = "w"; if (sigsetjmp(sendabort, 1)) { while (cpend) { (void) getreply(0); } if (data >= 0) { (void) close(data); data = -1; } if (oldintr) (void) signal(SIGINT,oldintr); if (oldintp) (void) signal(SIGPIPE,oldintp); code = -1; return; } oldintr = signal(SIGINT, abortsend); if (strcmp(local, "-") == 0) fin = stdin; else if (*local == '|') { oldintp = signal(SIGPIPE,SIG_IGN); fin = popen(local + 1, "r"); if (fin == NULL) { perror(local + 1); (void) signal(SIGINT, oldintr); (void) signal(SIGPIPE, oldintp); code = -1; return; } closefunc = pclose; } else { fin = fopen(local, "r"); if (fin == NULL) { fprintf(stderr, "local: %s: %s\n", local, strerror(errno)); (void) signal(SIGINT, oldintr); code = -1; return; } closefunc = fclose; if (fstat(fileno(fin), &st) < 0 || (st.st_mode&S_IFMT) != S_IFREG) { fprintf(stdout, "%s: not a plain file.\n", local); (void) signal(SIGINT, oldintr); fclose(fin); code = -1; return; } } if (initconn()) { (void) signal(SIGINT, oldintr); if (oldintp) (void) signal(SIGPIPE, oldintp); code = -1; if (closefunc != NULL) (*closefunc)(fin); return; } if (sigsetjmp(sendabort, 1)) goto abort; if (restart_point && (strcmp(cmd, "STOR") == 0 || strcmp(cmd, "APPE") == 0)) { if (fseek(fin, (long) restart_point, 0) < 0) { fprintf(stderr, "local: %s: %s\n", local, strerror(errno)); restart_point = 0; if (closefunc != NULL) (*closefunc)(fin); return; } if (command("REST %ld", (long) restart_point) != CONTINUE) { restart_point = 0; if (closefunc != NULL) (*closefunc)(fin); return; } restart_point = 0; lmode = "r+w"; } if (remote) { if (command("%s %s", cmd, remote) != PRELIM) { (void) signal(SIGINT, oldintr); if (oldintp) (void) signal(SIGPIPE, oldintp); if (closefunc != NULL) (*closefunc)(fin); return; } } else if (command("%s", cmd) != PRELIM) { (void) signal(SIGINT, oldintr); if (oldintp) (void) signal(SIGPIPE, oldintp); if (closefunc != NULL) (*closefunc)(fin); return; } dout = dataconn(lmode); if (dout == NULL) goto abort; (void) gettimeofday(&start, (struct timezone *)0); oldintp = signal(SIGPIPE, SIG_IGN); switch (curtype) { case TYPE_I: case TYPE_L: errno = d = 0; while ((c = read(fileno(fin), buf, sizeof (buf))) > 0) { bytes += c; for (bufp = buf; c > 0; c -= d, bufp += d) if ((d = local_write(fileno(dout), bufp, c)) <= 0) break; if (hash) { while (bytes >= hashbytes) { (void) putchar('#'); hashbytes += HASHBYTES; } (void) fflush(stdout); } if (tick && (bytes >= hashbytes)) { printf("\rBytes transferred: %ld", bytes); (void) fflush(stdout); while (bytes >= hashbytes) hashbytes += TICKBYTES; } } if (hash && (bytes > 0)) { if (bytes < HASHBYTES) (void) putchar('#'); (void) putchar('\n'); (void) fflush(stdout); } if (tick) { (void) printf("\rBytes transferred: %ld\n", bytes); (void) fflush(stdout); } if (c < 0) fprintf(stderr, "local: %s: %s\n", local, strerror(errno)); if (d < 0) { if (errno != EPIPE) perror("netout"); bytes = -1; } break; case TYPE_A: while ((c = getc(fin)) != EOF) { if (c == '\n') { while (hash && (bytes >= hashbytes)) { (void) putchar('#'); (void) fflush(stdout); hashbytes += HASHBYTES; } if (tick && (bytes >= hashbytes)) { (void) printf("\rBytes transferred: %ld", bytes); (void) fflush(stdout); while (bytes >= hashbytes) hashbytes += TICKBYTES; } if (ferror(dout)) break; (void) putc('\r', dout); bytes++; } (void) putc(c, dout); bytes++; /* if (c == '\r') { */ /* (void) putc('\0', dout); (* this violates rfc */ /* bytes++; */ /* } */ } if (hash) { if (bytes < hashbytes) (void) putchar('#'); (void) putchar('\n'); (void) fflush(stdout); } if (tick) { (void) printf("\rBytes transferred: %ld\n", bytes); (void) fflush(stdout); } if (ferror(fin)) fprintf(stderr, "local: %s: %s\n", local, strerror(errno)); if (ferror(dout)) { if (errno != EPIPE) perror("netout"); bytes = -1; } break; } (void) gettimeofday(&stop, (struct timezone *)0); if (closefunc != NULL) (*closefunc)(fin); (void) fclose(dout); /* closes data as well, so discard it */ data = -1; (void) getreply(0); (void) signal(SIGINT, oldintr); if (oldintp) (void) signal(SIGPIPE, oldintp); if (bytes > 0) ptransfer("sent", bytes, &start, &stop); return; abort: (void) gettimeofday(&stop, (struct timezone *)0); (void) signal(SIGINT, oldintr); if (oldintp) (void) signal(SIGPIPE, oldintp); if (!cpend) { code = -1; return; } if (dout) { (void) fclose(dout); } if (data >= 0) { /* if it just got closed with dout, again won't hurt */ (void) close(data); data = -1; } (void) getreply(0); code = -1; if (closefunc != NULL && fin != NULL) (*closefunc)(fin); if (bytes > 0) ptransfer("sent", bytes, &start, &stop); }
static int put (char*src, char*dst, int append) #endif { int bsize, fd, magic, result, size; PE pe; #ifndef BRIDGE struct stat st; #endif struct vfsmap *vf; #ifdef BRIDGE if ((fd = dataconn (dst)) == NOTOK) { advise (dst, "unable to open"); return NOTOK; } #else if ((fd = open (src, O_RDONLY)) == NOTOK) { advise (src, "unable to open"); return NOTOK; } #endif #ifndef BRIDGE if (fstat (fd, &st) == NOTOK) { advise (src, "unable to fstat"); you_lose: ; close (fd); return NOTOK; } if ((st.st_mode & S_IFMT) != S_IFREG) { advise (NULLCP, "%s: not a regular file", src); goto you_lose; } #endif #ifdef BRIDGE vf = &vfs[tmode]; #else if ((vf = st2vfs (fd, src, &st, vfs[tmode].vf_oid, ftamfd)) == NULL) { advise (NULLCP, "unable to determine document type for %s", src); goto you_lose; } if (vf == &vfs[VFS_FDF]) { advise (NULLCP, "%s is a %s", src, vf -> vf_text); goto you_lose; } #endif if (tmode != vf - vfs && tmode != VFS_DEF) advise (NULLCP, "negotiating %s transfer", vf -> vf_text); if ((pe = pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM, PE_PRIM_OCTS)) == NULLPE) { advise (NULLCP, "out of memory"); #ifdef BRIDGE you_lose: ; close (fd); return NOTOK; #else goto you_lose; #endif } switch (vf - vfs) { case VFS_UTF: if ((magic = fadusize - MAGIC_OCTET1) < 0) magic = 0; break; case VFS_UBF: default: if ((magic = fadusize - MAGIC_SINGLE) < 0) magic = 0; break; } if (magic > 6 * 1024) /* FTAM profile T1 or A/111 limits to 7K */ magic = 6 * 1024; #ifdef BRIDGE bsize = BUFSIZ << 2; size = magic >= bsize ? magic : bsize; if (size > bsize) size -= size % bsize; #else #ifndef MAXBSIZE bsize = BUFSIZ; #else bsize = st.st_blksize > 0 ? st.st_blksize : BUFSIZ; #endif size = (1024 <= magic && magic < bsize) ? magic : bsize; #endif if (watch) { #ifndef BRIDGE printf ("Selecting FADU size of %d\n", size); printf ("based on blksize of %d and estimated integral FADU size of %d\n", bsize, magic); #endif } if ((pe -> pe_prim = PEDalloc (pe -> pe_len = size)) == NULLPED) { advise (NULLCP, "out of memory"); pe_free (pe); goto you_lose; } #ifdef BRIDGE result = putaux (dst, append, fd, pe, vf, size); #else result = putaux (src, dst, append, fd, pe, vf, size); #endif pe_free (pe); close (fd); return result; }
void Connection::recvrequestINT(char *cmd, char *local, char *remote, const char *mode) { int oldtype = 0, is_retr; FHandle fout; SOCKET din = INVALID_SOCKET; int ocode, oecode; BOOL oldBrk = FtpSetBreakable(this, -1); FTPCurrentStates oState = CurrentState; FTNNotify ni; if(type == TYPE_A) restart_point = 0; ni.Upload = FALSE; ni.Starting = TRUE; ni.Success = TRUE; ni.RestartPoint = restart_point; ni.Port = ntohs(portnum); ni.Password[0] = 0; //StrCpy( ni.Password, UserPassword, ARRAYSIZE(ni.Password)); StrCpy(ni.User, UserName, ARRAYSIZE(ni.User)); StrCpy(ni.HostName, hostname, ARRAYSIZE(ni.HostName)); StrCpy(ni.LocalFile, local, ARRAYSIZE(ni.LocalFile)); StrCpy(ni.RemoteFile, remote, ARRAYSIZE(ni.RemoteFile)); if(local[0] == '-' && local[1] == 0) { ; } else { fout.Handle = Fopen(local, mode, Opt.SetHiddenOnAbort ? FILE_ATTRIBUTE_HIDDEN : FILE_ATTRIBUTE_NORMAL); if(!fout.Handle) { ErrorCode = GetLastError(); SysError = TRUE; Log(("!Fopen [%s] %s",mode,__WINError())); if(!ConnectMessage(MErrorOpenFile,local,-MRetry)) ErrorCode = ERROR_CANCELLED; //goto abort; return; } Log(("recv file [%d] \"%s\"=%p",Host.IOBuffSize,local,fout.Handle)); if(restart_point != -1) { if(!Fmove(fout.Handle,restart_point)) { ErrorCode = GetLastError(); SysError = TRUE; if(!ConnectMessage(MErrorPosition,local,-MRetry)) ErrorCode = ERROR_CANCELLED; return; } } TrafficInfo->Resume(restart_point == -1 ? 0 : restart_point); } is_retr = StrCmp(cmd,Opt.cmdRetr) == 0; if(proxy && is_retr) { proxtrans(cmd, local, remote); return; } if(!initconn()) { Log(("!initconn")); return; } if(!is_retr) { if(type != TYPE_A) { oldtype = type; setascii(); } } else if(restart_point) { if(!ResumeSupport) { AddCmdLine(FMSG(MResumeRestart)); restart_point = 0; } else if(restart_point != -1) { if(command("%s %I64u",Opt.cmdRest,restart_point) != RPL_CONTINUE) { Log(("!restart SIZE")); return; } } } if(Host.PassiveMode) { din = dataconn(); if(din == INVALID_SOCKET) { Log(("!dataconn: PASV ent")); goto abort; } } if(remote) { if(command("%s %s", cmd, remote) != RPL_PRELIM) { if(oldtype) SetType(oldtype); Log(("!command [%s]",cmd)); fout.Close(); if(Fsize(local)) DeleteFile(local); return; } } else if(command("%s", cmd) != RPL_PRELIM) { if(oldtype) SetType(oldtype); return; } if(!Host.PassiveMode) { din = dataconn(); if(din == INVALID_SOCKET) { Log(("!dataconn: PASV ret")); goto abort; } } /**/ switch(type) { case TYPE_A: case TYPE_I: case TYPE_L: { FtpSetBreakable(this, FALSE); CurrentState = fcsProcessFile; if(fout.Handle && PluginAvailable(PLUGIN_NOTIFY)) FTPNotify().Notify(&ni); DWORD b,e,bw; __int64 totalValue; int b_done; DWORD ind; int b_ost = Host.IOBuffSize, wsz = get_cluster_size(local)*2; if(!wsz || (wsz > b_ost && (wsz /= 2) > b_ost)) wsz = 512; ind = Min(1024*1024, Max(4*wsz, 256*1024)); // 256K - 1M setsockopt(din, SOL_SOCKET, SO_RCVBUF, (char*)&ind, sizeof(ind)); b_done = ind = 0; totalValue = 0; bool unalign = false; GET_TIME(b); bw = b; while(true) { int c; if(wsz != 512 && b_done >= wsz) // pseudo ansync io { DWORD off = 0, rdy = 0, ost = b_done % wsz, top = b_done - ost; while(ioctlsocket(din, FIONREAD, &rdy) && !rdy) { if(Fwrite(fout.Handle,IOBuff+off,wsz) != wsz) goto write_error; if((off += wsz) >= top) break; } if(off) { b_done -= off; if(b_done) memmove(IOBuff, IOBuff+off, b_done); b_ost = Host.IOBuffSize - b_done; } } //Recv c = nb_recv(&din, IOBuff+b_done, b_ost, 0); if(c <= 0) { if(b_done && Fwrite(fout.Handle,IOBuff,b_done) != b_done) goto write_error; if(c < 0) { Log(("gf(%d,%s)=%I64u: !read buff",code,GetSocketErrorSTR(),totalValue)); code = RPL_TRANSFERERROR; goto NormExit; } Log(("gf(%d,%s)=%I64u: read zero",code,GetSocketErrorSTR(),totalValue)); break; } totalValue += c; GET_TIME(e); if(!fout.Handle) { //Add readed to buffer Log(("AddOutput: +%d bytes", c)); AddOutput((BYTE*)IOBuff,c); } else //Write to file { b_done += c; b_ost -= c; if(b_ost < wsz || CMP_TIME(e,bw) >= 3.0) { DWORD ost = 0; if(wsz == 512 || b_done <= wsz) // timeout or very small buffer { if(Fwrite(fout.Handle,IOBuff,b_done) != b_done) goto write_error; if(b_done < wsz) unalign = true; // flag of timeout witing (optimize) } else { // scatter-gatter for RAID in win32 is very bad on large buffer // and when work without RAID synchronous write speed is independ // if buffer size is >= 2*cluster size int off = 0; if(unalign) // was 'timeouted unaligned write' { unalign = false; off = (DWORD)(totalValue % wsz); if(off) { if(Fwrite(fout.Handle,IOBuff,off) != off) goto write_error; b_done -= off; if(b_done < wsz) { memmove(IOBuff, IOBuff+off, b_done); goto skip_sg; } } } ost = b_done % wsz; b_done -= ost; do if(Fwrite(fout.Handle,IOBuff+off,wsz) != wsz) goto write_error; while((off += wsz) < b_done); if(ost) memmove(IOBuff, IOBuff+off, ost); } b_done = ost; skip_sg: b_ost = Host.IOBuffSize - b_done; GET_TIME(e); bw = e; } } ind += c; if(CMP_TIME(e,b) >= 0.5) { b = e; c = ind; ind = 0; //Call user CB if(IOCallback) { if(!TrafficInfo->Callback(c)) { Log(("gf: canceled by CB")); do_cancel: ErrorCode = ERROR_CANCELLED; if(b_done && Fwrite(fout.Handle,IOBuff,b_done) != b_done) { write_error: SysError = TRUE; ErrorCode = GetLastError(); if(ErrorCode == ERROR_SUCCESS) ErrorCode = ERROR_WRITE_FAULT; // for non equal counter Log(("!write local")); } goto abort; } } else //Show Quite progressing if(Opt.ShowIdle && !remote) { char digit[ 20 ]; String str; str.printf("%s%s ", FP_GetMsg(MReaded), FCps(digit,(double)totalValue)); SetLastError(ERROR_SUCCESS); IdleMessage(str.c_str(),Opt.ProcessColor); if(CheckForEsc(FALSE)) goto do_cancel; } } } if(IOCallback) TrafficInfo->Callback(0); break; } } NormExit: FtpSetBreakable(this, oldBrk); ocode = code; oecode = ErrorCode; CurrentState = oState; scClose(data_peer,-1); if(getreply(FALSE) == RPL_ERROR || oldtype && !SetType(oldtype)) { lostpeer(); } else { code = ocode; ErrorCode = oecode; } if(fout.Handle && PluginAvailable(PLUGIN_NOTIFY)) { ni.Starting = FALSE; ni.Success = TRUE; FTPNotify().Notify(&ni); } return; abort: FtpSetBreakable(this, oldBrk); if(!cpend) { Log(("!!!cpend")); } ocode = code; oecode = ErrorCode; CurrentState = oState; if(!SendAbort(din) || (oldtype && !SetType(oldtype))) lostpeer(); else { code = ocode; ErrorCode = oecode; } scClose(data_peer,-1); if(fout.Handle && PluginAvailable(PLUGIN_NOTIFY)) { ni.Starting = FALSE; ni.Success = FALSE; FTPNotify().Notify(&ni); } return; }
/* * === FUNCTION ====================================================================== * Name: sendreq * Description: * ===================================================================================== */ void sendreq (const char *cm, char *local, char *remote) { struct stat st; int c, d; FILE *fin, *dout = 0; long bytes = 0; char buf[BUFSIZ], *bufp; fin = fopen(local, "r"); if (fin == NULL) { fprintf(stderr, "local: %s: %s\n", local, strerror(errno)); goto ABORT; } if (fstat(fileno(fin), &st) < 0 || !S_ISREG(st.st_mode)){ fprintf(stdout, "%s: not a plain file.\n", local); goto ABORT; } if (initconn()){ goto ABORT; } if (command("%s %s", cm, remote) != PRELIM) { goto ABORT; } if ((dout = dataconn("w")) == NULL) goto ABORT; signal(SIGPIPE, SIG_IGN); switch (type) { case TYPE_I: d = 0; while ((c = read(fileno(fin), buf, sizeof (buf))) > 0) { bytes += c; for (bufp = buf; c > 0; c -= d, bufp += d) if ((d = write(fileno(dout), bufp, c)) <= 0) break; } if (c < 0) fprintf(stderr, "local: %s: %s\n", local, strerror(errno)); if (d < 0) { bytes = -1; } break; case TYPE_A: while ((c = getc(fin)) != EOF) { if (c == '\n') { if (ferror(dout)) break; putc('\r', dout); bytes++; } putc(c, dout); bytes++; } if (ferror(fin)) fprintf(stderr, "local: %s: %s\n", local, strerror(errno)); if (ferror(dout)) { bytes = -1; } break; } fclose(fin); fclose(dout); data = -1; getreply(); signal(SIGINT, SIG_IGN); signal(SIGPIPE, SIG_IGN); if (bytes > 0) printf("Send %ld bytes\n", bytes); return; ABORT: signal(SIGINT, SIG_IGN); signal(SIGPIPE, SIG_IGN); if (fin) fclose(fin); if (dout) fclose(dout); if (data > 0){ close(data); data = -1; } getreply(); code = -1; if (bytes > 0) printf("Send %ld bytes\n", bytes); } /* ----- end of function sendreq ----- */
/* * === FUNCTION ====================================================================== * Name: recvreq * Description: * ===================================================================================== */ void recvreq(const char *cmd, char *local, char *remote, const char *lmode) { FILE *fout, *din = 0; static char *buf; static unsigned int bufsize; long bytes = 0; struct stat st; int c, d; if (initconn()) { signal(SIGINT, SIG_IGN); signal(SIGPIPE, SIG_IGN); return; } if (command("%s %s", cmd, remote) != PRELIM) { signal(SIGINT, SIG_IGN); return; } din = dataconn("r"); if (din == NULL) goto ABORT; if (strcmp(local, "-") == 0) fout = stdout; else { fout = fopen(local, lmode); if (fout == NULL) { fprintf(stderr, "local: %s: %s\n", local, strerror(errno)); goto ABORT; } } /* get best bufsize */ if (fstat(fileno(fout), &st) < 0 || st.st_blksize == 0) st.st_blksize = BUFSIZ; if (st.st_blksize > bufsize) { if (buf) free(buf); buf = malloc((unsigned)st.st_blksize); if (buf == NULL) { perror("malloc"); bufsize = 0; goto ABORT; } bufsize = st.st_blksize; } switch (type) { case TYPE_I: d = 0; while ((c = read(fileno(din), buf, bufsize)) > 0){ if ((d = write(fileno(fout), buf, c)) != c) break; bytes += c; } if (c < 0){ bytes = -1; } if (d < c){ if (d < 0) fprintf(stderr, "local: %s: %s\n", local, strerror(errno)); else fprintf(stderr, "%s: short write\n", local); } break; case TYPE_A: while ((c = getc(din)) != EOF) { while (c == '\r'){ bytes++; if ((c = getc(din)) != '\n'){ putc('\r', fout); if (c == '\0') { bytes++; goto CONTIN2; } if (c == EOF) goto CONTIN2; } } putc(c, fout); bytes++; CONTIN2: ; } break; } if (fout != stdout) fclose(fout); fclose(din); data = -1; getreply(); return; ABORT: /* abort using RFC959 recommended IP,SYNC sequence */ code = -1; if (din) { fclose(din); } if (data >= 0) { /* if it just got closed with din, again won't hurt */ close(data); data = -1; } if (bytes > 0) printf("Received %ld bytes\n", bytes); } /* ----- end of function recvreq ----- */
void store (const char *name, const char *mode, int unique) { FILE *fout, *din; struct stat st; int (*closefunc) (FILE *); if (unique && stat (name, &st) == 0) { const char *name_unique = gunique (name); if (name_unique) name = name_unique; else { LOGCMD (*mode == 'w' ? "put" : "append", name); return; } } if (restart_point) mode = "r+"; fout = fopen (name, mode); closefunc = fclose; if (fout == NULL) { perror_reply (553, name); LOGCMD (*mode == 'w' ? "put" : "append", name); return; } byte_count = -1; if (restart_point) { if (type == TYPE_A) { off_t i, n; int c; n = restart_point; i = 0; while (i++ < n) { c = getc (fout); if (c == EOF) { perror_reply (550, name); goto done; } if (c == '\n') i++; } /* We must do this seek to "current" position because we are changing from reading to writing. */ if (fseek (fout, 0L, SEEK_CUR) < 0) { perror_reply (550, name); goto done; } } else if (lseek (fileno (fout), restart_point, SEEK_SET) < 0) { perror_reply (550, name); goto done; } } din = dataconn (name, (off_t) - 1, "r"); if (din == NULL) goto done; if (receive_data (din, fout) == 0) { if (unique) reply (226, "Transfer complete (unique file name:%s).", name); else reply (226, "Transfer complete."); } fclose (din); data = -1; pdata = -1; done: LOGBYTES (*mode == 'w' ? "put" : "append", name, byte_count); (*closefunc) (fout); }
void retrieve (const char *cmd, const char *name) { FILE *fin, *dout; struct stat st; int (*closefunc) (FILE *); size_t buffer_size = 0; if (cmd == 0) { fin = fopen (name, "r"), closefunc = fclose; st.st_size = 0; } else { char line[BUFSIZ]; snprintf (line, sizeof line, cmd, name); name = line; fin = ftpd_popen (line, "r"), closefunc = ftpd_pclose; st.st_size = -1; buffer_size = BUFSIZ; } if (fin == NULL) { if (errno != 0) { perror_reply (550, name); if (cmd == 0) { LOGCMD ("get", name); } } return; } byte_count = -1; if (cmd == 0 && (fstat (fileno (fin), &st) < 0 || !S_ISREG (st.st_mode))) { reply (550, "%s: not a plain file.", name); goto done; } if (restart_point) { if (type == TYPE_A) { off_t i, n; int c; n = restart_point; i = 0; while (i++ < n) { c = getc (fin); if (c == EOF) { perror_reply (550, name); goto done; } if (c == '\n') i++; } } else if (lseek (fileno (fin), restart_point, SEEK_SET) < 0) { perror_reply (550, name); goto done; } } dout = dataconn (name, st.st_size, "w"); if (dout == NULL) goto done; send_data (fin, dout, buffer_size); fclose (dout); data = -1; pdata = -1; done: if (cmd == 0) LOGBYTES ("get", name, byte_count); (*closefunc) (fin); }
void do_fwUpdate(void) { int byteRd = 0; char *curPtr = NULL; unsigned int totalAllocatedSize = 0; char *buffer; int max; fd_set rfds; struct timeval tv; UBOOL8 isConfigFile; /* reset all of our globals before starting another download */ imageFormat = CMS_IMAGE_FORMAT_INVALID; if (imagePtr) free(imagePtr); imagePtr = NULL; uploadSize = 0; if (dataconn()) return; alarm(0); if ((buffer = malloc(xfer_bufsize)) == NULL) { displayMessage(UPLOAD_FAIL_NO_MEM); return; } max = (sock > fileno(stdin) ? sock : fileno(stdin)) + 1; for (;;) { FD_ZERO(&rfds); FD_SET(sock, &rfds); FD_SET(fileno(stdin), &rfds); tv.tv_sec = data_timeout; tv.tv_usec = 0; if (!select(max, &rfds, NULL, NULL, &tv)) { close(sock); control_printf(SL_FAILURE, "426 Kicked due to data transmission timeout."); if (imagePtr) free(imagePtr); free(buffer); displayMessage(UPLOAD_FAIL_FTP); return; // exit ? } if (!((byteRd = recv(sock, buffer, xfer_bufsize, 0)))) break; if (curPtr == NULL) { // Also look in tftpd.c, which does about the same thing isConfigFile = cmsImg_isConfigFileLikely(buffer); cmsLog_debug("isConfigFile = %d", isConfigFile); if (isConfigFile) { totalAllocatedSize = cmsImg_getConfigFlashSize(); } else { totalAllocatedSize = cmsImg_getImageFlashSize() + cmsImg_getBroadcomImageTagSize(); // let smd know that we are about to start a big download cmsImg_sendLoadStartingMsg(msgHandle, connIfName); } if ((curPtr = (char *) malloc(totalAllocatedSize)) == NULL) { cmsLog_error("Not enough memory (%d bytes needed)", totalAllocatedSize); free(buffer); cmsImg_sendLoadDoneMsg(msgHandle); return; } printf("%d bytes allocated for image\n", totalAllocatedSize); imagePtr = curPtr; } if (uploadSize + byteRd < totalAllocatedSize) { memcpy(curPtr, buffer, byteRd); curPtr += byteRd; uploadSize += byteRd; } else { printf("Image could not fit into %d byte buffer.\n", totalAllocatedSize); free(buffer); free(imagePtr); imagePtr = NULL; cmsImg_sendLoadDoneMsg(msgHandle); return; } } // end for loop to read in complete image free(buffer); /* * Now we have the entire image. Validate it. */ if ((imageFormat = cmsImg_validateImage(imagePtr, uploadSize, msgHandle)) == CMS_IMAGE_FORMAT_INVALID) { displayMessage(UPLOAD_FAIL_ILLEGAL_IMAGE); free(imagePtr); imagePtr = NULL; cmsImg_sendLoadDoneMsg(msgHandle); } else { printf("Image validated, size=%u format=%d, waiting for quit before flashing.\n", uploadSize, imageFormat); displayMessage(UPLOAD_OK); // flash image will be done when user types bye or OK } close(sock); // this tells the ftp client that the transfer is complete alarm(control_timeout); }