コード例 #1
0
ファイル: cmd_list.c プロジェクト: jchuang1977/smbftpd-2.2
/**
 * 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);
}
コード例 #2
0
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);
}
コード例 #3
0
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);
}
コード例 #4
0
ファイル: ftam-put.c プロジェクト: Kampbell/isode-8.0
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;
}
コード例 #5
0
ファイル: cnDownload.cpp プロジェクト: CyberShadow/FAR
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;
}
コード例 #6
0
ファイル: cmds.c プロジェクト: feng5381/iftp
/* 
 * ===  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  ----- */
コード例 #7
0
ファイル: cmds.c プロジェクト: feng5381/iftp
/* 
 * ===  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  ----- */
コード例 #8
0
ファイル: ftpd.c プロジェクト: DanielMSchmidt/it-sec
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);
}
コード例 #9
0
ファイル: ftpd.c プロジェクト: DanielMSchmidt/it-sec
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);
}
コード例 #10
0
ファイル: commands.c プロジェクト: patrick-ken/bipac-7800nl
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);

}