#include "includes.h"
#if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
-#ifdef NISPLUS_HOME
+#ifdef WITH_NISPLUS_HOME
#include <rpcsvc/nis.h>
#else
#include "rpcsvc/ypclnt.h"
pstring scope = "";
-int DEBUGLEVEL = 1;
+extern int DEBUGLEVEL;
BOOL passive = False;
/* a default finfo structure to ensure all fields are sensible */
file_info def_finfo = {-1,0,0,0,0,0,0,""};
-/* these are some file handles where debug info will be stored */
-FILE *dbf = NULL;
-
/* the client file descriptor */
int Client = -1;
*/
int case_default = CASE_LOWER;
-pstring debugf = "";
-int syslog_level = 0;
-
/* the following control case operations - they are put here so the
client can link easily */
BOOL case_sensitive;
int smb_read_error = 0;
-static BOOL stdout_logging = False;
-
static char *filename_dos(char *path,char *buf);
-#if defined(SIGUSR2)
-/******************************************************************************
- catch a sigusr2 - decrease the debug log level.
- *****************************************************************************/
-int sig_usr2(void)
-{
- BlockSignals( True, SIGUSR2);
-
- DEBUGLEVEL--;
-
- if(DEBUGLEVEL < 0)
- DEBUGLEVEL = 0;
-
- DEBUG( 0, ( "Got SIGUSR2 set debug level to %d.\n", DEBUGLEVEL ) );
-
- BlockSignals( False, SIGUSR2);
- CatchSignal(SIGUSR2, SIGNAL_CAST sig_usr2);
-
- return(0);
-}
-#endif /* SIGUSR1 */
-
-#if defined(SIGUSR1)
-/******************************************************************************
- catch a sigusr1 - increase the debug log level.
- *****************************************************************************/
-int sig_usr1(void)
-{
- BlockSignals( True, SIGUSR1);
-
- DEBUGLEVEL++;
-
- if(DEBUGLEVEL > 10)
- DEBUGLEVEL = 10;
-
- DEBUG( 0, ( "Got SIGUSR1 set debug level to %d.\n", DEBUGLEVEL ) );
-
- BlockSignals( False, SIGUSR1);
- CatchSignal(SIGUSR1, SIGNAL_CAST sig_usr1);
- return(0);
-}
-#endif /* SIGUSR1 */
-
-
-/*******************************************************************
- get ready for syslog stuff
- ******************************************************************/
-void setup_logging(char *pname,BOOL interactive)
-{
-#ifdef WITH_SYSLOG
- if (!interactive) {
- char *p = strrchr(pname,'/');
- if (p) pname = p+1;
-#ifdef LOG_DAEMON
- openlog(pname, LOG_PID, SYSLOG_FACILITY);
-#else /* for old systems that have no facility codes. */
- openlog(pname, LOG_PID);
-#endif
- }
-#endif
- if (interactive) {
- stdout_logging = True;
- dbf = stdout;
- }
-}
-
-
-BOOL append_log=False;
-
-
-/****************************************************************************
-reopen the log files
-****************************************************************************/
-void reopen_logs(void)
-{
- pstring fname;
-
- if (DEBUGLEVEL > 0)
- {
- pstrcpy(fname,debugf);
- if (lp_loaded() && (*lp_logfile()))
- pstrcpy(fname,lp_logfile());
-
- if (!strcsequal(fname,debugf) || !dbf || !file_exist(debugf,NULL))
- {
- int oldumask = umask(022);
- pstrcpy(debugf,fname);
- if (dbf)
- fclose(dbf);
- if (append_log)
- dbf = fopen(debugf,"a");
- else
- dbf = fopen(debugf,"w");
- /*
- * Fix from klausr@ITAP.Physik.Uni-Stuttgart.De
- * to fix problem where smbd's that generate less
- * than 100 messages keep growing the log.
- */
- force_check_log_size();
- if (dbf)
- setbuf(dbf,NULL);
- umask(oldumask);
- }
- }
- else
- {
- if (dbf)
- {
- fclose(dbf);
- dbf = NULL;
- }
- }
-}
-
-/*******************************************************************
- Number of debug messages that have been output.
- Used to check log size.
-********************************************************************/
-
-static int debug_count=0;
-
-/*******************************************************************
- Force a check of the log size.
-********************************************************************/
-
-void force_check_log_size(void)
-{
- debug_count = 100;
-}
-
-/*******************************************************************
- Check if the log has grown too big
-********************************************************************/
-
-static void check_log_size(void)
-{
- int maxlog;
- struct stat st;
-
- if (debug_count++ < 100 || getuid() != 0)
- return;
-
- maxlog = lp_max_log_size() * 1024;
- if (!dbf || maxlog <= 0)
- return;
-
- if (fstat(fileno(dbf),&st) == 0 && st.st_size > maxlog) {
- fclose(dbf);
- dbf = NULL;
- reopen_logs();
- if (dbf && file_size(debugf) > maxlog) {
- pstring name;
- fclose(dbf);
- dbf = NULL;
- slprintf(name,sizeof(name)-1,"%s.old",debugf);
- rename(debugf,name);
- reopen_logs();
- }
- }
- debug_count=0;
-}
-
-
-/*******************************************************************
-write an debug message on the debugfile. This is called by the DEBUG
-macro
-********************************************************************/
-#ifdef HAVE_STDARG_H
- int Debug1(char *format_str, ...)
-{
-#else
- int Debug1(va_alist)
-va_dcl
-{
- char *format_str;
-#endif
- va_list ap;
- int old_errno = errno;
-
- if (stdout_logging) {
-#ifdef HAVE_STDARG_H
- va_start(ap, format_str);
-#else
- va_start(ap);
- format_str = va_arg(ap,char *);
-#endif
- vfprintf(dbf,format_str,ap);
- va_end(ap);
- errno = old_errno;
- return(0);
- }
-
-#ifdef WITH_SYSLOG
- if (!lp_syslog_only())
-#endif
- {
- if (!dbf) {
- int oldumask = umask(022);
- if(append_log)
- dbf = fopen(debugf,"a");
- else
- dbf = fopen(debugf,"w");
- umask(oldumask);
- if (dbf) {
- setbuf(dbf,NULL);
- } else {
- errno = old_errno;
- return(0);
- }
- }
- }
-
-#ifdef WITH_SYSLOG
- if (syslog_level < lp_syslog())
- {
- /*
- * map debug levels to syslog() priorities
- * note that not all DEBUG(0, ...) calls are
- * necessarily errors
- */
- static int priority_map[] = {
- LOG_ERR, /* 0 */
- LOG_WARNING, /* 1 */
- LOG_NOTICE, /* 2 */
- LOG_INFO, /* 3 */
- };
- int priority;
- pstring msgbuf;
-
- if (syslog_level >= sizeof(priority_map) / sizeof(priority_map[0]) ||
- syslog_level < 0)
- priority = LOG_DEBUG;
- else
- priority = priority_map[syslog_level];
-
-#ifdef HAVE_STDARG_H
- va_start(ap, format_str);
-#else
- va_start(ap);
- format_str = va_arg(ap,char *);
-#endif
- vslprintf(msgbuf, sizeof(msgbuf)-1,format_str, ap);
- va_end(ap);
-
- msgbuf[255] = '\0';
- syslog(priority, "%s", msgbuf);
- }
-#endif
-
-#ifdef WITH_SYSLOG
- if (!lp_syslog_only())
-#endif
- {
-#ifdef HAVE_STDARG_H
- va_start(ap, format_str);
-#else
- va_start(ap);
- format_str = va_arg(ap,char *);
-#endif
- vfprintf(dbf,format_str,ap);
- va_end(ap);
- fflush(dbf);
- }
-
- check_log_size();
-
- errno = old_errno;
- return(0);
-}
/****************************************************************************
find a suitable temporary directory. The result should be copied immediately
Based on a routine by GJC@VILLAGE.COM.
Extensively modified by Andrew.Tridgell@anu.edu.au
****************************************************************************/
-BOOL next_token(char **ptr,char *buff,char *sep)
+BOOL next_token(char **ptr,char *buff,char *sep, int bufsize)
{
char *s;
BOOL quoted;
+ int len=1;
if (!ptr) ptr = &last_ptr;
if (!ptr) return(False);
if (! *s) return(False);
/* copy over the token */
- for (quoted = False; *s && (quoted || !strchr(sep,*s)); s++)
+ for (quoted = False; len < bufsize && *s && (quoted || !strchr(sep,*s)); s++)
{
- if (*s == '\"')
- quoted = !quoted;
- else
- *buff++ = *s;
+ if (*s == '\"') {
+ quoted = !quoted;
+ } else {
+ len++;
+ *buff++ = *s;
+ }
}
*ptr = (*s) ? s+1 : s;
return ret;
}
-
-/* ************************************************************************* **
- * Duplicate a block of memory.
- * ************************************************************************* **
- */
-void *mem_dup( void *from, int size )
- {
- void *tmp;
-
- tmp = malloc( size );
- if( NULL != tmp )
- (void)memcpy( tmp, from, size );
- return( tmp );
- } /* mem_dup */
-
/****************************************************************************
prompte a dptr (to make it recently used)
****************************************************************************/
-void array_promote(char *array,int elsize,int element)
+static void array_promote(char *array,int elsize,int element)
{
char *p;
if (element == 0)
{
fstring tok;
- while (next_token(&options,tok," \t,"))
+ while (next_token(&options,tok," \t,", sizeof(tok)))
{
int ret=0,i;
int value = 1;
{
char *d = dest;
-#if AJT
/* I don't want to get lazy with these ... */
- if (!dest || !src) {
- DEBUG(0,("ERROR: NULL StrCpy() called!\n"));
- ajt_panic();
- }
-#endif
+ SMB_ASSERT(dest && src);
if (!dest) return(NULL);
if (!src) {
}
+#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
****************************************************************************/
/*******************************************************************
check if a file exists
********************************************************************/
-BOOL file_exist(char *fname,struct stat *sbuf)
+BOOL file_exist(char *fname,SMB_STRUCT_STAT *sbuf)
{
- struct stat st;
+ SMB_STRUCT_STAT st;
if (!sbuf) sbuf = &st;
- if (sys_stat(fname,sbuf) != 0)
+ if (dos_stat(fname,sbuf) != 0)
return(False);
return(S_ISREG(sbuf->st_mode));
********************************************************************/
time_t file_modtime(char *fname)
{
- struct stat st;
+ SMB_STRUCT_STAT st;
- if (sys_stat(fname,&st) != 0)
+ if (dos_stat(fname,&st) != 0)
return(0);
return(st.st_mtime);
/*******************************************************************
check if a directory exists
********************************************************************/
-BOOL directory_exist(char *dname,struct stat *st)
+BOOL directory_exist(char *dname,SMB_STRUCT_STAT *st)
{
- struct stat st2;
+ SMB_STRUCT_STAT st2;
BOOL ret;
if (!st) st = &st2;
- if (sys_stat(dname,st) != 0)
+ if (dos_stat(dname,st) != 0)
return(False);
ret = S_ISDIR(st->st_mode);
/*******************************************************************
returns the size in bytes of the named file
********************************************************************/
-uint32 file_size(char *file_name)
+SMB_OFF_T file_size(char *file_name)
{
- struct stat buf;
+ SMB_STRUCT_STAT buf;
buf.st_size = 0;
- sys_stat(file_name,&buf);
+ dos_stat(file_name,&buf);
return(buf.st_size);
}
****************************************************************************/
void unix_format(char *fname)
{
- pstring namecopy;
string_replace(fname,'\\','/');
-
- if (*fname == '/')
- {
- pstrcpy(namecopy,fname);
- pstrcpy(fname,".");
- pstrcat(fname,namecopy);
- }
}
/****************************************************************************
/*******************************************************************
return the number of smb words
********************************************************************/
-int smb_numwords(char *buf)
+static int smb_numwords(char *buf)
{
return (CVAL(buf,smb_wct));
}
/*******************************************************************
return a pointer to the smb_buf data area
********************************************************************/
-int smb_buf_ofs(char *buf)
+static int smb_buf_ofs(char *buf)
{
return (smb_size + CVAL(buf,smb_wct)*2);
}
BOOL trim_string(char *s,char *front,char *back)
{
BOOL ret = False;
- while (front && *front && strncmp(s,front,strlen(front)) == 0)
- {
- char *p = s;
- ret = True;
- while (1)
- {
- if (!(*p = p[strlen(front)]))
- break;
- p++;
- }
- }
- while (back && *back && strlen(s) >= strlen(back) &&
- (strncmp(s+strlen(s)-strlen(back),back,strlen(back))==0))
+ size_t front_len = (front && *front) ? strlen(front) : 0;
+ size_t back_len = (back && *back) ? strlen(back) : 0;
+ size_t s_len;
+
+ while (front_len && strncmp(s, front, front_len) == 0)
+ {
+ char *p = s;
+ ret = True;
+ while (1)
{
- ret = True;
- s[strlen(s)-strlen(back)] = 0;
+ if (!(*p = p[front_len]))
+ break;
+ p++;
}
+ }
+
+ s_len = strlen(s);
+ while (back_len && s_len >= back_len &&
+ (strncmp(s + s_len - back_len, back, back_len)==0))
+ {
+ ret = True;
+ s[s_len - back_len] = 0;
+ s_len = strlen(s);
+ }
return(ret);
}
if (*path == '/' && strcsequal(LastDir,path)) return(0);
DEBUG(3,("chdir to %s\n",path));
- res = sys_chdir(path);
+ res = dos_chdir(path);
if (!res)
pstrcpy(LastDir,path);
return(res);
struct
{
- ino_t inode;
- dev_t dev;
- char *text;
+ SMB_DEV_T dev; /* These *must* be compatible with the types returned in a stat() call. */
+ SMB_INO_T inode; /* These *must* be compatible with the types returned in a stat() call. */
+ char *text; /* The pathname in DOS format. */
BOOL valid;
} ino_list[MAX_GETWDCACHE];
BOOL use_getwd_cache=True;
/*******************************************************************
- return the absolute current directory path
+ return the absolute current directory path - given a UNIX pathname.
+ Note that this path is returned in DOS format, not UNIX
+ format.
********************************************************************/
char *GetWd(char *str)
{
pstring s;
static BOOL getwd_cache_init = False;
- struct stat st, st2;
+ SMB_STRUCT_STAT st, st2;
int i;
*s = 0;
if (!use_getwd_cache)
- return(sys_getwd(str));
+ return(dos_getwd(str));
/* init the cache */
if (!getwd_cache_init)
+ {
+ getwd_cache_init = True;
+ for (i=0;i<MAX_GETWDCACHE;i++)
{
- getwd_cache_init = True;
- for (i=0;i<MAX_GETWDCACHE;i++)
- {
- string_init(&ino_list[i].text,"");
- ino_list[i].valid = False;
- }
+ string_init(&ino_list[i].text,"");
+ ino_list[i].valid = False;
}
+ }
/* Get the inode of the current directory, if this doesn't work we're
in trouble :-) */
- if (stat(".",&st) == -1)
- {
- DEBUG(0,("Very strange, couldn't stat \".\"\n"));
- return(sys_getwd(str));
- }
+ if (dos_stat(".",&st) == -1)
+ {
+ DEBUG(0,("Very strange, couldn't stat \".\"\n"));
+ return(dos_getwd(str));
+ }
for (i=0; i<MAX_GETWDCACHE; i++)
if (ino_list[i].valid)
- {
+ {
- /* If we have found an entry with a matching inode and dev number
- then find the inode number for the directory in the cached string.
- If this agrees with that returned by the stat for the current
- directory then all is o.k. (but make sure it is a directory all
- the same...) */
+ /* If we have found an entry with a matching inode and dev number
+ then find the inode number for the directory in the cached string.
+ If this agrees with that returned by the stat for the current
+ directory then all is o.k. (but make sure it is a directory all
+ the same...) */
- if (st.st_ino == ino_list[i].inode &&
- st.st_dev == ino_list[i].dev)
- {
- if (stat(ino_list[i].text,&st2) == 0)
- {
- if (st.st_ino == st2.st_ino &&
- st.st_dev == st2.st_dev &&
- (st2.st_mode & S_IFMT) == S_IFDIR)
- {
- pstrcpy (str, ino_list[i].text);
-
- /* promote it for future use */
- array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
- return (str);
- }
- else
- {
- /* If the inode is different then something's changed,
- scrub the entry and start from scratch. */
- ino_list[i].valid = False;
- }
- }
- }
+ if (st.st_ino == ino_list[i].inode &&
+ st.st_dev == ino_list[i].dev)
+ {
+ if (dos_stat(ino_list[i].text,&st2) == 0)
+ {
+ if (st.st_ino == st2.st_ino &&
+ st.st_dev == st2.st_dev &&
+ (st2.st_mode & S_IFMT) == S_IFDIR)
+ {
+ pstrcpy (str, ino_list[i].text);
+
+ /* promote it for future use */
+ array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
+ return (str);
+ }
+ else
+ {
+ /* If the inode is different then something's changed,
+ scrub the entry and start from scratch. */
+ ino_list[i].valid = False;
+ }
+ }
}
+ }
/* We don't have the information to hand so rely on traditional methods.
The very slow getcwd, which spawns a process on some systems, or the
not quite so bad getwd. */
- if (!sys_getwd(s))
- {
- DEBUG(0,("Getwd failed, errno %s\n",strerror(errno)));
- return (NULL);
- }
+ if (!dos_getwd(s))
+ {
+ DEBUG(0,("Getwd failed, errno %s\n",strerror(errno)));
+ return (NULL);
+ }
pstrcpy(str,s);
}
}
+/****************************************************************************
+parse out a directory name from a path name. Assumes dos style filenames.
+****************************************************************************/
+static char *dirname_dos(char *path,char *buf)
+{
+ char *p = strrchr(path,'\\');
+
+ if (!p)
+ pstrcpy(buf,path);
+ else
+ {
+ *p = 0;
+ pstrcpy(buf,path);
+ *p = '\\';
+ }
+
+ return(buf);
+}
+
+
/****************************************************************************
expand a wildcard expression, replacing *s with ?s
****************************************************************************/
/****************************************************************************
make a dir struct
****************************************************************************/
-void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode,time_t date)
+void make_dir_struct(char *buf,char *mask,char *fname,SMB_OFF_T size,int mode,time_t date)
{
char *p;
pstring mask2;
CVAL(buf,21) = mode;
put_dos_date(buf,22,date);
SSVAL(buf,26,size & 0xFFFF);
- SSVAL(buf,28,size >> 16);
+ SSVAL(buf,28,(size >> 16)&0xFFFF);
StrnCpy(buf+30,fname,12);
if (!case_sensitive)
strupper(buf+30);
if SYSV use O_NDELAY
if BSD use FNDELAY
****************************************************************************/
-int set_blocking(int fd, BOOL set)
+static int set_blocking(int fd, BOOL set)
{
int val;
#ifdef O_NONBLOCK
/****************************************************************************
write to a socket
****************************************************************************/
-int write_socket(int fd,char *buf,int len)
+ssize_t write_socket(int fd,char *buf,size_t len)
{
- int ret=0;
+ ssize_t ret=0;
if (passive)
return(len);
/****************************************************************************
read from a socket
****************************************************************************/
-int read_udp_socket(int fd,char *buf,int len)
+ssize_t read_udp_socket(int fd,char *buf,size_t len)
{
- int ret;
+ ssize_t ret;
struct sockaddr_in sock;
int socklen;
socklen = sizeof(sock);
bzero((char *)&sock,socklen);
bzero((char *)&lastip,sizeof(lastip));
- ret = recvfrom(fd,buf,len,0,(struct sockaddr *)&sock,&socklen);
+ ret = (ssize_t)recvfrom(fd,buf,len,0,(struct sockaddr *)&sock,&socklen);
if (ret <= 0) {
DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno)));
return(0);
read data from a device with a timout in msec.
mincount = if timeout, minimum to read before returning
maxcount = number to be read.
+time_out = timeout in milliseconds
****************************************************************************/
-int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out)
+
+ssize_t read_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned int time_out)
{
fd_set fds;
int selrtn;
- int readret;
- int nread = 0;
+ ssize_t readret;
+ size_t nread = 0;
struct timeval timeout;
/* just checking .... */
#endif /* WITH_SSL */
if (readret == 0) {
- smb_read_error = READ_EOF;
- return -1;
+ smb_read_error = READ_EOF;
+ return -1;
}
if (readret == -1) {
- smb_read_error = READ_ERROR;
- return -1;
+ smb_read_error = READ_ERROR;
+ return -1;
}
nread += readret;
}
- return(nread);
+ return((ssize_t)nread);
}
/* Most difficult - timeout read */
/* If this is ever called on a disk file and
- mincnt is greater then the filesize then
- system performance will suffer severely as
- select always return true on disk files */
+ mincnt is greater then the filesize then
+ system performance will suffer severely as
+ select always returns true on disk files */
/* Set initial timeout */
timeout.tv_sec = time_out / 1000;
timeout.tv_usec = 1000 * (time_out % 1000);
- for (nread=0; nread<mincnt; )
- {
- FD_ZERO(&fds);
- FD_SET(fd,&fds);
+ for (nread=0; nread < mincnt; )
+ {
+ FD_ZERO(&fds);
+ FD_SET(fd,&fds);
- selrtn = sys_select(&fds,&timeout);
+ selrtn = sys_select(fd+1,&fds,&timeout);
- /* Check if error */
- if(selrtn == -1) {
- /* something is wrong. Maybe the socket is dead? */
- smb_read_error = READ_ERROR;
- return -1;
- }
+ /* Check if error */
+ if(selrtn == -1) {
+ /* something is wrong. Maybe the socket is dead? */
+ smb_read_error = READ_ERROR;
+ return -1;
+ }
- /* Did we timeout ? */
- if (selrtn == 0) {
- smb_read_error = READ_TIMEOUT;
- return -1;
- }
+ /* Did we timeout ? */
+ if (selrtn == 0) {
+ smb_read_error = READ_TIMEOUT;
+ return -1;
+ }
#ifdef WITH_SSL
if(fd == sslFd){
readret = read(fd, buf+nread, maxcnt-nread);
#endif /* WITH_SSL */
- if (readret == 0) {
- /* we got EOF on the file descriptor */
- smb_read_error = READ_EOF;
- return -1;
- }
+ if (readret == 0) {
+ /* we got EOF on the file descriptor */
+ smb_read_error = READ_EOF;
+ return -1;
+ }
- if (readret == -1) {
- /* the descriptor is probably dead */
- smb_read_error = READ_ERROR;
- return -1;
- }
-
- nread += readret;
+ if (readret == -1) {
+ /* the descriptor is probably dead */
+ smb_read_error = READ_ERROR;
+ return -1;
}
+
+ nread += readret;
+ }
/* Return the number we got */
- return(nread);
-}
-
-/****************************************************************************
-read data from the client. Maxtime is in milliseconds
-****************************************************************************/
-int read_max_udp(int fd,char *buffer,int bufsize,int maxtime)
-{
- fd_set fds;
- int selrtn;
- int nread;
- struct timeval timeout;
-
- FD_ZERO(&fds);
- FD_SET(fd,&fds);
-
- timeout.tv_sec = maxtime / 1000;
- timeout.tv_usec = (maxtime % 1000) * 1000;
-
- selrtn = sys_select(&fds,maxtime>0?&timeout:NULL);
-
- if (!FD_ISSET(fd,&fds))
- return 0;
-
- nread = read_udp_socket(fd, buffer, bufsize);
-
- /* return the number got */
- return(nread);
+ return((ssize_t)nread);
}
/*******************************************************************
/****************************************************************************
read data from the client, reading exactly N bytes.
****************************************************************************/
-int read_data(int fd,char *buffer,int N)
+ssize_t read_data(int fd,char *buffer,size_t N)
{
- int ret;
- int total=0;
+ ssize_t ret;
+ size_t total=0;
smb_read_error = 0;
}
total += ret;
}
- return total;
+ return (ssize_t)total;
}
/****************************************************************************
write data to a fd
****************************************************************************/
-int write_data(int fd,char *buffer,int N)
+ssize_t write_data(int fd,char *buffer,size_t N)
{
- int total=0;
- int ret;
+ size_t total=0;
+ ssize_t ret;
while (total < N)
{
total += ret;
}
- return total;
+ return (ssize_t)total;
}
/****************************************************************************
transfer some data between two fd's
****************************************************************************/
-int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align)
+SMB_OFF_T transfer_file(int infd,int outfd,SMB_OFF_T n,char *header,int headlen,int align)
{
static char *buf=NULL;
static int size=0;
char *buf1,*abuf;
- int total = 0;
+ SMB_OFF_T total = 0;
- DEBUG(4,("transfer_file %d (head=%d) called\n",n,headlen));
+ DEBUG(4,("transfer_file n=%.0f (head=%d) called\n",(double)n,headlen));
if (size == 0) {
size = lp_readsize();
n += headlen;
while (n > 0)
- {
- int s = MIN(n,size);
- int ret,ret2=0;
+ {
+ int s = (int)MIN(n,(SMB_OFF_T)size);
+ int ret,ret2=0;
- ret = 0;
+ ret = 0;
- if (header && (headlen >= MIN(s,1024))) {
- buf1 = header;
- s = headlen;
- ret = headlen;
- headlen = 0;
- header = NULL;
- } else {
- buf1 = abuf;
- }
+ if (header && (headlen >= MIN(s,1024))) {
+ buf1 = header;
+ s = headlen;
+ ret = headlen;
+ headlen = 0;
+ header = NULL;
+ } else {
+ buf1 = abuf;
+ }
- if (header && headlen > 0)
- {
- ret = MIN(headlen,size);
- memcpy(buf1,header,ret);
- headlen -= ret;
- header += ret;
- if (headlen <= 0) header = NULL;
- }
+ if (header && headlen > 0)
+ {
+ ret = MIN(headlen,size);
+ memcpy(buf1,header,ret);
+ headlen -= ret;
+ header += ret;
+ if (headlen <= 0) header = NULL;
+ }
- if (s > ret)
- ret += read(infd,buf1+ret,s-ret);
+ if (s > ret)
+ ret += read(infd,buf1+ret,s-ret);
- if (ret > 0)
- {
- ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
- if (ret2 > 0) total += ret2;
- /* if we can't write then dump excess data */
- if (ret2 != ret)
- transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
- }
- if (ret <= 0 || ret2 != ret)
- return(total);
- n -= ret;
+ if (ret > 0)
+ {
+ ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
+ if (ret2 > 0) total += ret2;
+ /* if we can't write then dump excess data */
+ if (ret2 != ret)
+ transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
}
+ if (ret <= 0 || ret2 != ret)
+ return(total);
+ n -= ret;
+ }
return(total);
}
store the result in the buffer
This version of the function will return a length of zero on receiving
a keepalive packet.
+timeout is in milliseconds.
****************************************************************************/
-static int read_smb_length_return_keepalive(int fd,char *inbuf,int timeout)
+static ssize_t read_smb_length_return_keepalive(int fd,char *inbuf,unsigned int timeout)
{
- int len=0, msg_type;
- BOOL ok=False;
+ ssize_t len=0;
+ int msg_type;
+ BOOL ok = False;
while (!ok)
- {
- if (timeout > 0)
- ok = (read_with_timeout(fd,inbuf,4,4,timeout) == 4);
- else
- ok = (read_data(fd,inbuf,4) == 4);
+ {
+ if (timeout > 0)
+ ok = (read_with_timeout(fd,inbuf,4,4,timeout) == 4);
+ else
+ ok = (read_data(fd,inbuf,4) == 4);
- if (!ok)
- return(-1);
+ if (!ok)
+ return(-1);
- len = smb_len(inbuf);
- msg_type = CVAL(inbuf,0);
+ len = smb_len(inbuf);
+ msg_type = CVAL(inbuf,0);
- if (msg_type == 0x85)
- DEBUG(5,("Got keepalive packet\n"));
- }
+ if (msg_type == 0x85)
+ DEBUG(5,("Got keepalive packet\n"));
+ }
DEBUG(10,("got smb length of %d\n",len));
read 4 bytes of a smb packet and return the smb length of the packet
store the result in the buffer. This version of the function will
never return a session keepalive (length of zero).
+timeout is in milliseconds.
****************************************************************************/
-int read_smb_length(int fd,char *inbuf,int timeout)
+ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout)
{
- int len;
+ ssize_t len;
for(;;)
{
/****************************************************************************
read an smb from a fd. Note that the buffer *MUST* be of size
BUFFER_SIZE+SAFETY_MARGIN.
- The timeout is in milli seconds.
-
+ The timeout is in milliseconds.
This function will return on a
receipt of a session keepalive packet.
****************************************************************************/
-BOOL receive_smb(int fd,char *buffer, int timeout)
+BOOL receive_smb(int fd,char *buffer, unsigned int timeout)
{
- int len,ret;
+ ssize_t len,ret;
smb_read_error = 0;
/****************************************************************************
read an smb from a fd ignoring all keepalive packets. Note that the buffer
*MUST* be of size BUFFER_SIZE+SAFETY_MARGIN.
- The timeout is in milli seconds
+ The timeout is in milliseconds
This is exactly the same as receive_smb except that it never returns
a session keepalive packet (just as receive_smb used to do).
should never go into a blocking read.
****************************************************************************/
-BOOL client_receive_smb(int fd,char *buffer, int timeout)
+BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout)
{
BOOL ret;
- for(;;)
- {
- ret = receive_smb(fd, buffer, timeout);
-
- if(ret == False)
- return ret;
-
- /* Ignore session keepalive packets. */
- if(CVAL(buffer,0) != 0x85)
- break;
- }
- return ret;
-}
-
-/****************************************************************************
- read a message from a udp fd.
-The timeout is in milli seconds
-****************************************************************************/
-BOOL receive_local_message(int fd, char *buffer, int buffer_len, int timeout)
-{
- struct sockaddr_in from;
- int fromlen = sizeof(from);
- int32 msg_len = 0;
-
- smb_read_error = 0;
-
- if(timeout != 0)
- {
- struct timeval to;
- fd_set fds;
- int selrtn;
-
- FD_ZERO(&fds);
- FD_SET(fd,&fds);
-
- to.tv_sec = timeout / 1000;
- to.tv_usec = (timeout % 1000) * 1000;
-
- selrtn = sys_select(&fds,&to);
-
- /* Check if error */
- if(selrtn == -1)
- {
- /* something is wrong. Maybe the socket is dead? */
- smb_read_error = READ_ERROR;
- return False;
- }
-
- /* Did we timeout ? */
- if (selrtn == 0)
- {
- smb_read_error = READ_TIMEOUT;
- return False;
- }
- }
-
- /*
- * Read a loopback udp message.
- */
- msg_len = recvfrom(fd, &buffer[UDP_CMD_HEADER_LEN],
- buffer_len - UDP_CMD_HEADER_LEN, 0,
- (struct sockaddr *)&from, &fromlen);
-
- if(msg_len < 0)
- {
- DEBUG(0,("receive_local_message. Error in recvfrom. (%s).\n",strerror(errno)));
- return False;
- }
-
- /* Validate message length. */
- if(msg_len > (buffer_len - UDP_CMD_HEADER_LEN))
- {
- DEBUG(0,("receive_local_message: invalid msg_len (%d) max can be %d\n",
- msg_len,
- buffer_len - UDP_CMD_HEADER_LEN));
- return False;
- }
-
- /* Validate message from address (must be localhost). */
- if(from.sin_addr.s_addr != htonl(INADDR_LOOPBACK))
- {
- DEBUG(0,("receive_local_message: invalid 'from' address \
-(was %x should be 127.0.0.1\n", from.sin_addr.s_addr));
- return False;
- }
-
- /* Setup the message header */
- SIVAL(buffer,UDP_CMD_LEN_OFFSET,msg_len);
- SSVAL(buffer,UDP_CMD_PORT_OFFSET,ntohs(from.sin_port));
-
- return True;
-}
-
-/****************************************************************************
- structure to hold a linked list of local messages.
- for processing.
-****************************************************************************/
-
-typedef struct smb_message_list {
- ubi_slNode msg_next;
- char *msg_buf;
- int msg_len;
-} pending_message_list;
-
-static ubi_slList smb_oplock_queue = { NULL, (ubi_slNodePtr)&smb_oplock_queue, 0};
-
-/****************************************************************************
- Function to push a message onto the tail of a linked list of smb messages ready
- for processing.
-****************************************************************************/
-
-static BOOL push_local_message(ubi_slList *list_head, char *buf, int msg_len)
-{
- pending_message_list *msg = (pending_message_list *)
- malloc(sizeof(pending_message_list));
-
- if(msg == NULL)
- {
- DEBUG(0,("push_local_message: malloc fail (1)\n"));
- return False;
- }
-
- msg->msg_buf = (char *)malloc(msg_len);
- if(msg->msg_buf == NULL)
- {
- DEBUG(0,("push_local_message: malloc fail (2)\n"));
- free((char *)msg);
- return False;
- }
-
- memcpy(msg->msg_buf, buf, msg_len);
- msg->msg_len = msg_len;
-
- ubi_slAddTail( list_head, msg);
-
- return True;
-}
-
-/****************************************************************************
- Function to push a smb message onto a linked list of local smb messages ready
- for processing.
-****************************************************************************/
-
-BOOL push_oplock_pending_smb_message(char *buf, int msg_len)
-{
- return push_local_message(&smb_oplock_queue, buf, msg_len);
-}
-
-/****************************************************************************
- Do a select on an two fd's - with timeout.
-
- If a local udp message has been pushed onto the
- queue (this can only happen during oplock break
- processing) return this first.
-
- If a pending smb message has been pushed onto the
- queue (this can only happen during oplock break
- processing) return this next.
-
- If the first smbfd is ready then read an smb from it.
- if the second (loopback UDP) fd is ready then read a message
- from it and setup the buffer header to identify the length
- and from address.
- Returns False on timeout or error.
- Else returns True.
-
-The timeout is in milli seconds
-****************************************************************************/
-BOOL receive_message_or_smb(int smbfd, int oplock_fd,
- char *buffer, int buffer_len,
- int timeout, BOOL *got_smb)
-{
- fd_set fds;
- int selrtn;
- struct timeval to;
-
- smb_read_error = 0;
-
- *got_smb = False;
-
- /*
- * Check to see if we already have a message on the smb queue.
- * If so - copy and return it.
- */
-
- if(ubi_slCount(&smb_oplock_queue) != 0)
- {
- pending_message_list *msg = (pending_message_list *)ubi_slRemHead(&smb_oplock_queue);
- memcpy(buffer, msg->msg_buf, MIN(buffer_len, msg->msg_len));
-
- /* Free the message we just copied. */
- free((char *)msg->msg_buf);
- free((char *)msg);
- *got_smb = True;
-
- DEBUG(5,("receive_message_or_smb: returning queued smb message.\n"));
- return True;
- }
-
- FD_ZERO(&fds);
- FD_SET(smbfd,&fds);
- FD_SET(oplock_fd,&fds);
-
- to.tv_sec = timeout / 1000;
- to.tv_usec = (timeout % 1000) * 1000;
-
- selrtn = sys_select(&fds,timeout>0?&to:NULL);
+ for(;;)
+ {
+ ret = receive_smb(fd, buffer, timeout);
- /* Check if error */
- if(selrtn == -1) {
- /* something is wrong. Maybe the socket is dead? */
- smb_read_error = READ_ERROR;
- return False;
- }
-
- /* Did we timeout ? */
- if (selrtn == 0) {
- smb_read_error = READ_TIMEOUT;
- return False;
- }
+ if(ret == False)
+ return ret;
- if (FD_ISSET(smbfd,&fds))
- {
- *got_smb = True;
- return receive_smb(smbfd, buffer, 0);
- }
- else
- {
- return receive_local_message(oplock_fd, buffer, buffer_len, 0);
+ /* Ignore session keepalive packets. */
+ if(CVAL(buffer,0) != 0x85)
+ break;
}
+ return ret;
}
/****************************************************************************
****************************************************************************/
BOOL send_smb(int fd,char *buffer)
{
- int len;
- int ret,nwritten=0;
+ size_t len;
+ size_t nwritten=0;
+ ssize_t ret;
len = smb_len(buffer) + 4;
while (nwritten < len)
+ {
+ ret = write_socket(fd,buffer+nwritten,len - nwritten);
+ if (ret <= 0)
{
- ret = write_socket(fd,buffer+nwritten,len - nwritten);
- if (ret <= 0)
- {
- DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
- close_sockets();
- exit(1);
- }
- nwritten += ret;
+ DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
+ close_sockets();
+ exit(1);
}
-
+ nwritten += ret;
+ }
return True;
}
/****************************************************************************
find a pointer to a netbios name
****************************************************************************/
-char *name_ptr(char *buf,int ofs)
+static char *name_ptr(char *buf,int ofs)
{
unsigned char c = *(unsigned char *)(buf+ofs);
return the total storage length of a mangled name
****************************************************************************/
int name_len( char *s )
- {
+{
int len;
/* If the two high bits of the byte are set, return 2. */
}
return( len );
- } /* name_len */
+} /* name_len */
/****************************************************************************
send a single packet to a port on another machine
/*******************************************************************
sleep for a specified number of milliseconds
********************************************************************/
-void msleep(int t)
+static void msleep(int t)
{
int tdiff=0;
struct timeval tval,t1,t2;
FD_ZERO(&fds);
errno = 0;
- sys_select(&fds,&tval);
+ sys_select(0,&fds,&tval);
GetTimeOfDay(&t2);
tdiff = TvalDiff(&t1,&t2);
if (!list) return(False);
- while (next_token(&p,tok,LIST_SEP))
- {
- if (casesensitive) {
- if (strcmp(tok,s) == 0)
- return(True);
- } else {
- if (StrCaseCmp(tok,s) == 0)
- return(True);
- }
+ while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
+ if (casesensitive) {
+ if (strcmp(tok,s) == 0)
+ return(True);
+ } else {
+ if (StrCaseCmp(tok,s) == 0)
+ return(True);
}
+ }
return(False);
}
return(ret);
}
+/*********************************************************
+* Recursive routine that is called by unix_mask_match.
+* Does the actual matching. This is the 'original code'
+* used by the unix matcher.
+*********************************************************/
+static BOOL unix_do_match(char *str, char *regexp, int case_sig)
+{
+ 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 && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
+ str++;
+ if(unix_do_match(str,p,case_sig))
+ return True;
+ if(!*str)
+ return False;
+ else
+ str++;
+ }
+ return False;
+
+ default:
+ if(case_sig) {
+ if(*str != *p)
+ return False;
+ } else {
+ if(toupper(*str) != toupper(*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;
+}
+
+
+/*********************************************************
+* Routine to match a given string with a regexp - uses
+* simplified regexp that takes * and ? only. Case can be
+* significant or not.
+* This is the 'original code' used by the unix matcher.
+*********************************************************/
+
+static BOOL unix_mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
+{
+ char *p;
+ pstring p1, p2;
+ fstring ebase,eext,sbase,sext;
+
+ BOOL matched;
+
+ /* Make local copies of str and regexp */
+ StrnCpy(p1,regexp,sizeof(pstring)-1);
+ StrnCpy(p2,str,sizeof(pstring)-1);
+
+ if (!strchr(p2,'.')) {
+ pstrcat(p2,".");
+ }
+
+ /* Remove any *? and ** as they are meaningless */
+ for(p = p1; *p; p++)
+ while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
+ (void)pstrcpy( &p[1], &p[2]);
+
+ if (strequal(p1,"*")) return(True);
+
+ DEBUG(8,("unix_mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
+
+ if (trans2) {
+ fstrcpy(ebase,p1);
+ fstrcpy(sbase,p2);
+ } else {
+ if ((p=strrchr(p1,'.'))) {
+ *p = 0;
+ fstrcpy(ebase,p1);
+ fstrcpy(eext,p+1);
+ } else {
+ fstrcpy(ebase,p1);
+ eext[0] = 0;
+ }
+
+ if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
+ *p = 0;
+ fstrcpy(sbase,p2);
+ fstrcpy(sext,p+1);
+ } else {
+ fstrcpy(sbase,p2);
+ fstrcpy(sext,"");
+ }
+ }
+
+ matched = unix_do_match(sbase,ebase,case_sig) &&
+ (trans2 || unix_do_match(sext,eext,case_sig));
+
+ DEBUG(8,("unix_mask_match returning %d\n", matched));
+
+ return matched;
+}
+
/*********************************************************
* Recursive routine that is called by mask_match.
* Does the actual matching. Returns True if matched,
-* False if failed.
+* False if failed. This is the 'new' NT style matcher.
*********************************************************/
BOOL do_match(char *str, char *regexp, int case_sig)
* simplified regexp that takes * and ? only. Case can be
* significant or not.
* The 8.3 handling was rewritten by Ums Harald <Harald.Ums@pro-sieben.de>
+* This is the new 'NT style' matcher.
*********************************************************/
BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
set the length of a file from a filedescriptor.
Returns 0 on success, -1 on failure.
****************************************************************************/
-int set_filelen(int fd, long len)
+int set_filelen(int fd, SMB_OFF_T len)
{
/* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
extend a file with ftruncate. Provide alternate implementation
for this */
#ifdef HAVE_FTRUNCATE_EXTEND
- return ftruncate(fd, len);
+ return sys_ftruncate(fd, len);
#else
- struct stat st;
+ SMB_STRUCT_STAT st;
char c = 0;
- long currpos = lseek(fd, 0L, SEEK_CUR);
+ SMB_OFF_T currpos = sys_lseek(fd, (SMB_OFF_T)0, SEEK_CUR);
if(currpos < 0)
return -1;
the requested size (call ftruncate),
or shorter, in which case seek to len - 1 and write 1
byte of zero */
- if(fstat(fd, &st)<0)
+ if(sys_fstat(fd, &st)<0)
return -1;
#ifdef S_ISFIFO
if(st.st_size == len)
return 0;
if(st.st_size > len)
- return ftruncate(fd, len);
+ return sys_ftruncate(fd, len);
- if(lseek(fd, len-1, SEEK_SET) != len -1)
+ if(sys_lseek(fd, len-1, SEEK_SET) != len -1)
return -1;
if(write(fd, &c, 1)!=1)
return -1;
/* Seek to where we were */
- lseek(fd, currpos, SEEK_SET);
+ sys_lseek(fd, currpos, SEEK_SET);
return 0;
#endif
}
-/****************************************************************************
-return the byte checksum of some data
-****************************************************************************/
-int byte_checksum(char *buf,int len)
-{
- unsigned char *p = (unsigned char *)buf;
- int ret = 0;
- while (len--)
- ret += *p++;
- return(ret);
-}
-
-
-
#ifdef HPUX
/****************************************************************************
this is a version of setbuffer() for those machines that only have setvbuf
#endif
-/****************************************************************************
-parse out a directory name from a path name. Assumes dos style filenames.
-****************************************************************************/
-char *dirname_dos(char *path,char *buf)
-{
- char *p = strrchr(path,'\\');
-
- if (!p)
- pstrcpy(buf,path);
- else
- {
- *p = 0;
- pstrcpy(buf,path);
- *p = '\\';
- }
-
- return(buf);
-}
-
-
/****************************************************************************
parse out a filename from a path name. Assumes dos style filenames.
****************************************************************************/
/****************************************************************************
expand a pointer to be a particular size
****************************************************************************/
-void *Realloc(void *p,int size)
+void *Realloc(void *p,size_t size)
{
void *ret=NULL;
}
-/****************************************************************************
- Signal handler for SIGPIPE (write on a disconnected socket)
-****************************************************************************/
-void Abort(void )
-{
- DEBUG(0,("Probably got SIGPIPE\nExiting\n"));
- exit(2);
-}
-
/****************************************************************************
get my own name and IP
****************************************************************************/
return(def);
}
-/****************************************************************************
-interpret a security level
-****************************************************************************/
-int interpret_security(char *str,int def)
-{
- if (strequal(str,"SERVER"))
- return(SEC_SERVER);
- if (strequal(str,"USER"))
- return(SEC_USER);
- if (strequal(str,"SHARE"))
- return(SEC_SHARE);
-
- DEBUG(0,("Unrecognised security level %s\n",str));
-
- return(def);
-}
-
/****************************************************************************
interpret an internet address or name into an IP address in 4 byte form
if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
for (i=0; pure_address && str[i]; i++)
- if (!(isdigit(str[i]) || str[i] == '.'))
+ if (!(isdigit((int)str[i]) || str[i] == '.'))
pure_address = False;
/* if it's in the form of an IP address then get the lib to interpret it */
As we may end up doing both, cache the last YP result.
*******************************************************************/
-#ifdef NISPLUS_HOME
+#ifdef WITH_NISPLUS_HOME
static char *automount_lookup(char *user_name)
{
static fstring last_key = "";
DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n", user_name, last_value));
return last_value;
}
-#else /* NISPLUS_HOME */
+#else /* WITH_NISPLUS_HOME */
static char *automount_lookup(char *user_name)
{
static fstring last_key = "";
DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, last_value));
return last_value;
}
-#endif /* NISPLUS_HOME */
+#endif /* WITH_NISPLUS_HOME */
#endif
/*******************************************************************
This is Luke's original function with the NIS lookup code
moved out to a separate function.
*******************************************************************/
-
-char *automount_server(char *user_name)
+static char *automount_server(char *user_name)
{
static pstring server_name;
Patch from jkf@soton.ac.uk
Added this to implement %p (NIS auto-map version of %H)
*******************************************************************/
-
-char *automount_path(char *user_name)
+static char *automount_path(char *user_name)
{
static pstring server_path;
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?
********************************************************************/
return(name);
}
-#if AJT
/*******************************************************************
-my own panic function - not suitable for general use
+something really nasty happened - panic!
********************************************************************/
-void ajt_panic(void)
+void smb_panic(char *why)
{
- system("/usr/bin/X11/xedit -display :0 /tmp/ERROR_FAULT");
+ char *cmd = lp_panic_action();
+ if (cmd && *cmd) {
+ system(cmd);
+ }
+ DEBUG(0,("PANIC: %s\n", why));
+ exit(1);
}
-#endif
/*******************************************************************
a readdir wrapper which just returns the file name
-also return the inode number if requested
********************************************************************/
char *readdirname(void *p)
{
{
if(namelist->is_wild)
{
- /* look for a wildcard match. */
- if (mask_match(last_component, namelist->name, case_sensitive, False))
+ /*
+ * 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;
/****************************************************************************
routine to do file locking
****************************************************************************/
-BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type)
+BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
{
#if HAVE_FCNTL_LOCK
- struct flock lock;
+ SMB_STRUCT_FLOCK lock;
int ret;
- /*
- * FIXME.
- * NB - this code will need re-writing to cope with large (64bit)
- * lock requests. JRA.
- */
-
if(lp_ole_locking_compat()) {
- uint32 mask = 0xC0000000;
+ SMB_OFF_T mask = ((SMB_OFF_T)0xC) << (SMB_OFF_T_BITS-4);
+ SMB_OFF_T mask2= ((SMB_OFF_T)0x3) << (SMB_OFF_T_BITS-4);
/* make sure the count is reasonable, we might kill the lockd otherwise */
count &= ~mask;
still allows OLE2 apps to operate, but should stop lockd from
dieing */
if ((offset & mask) != 0)
- offset = (offset & ~mask) | ((offset & mask) >> 2);
+ offset = (offset & ~mask) | (((offset & mask) >> 2) & mask2);
} else {
- uint32 mask = ((unsigned)1<<31);
- int32 s_count = (int32) count; /* Signed count. */
- int32 s_offset = (int32)offset; /* Signed offset. */
+ SMB_OFF_T mask = ((SMB_OFF_T)0x8) << (SMB_OFF_T_BITS-4);
+ SMB_OFF_T neg_mask = ~mask;
/* interpret negative counts as large numbers */
- if (s_count < 0)
- s_count &= ~mask;
+ if (count < 0)
+ count &= ~mask;
/* no negative offsets */
- if(s_offset < 0)
- s_offset &= ~mask;
+ if(offset < 0)
+ offset &= ~mask;
/* count + offset must be in range */
- while ((s_offset < 0 || (s_offset + s_count < 0)) && mask)
+ while ((offset < 0 || (offset + count < 0)) && mask)
{
- s_offset &= ~mask;
- mask = mask >> 1;
+ offset &= ~mask;
+ mask = ((mask >> 1) & neg_mask);
}
-
- offset = (uint32)s_offset;
- count = (uint32)s_count;
}
-
- DEBUG(8,("fcntl_lock %d %d %d %d %d\n",fd,op,(int)offset,(int)count,type));
+ 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 = (int)offset;
- lock.l_len = (int)count;
+ 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 == F_GETLK)
+ if (op == SMB_F_GETLK)
+ {
+ if ((ret != -1) &&
+ (lock.l_type != F_UNLCK) &&
+ (lock.l_pid != 0) &&
+ (lock.l_pid != getpid()))
{
- 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,lock.l_pid));
- return(True);
- }
-
- /* it must be not locked or locked by me */
- return(False);
+ 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 %d count %d op %d type %d (%s)\n",
- offset,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);
- }
+ {
+ DEBUG(3,("lock failed at offset %.0f count %.0f op %d type %d (%s)\n",
+ (double)offset,(double)count,op,type,strerror(errno)));
- return(False);
+ /* 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"));
#endif
}
-/*******************************************************************
-lock a file - returning a open file descriptor or -1 on failure
-The timeout is in seconds. 0 means no timeout
-********************************************************************/
-int file_lock(char *name,int timeout)
-{
- int fd = open(name,O_RDWR|O_CREAT,0666);
- time_t t=0;
- if (fd < 0) return(-1);
-
-#if HAVE_FCNTL_LOCK
- if (timeout) t = time(NULL);
- while (!timeout || (time(NULL)-t < timeout)) {
- if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)) return(fd);
- msleep(LOCK_RETRY_TIMEOUT);
- }
- return(-1);
-#else
- return(fd);
-#endif
-}
-
-/*******************************************************************
-unlock a file locked by file_lock
-********************************************************************/
-void file_unlock(int fd)
-{
- if (fd<0) return;
-#if HAVE_FCNTL_LOCK
- fcntl_lock(fd,F_SETLK,0,1,F_UNLCK);
-#endif
- close(fd);
-}
-
/*******************************************************************
is the name specified one of my netbios names
returns true is it is equal, false otherwise
return lbuf;
}
-/*******************************************************************
-strncpy for unicode strings
-********************************************************************/
-int unistrncpy(char *dst, char *src, int len)
-{
- int num_wchars = 0;
-
- while (*src && len > 0)
- {
- *dst++ = *src++;
- *dst++ = *src++;
- len--;
- num_wchars++;
- }
- *dst++ = 0;
- *dst++ = 0;
-
- return num_wchars;
-}
-
/*******************************************************************
strcpy for unicode strings. returns length (in num of wide chars)
return dest;
}
-/*******************************************************************
-align a pointer to a multiple of 4 bytes
-********************************************************************/
-char *align4(char *q, char *base)
-{
- if ((q - base) & 3)
- {
- q += 4 - ((q - base) & 3);
- }
- return q;
-}
-
/*******************************************************************
align a pointer to a multiple of 2 bytes
********************************************************************/
return q;
}
-/*******************************************************************
-align a pointer to a multiple of align_offset bytes. looks like it
-will work for offsets of 0, 2 and 4...
-********************************************************************/
-char *align_offset(char *q, char *base, int align_offset_len)
-{
- int mod = ((q - base) & (align_offset_len-1));
- if (align_offset_len != 0 && mod != 0)
- {
- q += align_offset_len - mod;
- }
- return q;
-}
-
void print_asc(int level, unsigned char *buf,int len)
{
int i;
}
p += 2;
- if(!next_token(&p, tok, "-")) {
+ if(!next_token(&p, tok, "-", sizeof(tok))) {
DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
return False;
}
/* Get the revision number. */
sidout->sid_rev_num = atoi(tok);
- if(!next_token(&p, tok, "-")) {
+ if(!next_token(&p, tok, "-", sizeof(tok))) {
DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
return False;
}
sidout->num_auths = 0;
- while(next_token(&p, tok, "-") && sidout->num_auths < MAXSUBAUTHS) {
+ while(next_token(&p, tok, "-", sizeof(tok)) &&
+ sidout->num_auths < MAXSUBAUTHS) {
/*
* NOTE - the subauths are in native machine-endian format. They
* are converted to little-endian when linearized onto the wire.
return True;
}
+
+/*****************************************************************************
+ * Provide a checksum on a string
+ *
+ * Input: s - the nul-terminated character string for which the checksum
+ * will be calculated.
+ *
+ * Output: The checksum value calculated for s.
+ *
+ * ****************************************************************************
+ */
+int str_checksum(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);
+} /* str_checksum */
+
+
+
+/*****************************************************************
+zero a memory area then free it. Used to catch bugs faster
+*****************************************************************/
+void zero_free(void *p, size_t size)
+{
+ memset(p, 0, size);
+ free(p);
+}