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

📄 smbctool.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	while (new_end > do_list_queue_size) {		do_list_queue_size *= 2;		DEBUG(4,("enlarging do_list_queue to %d\n",			 (int)do_list_queue_size));		dlq = SMB_REALLOC(do_list_queue, do_list_queue_size);		if (! dlq) {			d_printf("failure enlarging do_list_queue to %d bytes\n",				 (int)do_list_queue_size);			reset_do_list_queue();		} else {			do_list_queue = dlq;			memset(do_list_queue + do_list_queue_size / 2,				   0, do_list_queue_size / 2);		}	}	if (do_list_queue) {		safe_strcpy_base(do_list_queue + do_list_queue_end, 				 entry, do_list_queue, do_list_queue_size);		do_list_queue_end = new_end;		DEBUG(4,("added %s to do_list_queue (start=%d, end=%d)\n",			 entry, (int)do_list_queue_start, (int)do_list_queue_end));	}}static char *do_list_queue_head(void){	return do_list_queue + do_list_queue_start;}static void remove_do_list_queue_head(void){	if (do_list_queue_end > do_list_queue_start) {		do_list_queue_start += strlen(do_list_queue_head()) + 1;		adjust_do_list_queue();		DEBUG(4,("removed head of do_list_queue (start=%d, end=%d)\n",			 (int)do_list_queue_start, (int)do_list_queue_end));	}}static int do_list_queue_empty(void){	return (! (do_list_queue && *do_list_queue));}/**************************************************************************** A helper for tool_list.****************************************************************************/static void tool_list_helper(const char *mntpoint, struct stat *f, const char *mask, void *state){	/*if (f is a directory)	{		if (we want to do directories and we want to do this f)		{			execute the callback on f		}		if (recursion is set and f isn't . and it isn't ..)		{			make sure the name is valid			construct a full path out of the name			add the full path to the list		}		return;	}	if (we want to do this f)	{		execute the callback on f	}*/}/**************************************************************************** A cli_list-like function that executes fn on each directory entry. fn operates on the returned entry name and struct stat.****************************************************************************/int tool_list(	char *mask,				mode_t mode,				void (*fn)(char *, struct stat *),				BOOL rec,				BOOL dirs){	int dh;	pstring dentname;	pstring res;	struct stat stat;	struct smbc_dirent* dent;		pstrcpy(res, "smb:");	pstrcat(res, service);	pstrcat(res, cur_dir);		if ((dh = smbc_opendir(res)) < 1)	{		d_printf("Error: %s opening %s\n", strerror(errno), res);		return 1;	}		while (dent = smbc_readdir(dh))	{		switch(dent->smbc_type)		{		case SMBC_WORKGROUP:		case SMBC_SERVER:		case SMBC_FILE_SHARE:		case SMBC_PRINTER_SHARE:		case SMBC_COMMS_SHARE:		case SMBC_IPC_SHARE:			break;		case SMBC_DIR:			if (!dirs)				break;		case SMBC_FILE:			pstrcpy(dentname, res);			pstrcat(dentname, dent->name);			/*if (mask_match(dent->name, mask, False))*/			if (mask_match(dentname, mask, False))			{				if (smbc_stat(dentname, &stat) < 0)				{					d_printf("> %s - stat error: %s\n", dent->name, strerror(errno));				}				else				{					fn(dent->name, &stat);				}			}			break;		case SMBC_LINK:			break;		}	}	smbc_closedir(dh);}/**************************************************************************** A helper for do_list.****************************************************************************/static void do_list_helper(const char *mntpoint, file_info *f, const char *mask, void *state){	if (f->mode & aDIR) {		if (do_list_dirs && do_this_one(f)) {			do_list_fn(f);		}		if (do_list_recurse && 			!strequal(f->name,".") && 			!strequal(f->name,"..")) {			pstring mask2;			char *p;			if (!f->name[0]) {				d_printf("Empty dir name returned. Possible server misconfiguration.\n");				return;			}			pstrcpy(mask2, mntpoint);			pstrcat(mask2, mask);			p = strrchr_m(mask2,'/');			if (!p)				return;			p[1] = 0;			pstrcat(mask2, f->name);			pstrcat(mask2,"/*");			add_to_do_list_queue(mask2);		}		return;	}	if (do_this_one(f)) {		do_list_fn(f);	}}/**************************************************************************** A wrapper around cli_list that adds recursion.****************************************************************************/void do_list(const char *mask,uint16 attribute,void (*fn)(file_info *),BOOL rec, BOOL dirs){	static int in_do_list = 0;	struct cli_state *targetcli;	pstring targetpath;	if (in_do_list && rec) {		fprintf(stderr, "INTERNAL ERROR: do_list called recursively when the recursive flag is true\n");		exit(1);	}	in_do_list = 1;	do_list_recurse = rec;	do_list_dirs = dirs;	do_list_fn = fn;	if (rec) {		init_do_list_queue();		add_to_do_list_queue(mask);				while (! do_list_queue_empty()) {			/*			 * Need to copy head so that it doesn't become			 * invalid inside the call to cli_list.	 This			 * would happen if the list were expanded			 * during the call.			 * Fix from E. Jay Berkenbilt (ejb@ql.org)			 */			pstring head;			pstrcpy(head, do_list_queue_head());						/* check for dfs */						if ( !cli_resolve_path( "", cli, head, &targetcli, targetpath ) ) {				d_printf("do_list: [%s] %s\n", head, cli_errstr(cli));				remove_do_list_queue_head();				continue;			}						cli_list(targetcli, targetpath, attribute, do_list_helper, NULL);			remove_do_list_queue_head();			if ((! do_list_queue_empty()) && (fn == display_finfo)) {				char* next_file = do_list_queue_head();				char* save_ch = 0;				if ((strlen(next_file) >= 2) &&					(next_file[strlen(next_file) - 1] == '*') &&					(next_file[strlen(next_file) - 2] == '/')) {					save_ch = next_file +						strlen(next_file) - 2;					*save_ch = '\0';				}				d_printf("\n%s\n",next_file);				if (save_ch) {					*save_ch = '/';				}			}		}	} else {		/* check for dfs */					if ( cli_resolve_path( "", cli, mask, &targetcli, targetpath ) ) {			if (cli_list(targetcli, targetpath, attribute, do_list_helper, NULL) == -1) 				d_printf("%s listing %s\n", cli_errstr(targetcli), targetpath);		}		else			d_printf("do_list: [%s] %s\n", mask, cli_errstr(cli));			}	in_do_list = 0;	reset_do_list_queue();}/**************************************************************************** Get a directory listing.****************************************************************************/static int cmd_dir(void){	mode_t mode = S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO;	pstring mask;	pstring buf;	char *p=buf;		pstrcpy(mask, "smb:");	pstrcat(mask, service);	pstrcat(mask, cur_dir);		if (next_token_nr(NULL,buf,NULL,sizeof(buf)))		pstrcat(mask,buf);	else		pstrcat(mask,"*");		tool_list(mask, mode, display_stat, recurse, True);	return 0;}/**************************************************************************** Get a directory listing.****************************************************************************/static int cmd_du(void){	uint16 attribute = aDIR | aSYSTEM | aHIDDEN;	pstring mask;	pstring buf;	char *p=buf;	int rc;		dir_total = 0;	pstrcpy(mask,cur_dir);	if(mask[strlen(mask)-1]!='/')		pstrcat(mask,"/");		if (next_token_nr(NULL,buf,NULL,sizeof(buf))) {		dos_format(p);		if (*p == '/')			pstrcpy(mask,p);		else			pstrcat(mask,p);	} else {		pstrcat(mask,"*");	}	do_list(mask, attribute, do_du, recurse, True);	rc = do_dskattr();	d_printf("Total number of bytes: %.0f\n", dir_total);	return rc;}/**************************************************************************** Get a file from rname to lname****************************************************************************/static int do_get(char *rname, char *lname, BOOL reget){  	int handle = 0, fnum;	BOOL newhandle = False;	char *data;	struct timeval tp_start;	int read_size = io_bufsize;	/*uint16 attr;*/	struct stat stat;	off_t start = 0;	off_t nread = 0;	int rc = 0;	if (lowercase) {		strlower_m(lname);	}	GetTimeOfDay(&tp_start);		fnum = smbc_open(rname, O_RDONLY, 0666);	if (fnum < 0)	{		d_printf("%s opening remote file %s\n", strerror(errno), rname);		return 1;	}	if(!strcmp(lname,"-")) {		handle = fileno(stdout);	} else {		if (reget) {			handle = sys_open(lname, O_WRONLY|O_CREAT, 0644);			if (handle >= 0) {				start = sys_lseek(handle, 0, SEEK_END);				if (start == -1) {					smbc_close(fnum);					d_printf("Error seeking local file\n");					return 1;				}			}		} else {			handle = sys_open(lname, O_WRONLY|O_CREAT|O_TRUNC, 0644);		}		newhandle = True;	}	if (handle < 0) {		d_printf("Error opening local file %s\n",lname);		smbc_close(fnum);		return 1;	}	if (smbc_fstat(fnum, &stat) < 0)	{		d_printf("%s trying to stat remote file %s\n", strerror(errno), rname);		if (newhandle)			close(handle);		smbc_close(fnum);		return 1;	}	DEBUG(1,("getting file %s of size %.0f as %s ", 		 rname, (double)stat.st_size, lname));	if(!(data = (char *)SMB_MALLOC(read_size))) { 		d_printf("malloc fail for size %d\n", read_size);		if (newhandle)			close(handle);		smbc_close(fnum);		return 1;	}	if (smbc_lseek(fnum, start, SEEK_SET) < 0)	{		d_printf("%s trying to lseek remote file %s\n", strerror(errno), rname);		if (newhandle)			close(handle);		smbc_close(fnum);		SAFE_FREE(data);		return 1;	}	while (1) {		int n = smbc_read(fnum, data, read_size);		if (n < 0)		{			d_printf("%s while reading remote file %s\n", strerror(errno), rname);			if (newhandle)				close(handle);			smbc_close(fnum);			SAFE_FREE(data);			return 1;		}		if (n == 0)			break; 		if (writefile(handle,data, n) != n) {			d_printf("Error writing local file\n");			rc = 1;			break;		}	  		nread += n;	}	if (nread + start < stat.st_size) {		DEBUG (1, ("Short read when getting file %s. Only got %ld bytes.\n", rname, (long)nread));		rc = 1;	}	SAFE_FREE(data);		if (smbc_close(fnum) < 0)	{		d_printf("%s closing remote file %s\n", strerror(errno), rname);		rc = 1;	}	if (newhandle) {		close(handle);	}	/*if (archive_level >= 2 && (attr & aARCH)) {		cli_setatr(cli, rname, attr & ~(uint16)aARCH, 0);	}*/	{		struct timeval tp_end;		int this_time;				GetTimeOfDay(&tp_end);		this_time = 			(tp_end.tv_sec - tp_start.tv_sec)*1000 +			(tp_end.tv_usec - tp_start.tv_usec)/1000;		get_total_time_ms += this_time;		get_total_size += nread;				DEBUG(1,("(%3.1f kb/s) (average %3.1f kb/s)\n",			 nread / (1.024*this_time + 1.0e-4),			 get_total_size / (1.024*get_total_time_ms)));	}		return rc;}/**************************************************************************** Get a file.****************************************************************************/static int cmd_get(void){	pstring lname;	pstring rname;	char *p;	pstrcpy(rname, "smb:");	pstrcat(rname, service);	pstrcat(rname, cur_dir);		p = rname + strlen(rname);		if (!next_token_nr(NULL,p,NULL,sizeof(rname)-strlen(rname))) {		d_printf("get <filename>\n");		return 1;	}	pstrcpy(lname,p);		next_token_nr(NULL,lname,NULL,sizeof(lname));	/*d_printf("lname: %s, rname: %s\n", lname, rname);*/	return do_get(rname, lname, False);}/**************************************************************************** Do an mget operation on one file.****************************************************************************/static void do_mget(char *name, struct stat *st){	pstring rname;	pstring quest;	pstring saved_curdir;	pstring mget_mask;	mode_t mode;	if (strequal(name,".") || strequal(name,".."))		return;	if (S_ISDIR(st->st_mode))		slprintf(quest,sizeof(pstring)-1, "Get directory %s%s? ", cur_dir, name);	else		slprintf(quest,sizeof(pstring)-1, "Get file %s%s? ", cur_dir, name);	if (prompt && !yesno(quest))		return;	if (!S_ISDIR(st->st_mode)) {		pstrcpy(rname,"smb:");		pstrcat(rname,service);		pstrcat(rname,cur_dir);		pstrcat(rname,name);		do_get(rname,name, False);		return;	}	/* handle directories */	/* TODO: clean this code up for recursive calls */	pstrcpy(saved_curdir,cur_dir);	pstrcat(cur_dir,name);	pstrcat(cur_dir,"/");	unix_format(name);	if (lowercase)		strlower_m(name);		if (!directory_exist(name,NULL) && 		mkdir(name,0777) != 0) {		d_printf("failed to create directory %s\n",name);		pstrcpy(cur_dir,saved_curdir);		return;	}		if (chdir(name) != 0) {		d_printf("failed to chdir to directory %s\n",name);		pstrcpy(cur_dir,saved_curdir);		return;	}	pstrcpy(mget_mask,"smb:");	pstrcat(mget_mask,service);	pstrcat(mget_mask,cur_dir);	pstrcat(mget_mask,"*");		/*d_printf("Calling with mask: %s\n", mget_mask);*/	tool_list(mget_mask, mode, do_mget, recurse, recurse);

⌨️ 快捷键说明

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