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

📄 client.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 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   Copyright (C) Gerald (Jerry) Carter    2004      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"#include "client/client_proto.h"#ifndef REGISTER#define REGISTER 0#endifextern BOOL AllowDebugChange;extern BOOL override_logfile;extern char tar_type;extern BOOL in_client;static int port = 0;pstring cur_dir = "\\";static pstring cd_path = "";static pstring service;static pstring desthost;static pstring username;static pstring calling_name;static BOOL grepable=False;static char *cmdstr = NULL;static int io_bufsize = 64512;static int name_type = 0x20;extern int max_protocol;static int process_tok(pstring tok);static int cmd_help(void);/* 30 second timeout on most commands */#define CLIENT_TIMEOUT (30*1000)#define SHORT_TIMEOUT (5*1000)/* value for unused fid field in trans2 secondary request */#define FID_UNUSED (0xFFFF)time_t newer_than = 0;static int archive_level = 0;static BOOL translation = False;static BOOL have_ip;/* clitar bits insert */extern int blocksize;extern BOOL tar_inc;extern BOOL tar_reset;/* clitar bits end */ static BOOL prompt = True;static BOOL recurse = False;BOOL lowercase = False;static struct in_addr dest_ip;#define SEPARATORS " \t\n\r"static BOOL abort_mget = True;static pstring fileselection = "";extern file_info def_finfo;/* timing globals */SMB_BIG_UINT get_total_size = 0;unsigned int get_total_time_ms = 0;static SMB_BIG_UINT put_total_size = 0;static unsigned int put_total_time_ms = 0;/* totals globals */static double dir_total;/* root cli_state connection */struct cli_state *cli;/**************************************************************************** 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, char *b, int n){	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(char *b, int n, XFILE *f){	int i;	int c;	if (!translation)		return x_fread(b,1,n,f);  	i = 0;	while (i < (n - 1) && (i < BUFFER_SIZE)) {		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(void){	int total_len = 0;	int grp_id;	if (!cli_message_start(cli, desthost, username, &grp_id)) {		d_printf("message start: %s\n", cli_errstr(cli));		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);		pstring msg;		int l=0;		int c;		ZERO_ARRAY(msg);		for (l=0;l<maxlen && (c=fgetc(stdin))!=EOF;l++) {			if (c == '\n')				msg[l++] = '\r';			msg[l] = c;   		}		if (!cli_message_text(cli, msg, l, grp_id)) {			d_printf("SMBsendtxt failed (%s)\n",cli_errstr(cli));			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 (!cli_message_end(cli, grp_id)) {		d_printf("SMBsendend failed (%s)\n",cli_errstr(cli));		return;	}      }/**************************************************************************** Check the space on a device.****************************************************************************/static int do_dskattr(void){	int total, bsize, avail;	struct cli_state *targetcli;	pstring targetpath;	if ( !cli_resolve_path( "", cli, cur_dir, &targetcli, targetpath ) ) {		d_printf("Error in dskattr: %s\n", cli_errstr(cli));		return 1;	}	if (!cli_dskattr(targetcli, &bsize, &total, &avail)) {		d_printf("Error in dskattr: %s\n",cli_errstr(targetcli)); 		return 1;	}	d_printf("\n\t\t%d blocks of size %d. %d blocks available\n",		 total, bsize, avail);	return 0;}/**************************************************************************** Show cd/pwd.****************************************************************************/static int cmd_pwd(void){	d_printf("Current directory is %s",service);	d_printf("%s\n",cur_dir);	return 0;}/**************************************************************************** Change directory - inner section.****************************************************************************/static int do_cd(char *newdir){	char *p = newdir;	pstring saved_dir;	pstring dname;	pstring targetpath;	struct cli_state *targetcli;	SMB_STRUCT_STAT sbuf;	uint32 attributes;	int ret = 1;      	dos_format(newdir);	/* Save the current directory in case the new directory is invalid */	pstrcpy(saved_dir, cur_dir);	if (*p == '\\')		pstrcpy(cur_dir,p);	else		pstrcat(cur_dir,p);	if (*(cur_dir+strlen(cur_dir)-1) != '\\') {		pstrcat(cur_dir, "\\");	}		dos_clean_name(cur_dir);	pstrcpy( dname, cur_dir );	pstrcat(cur_dir,"\\");	dos_clean_name(cur_dir);		if ( !cli_resolve_path( "", cli, dname, &targetcli, targetpath ) ) {		d_printf("cd %s: %s\n", dname, cli_errstr(cli));		pstrcpy(cur_dir,saved_dir);		goto out;	}		if ( strequal(targetpath,"\\" ) )		return 0;   			/* Use a trans2_qpathinfo to test directories for modern servers.	   Except Win9x doesn't support the qpathinfo_basic() call..... */ 		if ( targetcli->protocol >  PROTOCOL_LANMAN2 && !targetcli->win95 ) {		if ( !cli_qpathinfo_basic( targetcli, targetpath, &sbuf, &attributes ) ) {			d_printf("cd %s: %s\n", dname, cli_errstr(targetcli));			pstrcpy(cur_dir,saved_dir);			goto out;		}				if ( !(attributes&FILE_ATTRIBUTE_DIRECTORY) ) {			d_printf("cd %s: not a directory\n", dname);			pstrcpy(cur_dir,saved_dir);			goto out;		}			} else {		pstrcat( targetpath, "\\" );		dos_clean_name( targetpath );				if ( !cli_chkpath(targetcli, targetpath) ) {			d_printf("cd %s: %s\n", dname, cli_errstr(targetcli));			pstrcpy(cur_dir,saved_dir);			goto out;		}	}	ret = 0;out:		pstrcpy(cd_path,cur_dir);	return ret;}/**************************************************************************** Change directory.****************************************************************************/static int cmd_cd(void){	pstring buf;	int rc = 0;			if (next_token_nr(NULL,buf,NULL,sizeof(buf)))		rc = do_cd(buf);	else		d_printf("Current directory is %s\n",cur_dir);	return rc;}/******************************************************************* Decide if a file should be operated on.********************************************************************/static BOOL do_this_one(file_info *finfo){	if (finfo->mode & aDIR)		return(True);	if (*fileselection && 	    !mask_match(finfo->name,fileselection,False)) {		DEBUG(3,("mask_match %s failed\n", finfo->name));		return False;	}	if (newer_than && finfo->mtime < newer_than) {		DEBUG(3,("newer_than %s failed\n", finfo->name));		return(False);	}	if ((archive_level==1 || archive_level==2) && !(finfo->mode & aARCH)) {		DEBUG(3,("archive %s failed\n", finfo->name));		return(False);	}		return(True);}/**************************************************************************** Display info about a file.****************************************************************************/static void display_finfo(file_info *finfo){	if (do_this_one(finfo)) {		time_t t = finfo->mtime; /* the time is assumed to be passed as GMT */		d_printf("  %-30s%7.7s %8.0f  %s",			 finfo->name,			 attrib_string(finfo->mode),			 (double)finfo->size,			 asctime(localtime(&t)));		dir_total += finfo->size;	}}/**************************************************************************** Accumulate size of a file.****************************************************************************/static void do_du(file_info *finfo){	if (do_this_one(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)(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 = SMB_MALLOC(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 the starting point of the queue is more than half way through,	 * move everything toward the beginning.	 */	if (do_list_queue && (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 = 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 do_list.****************************************************************************/static void do_list_helper(const char *mntpoint, file_info *f, const char *mask, void *state){	char *dir_end;	/* save the directory */	pstrcpy( f->dir, mask );	if ( (dir_end = strrchr( f->dir, '\\' )) != NULL ) {		*dir_end = '\0';	}	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,'\\');

⌨️ 快捷键说明

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