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

📄 client.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 5 页
字号:
/*    Unix SMB/CIFS implementation.   SMB client   Copyright (C) Andrew Tridgell 1994-1998   Copyright (C) Simo Sorce 2001-2002   Copyright (C) Jelmer Vernooij 2003-2004   Copyright (C) James J Myers   2003 <myersjj@samba.org>      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 3 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, see <http://www.gnu.org/licenses/>.*//*  * TODO: remove this ... and don't use talloc_append_string() * * NOTE: I'm not changing the code yet, because I assume there're *       some bugs in the existing code and I'm not sure how to fix *	 them correctly. */#define TALLOC_DEPRECATED 1#include "includes.h"#include "version.h"#include "libcli/libcli.h"#include "lib/events/events.h"#include "lib/cmdline/popt_common.h"#include "librpc/gen_ndr/ndr_srvsvc_c.h"#include "librpc/gen_ndr/ndr_lsa.h"#include "librpc/gen_ndr/ndr_security.h"#include "libcli/raw/libcliraw.h"#include "libcli/util/clilsa.h"#include "system/dir.h"#include "system/filesys.h"#include "lib/util/dlinklist.h"#include "system/readline.h"#include "auth/credentials/credentials.h"#include "auth/gensec/gensec.h"#include "system/time.h" /* needed by some systems for asctime() */#include "libcli/resolve/resolve.h"#include "libcli/security/security.h"#include "lib/smbreadline/smbreadline.h"#include "librpc/gen_ndr/ndr_nbt.h"#include "param/param.h"#include "librpc/rpc/dcerpc.h"struct smbclient_context {	char *remote_cur_dir;	struct smbcli_state *cli;	char *fileselection;	time_t newer_than;	bool prompt;	bool recurse;	int archive_level;	bool lowercase;	int printmode;	bool translation;	int io_bufsize;};/* timing globals */static uint64_t get_total_size = 0;static uint_t get_total_time_ms = 0;static uint64_t put_total_size = 0;static uint_t put_total_time_ms = 0;/* Unfortunately, there is no way to pass the a context to the completion function as an argument */static struct smbclient_context *rl_ctx; /* totals globals */static double dir_total;/******************************************************************* Reduce a file name, removing .. elements.********************************************************************/static void dos_clean_name(char *s){	char *p=NULL,*r;	DEBUG(3,("dos_clean_name [%s]\n",s));	/* remove any double slashes */	all_string_sub(s, "\\\\", "\\", 0);	while ((p = strstr(s,"\\..\\")) != NULL) {		*p = '\0';		if ((r = strrchr(s,'\\')) != NULL)			memmove(r,p+3,strlen(p+3)+1);	}	trim_string(s,NULL,"\\..");	all_string_sub(s, "\\.\\", "\\", 0);}/****************************************************************************write to a local file with CR/LF->LF translation if appropriate. return the number taken from the buffer. This may not equal the number written.****************************************************************************/static int writefile(int f, const void *_b, int n, bool translation){	const uint8_t *b = (const uint8_t *)_b;	int i;	if (!translation) {		return write(f,b,n);	}	i = 0;	while (i < n) {		if (*b == '\r' && (i<(n-1)) && *(b+1) == '\n') {			b++;i++;		}		if (write(f, b, 1) != 1) {			break;		}		b++;		i++;	}  	return(i);}/****************************************************************************  read from a file with LF->CR/LF translation if appropriate. return the   number read. read approx n bytes.****************************************************************************/static int readfile(void *_b, int n, XFILE *f, bool translation){	uint8_t *b = (uint8_t *)_b;	int i;	int c;	if (!translation)		return x_fread(b,1,n,f);  	i = 0;	while (i < (n - 1)) {		if ((c = x_getc(f)) == EOF) {			break;		}      		if (c == '\n') { /* change all LFs to CR/LF */			b[i++] = '\r';		}      		b[i++] = c;	}  	return(i);} /****************************************************************************send a message****************************************************************************/static void send_message(struct smbcli_state *cli, const char *desthost){	char msg[1600];	int total_len = 0;	int grp_id;	if (!smbcli_message_start(cli->tree, desthost, cli_credentials_get_username(cmdline_credentials), &grp_id)) {		d_printf("message start: %s\n", smbcli_errstr(cli->tree));		return;	}	d_printf("Connected. Type your message, ending it with a Control-D\n");	while (!feof(stdin) && total_len < 1600) {		int maxlen = MIN(1600 - total_len,127);		int l=0;		int c;		for (l=0;l<maxlen && (c=fgetc(stdin))!=EOF;l++) {			if (c == '\n')				msg[l++] = '\r';			msg[l] = c;   		}		if (!smbcli_message_text(cli->tree, msg, l, grp_id)) {			d_printf("SMBsendtxt failed (%s)\n",smbcli_errstr(cli->tree));			return;		}      				total_len += l;	}	if (total_len >= 1600)		d_printf("the message was truncated to 1600 bytes\n");	else		d_printf("sent %d bytes\n",total_len);	if (!smbcli_message_end(cli->tree, grp_id)) {		d_printf("SMBsendend failed (%s)\n",smbcli_errstr(cli->tree));		return;	}      }/****************************************************************************check the space on a device****************************************************************************/static int do_dskattr(struct smbclient_context *ctx){	uint32_t bsize;	uint64_t total, avail;	if (NT_STATUS_IS_ERR(smbcli_dskattr(ctx->cli->tree, &bsize, &total, &avail))) {		d_printf("Error in dskattr: %s\n",smbcli_errstr(ctx->cli->tree)); 		return 1;	}	d_printf("\n\t\t%llu blocks of size %u. %llu blocks available\n",		 (unsigned long long)total, 		 (unsigned)bsize, 		 (unsigned long long)avail);	return 0;}/****************************************************************************show cd/pwd****************************************************************************/static int cmd_pwd(struct smbclient_context *ctx, const char **args){	d_printf("Current directory is %s\n", ctx->remote_cur_dir);	return 0;}/*  convert a string to dos format*/static void dos_format(char *s){	string_replace(s, '/', '\\');}/****************************************************************************change directory - inner section****************************************************************************/static int do_cd(struct smbclient_context *ctx, const char *newdir){	char *dname;      	/* Save the current directory in case the	   new directory is invalid */	if (newdir[0] == '\\')		dname = talloc_strdup(NULL, newdir);	else		dname = talloc_asprintf(NULL, "%s\\%s", ctx->remote_cur_dir, newdir);	dos_format(dname);	if (*(dname+strlen(dname)-1) != '\\') {		dname = talloc_append_string(NULL, dname, "\\");	}	dos_clean_name(dname);		if (NT_STATUS_IS_ERR(smbcli_chkpath(ctx->cli->tree, dname))) {		d_printf("cd %s: %s\n", dname, smbcli_errstr(ctx->cli->tree));		talloc_free(dname);	} else {		ctx->remote_cur_dir = dname;	}		return 0;}/****************************************************************************change directory****************************************************************************/static int cmd_cd(struct smbclient_context *ctx, const char **args){	int rc = 0;	if (args[1]) 		rc = do_cd(ctx, args[1]);	else		d_printf("Current directory is %s\n",ctx->remote_cur_dir);	return rc;}static bool mask_match(struct smbcli_state *c, const char *string, 		const char *pattern, bool is_case_sensitive){	char *p2, *s2;	bool ret;	if (ISDOTDOT(string))		string = ".";	if (ISDOT(pattern))		return false;		if (is_case_sensitive)		return ms_fnmatch(pattern, string, 				  c->transport->negotiate.protocol) == 0;	p2 = strlower_talloc(NULL, pattern);	s2 = strlower_talloc(NULL, string);	ret = ms_fnmatch(p2, s2, c->transport->negotiate.protocol) == 0;	talloc_free(p2);	talloc_free(s2);	return ret;}/*******************************************************************  decide if a file should be operated on  ********************************************************************/static bool do_this_one(struct smbclient_context *ctx, struct clilist_file_info *finfo){	if (finfo->attrib & FILE_ATTRIBUTE_DIRECTORY) return(true);	if (ctx->fileselection && 	    !mask_match(ctx->cli, finfo->name,ctx->fileselection,false)) {		DEBUG(3,("mask_match %s failed\n", finfo->name));		return false;	}	if (ctx->newer_than && finfo->mtime < ctx->newer_than) {		DEBUG(3,("newer_than %s failed\n", finfo->name));		return(false);	}	if ((ctx->archive_level==1 || ctx->archive_level==2) && !(finfo->attrib & FILE_ATTRIBUTE_ARCHIVE)) {		DEBUG(3,("archive %s failed\n", finfo->name));		return(false);	}		return(true);}/****************************************************************************  display info about a file  ****************************************************************************/static void display_finfo(struct smbclient_context *ctx, struct clilist_file_info *finfo){	if (do_this_one(ctx, finfo)) {		time_t t = finfo->mtime; /* the time is assumed to be passed as GMT */		char *astr = attrib_string(NULL, finfo->attrib);		d_printf("  %-30s%7.7s %8.0f  %s",			 finfo->name,			 astr,			 (double)finfo->size,			 asctime(localtime(&t)));		dir_total += finfo->size;		talloc_free(astr);	}}/****************************************************************************   accumulate size of a file  ****************************************************************************/static void do_du(struct smbclient_context *ctx, struct clilist_file_info *finfo){	if (do_this_one(ctx, finfo)) {		dir_total += finfo->size;	}}static bool do_list_recurse;static bool do_list_dirs;static char *do_list_queue = 0;static long do_list_queue_size = 0;static long do_list_queue_start = 0;static long do_list_queue_end = 0;static void (*do_list_fn)(struct smbclient_context *, struct clilist_file_info *);/****************************************************************************functions for do_list_queue  ****************************************************************************//* * The do_list_queue is a NUL-separated list of strings stored in a * char*.  Since this is a FIFO, we keep track of the beginning and * ending locations of the data in the queue.  When we overflow, we * double the size of the char*.  When the start of the data passes * the midpoint, we move everything back.  This is logically more * complex than a linked list, but easier from a memory management * angle.  In any memory error condition, do_list_queue is reset. * Functions check to ensure that do_list_queue is non-NULL before * accessing it. */static void reset_do_list_queue(void){	SAFE_FREE(do_list_queue);	do_list_queue_size = 0;	do_list_queue_start = 0;	do_list_queue_end = 0;}static void init_do_list_queue(void){	reset_do_list_queue();	do_list_queue_size = 1024;	do_list_queue = malloc_array_p(char, do_list_queue_size);	if (do_list_queue == 0) { 		d_printf("malloc fail for size %d\n",			 (int)do_list_queue_size);		reset_do_list_queue();	} else {		memset(do_list_queue, 0, do_list_queue_size);	}}static void adjust_do_list_queue(void){	if (do_list_queue == NULL) return;	/*	 * If the starting point of the queue is more than half way through,	 * move everything toward the beginning.	 */	if (do_list_queue_start == do_list_queue_end)	{		DEBUG(4,("do_list_queue is empty\n"));		do_list_queue_start = do_list_queue_end = 0;		*do_list_queue = '\0';	}	else if (do_list_queue_start > (do_list_queue_size / 2))	{		DEBUG(4,("sliding do_list_queue backward\n"));		memmove(do_list_queue,			do_list_queue + do_list_queue_start,			do_list_queue_end - do_list_queue_start);		do_list_queue_end -= do_list_queue_start;		do_list_queue_start = 0;	}	   }static void add_to_do_list_queue(const char* entry){	char *dlq;	long new_end = do_list_queue_end + ((long)strlen(entry)) + 1;	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 = realloc_p(do_list_queue, char, 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(do_list_queue + do_list_queue_end, entry, 			    do_list_queue_size - do_list_queue_end - 1);		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));

⌨️ 快捷键说明

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