📄 util.c
字号:
if (my_name) { /* split off any parts after an initial . */ char *p = strchr_m(hostname,'.'); if (p) *p = 0; fstrcpy(my_name,hostname); } return(True);}/**************************************************************************** Get my own canonical name, including domain.****************************************************************************/BOOL get_mydnsfullname(fstring my_dnsname){ static fstring dnshostname; struct hostent *hp; if (!*dnshostname) { /* get my host name */ if (gethostname(dnshostname, sizeof(dnshostname)) == -1) { *dnshostname = '\0'; DEBUG(0,("gethostname failed\n")); return False; } /* Ensure null termination. */ dnshostname[sizeof(dnshostname)-1] = '\0'; /* Ensure we get the cannonical name. */ if (!(hp = sys_gethostbyname(dnshostname))) { *dnshostname = '\0'; return False; } fstrcpy(dnshostname, hp->h_name); } fstrcpy(my_dnsname, dnshostname); return True;}/**************************************************************************** Get my own domain name.****************************************************************************/BOOL get_mydnsdomname(fstring my_domname){ fstring domname; char *p; *my_domname = '\0'; if (!get_mydnsfullname(domname)) { return False; } p = strchr_m(domname, '.'); if (p) { p++; fstrcpy(my_domname, p); } return False;}/**************************************************************************** Interpret a protocol description string, with a default.****************************************************************************/int interpret_protocol(const char *str,int def){ if (strequal(str,"NT1")) return(PROTOCOL_NT1); if (strequal(str,"LANMAN2")) return(PROTOCOL_LANMAN2); if (strequal(str,"LANMAN1")) return(PROTOCOL_LANMAN1); if (strequal(str,"CORE")) return(PROTOCOL_CORE); if (strequal(str,"COREPLUS")) return(PROTOCOL_COREPLUS); if (strequal(str,"CORE+")) return(PROTOCOL_COREPLUS); DEBUG(0,("Unrecognised protocol level %s\n",str)); return(def);}/**************************************************************************** Return true if a string could be a pure IP address.****************************************************************************/BOOL is_ipaddress(const char *str){ BOOL pure_address = True; int i; for (i=0; pure_address && str[i]; i++) if (!(isdigit((int)str[i]) || str[i] == '.')) pure_address = False; /* Check that a pure number is not misinterpreted as an IP */ pure_address = pure_address && (strchr_m(str, '.') != NULL); return pure_address;}/**************************************************************************** Interpret an internet address or name into an IP address in 4 byte form.****************************************************************************/uint32 interpret_addr(const char *str){ struct hostent *hp; uint32 res; if (strcmp(str,"0.0.0.0") == 0) return(0); if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF); /* if it's in the form of an IP address then get the lib to interpret it */ if (is_ipaddress(str)) { res = inet_addr(str); } else { /* otherwise assume it's a network name of some sort and use sys_gethostbyname */ if ((hp = sys_gethostbyname(str)) == 0) { DEBUG(3,("sys_gethostbyname: Unknown host. %s\n",str)); return 0; } if(hp->h_addr == NULL) { DEBUG(3,("sys_gethostbyname: host address is invalid for host %s\n",str)); return 0; } putip((char *)&res,(char *)hp->h_addr); } if (res == (uint32)-1) return(0); return(res);}/******************************************************************* A convenient addition to interpret_addr().******************************************************************/struct in_addr *interpret_addr2(const char *str){ static struct in_addr ret; uint32 a = interpret_addr(str); ret.s_addr = a; return(&ret);}/******************************************************************* Check if an IP is the 0.0.0.0.******************************************************************/BOOL is_zero_ip(struct in_addr ip){ uint32 a; putip((char *)&a,(char *)&ip); return(a == 0);}/******************************************************************* Set an IP to 0.0.0.0.******************************************************************/void zero_ip(struct in_addr *ip){ static BOOL init; static struct in_addr ipzero; if (!init) { ipzero = *interpret_addr2("0.0.0.0"); init = True; } *ip = ipzero;}#if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))/****************************************************************** Remove any mount options such as -rsize=2048,wsize=2048 etc. Based on a fix from <Thomas.Hepper@icem.de>.*******************************************************************/static void strip_mount_options( pstring *str){ if (**str == '-') { char *p = *str; while(*p && !isspace(*p)) p++; while(*p && isspace(*p)) p++; if(*p) { pstring tmp_str; pstrcpy(tmp_str, p); pstrcpy(*str, tmp_str); } }}/******************************************************************* Patch from jkf@soton.ac.uk Split Luke's automount_server into YP lookup and string splitter so can easily implement automount_path(). As we may end up doing both, cache the last YP result. *******************************************************************/#ifdef WITH_NISPLUS_HOMEchar *automount_lookup(const char *user_name){ static fstring last_key = ""; static pstring last_value = ""; char *nis_map = (char *)lp_nis_home_map_name(); char buffer[NIS_MAXATTRVAL + 1]; nis_result *result; nis_object *object; entry_obj *entry; if (strcmp(user_name, last_key)) { slprintf(buffer, sizeof(buffer)-1, "[key=%s],%s", user_name, nis_map); DEBUG(5, ("NIS+ querystring: %s\n", buffer)); if (result = nis_list(buffer, FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP, NULL, NULL)) { if (result->status != NIS_SUCCESS) { DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status))); fstrcpy(last_key, ""); pstrcpy(last_value, ""); } else { object = result->objects.objects_val; if (object->zo_data.zo_type == ENTRY_OBJ) { entry = &object->zo_data.objdata_u.en_data; DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type)); DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val)); pstrcpy(last_value, entry->en_cols.en_cols_val[1].ec_value.ec_value_val); pstring_sub(last_value, "&", user_name); fstrcpy(last_key, user_name); } } } nis_freeresult(result); } strip_mount_options(&last_value); DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n", user_name, last_value)); return last_value;}#else /* WITH_NISPLUS_HOME */char *automount_lookup(const char *user_name){ static fstring last_key = ""; static pstring last_value = ""; int nis_error; /* returned by yp all functions */ char *nis_result; /* yp_match inits this */ int nis_result_len; /* and set this */ char *nis_domain; /* yp_get_default_domain inits this */ char *nis_map = (char *)lp_nis_home_map_name(); if ((nis_error = yp_get_default_domain(&nis_domain)) != 0) { DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error))); return last_value; } DEBUG(5, ("NIS Domain: %s\n", nis_domain)); if (!strcmp(user_name, last_key)) { nis_result = last_value; nis_result_len = strlen(last_value); nis_error = 0; } else { if ((nis_error = yp_match(nis_domain, nis_map, user_name, strlen(user_name), &nis_result, &nis_result_len)) == 0) { fstrcpy(last_key, user_name); pstrcpy(last_value, nis_result); strip_mount_options(&last_value); } else if(nis_error == YPERR_KEY) { /* If Key lookup fails user home server is not in nis_map use default information for server, and home directory */ last_value[0] = 0; DEBUG(3, ("YP Key not found: while looking up \"%s\" in map \"%s\"\n", user_name, nis_map)); DEBUG(3, ("using defaults for server and home directory\n")); } else { DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n", yperr_string(nis_error), user_name, nis_map)); } } DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, last_value)); return last_value;}#endif /* WITH_NISPLUS_HOME */#endif/******************************************************************* Are two IPs on the same subnet?********************************************************************/BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask){ uint32 net1,net2,nmask; nmask = ntohl(mask.s_addr); net1 = ntohl(ip1.s_addr); net2 = ntohl(ip2.s_addr); return((net1 & nmask) == (net2 & nmask));}/**************************************************************************** Check if a process exists. Does this work on all unixes?****************************************************************************/BOOL process_exists(const struct process_id pid){ if (!procid_is_local(&pid)) { /* This *SEVERELY* needs fixing. */ return True; } /* Doing kill with a non-positive pid causes messages to be * sent to places we don't want. */ SMB_ASSERT(pid.pid > 0); return(kill(pid.pid,0) == 0 || errno != ESRCH);}BOOL process_exists_by_pid(pid_t pid){ return process_exists(pid_to_procid(pid));}/******************************************************************* Convert a uid into a user name.********************************************************************/const char *uidtoname(uid_t uid){ static fstring name; struct passwd *pass; pass = getpwuid_alloc(uid); if (pass) { fstrcpy(name, pass->pw_name); passwd_free(&pass); } else { slprintf(name, sizeof(name) - 1, "%ld",(long int)uid); } return name;}/******************************************************************* Convert a gid into a group name.********************************************************************/char *gidtoname(gid_t gid){ static fstring name; struct group *grp; grp = getgrgid(gid); if (grp) return(grp->gr_name); slprintf(name,sizeof(name) - 1, "%d",(int)gid); return(name);}/******************************************************************* Convert a user name into a uid. ********************************************************************/uid_t nametouid(const char *name){ struct passwd *pass; char *p; uid_t u; pass = getpwnam_alloc(name); if (pass) { u = pass->pw_uid; passwd_free(&pass); return u; } u = (uid_t)strtol(name, &p, 0); if ((p != name) && (*p == '\0')) return u; return (uid_t)-1;}/******************************************************************* Convert a name to a gid_t if possible. Return -1 if not a group. ********************************************************************/gid_t nametogid(const char *name){ struct group *grp; char *p; gid_t g; g = (gid_t)strtol(name, &p, 0); if ((p != name) && (*p == '\0')) return g; grp = sys_getgrnam(name); if (grp) return(grp->gr_gid); return (gid_t)-1;}/******************************************************************* legacy wrapper for smb_panic2()********************************************************************/void smb_panic( const char *why ){ smb_panic2( why, True );}/******************************************************************* Something really nasty happened - panic !********************************************************************/#ifdef HAVE_LIBEXC_H#include <libexc.h>#endifvoid smb_panic2(const char *why, BOOL decrement_pid_count ){ char *cmd; int result;#ifdef HAVE_BACKTRACE_SYMBOLS void *backtrace_stack[BACKTRACE_STACK_SIZE]; size_t backtrace_size; char **backtrace_strings;#endif#ifdef DEVELOPER { if (global_clobber_region_function) { DEBUG(0,("smb_panic: clobber_region() last called from [%s(%u)]\n", global_clobber_region_function, global_clobber_region_line)); } }#endif /* only smbd needs to decrement the smbd counter in connections.tdb */ if ( decrement_pid_count ) decrement_smbd_process_count(); cmd = lp_panic_action(); if (cmd && *cmd) { DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd)); result = system(cmd); if (result == -1) DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n", strerror(errno))); else DEBUG(0, ("smb_panic(): action returned status %d\n", WEXITSTATUS(result))); } DEBUG(0,("PANIC: %s\n", why));#ifdef HAVE_BACKTRACE_SYMBOLS /* get the backtrace (stack frames) */ backtrace_size = backtrace(backtrace_stack,BACKTRACE_STACK_SIZE); backtrace_strings = backtrace_symbols(backtrace_stack, backtrace_size); DEBUG(0, ("BACKTRACE: %lu stack frames:\n", (unsigned long)backtrace_size)); if (backtrace_strings) { int i; for (i = 0; i < backtrace_size; i++) DEBUGADD(0, (" #%u %s\n", i, backtrace_strings[i])); /* Leak the backtrace_strings, rather than risk what free() might do */ }#elif HAVE_LIBEXC#define NAMESIZE 32 /* Arbitrary */ /* The IRIX libexc library provides an API for unwinding the stack. See * libexc(3) for details. Apparantly trace_back_stack leaks memory, but * since we are about to abort anyway, it hardly matters. * * Note that if we paniced due to a SIGSEGV or SIGBUS (or similar) this * will fail with a nasty message upon failing to open the /proc entry. */ { __uint64_t addrs[BACKTRACE_STACK_SIZE]; char * names[BACKTRACE_STACK_SIZE]; char namebuf[BACKTRACE_STACK_SIZE * NAMESIZE]; int i; int levels; ZERO_ARRAY(addrs); ZERO_ARRAY(names); ZERO_ARRAY(namebuf); /* We need to be root so we can open our /proc entry to walk * our stack. It also helps when we want to dump core. */ become_root(); for (i = 0; i < BACKTRACE_STACK_SIZE; i++) { names[i] = namebuf + (i * NAMESIZE); } levels = trace_back_stack(0, addrs, names, BACKTRACE_STACK_SIZE, NAMESIZE - 1); DEBUG(0, ("BACKTRACE: %d stack frames:\n", levels));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -