📄 util.c
字号:
/* Unix SMB/Netbios implementation. Version 1.9. Samba utility functions Copyright (C) Andrew Tridgell 1992-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"#if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))#ifdef WITH_NISPLUS_HOME#ifdef BROKEN_NISPLUS_INCLUDE_FILES/* * The following lines are needed due to buggy include files * in Solaris 2.6 which define GROUP in both /usr/include/sys/acl.h and * also in /usr/include/rpcsvc/nis.h. The definitions conflict. JRA. * Also GROUP_OBJ is defined as 0x4 in /usr/include/sys/acl.h and as * an enum in /usr/include/rpcsvc/nis.h. */#if defined(GROUP)#undef GROUP#endif#if defined(GROUP_OBJ)#undef GROUP_OBJ#endif#endif /* BROKEN_NISPLUS_INCLUDE_FILES */#include <rpcsvc/nis.h>#else /* !WITH_NISPLUS_HOME */#include "rpcsvc/ypclnt.h"#endif /* WITH_NISPLUS_HOME */#endif /* HAVE_NETGROUP && WITH_AUTOMOUNT */#ifdef WITH_SSL#include <ssl.h>#undef Realloc /* SSLeay defines this and samba has a function of this name */extern SSL *ssl;extern int sslFd;#endif /* WITH_SSL */extern int DEBUGLEVEL;int Protocol = PROTOCOL_COREPLUS;/* a default finfo structure to ensure all fields are sensible */file_info def_finfo = {-1,0,0,0,0,0,0,""};/* the client file descriptor */extern int Client;/* this is used by the chaining code */int chain_size = 0;int trans_num = 0;/* case handling on filenames */int case_default = CASE_LOWER;/* the following control case operations - they are put here so the client can link easily */BOOL case_sensitive;BOOL case_preserve;BOOL use_mangled_map = False;BOOL short_case_preserve;BOOL case_mangle;fstring remote_machine="";fstring local_machine="";fstring remote_arch="UNKNOWN";static enum remote_arch_types ra_type = RA_UNKNOWN;fstring remote_proto="UNKNOWN";pstring myhostname="";pstring user_socket_options=""; pstring sesssetup_user="";pstring samlogon_user="";BOOL sam_logon_in_ssb = False;pstring global_myname = "";fstring global_myworkgroup = "";char **my_netbios_names;static char *filename_dos(char *path,char *buf);/**************************************************************************** find a suitable temporary directory. The result should be copied immediately as it may be overwritten by a subsequent call ****************************************************************************/char *tmpdir(void){ char *p; if ((p = getenv("TMPDIR"))) { return p; } return "/tmp";}/****************************************************************************determine whether we are in the specified group****************************************************************************/BOOL in_group(gid_t group, gid_t current_gid, int ngroups, gid_t *groups){ int i; if (group == current_gid) return(True); for (i=0;i<ngroups;i++) if (group == groups[i]) return(True); return(False);}/****************************************************************************like atoi but gets the value up to the separater character****************************************************************************/char *Atoic(char *p, int *n, char *c){ if (!isdigit((int)*p)) { DEBUG(5, ("Atoic: malformed number\n")); return NULL; } (*n) = atoi(p); while ((*p) && isdigit((int)*p)) { p++; } if (strchr(c, *p) == NULL) { DEBUG(5, ("Atoic: no separator characters (%s) not found\n", c)); return NULL; } return p;}/************************************************************************* reads a list of numbers *************************************************************************/char *get_numlist(char *p, uint32 **num, int *count){ int val; if (num == NULL || count == NULL) { return NULL; } (*count) = 0; (*num ) = NULL; while ((p = Atoic(p, &val, ":,")) != NULL && (*p) != ':') { (*num) = Realloc((*num), ((*count)+1) * sizeof(uint32)); if ((*num) == NULL) { return NULL; } (*num)[(*count)] = val; (*count)++; p++; } return p;}/*******************************************************************copy an IP address from one buffer to another********************************************************************/void putip(void *dest,void *src){ memcpy(dest,src,4);}#define TRUNCATE_NETBIOS_NAME 1/******************************************************************* convert, possibly using a stupid microsoft-ism which has destroyed the transport independence of netbios (for CIFS vendors that usually use the Win95-type methods, not for NT to NT communication, which uses DCE/RPC and therefore full-length unicode strings...) a dns name into a netbios name. the netbios name (NOT necessarily null-terminated) is truncated to 15 characters. ******************************************************************/char *dns_to_netbios_name(char *dns_name){ static char netbios_name[16]; int i; StrnCpy(netbios_name, dns_name, 15); netbios_name[15] = 0; #ifdef TRUNCATE_NETBIOS_NAME /* ok. this is because of a stupid microsoft-ism. if the called host name contains a '.', microsoft clients expect you to truncate the netbios name up to and including the '.' this even applies, by mistake, to workgroup (domain) names, which is _really_ daft. */ for (i = 15; i >= 0; i--) { if (netbios_name[i] == '.') { netbios_name[i] = 0; break; } }#endif /* TRUNCATE_NETBIOS_NAME */ return netbios_name;}/****************************************************************************interpret the weird netbios "name". Return the name type****************************************************************************/static int name_interpret(char *in,char *out){ int ret; int len = (*in++) / 2; *out=0; if (len > 30 || len<1) return(0); while (len--) { if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') { *out = 0; return(0); } *out = ((in[0]-'A')<<4) + (in[1]-'A'); in += 2; out++; } *out = 0; ret = out[-1];#ifdef NETBIOS_SCOPE /* Handle any scope names */ while(*in) { *out++ = '.'; /* Scope names are separated by periods */ len = *(unsigned char *)in++; StrnCpy(out, in, len); out += len; *out=0; in += len; }#endif return(ret);}/****************************************************************************mangle a name into netbios format Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.****************************************************************************/int name_mangle( char *In, char *Out, char name_type ) { int i; int c; int len; char buf[20]; char *p = Out; extern pstring global_scope; /* Safely copy the input string, In, into buf[]. */ (void)memset( buf, 0, 20 ); if (strcmp(In,"*") == 0) buf[0] = '*'; else (void)slprintf( buf, sizeof(buf) - 1, "%-15.15s%c", In, name_type ); /* Place the length of the first field into the output buffer. */ p[0] = 32; p++; /* Now convert the name to the rfc1001/1002 format. */ for( i = 0; i < 16; i++ ) { c = toupper( buf[i] ); p[i*2] = ( (c >> 4) & 0x000F ) + 'A'; p[(i*2)+1] = (c & 0x000F) + 'A'; } p += 32; p[0] = '\0'; /* Add the scope string. */ for( i = 0, len = 0; NULL != global_scope; i++, len++ ) { switch( global_scope[i] ) { case '\0': p[0] = len; if( len > 0 ) p[len+1] = 0; return( name_len(Out) ); case '.': p[0] = len; p += (len + 1); len = -1; break; default: p[len+1] = global_scope[i]; break; } } return( name_len(Out) ); } /* name_mangle *//******************************************************************* check if a file exists********************************************************************/BOOL file_exist(char *fname,SMB_STRUCT_STAT *sbuf){ SMB_STRUCT_STAT st; if (!sbuf) sbuf = &st; if (sys_stat(fname,sbuf) != 0) return(False); return(S_ISREG(sbuf->st_mode));}/*******************************************************************check a files mod time********************************************************************/time_t file_modtime(char *fname){ SMB_STRUCT_STAT st; if (sys_stat(fname,&st) != 0) return(0); return(st.st_mtime);}/******************************************************************* check if a directory exists********************************************************************/BOOL directory_exist(char *dname,SMB_STRUCT_STAT *st){ SMB_STRUCT_STAT st2; BOOL ret; if (!st) st = &st2; if (sys_stat(dname,st) != 0) return(False); ret = S_ISDIR(st->st_mode); if(!ret) errno = ENOTDIR; return ret;}/*******************************************************************returns the size in bytes of the named file********************************************************************/SMB_OFF_T file_size(char *file_name){ SMB_STRUCT_STAT buf; buf.st_size = 0; if(sys_stat(file_name,&buf) != 0) return (SMB_OFF_T)-1; return(buf.st_size);}/*******************************************************************return a string representing an attribute for a file********************************************************************/char *attrib_string(uint16 mode){ static fstring attrstr; attrstr[0] = 0; if (mode & aVOLID) fstrcat(attrstr,"V"); if (mode & aDIR) fstrcat(attrstr,"D"); if (mode & aARCH) fstrcat(attrstr,"A"); if (mode & aHIDDEN) fstrcat(attrstr,"H"); if (mode & aSYSTEM) fstrcat(attrstr,"S"); if (mode & aRONLY) fstrcat(attrstr,"R"); return(attrstr);}/**************************************************************************** make a file into unix format****************************************************************************/void unix_format(char *fname){ string_replace(fname,'\\','/');}/**************************************************************************** make a file into dos format****************************************************************************/void dos_format(char *fname){ string_replace(fname,'/','\\');}/******************************************************************* show a smb message structure********************************************************************/void show_msg(char *buf){ int i; int bcc=0; if (DEBUGLEVEL < 5) return; DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n", smb_len(buf), (int)CVAL(buf,smb_com), (int)CVAL(buf,smb_rcls), (int)CVAL(buf,smb_reh), (int)SVAL(buf,smb_err), (int)CVAL(buf,smb_flg), (int)SVAL(buf,smb_flg2))); DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n", (int)SVAL(buf,smb_tid), (int)SVAL(buf,smb_pid), (int)SVAL(buf,smb_uid), (int)SVAL(buf,smb_mid), (int)CVAL(buf,smb_wct))); for (i=0;i<(int)CVAL(buf,smb_wct);i++) { DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i, SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i))); } bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct))); DEBUG(5,("smb_bcc=%d\n",bcc)); if (DEBUGLEVEL < 10) return; if (DEBUGLEVEL < 50) { bcc = MIN(bcc, 512); } dump_data(10, smb_buf(buf), bcc);}/******************************************************************* return the length of an smb packet********************************************************************/int smb_len(char *buf){ return( PVAL(buf,3) | (PVAL(buf,2)<<8) | ((PVAL(buf,1)&1)<<16) );}/******************************************************************* set the length of an smb packet********************************************************************/void _smb_setlen(char *buf,int len){ buf[0] = 0; buf[1] = (len&0x10000)>>16; buf[2] = (len&0xFF00)>>8; buf[3] = len&0xFF;}/******************************************************************* set the length and marker of an smb packet********************************************************************/void smb_setlen(char *buf,int len){ _smb_setlen(buf,len); CVAL(buf,4) = 0xFF; CVAL(buf,5) = 'S'; CVAL(buf,6) = 'M'; CVAL(buf,7) = 'B';}/******************************************************************* setup the word count and byte count for a smb message********************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -