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

📄 torture.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*    Unix SMB/CIFS implementation.   SMB torture tester   Copyright (C) Andrew Tridgell 1997-1998      This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2 of the License, or   (at your option) any later version.      This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.      You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include "includes.h"extern char *optarg;extern int optind;static fstring host, workgroup, share, password, username, myname;static int max_protocol = PROTOCOL_NT1;static const char *sockops="TCP_NODELAY";static int nprocs=1;static int port_to_use=0;int torture_numops=100;static int procnum; /* records process count number when forking */static struct cli_state *current_cli;static fstring randomfname;static BOOL use_oplocks;static BOOL use_level_II_oplocks;static const char *client_txt = "client_oplocks.txt";static BOOL use_kerberos;BOOL torture_showall = False;static double create_procs(BOOL (*fn)(int), BOOL *result);static struct timeval tp1,tp2;void start_timer(void){	GetTimeOfDay(&tp1);}double end_timer(void){	GetTimeOfDay(&tp2);	return((tp2.tv_sec - tp1.tv_sec) + 	       (tp2.tv_usec - tp1.tv_usec)*1.0e-6);}/* return a pointer to a anonymous shared memory segment of size "size"   which will persist across fork() but will disappear when all processes   exit    The memory is not zeroed    This function uses system5 shared memory. It takes advantage of a property   that the memory is not destroyed if it is attached when the id is removed   */void *shm_setup(int size){	int shmid;	void *ret;	shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);	if (shmid == -1) {		printf("can't get shared memory\n");		exit(1);	}	ret = (void *)shmat(shmid, 0, 0);	if (!ret || ret == (void *)-1) {		printf("can't attach to shared memory\n");		return NULL;	}	/* the following releases the ipc, but note that this process	   and all its children will still have access to the memory, its	   just that the shmid is no longer valid for other shm calls. This	   means we don't leave behind lots of shm segments after we exit 	   See Stevens "advanced programming in unix env" for details	   */	shmctl(shmid, IPC_RMID, 0);		return ret;}static BOOL open_nbt_connection(struct cli_state *c){	struct nmb_name called, calling;	struct in_addr ip;	ZERO_STRUCTP(c);	make_nmb_name(&calling, myname, 0x0);	make_nmb_name(&called , host, 0x20);        zero_ip(&ip);	if (!cli_initialise(c)) {		printf("Failed initialize cli_struct to connect with %s\n", host);		return False;	}	c->port = port_to_use;	if (!cli_connect(c, host, &ip)) {		printf("Failed to connect with %s\n", host);		return False;	}	c->use_kerberos = use_kerberos;	c->timeout = 120000; /* set a really long timeout (2 minutes) */	if (use_oplocks) c->use_oplocks = True;	if (use_level_II_oplocks) c->use_level_II_oplocks = True;	if (!cli_session_request(c, &calling, &called)) {		/*		 * Well, that failed, try *SMBSERVER ... 		 * However, we must reconnect as well ...		 */		if (!cli_connect(c, host, &ip)) {			printf("Failed to connect with %s\n", host);			return False;		}		make_nmb_name(&called, "*SMBSERVER", 0x20);		if (!cli_session_request(c, &calling, &called)) {			printf("%s rejected the session\n",host);			printf("We tried with a called name of %s & %s\n",				host, "*SMBSERVER");			cli_shutdown(c);			return False;		}	}	return True;}BOOL torture_open_connection(struct cli_state **c){	BOOL retry;	int flags = 0;	NTSTATUS status;	if (use_kerberos)		flags |= CLI_FULL_CONNECTION_USE_KERBEROS;		status = cli_full_connection(c, myname,				     host, NULL, port_to_use, 				     share, "?????", 				     username, workgroup, 				     password, flags, Undefined, &retry);	if (!NT_STATUS_IS_OK(status)) {		return False;	}	if (use_oplocks) (*c)->use_oplocks = True;	if (use_level_II_oplocks) (*c)->use_level_II_oplocks = True;	(*c)->timeout = 120000; /* set a really long timeout (2 minutes) */	return True;}BOOL torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid){	uint16 old_vuid = cli->vuid;	fstring old_user_name;	size_t passlen = strlen(password);	BOOL ret;	fstrcpy(old_user_name, cli->user_name);	cli->vuid = 0;	ret = cli_session_setup(cli, username, password, passlen, password, passlen, workgroup);	*new_vuid = cli->vuid;	cli->vuid = old_vuid;	fstrcpy(cli->user_name, old_user_name);	return ret;}BOOL torture_close_connection(struct cli_state *c){	BOOL ret = True;	if (!cli_tdis(c)) {		printf("tdis failed (%s)\n", cli_errstr(c));		ret = False;	}        cli_shutdown(c);	return ret;}/* check if the server produced the expected error code */static BOOL check_error(int line, struct cli_state *c, 			uint8 eclass, uint32 ecode, NTSTATUS nterr){        if (cli_is_dos_error(c)) {                uint8 cclass;                uint32 num;                /* Check DOS error */                cli_dos_error(c, &cclass, &num);                if (eclass != cclass || ecode != num) {                        printf("unexpected error code class=%d code=%d\n",                                (int)cclass, (int)num);                        printf(" expected %d/%d %s (line=%d)\n",                                (int)eclass, (int)ecode, nt_errstr(nterr), line);                        return False;                }        } else {                NTSTATUS status;                /* Check NT error */                status = cli_nt_error(c);                if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {                        printf("unexpected error code %s\n", nt_errstr(status));                        printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);                        return False;                }        }	return True;}static BOOL wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len){	while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {		if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;	}	return True;}static BOOL rw_torture(struct cli_state *c){	const char *lockfname = "\\torture.lck";	fstring fname;	int fnum;	int fnum2;	pid_t pid2, pid = getpid();	int i, j;	char buf[1024];	BOOL correct = True;	fnum2 = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL, 			 DENY_NONE);	if (fnum2 == -1)		fnum2 = cli_open(c, lockfname, O_RDWR, DENY_NONE);	if (fnum2 == -1) {		printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));		return False;	}	for (i=0;i<torture_numops;i++) {		unsigned n = (unsigned)sys_random()%10;		if (i % 10 == 0) {			printf("%d\r", i); fflush(stdout);		}		slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);		if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {			return False;		}		fnum = cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);		if (fnum == -1) {			printf("open failed (%s)\n", cli_errstr(c));			correct = False;			break;		}		if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {			printf("write failed (%s)\n", cli_errstr(c));			correct = False;		}		for (j=0;j<50;j++) {			if (cli_write(c, fnum, 0, (char *)buf, 				      sizeof(pid)+(j*sizeof(buf)), 				      sizeof(buf)) != sizeof(buf)) {				printf("write failed (%s)\n", cli_errstr(c));				correct = False;			}		}		pid2 = 0;		if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {			printf("read failed (%s)\n", cli_errstr(c));			correct = False;		}		if (pid2 != pid) {			printf("data corruption!\n");			correct = False;		}		if (!cli_close(c, fnum)) {			printf("close failed (%s)\n", cli_errstr(c));			correct = False;		}		if (!cli_unlink(c, fname)) {			printf("unlink failed (%s)\n", cli_errstr(c));			correct = False;		}		if (!cli_unlock(c, fnum2, n*sizeof(int), sizeof(int))) {			printf("unlock failed (%s)\n", cli_errstr(c));			correct = False;		}	}	cli_close(c, fnum2);	cli_unlink(c, lockfname);	printf("%d\n", i);	return correct;}static BOOL run_torture(int dummy){	struct cli_state *cli;        BOOL ret;	cli = current_cli;	cli_sockopt(cli, sockops);	ret = rw_torture(cli);		if (!torture_close_connection(cli)) {		ret = False;	}	return ret;}static BOOL rw_torture3(struct cli_state *c, char *lockfname){	int fnum = -1;	unsigned int i = 0;	char buf[131072];	char buf_rd[131072];	unsigned count;	unsigned countprev = 0;	ssize_t sent = 0;	BOOL correct = True;	srandom(1);	for (i = 0; i < sizeof(buf); i += sizeof(uint32))	{		SIVAL(buf, i, sys_random());	}	if (procnum == 0)	{		fnum = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL, 				 DENY_NONE);		if (fnum == -1) {			printf("first open read/write of %s failed (%s)\n",					lockfname, cli_errstr(c));			return False;		}	}	else	{		for (i = 0; i < 500 && fnum == -1; i++)		{			fnum = cli_open(c, lockfname, O_RDONLY, 					 DENY_NONE);			smb_msleep(10);		}		if (fnum == -1) {			printf("second open read-only of %s failed (%s)\n",					lockfname, cli_errstr(c));			return False;		}	}	i = 0;	for (count = 0; count < sizeof(buf); count += sent)	{		if (count >= countprev) {			printf("%d %8d\r", i, count);			fflush(stdout);			i++;			countprev += (sizeof(buf) / 20);		}		if (procnum == 0)		{			sent = ((unsigned)sys_random()%(20))+ 1;			if (sent > sizeof(buf) - count)			{				sent = sizeof(buf) - count;			}			if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {				printf("write failed (%s)\n", cli_errstr(c));				correct = False;			}		}		else		{			sent = cli_read(c, fnum, buf_rd+count, count,						  sizeof(buf)-count);			if (sent < 0)			{				printf("read failed offset:%d size:%ld (%s)\n",				       count, (unsigned long)sizeof(buf)-count,				       cli_errstr(c));				correct = False;				sent = 0;			}			if (sent > 0)			{				if (memcmp(buf_rd+count, buf+count, sent) != 0)				{					printf("read/write compare failed\n");					printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);					correct = False;					break;				}			}		}	}	if (!cli_close(c, fnum)) {		printf("close failed (%s)\n", cli_errstr(c));		correct = False;	}	return correct;}static BOOL rw_torture2(struct cli_state *c1, struct cli_state *c2){	const char *lockfname = "\\torture2.lck";	int fnum1;	int fnum2;	int i;	uchar buf[131072];	uchar buf_rd[131072];	BOOL correct = True;	ssize_t bytes_read;	if (!cli_unlink(c1, lockfname)) {		printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));	}	fnum1 = cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL, 			 DENY_NONE);	if (fnum1 == -1) {		printf("first open read/write of %s failed (%s)\n",				lockfname, cli_errstr(c1));		return False;	}	fnum2 = cli_open(c2, lockfname, O_RDONLY, 			 DENY_NONE);	if (fnum2 == -1) {		printf("second open read-only of %s failed (%s)\n",				lockfname, cli_errstr(c2));		cli_close(c1, fnum1);		return False;	}	for (i=0;i<torture_numops;i++)	{		size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;		if (i % 10 == 0) {			printf("%d\r", i); fflush(stdout);		}		generate_random_buffer(buf, buf_size);		if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {			printf("write failed (%s)\n", cli_errstr(c1));			correct = False;			break;		}		if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {			printf("read failed (%s)\n", cli_errstr(c2));			printf("read %d, expected %ld\n", bytes_read, 			       (unsigned long)buf_size); 			correct = False;			break;		}		if (memcmp(buf_rd, buf, buf_size) != 0)		{			printf("read/write compare failed\n");			correct = False;			break;		}	}	if (!cli_close(c2, fnum2)) {		printf("close failed (%s)\n", cli_errstr(c2));		correct = False;	}	if (!cli_close(c1, fnum1)) {		printf("close failed (%s)\n", cli_errstr(c1));		correct = False;	}	if (!cli_unlink(c1, lockfname)) {		printf("unlink failed (%s)\n", cli_errstr(c1));		correct = False;	}	return correct;}static BOOL run_readwritetest(int dummy){	static struct cli_state *cli1, *cli2;	BOOL test1, test2 = False;	if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {		return False;	}	cli_sockopt(cli1, sockops);	cli_sockopt(cli2, sockops);	printf("starting readwritetest\n");	test1 = rw_torture2(cli1, cli2);

⌨️ 快捷键说明

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