📄 util.c
字号:
} else { p += 2; } break; } case 'N' : string_sub(p,"%N", automount_server(username)); break; case 'I' : string_sub(p,"%I", client_addr(Client)); break; case 'L' : string_sub(p,"%L", local_machine); break; case 'M' : string_sub(p,"%M", client_name(Client)); break; case 'R' : string_sub(p,"%R", remote_proto); break; case 'T' : string_sub(p,"%T", timestring()); break; case 'U' : string_sub(p,"%U", username); break; case 'a' : string_sub(p,"%a", remote_arch); break; case 'd' : { slprintf(pidstr,sizeof(pidstr) - 1, "%d",(int)getpid()); string_sub(p,"%d", pidstr); break; } case 'h' : string_sub(p,"%h", myhostname); break; case 'm' : string_sub(p,"%m", remote_machine); break; case 'v' : string_sub(p,"%v", VERSION); break; case '$' : /* Expand environment variables */ { /* Contributed by Branko Cibej <branko.cibej@hermes.si> */ fstring envname; char *envval; char *q, *r; int copylen; if (*(p+2) != '(') { p+=2; break; } if ((q = strchr(p,')')) == NULL) { DEBUG(0,("standard_sub_basic: Unterminated environment \ variable [%s]\n", p)); p+=2; break; } r = p+3; copylen = MIN((q-r),(sizeof(envname)-1)); strncpy(envname,r,copylen); envname[copylen] = '\0'; if ((envval = getenv(envname)) == NULL) { DEBUG(0,("standard_sub_basic: Environment variable [%s] not set\n", envname)); p+=2; break; } copylen = MIN((q+1-p),(sizeof(envname)-1)); strncpy(envname,p,copylen); envname[copylen] = '\0'; string_sub(p,envname,envval); break; } case '\0': p++; break; /* don't run off end if last character is % */ default : p+=2; break; } } return;}/****************************************************************************do some standard substitutions in a string****************************************************************************/void standard_sub(connection_struct *conn,char *str){ char *p, *s, *home; for (s=str; (p=strchr(s, '%'));s=p) { switch (*(p+1)) { case 'H': if ((home = get_home_dir(conn->user))) { string_sub(p,"%H",home); } else { p += 2; } break; case 'P': string_sub(p,"%P",conn->connectpath); break; case 'S': string_sub(p,"%S", lp_servicename(SNUM(conn))); break; case 'g': string_sub(p,"%g", gidtoname(conn->gid)); break; case 'u': string_sub(p,"%u",conn->user); break; /* Patch from jkf@soton.ac.uk Left the %N (NIS * server name) in standard_sub_basic as it is * a feature for logon servers, hence uses the * username. The %p (NIS server path) code is * here as it is used instead of the default * "path =" string in [homes] and so needs the * service name, not the username. */ case 'p': string_sub(p,"%p", automount_path(lp_servicename(SNUM(conn)))); break; case '\0': p++; break; /* don't run off the end of the string */ default: p+=2; break; } } standard_sub_basic(str);}/*******************************************************************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));}/****************************************************************************a wrapper for gethostbyname() that tries with all lower and all upper case if the initial name fails****************************************************************************/struct hostent *Get_Hostbyname(const char *name){ char *name2 = strdup(name); struct hostent *ret; if (!name2) { DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n")); exit(0); } /* * This next test is redundent and causes some systems (with * broken isalnum() calls) problems. * JRA. */#if 0 if (!isalnum(*name2)) { free(name2); return(NULL); }#endif /* 0 */ ret = sys_gethostbyname(name2); if (ret != NULL) { free(name2); return(ret); } /* try with all lowercase */ strlower(name2); ret = sys_gethostbyname(name2); if (ret != NULL) { free(name2); return(ret); } /* try with all uppercase */ strupper(name2); ret = sys_gethostbyname(name2); if (ret != NULL) { free(name2); return(ret); } /* nothing works :-( */ free(name2); return(NULL);}/*******************************************************************turn a uid into a user name********************************************************************/char *uidtoname(uid_t uid){ static char name[40]; struct passwd *pass = getpwuid(uid); if (pass) return(pass->pw_name); slprintf(name, sizeof(name) - 1, "%d",(int)uid); return(name);}/*******************************************************************turn a gid into a group name********************************************************************/char *gidtoname(gid_t gid){ static char name[40]; struct group *grp = getgrgid(gid); if (grp) return(grp->gr_name); slprintf(name,sizeof(name) - 1, "%d",(int)gid); return(name);}/*******************************************************************turn a user name into a uid********************************************************************/uid_t nametouid(const char *name){ struct passwd *pass = getpwnam(name); if (pass) return(pass->pw_uid); return (uid_t)-1;}/*******************************************************************something really nasty happened - panic!********************************************************************/void smb_panic(char *why){ char *cmd = lp_panic_action(); if (cmd && *cmd) { system(cmd); } DEBUG(0,("PANIC: %s\n", why)); dbgflush(); abort();}/*******************************************************************a readdir wrapper which just returns the file name********************************************************************/char *readdirname(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; memcpy(buf, dname, NAMLEN(ptr)+1); 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(char *name, name_compare_entry *namelist){ pstring last_component; char *p; DEBUG(8, ("is_in_path: %s\n", name)); /* if we have no list it's obviously not in the path */ if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL))) { DEBUG(8,("is_in_path: no name list.\n")); return False; } /* Get the last component of the unix name. */ p = strrchr(name, '/'); strncpy(last_component, p ? ++p : name, sizeof(last_component)-1); last_component[sizeof(last_component)-1] = '\0'; for(; namelist->name != NULL; namelist++) { if(namelist->is_wild) { /* * Look for a wildcard match. Use the old * 'unix style' mask match, rather than the * new NT one. */ if (unix_mask_match(last_component, namelist->name, case_sensitive, False)) { 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(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) = (name_compare_entry *)malloc( (num_entries + 1) * sizeof(name_compare_entry))) == 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(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 = ((strchr( nameptr, '?')!=NULL) || (strchr( nameptr, '*')!=NULL)); if(((*ppname_array)[i].name = 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){ if(name_array == 0) return; if(name_array->name != NULL) free(name_array->name); free((char *)name_array);}/****************************************************************************routine to do file locking****************************************************************************/BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type){#ifdef HAVE_FCNTL_LOCK SMB_STRUCT_FLOCK lock; int ret; if(lp_ole_locking_compat()) { SMB_OFF_T mask2= ((SMB_OFF_T)0x3) << (SMB_OFF_T_BITS-4); SMB_OFF_T mask = (mask2<<2); /* make sure the count is reasonable, we might kill the lockd otherwise */ count &= ~mask; /* the offset is often strange - remove 2 of its bits if either of the top two bits are set. Shift the top ones by two bits. This still allows OLE2 apps to operate, but should stop lockd from dieing */ if ((offset & mask) != 0) offset = (offset & ~mask) | (((offset & mask) >> 2) & mask2); } else { SMB_OFF_T mask2 = ((SMB_OFF_T)0x4) << (SMB_OFF_T_BITS-4); SMB_OFF_T mask = (mask2<<1); SMB_OFF_T neg_mask = ~mask; /* interpret negative counts as large numbers */ if (count < 0) count &= ~mask; /* no negative offsets */ if(offset < 0) offset &= ~mask; /* count + offset must be in range */ while ((offset < 0 || (offset + count < 0)) && mask) { offset &= ~mask; mask = ((mask >> 1) & neg_mask); } } 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; errno = 0; ret = fcntl(fd,op,&lock); if (errno == EFBIG) { if( DEBUGLVL( 0 )) { dbgtext("fcntl_lock: WARNING: lock request at offset %.0f, length %.0f returned\n",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -