From 9c72a0b1d7deb5358b8d9e08822337c9d6bcb92d Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 20 Jan 2000 05:15:02 +0000 Subject: moved some more functions out of lib/util.c. --- source/lib/util.c | 306 ------------------------------------------------- source/lib/util_file.c | 112 ++++++++++++++++++ source/libsmb/nmblib.c | 194 +++++++++++++++++++++++++++++++ 3 files changed, 306 insertions(+), 306 deletions(-) diff --git a/source/lib/util.c b/source/lib/util.c index 6c84c192de6..6ed6dc0aa4a 100644 --- a/source/lib/util.c +++ b/source/lib/util.c @@ -227,145 +227,6 @@ 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 = *(uchar *)in++; - StrnCpy(out, in, len); - out += len; - *out=0; - in += len; - } -#endif - return(ret); -} - -/**************************************************************************** -mangle a name into netbios format - - Note: 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; - - /* 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 != scope; i++, len++ ) - { - switch( 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 = 0; - break; - default: - p[len+1] = scope[i]; - break; - } - } - - return( name_len(Out) ); - } /* name_mangle */ - /******************************************************************* check if a file exists ********************************************************************/ @@ -818,61 +679,6 @@ SMB_OFF_T transfer_file(int infd,int outfd,SMB_OFF_T n,char *header,int headlen, -/**************************************************************************** -find a pointer to a netbios name -****************************************************************************/ -static char *name_ptr(char *buf,int ofs) -{ - uchar c = *(uchar *)(buf+ofs); - - if ((c & 0xC0) == 0xC0) - { - uint16 l; - char p[2]; - memcpy(p,buf+ofs,2); - p[0] &= ~0xC0; - l = RSVAL(p,0); - DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l)); - return(buf + l); - } - else - return(buf+ofs); -} - -/**************************************************************************** -extract a netbios name from a buf -****************************************************************************/ -int name_extract(char *buf,int ofs,char *name) -{ - char *p = name_ptr(buf,ofs); - int d = PTR_DIFF(p,buf+ofs); - pstrcpy(name,""); - if (d < -50 || d > 50) return(0); - return(name_interpret(p,name)); -} - -/**************************************************************************** -return the total storage length of a mangled name -****************************************************************************/ -int name_len(char *s1) -{ - /* NOTE: this argument _must_ be unsigned */ - uchar *s = (uchar *)s1; - int len; - - /* If the two high bits of the byte are set, return 2. */ - if (0xC0 == (*s & 0xC0)) - return(2); - - /* Add up the length bytes. */ - for (len = 1; (*s); s += (*s) + 1) { - len += *s + 1; - SMB_ASSERT(len < 80); - } - - return(len); -} /* name_len */ - /******************************************************************* sleep for a specified number of milliseconds @@ -2492,118 +2298,6 @@ void free_namearray(name_compare_entry *name_array) 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) -{ -#if 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", (double)offset,(double)count); - dbgtext("a 'file too large' error. This can happen when using 64 bit lock offsets\n"); - dbgtext("on 32 bit NFS mounted file systems. Retrying with 32 bit truncated length.\n"); - } - /* 32 bit NFS file system, retry with smaller offset */ - errno = 0; - lock.l_len = count & 0xffffffff; - ret = fcntl(fd,op,&lock); - } - - if (errno != 0) - DEBUG(3,("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 != getpid())) - { - DEBUG(3,("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,("lock failed at offset %.0f count %.0f op %d type %d (%s)\n", - (double)offset,(double)count,op,type,strerror(errno))); - - /* perhaps it doesn't support this sort of locking?? */ - if (errno == EINVAL) - { - DEBUG(3,("locking not supported? returning True\n")); - return(True); - } - - return(False); - } - - /* everything went OK */ - DEBUG(8,("Lock call successful\n")); - - return(True); -#else - return(False); -#endif -} - /******************************************************************* is the name specified one of my netbios names returns true is it is equal, false otherwise diff --git a/source/lib/util_file.c b/source/lib/util_file.c index f4325b813bb..44b37466c71 100644 --- a/source/lib/util_file.c +++ b/source/lib/util_file.c @@ -108,6 +108,117 @@ BOOL file_unlock(int fd, int *plock_depth) return ret; } +/**************************************************************************** +routine to do file locking +****************************************************************************/ +BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type) +{ +#if 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", (double)offset,(double)count); + dbgtext("a 'file too large' error. This can happen when using 64 bit lock offsets\n"); + dbgtext("on 32 bit NFS mounted file systems. Retrying with 32 bit truncated length.\n"); + } + /* 32 bit NFS file system, retry with smaller offset */ + errno = 0; + lock.l_len = count & 0xffffffff; + ret = fcntl(fd,op,&lock); + } + + if (errno != 0) + DEBUG(3,("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 != getpid())) + { + DEBUG(3,("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,("lock failed at offset %.0f count %.0f op %d type %d (%s)\n", + (double)offset,(double)count,op,type,strerror(errno))); + + /* perhaps it doesn't support this sort of locking?? */ + if (errno == EINVAL) + { + DEBUG(3,("locking not supported? returning True\n")); + return(True); + } + + return(False); + } + + /* everything went OK */ + DEBUG(8,("Lock call successful\n")); + + return(True); +#else + return(False); +#endif +} /*************************************************************** locks a file for enumeration / modification. update to be set = True if modification is required. @@ -365,3 +476,4 @@ void *open_file_if_modified(const char *filename, char *mode, time_t *lastmodifi return (void *)f; } + diff --git a/source/libsmb/nmblib.c b/source/libsmb/nmblib.c index af4e03bb10e..7dd1b484191 100644 --- a/source/libsmb/nmblib.c +++ b/source/libsmb/nmblib.c @@ -1132,3 +1132,197 @@ int get_nmb_sock(void) return open_pipe_sock(path); } + +#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 = *(uchar *)in++; + StrnCpy(out, in, len); + out += len; + *out=0; + in += len; + } +#endif + return(ret); +} + +/**************************************************************************** +mangle a name into netbios format + + Note: must be (33 + strlen(scope) + 2) bytes long, at minimum. +****************************************************************************/ +int name_mangle( char *In, char *Out, char name_type ) + { + extern pstring scope; + int i; + int c; + int len; + char buf[20]; + char *p = Out; + + /* 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 != scope; i++, len++ ) + { + switch( 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 = 0; + break; + default: + p[len+1] = scope[i]; + break; + } + } + + return( name_len(Out) ); + } /* name_mangle */ + +/**************************************************************************** +find a pointer to a netbios name +****************************************************************************/ +static char *name_ptr(char *buf,int ofs) +{ + uchar c = *(uchar *)(buf+ofs); + + if ((c & 0xC0) == 0xC0) + { + uint16 l; + char p[2]; + memcpy(p,buf+ofs,2); + p[0] &= ~0xC0; + l = RSVAL(p,0); + DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l)); + return(buf + l); + } + else + return(buf+ofs); +} + +/**************************************************************************** +extract a netbios name from a buf +****************************************************************************/ +int name_extract(char *buf,int ofs,char *name) +{ + char *p = name_ptr(buf,ofs); + int d = PTR_DIFF(p,buf+ofs); + pstrcpy(name,""); + if (d < -50 || d > 50) return(0); + return(name_interpret(p,name)); +} + +/**************************************************************************** +return the total storage length of a mangled name +****************************************************************************/ +int name_len(char *s1) +{ + /* NOTE: this argument _must_ be unsigned */ + uchar *s = (uchar *)s1; + int len; + + /* If the two high bits of the byte are set, return 2. */ + if (0xC0 == (*s & 0xC0)) + return(2); + + /* Add up the length bytes. */ + for (len = 1; (*s); s += (*s) + 1) { + len += *s + 1; + SMB_ASSERT(len < 80); + } + + return(len); +} /* name_len */ -- cgit