📄 util.c
字号:
for (i = 0; i < levels; i++) { DEBUGADD(0, (" #%d 0x%llx %s\n", i, addrs[i], names[i])); } }#undef NAMESIZE#endif dbgflush();#ifdef SIGABRT CatchSignal(SIGABRT,SIGNAL_CAST SIG_DFL);#endif abort();}/******************************************************************* A readdir wrapper which just returns the file name. ********************************************************************/const char *readdirname(SMB_STRUCT_DIR *p){ SMB_STRUCT_DIRENT *ptr; char *dname; if (!p) return(NULL); ptr = (SMB_STRUCT_DIRENT *)sys_readdir(p); if (!ptr) return(NULL); dname = ptr->d_name;#ifdef NEXT2 if (telldir(p) < 0) return(NULL);#endif#ifdef HAVE_BROKEN_READDIR /* using /usr/ucb/cc is BAD */ dname = dname - 2;#endif { static pstring buf; int len = NAMLEN(ptr); memcpy(buf, dname, len); buf[len] = 0; dname = buf; } return(dname);}/******************************************************************* Utility function used to decide if the last component of a path matches a (possibly wildcarded) entry in a namelist.********************************************************************/BOOL is_in_path(const char *name, name_compare_entry *namelist, BOOL case_sensitive){ pstring last_component; char *p; /* if we have no list it's obviously not in the path */ if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL))) { return False; } DEBUG(8, ("is_in_path: %s\n", name)); /* Get the last component of the unix name. */ p = strrchr_m(name, '/'); pstrcpy(last_component, p ? ++p : name); for(; namelist->name != NULL; namelist++) { if(namelist->is_wild) { if (mask_match(last_component, namelist->name, case_sensitive)) { DEBUG(8,("is_in_path: mask match succeeded\n")); return True; } } else { if((case_sensitive && (strcmp(last_component, namelist->name) == 0))|| (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0))) { DEBUG(8,("is_in_path: match succeeded\n")); return True; } } } DEBUG(8,("is_in_path: match not found\n")); return False;}/******************************************************************* Strip a '/' separated list into an array of name_compare_enties structures suitable for passing to is_in_path(). We do this for speed so we can pre-parse all the names in the list and don't do it for each call to is_in_path(). namelist is modified here and is assumed to be a copy owned by the caller. We also check if the entry contains a wildcard to remove a potentially expensive call to mask_match if possible.********************************************************************/ void set_namearray(name_compare_entry **ppname_array, char *namelist){ char *name_end; char *nameptr = namelist; int num_entries = 0; int i; (*ppname_array) = NULL; if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0'))) return; /* We need to make two passes over the string. The first to count the number of elements, the second to split it. */ while(*nameptr) { if ( *nameptr == '/' ) { /* cope with multiple (useless) /s) */ nameptr++; continue; } /* find the next / */ name_end = strchr_m(nameptr, '/'); /* oops - the last check for a / didn't find one. */ if (name_end == NULL) break; /* next segment please */ nameptr = name_end + 1; num_entries++; } if(num_entries == 0) return; if(( (*ppname_array) = SMB_MALLOC_ARRAY(name_compare_entry, num_entries + 1)) == NULL) { DEBUG(0,("set_namearray: malloc fail\n")); return; } /* Now copy out the names */ nameptr = namelist; i = 0; while(*nameptr) { if ( *nameptr == '/' ) { /* cope with multiple (useless) /s) */ nameptr++; continue; } /* find the next / */ if ((name_end = strchr_m(nameptr, '/')) != NULL) *name_end = 0; /* oops - the last check for a / didn't find one. */ if(name_end == NULL) break; (*ppname_array)[i].is_wild = ms_has_wild(nameptr); if(((*ppname_array)[i].name = SMB_STRDUP(nameptr)) == NULL) { DEBUG(0,("set_namearray: malloc fail (1)\n")); return; } /* next segment please */ nameptr = name_end + 1; i++; } (*ppname_array)[i].name = NULL; return;}/**************************************************************************** Routine to free a namearray.****************************************************************************/void free_namearray(name_compare_entry *name_array){ int i; if(name_array == NULL) return; for(i=0; name_array[i].name!=NULL; i++) SAFE_FREE(name_array[i].name); SAFE_FREE(name_array);}#undef DBGC_CLASS#define DBGC_CLASS DBGC_LOCKING/**************************************************************************** Simple routine to do POSIX file locking. Cruft in NFS and 64->32 bit mapping is dealt with in posix.c****************************************************************************/BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type){ SMB_STRUCT_FLOCK lock; int ret; DEBUG(8,("fcntl_lock %d %d %.0f %.0f %d\n",fd,op,(double)offset,(double)count,type)); lock.l_type = type; lock.l_whence = SEEK_SET; lock.l_start = offset; lock.l_len = count; lock.l_pid = 0; ret = sys_fcntl_ptr(fd,op,&lock); if (ret == -1 && errno != 0) DEBUG(3,("fcntl_lock: fcntl lock gave errno %d (%s)\n",errno,strerror(errno))); /* a lock query */ if (op == SMB_F_GETLK) { if ((ret != -1) && (lock.l_type != F_UNLCK) && (lock.l_pid != 0) && (lock.l_pid != sys_getpid())) { DEBUG(3,("fcntl_lock: fd %d is locked by pid %d\n",fd,(int)lock.l_pid)); return(True); } /* it must be not locked or locked by me */ return(False); } /* a lock set or unset */ if (ret == -1) { DEBUG(3,("fcntl_lock: lock failed at offset %.0f count %.0f op %d type %d (%s)\n", (double)offset,(double)count,op,type,strerror(errno))); return(False); } /* everything went OK */ DEBUG(8,("fcntl_lock: Lock call successful\n")); return(True);}#undef DBGC_CLASS#define DBGC_CLASS DBGC_ALL/******************************************************************* Is the name specified one of my netbios names. Returns true if it is equal, false otherwise.********************************************************************/BOOL is_myname(const char *s){ int n; BOOL ret = False; for (n=0; my_netbios_names(n); n++) { if (strequal(my_netbios_names(n), s)) { ret=True; break; } } DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret)); return(ret);}BOOL is_myname_or_ipaddr(const char *s){ fstring name, dnsname; char *servername; if ( !s ) return False; /* santize the string from '\\name' */ fstrcpy( name, s ); servername = strrchr_m( name, '\\' ); if ( !servername ) servername = name; else servername++; /* optimize for the common case */ if (strequal(servername, global_myname())) return True; /* check for an alias */ if (is_myname(servername)) return True; /* check for loopback */ if (strequal(servername, "localhost")) return True; /* maybe it's my dns name */ if ( get_mydnsfullname( dnsname ) ) if ( strequal( servername, dnsname ) ) return True; /* handle possible CNAME records */ if ( !is_ipaddress( servername ) ) { /* use DNS to resolve the name, but only the first address */ struct hostent *hp; if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) { struct in_addr return_ip; putip( (char*)&return_ip, (char*)hp->h_addr ); fstrcpy( name, inet_ntoa( return_ip ) ); servername = name; } } /* maybe its an IP address? */ if (is_ipaddress(servername)) { struct iface_struct nics[MAX_INTERFACES]; int i, n; uint32 ip; ip = interpret_addr(servername); if ((ip==0) || (ip==0xffffffff)) return False; n = get_interfaces(nics, MAX_INTERFACES); for (i=0; i<n; i++) { if (ip == nics[i].ip.s_addr) return True; } } /* no match */ return False;}/******************************************************************* Is the name specified our workgroup/domain. Returns true if it is equal, false otherwise.********************************************************************/BOOL is_myworkgroup(const char *s){ BOOL ret = False; if (strequal(s, lp_workgroup())) { ret=True; } DEBUG(8, ("is_myworkgroup(\"%s\") returns %d\n", s, ret)); return(ret);}/******************************************************************* we distinguish between 2K and XP by the "Native Lan Manager" string WinXP => "Windows 2002 5.1" Win2k => "Windows 2000 5.0" NT4 => "Windows NT 4.0" Win9x => "Windows 4.0" Windows 2003 doesn't set the native lan manager string but they do set the domain to "Windows 2003 5.2" (probably a bug).********************************************************************/void ra_lanman_string( const char *native_lanman ){ if ( strcmp( native_lanman, "Windows 2002 5.1" ) == 0 ) set_remote_arch( RA_WINXP ); else if ( strcmp( native_lanman, "Windows Server 2003 5.2" ) == 0 ) set_remote_arch( RA_WIN2K3 );}/******************************************************************* Set the horrid remote_arch string based on an enum.********************************************************************/void set_remote_arch(enum remote_arch_types type){ ra_type = type; switch( type ) { case RA_WFWG: fstrcpy(remote_arch, "WfWg"); break; case RA_OS2: fstrcpy(remote_arch, "OS2"); break; case RA_WIN95: fstrcpy(remote_arch, "Win95"); break; case RA_WINNT: fstrcpy(remote_arch, "WinNT"); break; case RA_WIN2K: fstrcpy(remote_arch, "Win2K"); break; case RA_WINXP: fstrcpy(remote_arch, "WinXP"); break; case RA_WIN2K3: fstrcpy(remote_arch, "Win2K3"); break; case RA_SAMBA: fstrcpy(remote_arch,"Samba"); break; case RA_CIFSFS: fstrcpy(remote_arch,"CIFSFS"); break; default: ra_type = RA_UNKNOWN; fstrcpy(remote_arch, "UNKNOWN"); break; } DEBUG(10,("set_remote_arch: Client arch is \'%s\'\n", remote_arch));}/******************************************************************* Get the remote_arch type.********************************************************************/enum remote_arch_types get_remote_arch(void){ return ra_type;}void print_asc(int level, const unsigned char *buf,int len){ int i; for (i=0;i<len;i++) DEBUG(level,("%c", isprint(buf[i])?buf[i]:'.'));}void dump_data(int level, const char *buf1,int len){ const unsigned char *buf = (const unsigned char *)buf1; int i=0; if (len<=0) return; if (!DEBUGLVL(level)) return; DEBUGADD(level,("[%03X] ",i)); for (i=0;i<len;) { DEBUGADD(level,("%02X ",(int)buf[i])); i++; if (i%8 == 0) DEBUGADD(level,(" ")); if (i%16 == 0) { print_asc(level,&buf[i-16],8); DEBUGADD(level,(" ")); print_asc(level,&buf[i-8],8); DEBUGADD(level,("\n")); if (i<len) DEBUGADD(level,("[%03X] ",i)); } } if (i%16) { int n; n = 16 - (i%16); DEBUGADD(level,(" ")); if (n>8) DEBUGADD(level,(" ")); while (n--) DEBUGADD(level,(" ")); n = MIN(8,i%16); print_asc(level,&buf[i-(i%16)],n); DEBUGADD(level,( " " )); n = (i%16) - n; if (n>0) print_asc(level,&buf[i-n],n); DEBUGADD(level,("\n")); } }void dump_data_pw(const char *msg, const uchar * data, size_t len){#ifdef DEBUG_PASSWORD DEBUG(11, ("%s", msg)); if (data != NULL && len > 0) { dump_data(11, (const char *)data, len); }#endif}char *tab_depth(int depth){ static pstring spaces; memset(spaces, ' ', depth * 4); spaces[depth * 4] = 0; return spaces;}/***************************************************************************** Provide a checksum on a string Input: s - the null-terminated character string for which the checksum will be calculated. Output: The checksum value calculated for s.*****************************************************************************/int str_checksum(const char *s){ int res = 0; int c; int i=0; while(*s) { c = *s; res ^= (c << (i % 15)) ^ (c >> (15-(i%15))); s++; i++; } return(res);}/***************************************************************** Zero a memory area then free it. Used to catch bugs faster.*****************************************************************/ void zero_free(void *p, size_t size){ memset(p, 0, size); SAFE_FREE(p);}/***************************************************************** Set our open file limit to a requested max and return the limit.*****************************************************************/ int set_maxfiles(int requested_max){#if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -