#include "includes.h"
-#if (defined(NETGROUP) && defined (AUTOMOUNT))
-#ifdef NISPLUS_HOME
+#if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
+#ifdef WITH_NISPLUS_HOME
#include <rpcsvc/nis.h>
#else
#include "rpcsvc/ypclnt.h"
#endif
#endif
-#ifdef USE_SSL
+#ifdef WITH_SSL
#include <ssl.h>
#undef Realloc /* SSLeay defines this and samba has a function of this name */
extern SSL *ssl;
extern int sslFd;
-#endif /* USE_SSL */
+#endif /* WITH_SSL */
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;
-
/* 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);
-#ifndef DONT_REINSTALL_SIG
- signal(SIGUSR2, SIGNAL_CAST sig_usr2);
-#endif
- 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);
-#ifndef DONT_REINSTALL_SIG
- signal(SIGUSR1, SIGNAL_CAST sig_usr1);
-#endif
- return(0);
-}
-#endif /* SIGUSR1 */
-
-
-/*******************************************************************
- get ready for syslog stuff
- ******************************************************************/
-void setup_logging(char *pname,BOOL interactive)
-{
-#ifdef 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 __STDC__
- 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 __STDC__
- 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 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 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 __STDC__
- 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 SYSLOG
- if (!lp_syslog_only())
-#endif
- {
-#ifdef __STDC__
- 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
as it may be overwritten by a subsequent call
return ret;
}
-#ifndef HAVE_MEMMOVE
-/*******************************************************************
-safely copies memory, ensuring no overlap problems.
-this is only used if the machine does not have it's own memmove().
-this is not the fastest algorithm in town, but it will do for our
-needs.
-********************************************************************/
-void *MemMove(void *dest,void *src,int size)
-{
- unsigned long d,s;
- int i;
- if (dest==src || !size) return(dest);
-
- d = (unsigned long)dest;
- s = (unsigned long)src;
-
- if ((d >= (s+size)) || (s >= (d+size))) {
- /* no overlap */
- memcpy(dest,src,size);
- return(dest);
- }
-
- if (d < s)
- {
- /* we can forward copy */
- if (s-d >= sizeof(int) &&
- !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
- /* do it all as words */
- int *idest = (int *)dest;
- int *isrc = (int *)src;
- size /= sizeof(int);
- for (i=0;i<size;i++) idest[i] = isrc[i];
- } else {
- /* simplest */
- char *cdest = (char *)dest;
- char *csrc = (char *)src;
- for (i=0;i<size;i++) cdest[i] = csrc[i];
- }
- }
- else
- {
- /* must backward copy */
- if (d-s >= sizeof(int) &&
- !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
- /* do it all as words */
- int *idest = (int *)dest;
- int *isrc = (int *)src;
- size /= sizeof(int);
- for (i=size-1;i>=0;i--) idest[i] = isrc[i];
- } else {
- /* simplest */
- char *cdest = (char *)dest;
- char *csrc = (char *)src;
- for (i=size-1;i>=0;i--) cdest[i] = csrc[i];
- }
- }
- return(dest);
-}
-#endif
/* ************************************************************************* **
* Duplicate a block of memory.
****************************************************************************/
void close_sockets(void )
{
-#ifdef USE_SSL
+#ifdef WITH_SSL
sslutil_disconnect(Client);
-#endif /* USE_SSL */
+#endif /* WITH_SSL */
close(Client);
Client = 0;
/****************************************************************************
determine whether we are in the specified group
****************************************************************************/
-BOOL in_group(gid_t group, int current_gid, int ngroups, int *groups)
+BOOL in_group(gid_t group, int current_gid, int ngroups, GID_T *groups)
{
- int i;
+ int i;
- if (group == current_gid) return(True);
+ if (group == current_gid) return(True);
- for (i=0;i<ngroups;i++)
- if (group == groups[i])
- return(True);
+ for (i=0;i<ngroups;i++)
+ if (group == groups[i])
+ return(True);
- return(False);
+ return(False);
}
/****************************************************************************
{
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();
+ DEBUG(0,("ERROR: NULL StrCpy() called!\n"));
+ smb_panic("invalid StrCpy");
}
-#endif
if (!dest) return(NULL);
if (!src) {
if (mincnt == 0) mincnt = maxcnt;
while (nread < mincnt) {
-#ifdef USE_SSL
+#ifdef WITH_SSL
if(fd == sslFd){
readret = SSL_read(ssl, buf + nread, maxcnt - nread);
}else{
readret = read(fd, buf + nread, maxcnt - nread);
}
-#else /* USE_SSL */
+#else /* WITH_SSL */
readret = read(fd, buf + nread, maxcnt - nread);
-#endif /* USE_SSL */
+#endif /* WITH_SSL */
if (readret == 0) {
smb_read_error = READ_EOF;
return -1;
}
-#ifdef USE_SSL
+#ifdef WITH_SSL
if(fd == sslFd){
readret = SSL_read(ssl, buf + nread, maxcnt - nread);
}else{
readret = read(fd, buf + nread, maxcnt - nread);
}
-#else /* USE_SSL */
+#else /* WITH_SSL */
readret = read(fd, buf+nread, maxcnt-nread);
-#endif /* USE_SSL */
+#endif /* WITH_SSL */
if (readret == 0) {
/* we got EOF on the file descriptor */
while (total < N)
{
-#ifdef USE_SSL
+#ifdef WITH_SSL
if(fd == sslFd){
ret = SSL_read(ssl, buffer + total, N - total);
}else{
ret = read(fd,buffer + total,N - total);
}
-#else /* USE_SSL */
+#else /* WITH_SSL */
ret = read(fd,buffer + total,N - total);
-#endif /* USE_SSL */
+#endif /* WITH_SSL */
if (ret == 0)
{
while (total < N)
{
-#ifdef USE_SSL
+#ifdef WITH_SSL
if(fd == sslFd){
ret = SSL_write(ssl,buffer + total,N - total);
}else{
ret = write(fd,buffer + total,N - total);
}
-#else /* USE_SSL */
+#else /* WITH_SSL */
ret = write(fd,buffer + total,N - total);
-#endif /* USE_SSL */
+#endif /* WITH_SSL */
if (ret == -1) return -1;
if (ret == 0) return total;
for processing.
****************************************************************************/
-typedef struct _message_list {
- struct _message_list *msg_next;
+typedef struct {
+ ubi_slNode msg_next;
char *msg_buf;
int msg_len;
} pending_message_list;
-static pending_message_list *smb_msg_head = NULL;
+static ubi_slList smb_oplock_queue = { NULL, (ubi_slNodePtr)&smb_oplock_queue, 0};
/****************************************************************************
- Function to push a linked list of local messages ready
+ Function to push a message onto the tail of a linked list of smb messages ready
for processing.
****************************************************************************/
-static BOOL push_local_message(pending_message_list **pml, char *buf, int msg_len)
+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_message: malloc fail (1)\n"));
+ DEBUG(0,("push_local_message: malloc fail (1)\n"));
return False;
}
memcpy(msg->msg_buf, buf, msg_len);
msg->msg_len = msg_len;
- msg->msg_next = *pml;
- *pml = msg;
+ ubi_slAddTail( list_head, msg);
return True;
}
/****************************************************************************
- Function to push a linked list of local smb messages ready
+ Function to push a smb message onto a linked list of local smb messages ready
for processing.
****************************************************************************/
-BOOL push_smb_message(char *buf, int msg_len)
+BOOL push_oplock_pending_smb_message(char *buf, int msg_len)
{
- return push_local_message(&smb_msg_head, buf, msg_len);
+ return push_local_message(&smb_oplock_queue, buf, msg_len);
}
/****************************************************************************
* If so - copy and return it.
*/
- if(smb_msg_head)
+ if(ubi_slCount(&smb_oplock_queue) != 0)
{
- pending_message_list *msg = smb_msg_head;
+ pending_message_list *msg = (pending_message_list *)ubi_slRemHead(&smb_oplock_queue);
memcpy(buffer, msg->msg_buf, MIN(buffer_len, msg->msg_len));
- smb_msg_head = msg->msg_next;
/* Free the message we just copied. */
free((char *)msg->msg_buf);
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)
****************************************************************************/
void become_daemon(void)
{
-#ifndef NO_FORK_DEBUG
- if (fork())
- _exit(0);
+ if (fork()) {
+ _exit(0);
+ }
/* detach from the terminal */
-#ifdef USE_SETSID
- setsid();
-#else /* USE_SETSID */
-#ifdef TIOCNOTTY
- {
- int i = open("/dev/tty", O_RDWR);
- if (i >= 0)
- {
- ioctl(i, (int) TIOCNOTTY, (char *)0);
- close(i);
- }
- }
-#endif /* TIOCNOTTY */
-#endif /* USE_SETSID */
- /* Close fd's 0,1,2. Needed if started by rsh */
- close_low_fds();
-#endif /* NO_FORK_DEBUG */
+#ifdef HAVE_SETSID
+ setsid();
+#elif defined(TIOCNOTTY)
+ {
+ int i = open("/dev/tty", O_RDWR);
+ if (i != -1) {
+ ioctl(i, (int) TIOCNOTTY, (char *)0);
+ close(i);
+ }
+ }
+#endif /* HAVE_SETSID */
+
+ /* Close fd's 0,1,2. Needed if started by rsh */
+ close_low_fds();
}
extend a file with ftruncate. Provide alternate implementation
for this */
-#if FTRUNCATE_CAN_EXTEND
+#ifdef HAVE_FTRUNCATE_EXTEND
return ftruncate(fd, len);
#else
struct stat st;
return(ret);
}
-#ifdef NOSTRDUP
-/****************************************************************************
-duplicate a string
-****************************************************************************/
- char *strdup(char *s)
-{
- char *ret = NULL;
- int len;
- if (!s) return(NULL);
- ret = (char *)malloc((len = strlen(s))+1);
- if (!ret) return(NULL);
- safe_strcpy(ret,s,len);
- return(ret);
-}
-#endif
-
/****************************************************************************
Signal handler for SIGPIPE (write on a disconnected socket)
bzero((char *)&sock,sizeof(sock));
memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
-#if defined(__FreeBSD__) || defined(NETBSD) || defined(__OpenBSD__) /* XXX not the right ifdef */
+
+#ifdef HAVE_SOCK_SIN_LEN
sock.sin_len = sizeof(sock);
#endif
sock.sin_port = htons( port );
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 */
return addr_buf;
}
-#if (defined(NETGROUP) && defined(AUTOMOUNT))
+#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>.
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
/*******************************************************************
static pstring server_name;
/* use the local machine name as the default */
- /* this will be the default if AUTOMOUNT is not used or fails */
+ /* this will be the default if WITH_AUTOMOUNT is not used or fails */
pstrcpy(server_name, local_machine);
-#if (defined(NETGROUP) && defined (AUTOMOUNT))
+#if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
if (lp_nis_home_map())
{
static pstring server_path;
/* use the passwd entry as the default */
- /* this will be the default if AUTOMOUNT is not used or fails */
+ /* this will be the default if WITH_AUTOMOUNT is not used or fails */
/* pstrcpy() copes with get_home_dir() returning NULL */
pstrcpy(server_path, get_home_dir(user_name));
-#if (defined(NETGROUP) && defined (AUTOMOUNT))
+#if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
if (lp_nis_home_map())
{
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?
********************************************************************/
********************************************************************/
char *gidtoname(int gid)
{
- static char name[40];
- struct group *grp = getgrgid(gid);
- if (grp) return(grp->gr_name);
- slprintf(name,sizeof(name) - 1, "%d",gid);
- return(name);
-}
-
-/*******************************************************************
-block sigs
-********************************************************************/
-void BlockSignals(BOOL block,int signum)
-{
-#ifdef USE_SIGBLOCK
- int block_mask = sigmask(signum);
- static int oldmask = 0;
- if (block)
- oldmask = sigblock(block_mask);
- else
- sigsetmask(oldmask);
-#elif defined(USE_SIGPROCMASK)
- sigset_t set;
- sigemptyset(&set);
- sigaddset(&set,signum);
- sigprocmask(block?SIG_BLOCK:SIG_UNBLOCK,&set,NULL);
-#endif
+ static char name[40];
+ struct group *grp = getgrgid(gid);
+ if (grp) return(grp->gr_name);
+ slprintf(name,sizeof(name) - 1, "%d",gid);
+ 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 solen:0 /tmp/ERROR_FAULT");
+ char *cmd = lp_panic_action();
+ if (cmd && *cmd) {
+ system(cmd);
+ exit(1);
+ }
}
-#endif
-#ifdef USE_DIRECT
-#define DIRECT direct
-#else
-#define DIRECT dirent
-#endif
/*******************************************************************
a readdir wrapper which just returns the file name
********************************************************************/
char *readdirname(void *p)
{
- struct DIRECT *ptr;
- char *dname;
+ struct dirent *ptr;
+ char *dname;
- if (!p) return(NULL);
+ if (!p) return(NULL);
- ptr = (struct DIRECT *)readdir(p);
- if (!ptr) return(NULL);
+ ptr = (struct dirent *)readdir(p);
+ if (!ptr) return(NULL);
- dname = ptr->d_name;
+ dname = ptr->d_name;
#ifdef NEXT2
- if (telldir(p) < 0) return(NULL);
+ if (telldir(p) < 0) return(NULL);
#endif
-#ifdef SUNOS5
- /* this handles a broken compiler setup, causing a mixture
- of BSD and SYSV headers and libraries */
- {
- static BOOL broken_readdir = False;
- if (!broken_readdir && !(*(dname)) && strequal("..",dname-2))
- {
- DEBUG(0,("Your readdir() is broken. You have somehow mixed SYSV and BSD headers and libraries\n"));
- broken_readdir = True;
- }
- if (broken_readdir)
- dname = dname - 2;
- }
+#ifdef HAVE_BROKEN_READDIR
+ /* using /usr/ucb/cc is BAD */
+ dname = dname - 2;
#endif
- {
- static pstring buf;
- pstrcpy(buf, dname);
- unix_to_dos(buf, True);
- dname = buf;
- }
+ {
+ static pstring buf;
+ memcpy(buf, dname, NAMLEN(ptr)+1);
+ unix_to_dos(buf, True);
+ dname = buf;
+ }
- return(dname);
+ return(dname);
}
/*******************************************************************
{
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;
struct flock lock;
int ret;
-#if 1
- uint32 mask = 0xC0000000;
+ /*
+ * FIXME.
+ * NB - this code will need re-writing to cope with large (64bit)
+ * lock requests. JRA.
+ */
- /* make sure the count is reasonable, we might kill the lockd otherwise */
- count &= ~mask;
+ if(lp_ole_locking_compat()) {
+ uint32 mask = 0xC0000000;
- /* 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);
-#else
- uint32 mask = ((unsigned)1<<31);
-
- /* interpret negative counts as large numbers */
- if (count < 0)
+ /* make sure the count is reasonable, we might kill the lockd otherwise */
count &= ~mask;
- /* no negative offsets */
- offset &= ~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);
+ } else {
+ uint32 mask = ((unsigned)1<<31);
+ int32 s_count = (int32) count; /* Signed count. */
+ int32 s_offset = (int32)offset; /* Signed offset. */
+
+ /* interpret negative counts as large numbers */
+ if (s_count < 0)
+ s_count &= ~mask;
+
+ /* no negative offsets */
+ if(s_offset < 0)
+ s_offset &= ~mask;
- /* count + offset must be in range */
- while ((offset < 0 || (offset + count < 0)) && mask)
+ /* count + offset must be in range */
+ while ((s_offset < 0 || (s_offset + s_count < 0)) && mask)
{
- offset &= ~mask;
+ s_offset &= ~mask;
mask = mask >> 1;
}
-#endif
+
+ 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));
(lock.l_pid != 0) &&
(lock.l_pid != getpid()))
{
- DEBUG(3,("fd %d is locked by pid %d\n",fd,lock.l_pid));
+ DEBUG(3,("fd %d is locked by pid %d\n",fd,(int)lock.l_pid));
return(True);
}
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 */