📄 util.c
字号:
struct rlimit rlp; int saved_current_limit; if(getrlimit(RLIMIT_NOFILE, &rlp)) { DEBUG(0,("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n", strerror(errno) )); /* just guess... */ return requested_max; } /* * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to * account for the extra fd we need * as well as the log files and standard * handles etc. Save the limit we want to set in case * we are running on an OS that doesn't support this limit (AIX) * which always returns RLIM_INFINITY for rlp.rlim_max. */ /* Try raising the hard (max) limit to the requested amount. */#if defined(RLIM_INFINITY) if (rlp.rlim_max != RLIM_INFINITY) { int orig_max = rlp.rlim_max; if ( rlp.rlim_max < requested_max ) rlp.rlim_max = requested_max; /* This failing is not an error - many systems (Linux) don't support our default request of 10,000 open files. JRA. */ if(setrlimit(RLIMIT_NOFILE, &rlp)) { DEBUG(3,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d max files failed with error %s\n", (int)rlp.rlim_max, strerror(errno) )); /* Set failed - restore original value from get. */ rlp.rlim_max = orig_max; } }#endif /* Now try setting the soft (current) limit. */ saved_current_limit = rlp.rlim_cur = MIN(requested_max,rlp.rlim_max); if(setrlimit(RLIMIT_NOFILE, &rlp)) { DEBUG(0,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n", (int)rlp.rlim_cur, strerror(errno) )); /* just guess... */ return saved_current_limit; } if(getrlimit(RLIMIT_NOFILE, &rlp)) { DEBUG(0,("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n", strerror(errno) )); /* just guess... */ return saved_current_limit; }#if defined(RLIM_INFINITY) if(rlp.rlim_cur == RLIM_INFINITY) return saved_current_limit;#endif if((int)rlp.rlim_cur > saved_current_limit) return saved_current_limit; return rlp.rlim_cur;#else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */ /* * No way to know - just guess... */ return requested_max;#endif}/***************************************************************** Possibly replace mkstemp if it is broken.*****************************************************************/ int smb_mkstemp(char *name_template){#if HAVE_SECURE_MKSTEMP return mkstemp(name_template);#else /* have a reasonable go at emulating it. Hope that the system mktemp() isn't completly hopeless */ char *p = mktemp(name_template); if (!p) return -1; return open(p, O_CREAT|O_EXCL|O_RDWR, 0600);#endif}/***************************************************************** malloc that aborts with smb_panic on fail or zero size. *****************************************************************/ void *smb_xmalloc_array(size_t size, unsigned int count){ void *p; if (size == 0) smb_panic("smb_xmalloc_array: called with zero size.\n"); if (count >= MAX_ALLOC_SIZE/size) { smb_panic("smb_xmalloc: alloc size too large.\n"); } if ((p = SMB_MALLOC(size*count)) == NULL) { DEBUG(0, ("smb_xmalloc_array failed to allocate %lu * %lu bytes\n", (unsigned long)size, (unsigned long)count)); smb_panic("smb_xmalloc_array: malloc fail.\n"); } return p;}/** Memdup with smb_panic on fail.**/void *smb_xmemdup(const void *p, size_t size){ void *p2; p2 = SMB_XMALLOC_ARRAY(unsigned char,size); memcpy(p2, p, size); return p2;}/** strdup that aborts on malloc fail.**/char *smb_xstrdup(const char *s){#if defined(PARANOID_MALLOC_CHECKER)#ifdef strdup#undef strdup#endif#endif char *s1 = strdup(s);#if defined(PARANOID_MALLOC_CHECKER)#define strdup(s) __ERROR_DONT_USE_STRDUP_DIRECTLY#endif if (!s1) smb_panic("smb_xstrdup: malloc fail\n"); return s1;}/** strndup that aborts on malloc fail.**/char *smb_xstrndup(const char *s, size_t n){#if defined(PARANOID_MALLOC_CHECKER)#ifdef strndup#undef strndup#endif#endif char *s1 = strndup(s, n);#if defined(PARANOID_MALLOC_CHECKER)#define strndup(s,n) __ERROR_DONT_USE_STRNDUP_DIRECTLY#endif if (!s1) smb_panic("smb_xstrndup: malloc fail\n"); return s1;}/* vasprintf that aborts on malloc fail*/ int smb_xvasprintf(char **ptr, const char *format, va_list ap){ int n; va_list ap2; VA_COPY(ap2, ap); n = vasprintf(ptr, format, ap2); if (n == -1 || ! *ptr) smb_panic("smb_xvasprintf: out of memory"); return n;}/***************************************************************** Like strdup but for memory.*****************************************************************/ void *memdup(const void *p, size_t size){ void *p2; if (size == 0) return NULL; p2 = SMB_MALLOC(size); if (!p2) return NULL; memcpy(p2, p, size); return p2;}/***************************************************************** Get local hostname and cache result.*****************************************************************/ char *myhostname(void){ static pstring ret; if (ret[0] == 0) get_myname(ret); return ret;}/***************************************************************** A useful function for returning a path in the Samba lock directory.*****************************************************************/ char *lock_path(const char *name){ static pstring fname; pstrcpy(fname,lp_lockdir()); trim_char(fname,'\0','/'); if (!directory_exist(fname,NULL)) mkdir(fname,0755); pstrcat(fname,"/"); pstrcat(fname,name); return fname;}/***************************************************************** A useful function for returning a path in the Samba pid directory.*****************************************************************/char *pid_path(const char *name){ static pstring fname; pstrcpy(fname,lp_piddir()); trim_char(fname,'\0','/'); if (!directory_exist(fname,NULL)) mkdir(fname,0755); pstrcat(fname,"/"); pstrcat(fname,name); return fname;}/** * @brief Returns an absolute path to a file in the Samba lib directory. * * @param name File to find, relative to LIBDIR. * * @retval Pointer to a static #pstring containing the full path. **/char *lib_path(const char *name){ static pstring fname; fstr_sprintf(fname, "%s/%s", dyn_LIBDIR, name); return fname;}/** * @brief Returns the platform specific shared library extension. * * @retval Pointer to a static #fstring containing the extension. **/const char *shlib_ext(void){ return dyn_SHLIBEXT;}/******************************************************************* Given a filename - get its directory name NB: Returned in static storage. Caveats: o Not safe in thread environment. o Caller must not free. o If caller wishes to preserve, they should copy.********************************************************************/char *parent_dirname(const char *path){ static pstring dirpath; char *p; if (!path) return(NULL); pstrcpy(dirpath, path); p = strrchr_m(dirpath, '/'); /* Find final '/', if any */ if (!p) { pstrcpy(dirpath, "."); /* No final "/", so dir is "." */ } else { if (p == dirpath) ++p; /* For root "/", leave "/" in place */ *p = '\0'; } return dirpath;}/******************************************************************* Determine if a pattern contains any Microsoft wildcard characters.*******************************************************************/BOOL ms_has_wild(const char *s){ char c; if (lp_posix_pathnames()) { /* With posix pathnames no characters are wild. */ return False; } while ((c = *s++)) { switch (c) { case '*': case '?': case '<': case '>': case '"': return True; } } return False;}BOOL ms_has_wild_w(const smb_ucs2_t *s){ smb_ucs2_t c; if (!s) return False; while ((c = *s++)) { switch (c) { case UCS2_CHAR('*'): case UCS2_CHAR('?'): case UCS2_CHAR('<'): case UCS2_CHAR('>'): case UCS2_CHAR('"'): return True; } } return False;}/******************************************************************* A wrapper that handles case sensitivity and the special handling of the ".." name.*******************************************************************/BOOL mask_match(const char *string, char *pattern, BOOL is_case_sensitive){ if (strcmp(string,"..") == 0) string = "."; if (strcmp(pattern,".") == 0) return False; return ms_fnmatch(pattern, string, Protocol <= PROTOCOL_LANMAN2, is_case_sensitive) == 0;}/******************************************************************* A wrapper that handles case sensitivity and the special handling of the ".." name. Varient that is only called by old search code which requires pattern translation.*******************************************************************/BOOL mask_match_search(const char *string, char *pattern, BOOL is_case_sensitive){ if (strcmp(string,"..") == 0) string = "."; if (strcmp(pattern,".") == 0) return False; return ms_fnmatch(pattern, string, True, is_case_sensitive) == 0;}/******************************************************************* A wrapper that handles a list of patters and calls mask_match() on each. Returns True if any of the patterns match.*******************************************************************/BOOL mask_match_list(const char *string, char **list, int listLen, BOOL is_case_sensitive){ while (listLen-- > 0) { if (mask_match(string, *list++, is_case_sensitive)) return True; } return False;}/********************************************************* Recursive routine that is called by unix_wild_match.*********************************************************/static BOOL unix_do_match(const char *regexp, const char *str){ const char *p; for( p = regexp; *p && *str; ) { switch(*p) { case '?': str++; p++; break; case '*': /* * Look for a character matching * the one after the '*'. */ p++; if(!*p) return True; /* Automatic match */ while(*str) { while(*str && (*p != *str)) str++; /* * Patch from weidel@multichart.de. In the case of the regexp * '*XX*' we want to ensure there are at least 2 'X' characters * in the string after the '*' for a match to be made. */ { int matchcount=0; /* * Eat all the characters that match, but count how many there were. */ while(*str && (*p == *str)) { str++; matchcount++; } /* * Now check that if the regexp had n identical characters that * matchcount had at least that many matches. */ while ( *(p+1) && (*(p+1) == *p)) { p++; matchcount--; } if ( matchcount <= 0 ) return False; } str--; /* We've eaten the match char after the '*' */ if(unix_do_match(p, str)) return True; if(!*str) return False; else str++; } return False; default: if(*str != *p) return False; str++; p++; break; } } if(!*p && !*str) return True; if (!*p && str[0] == '.' && str[1] == 0) return(True); if (!*str && *p == '?') { while (*p == '?') p++; return(!*p); } if(!*str && (*p == '*' && p[1] == '\0')) return True; return False;}/******************************************************************* Simple case insensitive interface to a UNIX wildcard matcher. Returns True if match, False if not.*******************************************************************/BOOL unix_wild_match(const char *pattern, const char *string){ pstring p2, s2; char *p; pstrcpy(p2, pattern); pstrcpy(s2, string); strlower_m(p2); strlower_m(s2); /* Remove any *? and ** from the pattern as they are meaningless */ for(p = p2; *p; p++) while( *p == '*' && (p[1] == '?' ||p[1] == '*')) pstrcpy( &p[1], &p[2]); if (strequal(p2,"*")) return True; return unix_do_match(p2, s2);}/********************************************************************** Converts a name to a fully qalified domain name.***********************************************************************/ void name_to_fqdn(fstring fqdn, const char *name){ struct hostent *hp = sys_gethostbyname(name); if ( hp && hp->h_name && *hp->h_name ) { DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name, hp->h_name)); fstrcpy(fqdn,hp->h_nam
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -