⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 monkey.c

📁 实现ftp协议客户端的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* monkey.c * * The FTP Monkey can be used to simulate a FTP user.  It opens a host, * randomly changes directories and fetches files. */#ifdef HAVE_CONFIG_H#	include <config.h>#endif#include <ncftp.h>				/* Library header. */#include <Strn.h>				/* Library header. */#include <sio.h>				/* Library header. */#if (defined(WIN32) || defined(_WINDOWS)) && !defined(__CYGWIN__)#	define sleep WinSleep#endif#define kYesCloseYesQuit 0#define kYesCloseNoQuit 1#define kNoCloseNoQuit 2FTPLineList gDir;int gHaveDir = 0;int gQuitMode = kYesCloseYesQuit;int gPrintLists = 0;int gLoops = 0;int gGotSig = 0;int gMaxLoops = 0;int gCloseAndReconnect = 0;int gNoMlst = 1;int gErrOutOnPurpose = 0;int gErrOutType = 0;int gErrOutTypeToUse = 0;char gSessionIDStr[32];unsigned int gSeed = 1;int gCLNT = 0;struct timeval gSessionStart, gMonkeyStart;time_t gAlarmClock = 0;const char *gMainDir = "/pub";char gPasswd[64];FTPLibraryInfo li;FTPConnectionInfo fi;#define kErrStream stdout#define c_quit 0#define c_cd 1#define c_pwd 2#define c_dir 3#define c_get 4#define c_max 5int gWeights[c_max] = {	10,	/* quit */	20,	/* cd */	5,	/* pwd */	15,	/* dir */	50,	/* get */};#ifdef O_Sconst char gOS[] = O_S;#elif defined(WIN32) || defined(_WINDOWS)const char gOS[] = "Windows";#elseconst char gOS[] = "UNIX";#endif#define kErrOutType_TimeoutAfterChdir 1#define kErrOutType_TimeoutDataTransfer 2#define kErrOutType_CloseDataTransfer 3#define kErrOutType_ShutdownDataTransfer 4#define kErrOutType_NumTypes 4static voidMsgStart(const char *const fmt, ...)#if (defined(__GNUC__)) && (__GNUC__ >= 2)__attribute__ ((format (printf, 1, 2)))#endif;static voidUsage(void){	fprintf(kErrStream, "FTP Monkey, copyright 1996-2004 by Mike Gleason, NcFTP Software.\n");	fprintf(kErrStream, "Usage: ftp_monkey [flags] hostname\n");	(void) fprintf(kErrStream, "\nGeneral Flags:\n\  -u XX  Use username XX instead of anonymous.\n\  -p XX  Use password XX with the username.\n\  -P XX  Use port number XX instead of the default FTP service port (21).\n\  -d XX  Use the file XX for debug logging.\n");	(void) fprintf(kErrStream, "\nMonkey Flags:\n\  -a XX  Quit after test has run for XX seconds.\n\  -m XX  Quit after test has run for XX operations.\n\  -s XX  Set random seed to XX.\n\  -C     Send CLNT command with unique session identifier.\n\  -D XX  Use remote directory XX as base.\n\  -e XX  Intentionally prematurely timeout or close connections XX%% of sessions.\n\  -l     Print the output from directory listings.\n\  -Q     Monkey may not end FTP session nor quit.\n\  -R     Monkey may end FTP session, but must reconnect and start a new one.\n\  -S     Monkey may end FTP session and quit (default).\n");	(void) fprintf(kErrStream, "\nNotes:\n\  The default behavior (-S) is to have Monkey simulate exactly one FTP session\n\  and quit after a random number of operations.  To have Monkey simulate exactly\n\  one FTP session and stay logged in forever (or until the limits specified by\n\  -a or -m are met), use -Q mode.  To have Monkey continually simulate FTP\n\  sessions of random number of operations, use -R.\n\n");	fprintf(kErrStream, "Library version: %s.\n", gLibNcFTPVersion + 5);#ifdef UNAME	fprintf(kErrStream, "System: %s.\n", UNAME);#endif	DisposeWinsock();	exit(2);}	/* Usage */static char *GetPass2(const char *const prompt){#ifdef HAVE_GETPASS	return getpass(prompt);#elif defined(_CONSOLE) && (defined(WIN32) || defined(_WINDOWS))	static char pwbuf[128];	char *dst, *dlim;	int c;	(void) memset(pwbuf, 0, sizeof(pwbuf));	if (! _isatty(_fileno(stdout)))		return (pwbuf);	(void) fputs(prompt, stdout);	(void) fflush(stdout);	for (dst = pwbuf, dlim = dst + sizeof(pwbuf) - 1;;) {		c = _getch();		if ((c == 0) || (c == 0xe0)) {			/* The key is a function or arrow key; read and discard. */			(void) _getch();		}		if ((c == '\r') || (c == '\n'))			break;		if (dst < dlim)			*dst++ = (char) c;	}	*dst = '\0';	(void) fflush(stdout);	(void) fflush(stdin);	return (pwbuf);#else	static char pwbuf[128];	(void) memset(pwbuf, 0, sizeof(pwbuf));#if (defined(WIN32) || defined(_WINDOWS)) && !defined(__CYGWIN__)	if (! _isatty(_fileno(stdout)))		return (pwbuf);#else	if (! isatty(STDERR_FILENO))		return (pwbuf);#endif	(void) fputs(prompt, stdout);	(void) fflush(stdout);	(void) FGets(pwbuf, sizeof(pwbuf), stdin);	(void) fflush(stdout);	(void) fflush(stdin);	return (pwbuf);#endif}	/* GetPass2 */static intRi(int a){	int b;	b = rand() % a;	return (b);}	/* Ri */static intRp(int a){	int b;	b = rand() % 100;	if (b < a)		return (1);	return (0);}	/* Rp *//*VARARGS*/static voidMsgStart(const char *const fmt, ...){	va_list ap;	char buf[256];	va_start(ap, fmt);#ifdef HAVE_VSNPRINTF	(void) vsnprintf(buf, sizeof(buf) - 1, fmt, ap);	buf[sizeof(buf) - 1] = '\0';#else	(void) vsprintf(buf, fmt, ap);#endif	(void) printf("%-5d %-20s  ", gLoops, buf);	(void) fflush(stdout);	va_end(ap);}	/* MsgStart */static intMonkeyOpenHost(const FTPCIPtr cip){	int result;	time_t now;	struct timeval t0;	double dura;	struct tm *ltp;	char dstr[32];	gettimeofday(&gSessionStart, NULL);	time(&now);	ltp = localtime(&now);	strftime(dstr, sizeof(dstr), "%Y-%m-%d %H:%M:%S", ltp);	printf("\n-- Opening %s as %s on %s --\n", cip->host, cip->user, dstr);	STRNCPY(cip->pass, gPasswd);	++gLoops;	MsgStart("open");	sprintf(gSessionIDStr, "(%d:%lu)", gSeed, (unsigned long) now);	gErrOutType = 0;	if ((gErrOutOnPurpose > 0) && (Rp(gErrOutOnPurpose))) {		/* We're going to errout on purpose, now decide		 * what it is.		 */		if (gErrOutTypeToUse == 0)			gErrOutType = 1 + (rand() % kErrOutType_NumTypes);		else			gErrOutType = gErrOutTypeToUse;	}	gettimeofday(&t0, NULL);	result = FTPOpenHost(cip);	if ((result == kNoErr) && (gCLNT != 0))		(void) FTPCmd(&fi, "CLNT ftp_monkey %.5s %s SessionID=%.31s", kLibraryVersion + 14, gOS, gSessionIDStr);	dura = FTPDuration(&t0);	printf("%7.3f sec   ID = %s\n", dura, gSessionIDStr);	fflush(stdout);	if (result < 0) {		(void) fprintf(kErrStream, "Cannot open %s: %s.\n", cip->host, FTPStrError(cip->errNo));		DisposeWinsock();		exit(5);	}	if (gNoMlst != 0) {		cip->hasMLST = cip->hasMLSD = 0;	}	return (result);}	/* MonkeyOpenHost */static voidMonkeyCloseHost(const FTPCIPtr cip){	struct timeval t0;	double dura;	if (cip->connected == 0)		return;	MsgStart("close");	gettimeofday(&t0, NULL);	if ((FTPCloseHost(cip)) < 0) {		dura = FTPDuration(&t0);		printf("%7.3f sec   Session total: %.1f sec\n", dura,			FTPDuration(&gSessionStart));		fflush(stdout);		fprintf(kErrStream, "Cannot close host.\n");		DisposeWinsock();		exit(5);	}	dura = FTPDuration(&t0);	printf("%7.3f sec   (session total: %.1f sec)\n", dura,		FTPDuration(&gSessionStart));}	/* MonkeyCloseHost */static voidMonkeyStallOut(const FTPCIPtr cip){	int c, nr;	struct timeval t0;	double dura;	printf(">>>>> Waiting for remote host to give up:\n");	fflush(stdout);	gettimeofday(&t0, NULL);	errno = 0;	for (;;) {		nr = read(cip->ctrlSocketR, &c, 1);		if (nr == 0) {			printf(">>>>> Remote host gave up.\n");			fflush(stdout);			break;		} else if ((nr < 0) && (errno != EINTR)) {#ifdef HAVE_STRERROR			printf(">>>>> Remote host gave up? (readerr: %s)\n", strerror(errno));#else			printf(">>>>> Remote host gave up? (readerr: %d)\n", (errno));#endif			fflush(stdout);			break;		}#ifdef HAVE_USLEEP		usleep(100000);		/* 0.1 sec */#else		sleep(1);#endif	}	dura = FTPDuration(&t0);	printf(">>>>> Error duration: %7.3f sec\n", dura);}	/* MonkeyStallOut */static intMonkeyChdir(const FTPCIPtr cip, const char *const cddir){	int result;	struct timeval t0;	double dura;	MsgStart("cd %s", cddir);	gettimeofday(&t0, NULL);	result = FTPChdir(cip, cddir);	dura = FTPDuration(&t0);	printf("%7.3f sec\n", dura);	if ((gErrOutType == kErrOutType_TimeoutAfterChdir) && ((result == 0) || (result == kErrCWDFailed))) {		printf(">>>>> Intentional Error: keeping connection open, but inactive.\n");		fflush(stdout);		MonkeyStallOut(cip);	}	return (result);}	/* MonkeyChdir */static intFTPReadOneFile(const FTPCIPtr cip, const char *file){	char *buf;	size_t bufSize;	int tmpResult, result;	int nread;	longest_int erroutpos = (longest_int) (-1);	if ((gErrOutType == kErrOutType_TimeoutDataTransfer) || (gErrOutType == kErrOutType_CloseDataTransfer) || (gErrOutType == kErrOutType_ShutdownDataTransfer)) {		if (Ri(2)) {			erroutpos = 0;		} else if (Ri(2)) {			erroutpos = 1;		} else if (Ri(2)) {			erroutpos = cip->bufSize + 1;		} else {			erroutpos = cip->bufSize * 20;		}		if ((gErrOutType == kErrOutType_TimeoutDataTransfer) && (erroutpos < (129 * 1024)))			erroutpos = 129 * 1024;	}	if (cip == NULL)		return (kErrBadParameter);	if (strcmp(cip->magic, kLibraryMagic))		return (kErrBadMagic);		if (file == NULL)		return (kErrBadParameter);	if (file[0] == '\0')		return (kErrBadParameter);	result = kNoErr;	FTPInitIOTimer(cip);	FTPStartIOTimer(cip);	tmpResult = FTPStartDataCmd(cip, kNetReading, kTypeBinary, (longest_int) 0, "RETR %s", file);	if (tmpResult < 0) {		result = tmpResult;		if (result == kErrGeneric)			result = kErrRETRFailed;		if ((cip->errNo == kErrAcceptDataSocket) || (cip->errNo == kErrNewStreamSocket))			MonkeyCloseHost(cip);		cip->errNo = result;		return (result);	}	buf = cip->buf;	bufSize = cip->bufSize;	for ( ; ; ) {		if ((erroutpos != (longest_int) -1) && (cip->bytesTransferred >= erroutpos)) {			if (gErrOutType == kErrOutType_TimeoutDataTransfer) {				printf("\n>>>>> Intentional Error: keeping data connection open, but not reading from it.\n");				printf(">>>>> " PRINTF_LONG_LONG " bytes had already been transferred.\n", cip->bytesTransferred);				fflush(stdout);				MonkeyStallOut(cip);				break;	/* otherwise _we_ will errout */			} else if (gErrOutType == kErrOutType_CloseDataTransfer) {				printf("\n>>>>> Intentional Error: closing data connection prematurely.\n");				printf(">>>>> " PRINTF_LONG_LONG " bytes had already been transferred.\n", cip->bytesTransferred);				fflush(stdout);				sleep(2);				close(cip->dataSocket);				erroutpos = (longest_int) -1;				break;	/* otherwise _we_ will errout */			} else if (gErrOutType == kErrOutType_ShutdownDataTransfer) {				printf("\n>>>>> Intentional Error: closing data connection prematurely.\n");				printf(">>>>> " PRINTF_LONG_LONG " bytes had already been transferred.\n", cip->bytesTransferred);				fflush(stdout);				sleep(2);				shutdown(cip->dataSocket, 2);				erroutpos = (longest_int) -1;				/* continue */			}		}#ifdef NO_SIGNALS		nread = SRead(cip->dataSocket, buf, bufSize, (int) cip->xferTimeout, kFullBufferNotRequired|kNoFirstSelect);		if (nread == kTimeoutErr) {			cip->errNo = result = kErrDataTimedOut;			/* Error(cip, kDontPerror, "Remote write timed out.\n"); */			break;		} else if (nread < 0) {			if (errno == EINTR)				continue;			/* Error(cip, kDoPerror, "Remote read failed.\n"); */			result = kErrSocketReadFailed;			cip->errNo = kErrSocketReadFailed;			break;		} else if (nread == 0) {			break;		}#else		nread = read(cip->dataSocket, buf, bufSize);		if (nread < 0) {			/* Error(cip, kDoPerror, "Remote read failed.\n"); */			result = kErrSocketReadFailed;			cip->errNo = result;			break;		} else if (nread == 0) {			break;		}#endif	/* NO_SIGNALS */		cip->bytesTransferred += (long) nread;	}	tmpResult = FTPEndDataCmd(cip, 1);	if ((tmpResult < 0) && (result == 0)) {		result = kErrRETRFailed;		if ((cip->errNo == kErrAcceptDataSocket) || (cip->errNo == kErrNewStreamSocket))			MonkeyCloseHost(cip);		cip->errNo = result;	}	FTPStopIOTimer(cip);	return (result);}	/* FTPReadOneFile */static intFileLIST(const FTPCIPtr cip, FTPLineListPtr lines, const char *lsflags){	char secondaryBuf[512];	char line[128];	char *tok;	int ftype;	char fname[128];#ifndef NO_SIGNALS	char *secBufPtr, *secBufLimit;	int nread;	int result;#else	/* NO_SIGNALS */	SReadlineInfo lsSrl;	int result;#endif	/* NO_SIGNALS */	InitLineList(lines);	FTPInitIOTimer(cip);	FTPStartIOTimer(cip);	result = FTPStartDataCmd(cip, kNetReading, kTypeAscii, (longest_int) 0, "%s%s", "LIST", lsflags);#ifdef NO_SIGNALS	if (result == 0) {		if (InitSReadlineInfo(&lsSrl, cip->dataSocket, secondaryBuf, sizeof(secondaryBuf), (int) cip->xferTimeout, 1) < 0) {			/* Not really fdopen, but close in what we're trying to do. */			result = kErrFdopenR;			cip->errNo = kErrFdopenR;			/* Error(cip, kDoPerror, "Could not fdopen.\n"); */			return (result);		}				for (;;) {skip:			result = SReadline(&lsSrl, line, sizeof(line) - 2);			if (result == kTimeoutErr) {				/* timeout */				/* Error(cip, kDontPerror, "Could not directory listing data -- timed out.\n"); */				cip->errNo = kErrDataTimedOut;				return (cip->errNo);			} else if (result == 0) {				/* end of listing -- done */				cip->numListings++;				break;			} else if (result < 0) {				/* error */				/* Error(cip, kDoPerror, "Could not read directory listing data"); */				result = kErrLISTFailed;				cip->errNo = kErrLISTFailed;				break;			} else if (strstr(line, "ermission denied") != NULL) {				result = kErrLISTFailed;				cip->errNo = kErrLISTFailed;				break;			}			if (line[result - 1] == '\n') {				line[result - 1] = '\0';			}			cip->bytesTransferred += (long) result;			ftype = line[0];			if ((ftype == '-') || (ftype == 'd')) {				tok = line + strlen(line);				while (*--tok != ' ') {					if (tok < line)						goto skip;				}				fname[0] = (char) ftype;				fname[1] = (char) ' ';				fname[2] = '\0';				STRNCAT(fname, tok + 1);				AddLine(lines, fname);			}		}		DisposeSReadlineInfo(&lsSrl);		result = FTPEndDataCmd(cip, 1);		FTPStopIOTimer(cip);		if (result < 0) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -