/*
- Unix SMB/Netbios implementation.
- Version 1.9.
+ Unix SMB/CIFS implementation.
Samba utility functions
Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Jeremy Allison 2001
+ Copyright (C) Simo Sorce 2001
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#endif /* WITH_NISPLUS_HOME */
#endif /* HAVE_NETGROUP && WITH_AUTOMOUNT */
-#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 /* WITH_SSL */
-
-extern int DEBUGLEVEL;
-
int Protocol = PROTOCOL_COREPLUS;
/* a default finfo structure to ensure all fields are sensible */
/****************************************************************************
- find a suitable temporary directory. The result should be copied immediately
- as it may be overwritten by a subsequent call
- ****************************************************************************/
+ Find a suitable temporary directory. The result should be copied immediately
+ as it may be overwritten by a subsequent call.
+****************************************************************************/
+
char *tmpdir(void)
{
char *p;
- if ((p = getenv("TMPDIR"))) {
+ if ((p = getenv("TMPDIR")))
return p;
- }
return "/tmp";
}
/****************************************************************************
-determine whether we are in the specified group
+ Determine whether we are in the specified group.
****************************************************************************/
BOOL in_group(gid_t group, gid_t current_gid, int ngroups, gid_t *groups)
{
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(False);
}
-
/****************************************************************************
-like atoi but gets the value up to the separater character
+ Like atoi but gets the value up to the separator character.
****************************************************************************/
-char *Atoic(char *p, int *n, char *c)
+
+static char *Atoic(char *p, int *n, char *c)
{
- if (!isdigit((int)*p))
- {
+ if (!isdigit((int)*p)) {
DEBUG(5, ("Atoic: malformed number\n"));
return NULL;
}
(*n) = atoi(p);
while ((*p) && isdigit((int)*p))
- {
p++;
- }
- if (strchr(c, *p) == NULL)
+ if (strchr_m(c, *p) == NULL)
{
DEBUG(5, ("Atoic: no separator characters (%s) not found\n", c));
return NULL;
}
/*************************************************************************
- reads a list of numbers
+ Reads a list of numbers.
*************************************************************************/
+
char *get_numlist(char *p, uint32 **num, int *count)
{
int val;
if (num == NULL || count == NULL)
- {
return NULL;
- }
(*count) = 0;
(*num ) = NULL;
- while ((p = Atoic(p, &val, ":,")) != NULL && (*p) != ':')
- {
- (*num) = Realloc((*num), ((*count)+1) * sizeof(uint32));
- if ((*num) == NULL)
+ while ((p = Atoic(p, &val, ":,")) != NULL && (*p) != ':') {
+ uint32 *tn;
+
+ tn = Realloc((*num), ((*count)+1) * sizeof(uint32));
+ if (tn == NULL)
{
+ SAFE_FREE(*num);
return NULL;
- }
+ } else
+ (*num) = tn;
(*num)[(*count)] = val;
(*count)++;
p++;
return p;
}
-
/*******************************************************************
- check if a file exists - call vfs_file_exist for samba files
+ Check if a file exists - call vfs_file_exist for samba files.
********************************************************************/
-BOOL file_exist(char *fname,SMB_STRUCT_STAT *sbuf)
+
+BOOL file_exist(const char *fname,SMB_STRUCT_STAT *sbuf)
{
SMB_STRUCT_STAT st;
- if (!sbuf) sbuf = &st;
+ if (!sbuf)
+ sbuf = &st;
if (sys_stat(fname,sbuf) != 0)
return(False);
- return(S_ISREG(sbuf->st_mode));
+ return((S_ISREG(sbuf->st_mode)) || (S_ISFIFO(sbuf->st_mode)));
}
/*******************************************************************
- rename a unix file
+ Check a files mod time.
********************************************************************/
-int file_rename(char *from, char *to)
-{
- int rcode = rename (from, to);
-
- if (errno == EXDEV)
- {
- /* Rename across filesystems needed. */
- rcode = copy_reg (from, to);
- }
- return rcode;
-}
-/*******************************************************************
-check a files mod time
-********************************************************************/
-time_t file_modtime(char *fname)
+time_t file_modtime(const char *fname)
{
SMB_STRUCT_STAT st;
}
/*******************************************************************
- check if a directory exists
+ Check if a directory exists.
********************************************************************/
+
BOOL directory_exist(char *dname,SMB_STRUCT_STAT *st)
{
SMB_STRUCT_STAT st2;
{
_smb_setlen(buf,len);
- CVAL(buf,4) = 0xFF;
- CVAL(buf,5) = 'S';
- CVAL(buf,6) = 'M';
- CVAL(buf,7) = 'B';
+ SCVAL(buf,4,0xFF);
+ SCVAL(buf,5,'S');
+ SCVAL(buf,6,'M');
+ SCVAL(buf,7,'B');
}
/*******************************************************************
{
if (zero)
memset(buf + smb_size,'\0',num_words*2 + num_bytes);
- CVAL(buf,smb_wct) = num_words;
+ SCVAL(buf,smb_wct,num_words);
SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
return (smb_size + num_words*2 + num_bytes);
/*******************************************************************
setup only the byte count for a smb message
********************************************************************/
-void set_message_bcc(char *buf,int num_bytes)
+int set_message_bcc(char *buf,int num_bytes)
{
int num_words = CVAL(buf,smb_wct);
SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
+ return (smb_size + num_words*2 + num_bytes);
}
/*******************************************************************
setup only the byte count for a smb message, using the end of the
message as a marker
********************************************************************/
-void set_message_end(void *outbuf,void *end_ptr)
+int set_message_end(void *outbuf,void *end_ptr)
{
- set_message_bcc((char *)outbuf,PTR_DIFF(end_ptr,smb_buf((char *)outbuf)));
+ return set_message_bcc((char *)outbuf,PTR_DIFF(end_ptr,smb_buf((char *)outbuf)));
}
/*******************************************************************
*p = 0;
pstrcpy(s1,p+3);
- if ((p=strrchr(s,'\\')) != NULL)
+ if ((p=strrchr_m(s,'\\')) != NULL)
*p = 0;
else
*s = 0;
*p = 0;
pstrcpy(s1,p+3);
- if ((p=strrchr(s,'/')) != NULL)
+ if ((p=strrchr_m(s,'/')) != NULL)
*p = 0;
else
*s = 0;
trim_string(s,NULL,"/..");
}
+/*******************************************************************
+convert '\' to '/'
+reduce a file name, removing or reducing /../ , /./ , // elements.
+remove also any trailing . and /
+return a new allocated string.
+********************************************************************/
+smb_ucs2_t *unix_clean_path(const smb_ucs2_t *s)
+{
+ smb_ucs2_t *ns;
+ smb_ucs2_t *p, *r, *t;
+
+ DEBUG(3, ("unix_clean_path\n")); /* [%unicode]\n")); */
+ if(!s) return NULL;
+
+ /* convert '\' to '/' */
+ ns = strdup_w(s);
+ if (!ns) return NULL;
+ unix_format_w(ns);
+
+ /* remove all double slashes */
+ p = ns;
+ ns = all_string_sub_wa(p, "//", "/");
+ SAFE_FREE(p);
+ if (!ns) return NULL;
+
+ /* remove any /./ */
+ p = ns;
+ ns = all_string_sub_wa(p, "/./", "/");
+ SAFE_FREE(p);
+ if (!ns) return NULL;
+
+ /* reduce any /../ */
+ t = ns;
+ while (*t && (r = strstr_wa(t, "/.."))) {
+ t = &(r[3]);
+ if (*t == UCS2_CHAR('/') || *t == 0) {
+ *r = 0;
+ p = strrchr_w(ns, UCS2_CHAR('/'));
+ if (!p) p = ns;
+ if (*t == 0) *p = 0;
+ else memmove(p, t, (strlen_w(t) + 1) * sizeof(smb_ucs2_t));
+ t = p;
+ }
+ }
+
+ /* remove any leading ./ trailing /. */
+ trim_string_wa(ns, "./", "/.");
+
+ /* remove any leading and trailing / */
+ trim_string_wa(ns, "/", "/");
+
+ return ns;
+}
+
/****************************************************************************
make a dir struct
****************************************************************************/
size = 0;
memset(buf+1,' ',11);
- if ((p = strchr(mask2,'.')) != NULL)
+ if ((p = strchr_m(mask2,'.')) != NULL)
{
*p = 0;
- memcpy(buf+1,mask2,MIN(strlen(mask2),8));
- memcpy(buf+9,p+1,MIN(strlen(p+1),3));
+ push_ascii(buf+1,mask2,8, 0);
+ push_ascii(buf+9,p+1,3, 0);
*p = '.';
}
else
- memcpy(buf+1,mask2,MIN(strlen(mask2),11));
+ push_ascii(buf+1,mask2,11, 0);
memset(buf+21,'\0',DIR_STRUCT_SIZE-21);
- CVAL(buf,21) = mode;
+ SCVAL(buf,21,mode);
put_dos_date(buf,22,date);
SSVAL(buf,26,size & 0xFFFF);
SSVAL(buf,28,(size >> 16)&0xFFFF);
- StrnCpy(buf+30,fname,12);
+ push_ascii(buf+30,fname,12, 0);
if (!case_sensitive)
strupper(buf+30);
- DEBUG(8,("put name [%s] into dir struct\n",buf+30));
+ DEBUG(8,("put name [%s] from [%s] into dir struct\n",buf+30, fname));
}
#endif
#endif
- if((val = fcntl(fd, F_GETFL, 0)) == -1)
+ if((val = sys_fcntl_long(fd, F_GETFL, 0)) == -1)
return -1;
if(set) /* Turn blocking on - ie. clear nonblock flag */
val &= ~FLAG_TO_SET;
else
val |= FLAG_TO_SET;
- return fcntl( fd, F_SETFL, val);
+ return sys_fcntl_long( fd, F_SETFL, val);
#undef FLAG_TO_SET
}
/****************************************************************************
-transfer some data between two fd's
+ Transfer some data between two fd's.
****************************************************************************/
-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;
- SMB_OFF_T total = 0;
- DEBUG(4,("transfer_file n=%.0f (head=%d) called\n",(double)n,headlen));
-
- if (size == 0) {
- size = lp_readsize();
- size = MAX(size,1024);
- }
-
- while (!buf && size>0) {
- buf = (char *)Realloc(buf,size+8);
- if (!buf) size /= 2;
- }
-
- if (!buf) {
- DEBUG(0,("Can't allocate transfer buffer!\n"));
- exit(1);
- }
-
- abuf = buf + (align%8);
+#ifndef TRANSFER_BUF_SIZE
+#define TRANSFER_BUF_SIZE 65536
+#endif
- if (header)
- n += headlen;
+ssize_t transfer_file_internal(int infd, int outfd, size_t n, ssize_t (*read_fn)(int, void *, size_t),
+ ssize_t (*write_fn)(int, const void *, size_t))
+{
+ char *buf;
+ size_t total = 0;
+ ssize_t read_ret;
+ ssize_t write_ret;
+ size_t num_to_read_thistime;
+ size_t num_written = 0;
- while (n > 0)
- {
- int s = (int)MIN(n,(SMB_OFF_T)size);
- int ret,ret2=0;
+ if ((buf = malloc(TRANSFER_BUF_SIZE)) == NULL)
+ return -1;
- ret = 0;
+ while (total < n) {
+ num_to_read_thistime = MIN((n - total), TRANSFER_BUF_SIZE);
- if (header && (headlen >= MIN(s,1024))) {
- buf1 = header;
- s = headlen;
- ret = headlen;
- headlen = 0;
- header = NULL;
- } else {
- buf1 = abuf;
- }
+ read_ret = (*read_fn)(infd, buf, num_to_read_thistime);
+ if (read_ret == -1) {
+ DEBUG(0,("transfer_file_internal: read failure. Error = %s\n", strerror(errno) ));
+ SAFE_FREE(buf);
+ return -1;
+ }
+ if (read_ret == 0)
+ break;
- if (header && headlen > 0)
- {
- ret = MIN(headlen,size);
- memcpy(buf1,header,ret);
- headlen -= ret;
- header += ret;
- if (headlen <= 0) header = NULL;
- }
+ num_written = 0;
+
+ while (num_written < read_ret) {
+ write_ret = (*write_fn)(outfd,buf + num_written, read_ret - num_written);
+
+ if (write_ret == -1) {
+ DEBUG(0,("transfer_file_internal: write failure. Error = %s\n", strerror(errno) ));
+ SAFE_FREE(buf);
+ return -1;
+ }
+ if (write_ret == 0)
+ return (ssize_t)total;
+
+ num_written += (size_t)write_ret;
+ }
- if (s > ret)
- ret += read(infd,buf1+ret,s-ret);
+ total += (size_t)read_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);
+ SAFE_FREE(buf);
+ return (ssize_t)total;
}
+SMB_OFF_T transfer_file(int infd,int outfd,SMB_OFF_T n)
+{
+ return (SMB_OFF_T)transfer_file_internal(infd, outfd, (size_t)n, sys_read, sys_write);
+}
/*******************************************************************
-sleep for a specified number of milliseconds
+ Sleep for a specified number of milliseconds.
********************************************************************/
-void msleep(int t)
+
+void msleep(unsigned int t)
{
- int tdiff=0;
- struct timeval tval,t1,t2;
- fd_set fds;
+ unsigned int tdiff=0;
+ struct timeval tval,t1,t2;
+ fd_set fds;
- GetTimeOfDay(&t1);
- GetTimeOfDay(&t2);
+ GetTimeOfDay(&t1);
+ GetTimeOfDay(&t2);
- while (tdiff < t) {
- tval.tv_sec = (t-tdiff)/1000;
- tval.tv_usec = 1000*((t-tdiff)%1000);
-
- FD_ZERO(&fds);
- errno = 0;
- sys_select_intr(0,&fds,&tval);
+ while (tdiff < t) {
+ tval.tv_sec = (t-tdiff)/1000;
+ tval.tv_usec = 1000*((t-tdiff)%1000);
+
+ /* Never wait for more than 1 sec. */
+ if (tval.tv_sec > 1) {
+ tval.tv_sec = 1;
+ tval.tv_usec = 0;
+ }
- GetTimeOfDay(&t2);
- tdiff = TvalDiff(&t1,&t2);
- }
-}
+ FD_ZERO(&fds);
+ errno = 0;
+ sys_select_intr(0,&fds,NULL,NULL,&tval);
+ GetTimeOfDay(&t2);
+ if (t2.tv_sec < t1.tv_sec) {
+ /* Someone adjusted time... */
+ t1 = t2;
+ }
+
+ tdiff = TvalDiff(&t1,&t2);
+ }
+}
/****************************************************************************
-become a daemon, discarding the controlling terminal
+ Become a daemon, discarding the controlling terminal.
****************************************************************************/
+
void become_daemon(void)
{
if (sys_fork()) {
/****************************************************************************
-put up a yes/no prompt
+ Put up a yes/no prompt
****************************************************************************/
BOOL yesno(char *p)
{
return(False);
}
-#ifdef HPUX
/****************************************************************************
-this is a version of setbuffer() for those machines that only have setvbuf
+ Expand a pointer to be a particular size.
****************************************************************************/
- void setbuffer(FILE *f,char *buf,int bufsize)
-{
- setvbuf(f,buf,_IOFBF,bufsize);
-}
-#endif
-/****************************************************************************
-expand a pointer to be a particular size
-****************************************************************************/
void *Realloc(void *p,size_t size)
{
void *ret=NULL;
if (size == 0) {
- if (p) free(p);
+ SAFE_FREE(p);
DEBUG(5,("Realloc asked for 0 bytes\n"));
return NULL;
}
return(ret);
}
-
/****************************************************************************
-free memory, checks for NULL
+ Free memory, checks for NULL.
+use directly SAFE_FREE()
+exist only because we need to pass a function pointer somewhere --SSS
****************************************************************************/
+
void safe_free(void *p)
{
- if (p != NULL)
- {
- free(p);
- }
+ SAFE_FREE(p);
}
-
/****************************************************************************
-get my own name and IP
+ Get my own name and IP.
****************************************************************************/
+
BOOL get_myname(char *my_name)
{
pstring hostname;
if (my_name) {
/* split off any parts after an initial . */
- char *p = strchr(hostname,'.');
- if (p) *p = 0;
+ char *p = strchr_m(hostname,'.');
+
+ if (p)
+ *p = 0;
fstrcpy(my_name,hostname);
}
}
/****************************************************************************
-interpret a protocol description string, with a default
+ Interpret a protocol description string, with a default.
****************************************************************************/
+
int interpret_protocol(char *str,int def)
{
if (strequal(str,"NT1"))
pure_address = False;
/* Check that a pure number is not misinterpreted as an IP */
- pure_address = pure_address && (strchr(str, '.') != NULL);
+ pure_address = pure_address && (strchr_m(str, '.') != NULL);
return pure_address;
}
interpret an internet address or name into an IP address in 4 byte form
****************************************************************************/
-uint32 interpret_addr(char *str)
+uint32 interpret_addr(const char *str)
{
struct hostent *hp;
uint32 res;
/*******************************************************************
a convenient addition to interpret_addr()
******************************************************************/
-struct in_addr *interpret_addr2(char *str)
+struct in_addr *interpret_addr2(const char *str)
{
static struct in_addr ret;
uint32 a = interpret_addr(str);
}
/*******************************************************************
- check if an IP is the 0.0.0.0
+ Check if an IP is the 0.0.0.0
******************************************************************/
-BOOL zero_ip(struct in_addr ip)
+BOOL is_zero_ip(struct in_addr ip)
{
uint32 a;
putip((char *)&a,(char *)&ip);
return(a == 0);
}
+/*******************************************************************
+ Set an IP to 0.0.0.0
+ ******************************************************************/
+
+void zero_ip(struct in_addr *ip)
+{
+ static BOOL init;
+ static struct in_addr ipzero;
+
+ if (!init) {
+ ipzero = *interpret_addr2("0.0.0.0");
+ init = True;
+ }
+
+ *ip = ipzero;
+}
#if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
/******************************************************************
*******************************************************************/
#ifdef WITH_NISPLUS_HOME
-char *automount_lookup(char *user_name)
+char *automount_lookup(const char *user_name)
{
static fstring last_key = "";
static pstring last_value = "";
return last_value;
}
#else /* WITH_NISPLUS_HOME */
-char *automount_lookup(char *user_name)
+char *automount_lookup(const char *user_name)
{
static fstring last_key = "";
static pstring last_value = "";
BOOL process_exists(pid_t pid)
{
+ /* Doing kill with a non-positive pid causes messages to be
+ * sent to places we don't want. */
+ SMB_ASSERT(pid > 0);
return(kill(pid,0) == 0 || errno != ESRCH);
}
static fstring name;
struct passwd *pass;
- if (winbind_uidtoname(name, uid))
- return name;
-
pass = sys_getpwuid(uid);
- if (pass) return(pass->pw_name);
+ if (pass)
+ return(pass->pw_name);
slprintf(name, sizeof(name) - 1, "%d",(int)uid);
return(name);
}
static fstring name;
struct group *grp;
- if (winbind_gidtoname(name, gid))
- return name;
-
grp = getgrgid(gid);
- if (grp) return(grp->gr_name);
+ if (grp)
+ return(grp->gr_name);
slprintf(name,sizeof(name) - 1, "%d",(int)gid);
return(name);
}
/*******************************************************************
- Convert a user name into a uid. If winbindd is present uses this.
+ Convert a user name into a uid.
********************************************************************/
uid_t nametouid(char *name)
char *p;
uid_t u;
- u = (uid_t)strtol(name, &p, 0);
- if (p != name) return u;
+ pass = getpwnam_alloc(name);
+ if (pass) {
+ u = pass->pw_uid;
+ passwd_free(&pass);
+ return u;
+ }
- if (winbind_nametouid(&u, name))
+ u = (uid_t)strtol(name, &p, 0);
+ if ((p != name) && (*p == '\0'))
return u;
- pass = sys_getpwnam(name);
- if (pass) return(pass->pw_uid);
return (uid_t)-1;
}
/*******************************************************************
- Convert a name to a gid_t if possible. Return -1 if not a group. If winbindd
- is present does a shortcut lookup...
+ Convert a name to a gid_t if possible. Return -1 if not a group.
********************************************************************/
-gid_t nametogid(char *name)
+gid_t nametogid(const char *name)
{
struct group *grp;
char *p;
gid_t g;
g = (gid_t)strtol(name, &p, 0);
- if (p != name) return g;
-
- if (winbind_nametogid(&g, name))
+ if ((p != name) && (*p == '\0'))
return g;
grp = getgrnam(name);
- if (grp) return(grp->gr_gid);
+ if (grp)
+ return(grp->gr_gid);
return (gid_t)-1;
}
}
/* Get the last component of the unix name. */
- p = strrchr(name, '/');
+ p = strrchr_m(name, '/');
strncpy(last_component, p ? ++p : name, sizeof(last_component)-1);
last_component[sizeof(last_component)-1] = '\0';
continue;
}
/* find the next / */
- name_end = strchr(nameptr, '/');
+ name_end = strchr_m(nameptr, '/');
/* oops - the last check for a / didn't find one. */
if (name_end == NULL)
continue;
}
/* find the next / */
- if ((name_end = strchr(nameptr, '/')) != NULL)
+ if ((name_end = strchr_m(nameptr, '/')) != NULL)
{
*name_end = 0;
}
void free_namearray(name_compare_entry *name_array)
{
- if(name_array == 0)
+ if(name_array == NULL)
return;
- if(name_array->name != NULL)
- free(name_array->name);
-
- free((char *)name_array);
+ SAFE_FREE(name_array->name);
+ SAFE_FREE(name_array);
}
/****************************************************************************
lock.l_len = count;
lock.l_pid = 0;
- errno = 0;
-
- ret = fcntl(fd,op,&lock);
+ ret = sys_fcntl_ptr(fd,op,&lock);
- if (errno != 0)
+ if (ret == -1 && errno != 0)
DEBUG(3,("fcntl_lock: fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
/* a lock query */
}
/*******************************************************************
-is the name specified one of my netbios names
-returns true is it is equal, false otherwise
+ Is the name specified one of my netbios names.
+ Returns true if it is equal, false otherwise.
********************************************************************/
+
BOOL is_myname(char *s)
{
- int n;
- BOOL ret = False;
+ int n;
+ BOOL ret = False;
- for (n=0; my_netbios_names[n]; n++) {
- if (strequal(my_netbios_names[n], s))
- ret=True;
- }
- DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
- return(ret);
+ for (n=0; my_netbios_names[n]; n++) {
+ if (strequal(my_netbios_names[n], s))
+ ret=True;
+ }
+ DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
+ return(ret);
+}
+
+/********************************************************************
+ Return only the first IP address of our configured interfaces
+ as a string
+ *******************************************************************/
+
+const char* get_my_primary_ip (void)
+{
+ static fstring ip_string;
+ int n;
+ struct iface_struct nics[MAX_INTERFACES];
+
+ if ((n=get_interfaces(nics, MAX_INTERFACES)) <= 0)
+ return NULL;
+
+ fstrcpy(ip_string, inet_ntoa(nics[0].ip));
+ return ip_string;
+}
+
+BOOL is_myname_or_ipaddr(char *s)
+{
+ char **ptr;
+
+ /* optimize for the common case */
+ if (strequal(s, global_myname))
+ return True;
+
+ /* maybe its an IP address? */
+ if (is_ipaddress(s)) {
+ struct iface_struct nics[MAX_INTERFACES];
+ int i, n;
+ uint32 ip;
+
+ ip = interpret_addr(s);
+ if ((ip==0) || (ip==0xffffffff))
+ return False;
+
+ n = get_interfaces(nics, MAX_INTERFACES);
+ for (i=0; i<n; i++) {
+ if (ip == nics[i].ip.s_addr)
+ return True;
+ }
+ }
+
+ /* check for an alias */
+ ptr = lp_netbios_aliases();
+ for ( ; *ptr; ptr++ ) {
+ if (StrCaseCmp(s, *ptr) == 0)
+ return True;
+ }
+
+ /* no match */
+ return False;
}
/*******************************************************************
-set the horrid remote_arch string based on an enum.
+ Set the horrid remote_arch string based on an enum.
********************************************************************/
+
void set_remote_arch(enum remote_arch_types type)
{
- extern fstring remote_arch;
- ra_type = type;
- switch( type )
- {
- case RA_WFWG:
- fstrcpy(remote_arch, "WfWg");
- return;
- case RA_OS2:
- fstrcpy(remote_arch, "OS2");
- return;
- case RA_WIN95:
- fstrcpy(remote_arch, "Win95");
- return;
- case RA_WINNT:
- fstrcpy(remote_arch, "WinNT");
- return;
- case RA_WIN2K:
- fstrcpy(remote_arch, "Win2K");
- return;
- case RA_SAMBA:
- fstrcpy(remote_arch,"Samba");
- return;
- default:
- ra_type = RA_UNKNOWN;
- fstrcpy(remote_arch, "UNKNOWN");
- break;
- }
+ extern fstring remote_arch;
+ ra_type = type;
+ switch( type ) {
+ case RA_WFWG:
+ fstrcpy(remote_arch, "WfWg");
+ return;
+ case RA_OS2:
+ fstrcpy(remote_arch, "OS2");
+ return;
+ case RA_WIN95:
+ fstrcpy(remote_arch, "Win95");
+ return;
+ case RA_WINNT:
+ fstrcpy(remote_arch, "WinNT");
+ return;
+ case RA_WIN2K:
+ fstrcpy(remote_arch, "Win2K");
+ return;
+ case RA_SAMBA:
+ fstrcpy(remote_arch,"Samba");
+ return;
+ default:
+ ra_type = RA_UNKNOWN;
+ fstrcpy(remote_arch, "UNKNOWN");
+ break;
+ }
}
/*******************************************************************
Get the remote_arch type.
********************************************************************/
+
enum remote_arch_types get_remote_arch(void)
{
- return ra_type;
+ return ra_type;
}
{
int i;
for (i=0;i<len;i++)
- {
fprintf(f, "%c", isprint(buf[i])?buf[i]:'.');
- }
}
void out_data(FILE *f,char *buf1,int len, int per_line)
{
unsigned char *buf = (unsigned char *)buf1;
int i=0;
- if (len<=0)
- {
+ if (len<=0) {
return;
}
fprintf(f, "[%03X] ",i);
- for (i=0;i<len;)
- {
+ for (i=0;i<len;) {
fprintf(f, "%02X ",(int)buf[i]);
i++;
if (i%(per_line/2) == 0) fprintf(f, " ");
- if (i%per_line == 0)
- {
+ if (i%per_line == 0) {
out_ascii(f,&buf[i-per_line ],per_line/2); fprintf(f, " ");
out_ascii(f,&buf[i-per_line/2],per_line/2); fprintf(f, "\n");
if (i<len) fprintf(f, "[%03X] ",i);
}
}
- if ((i%per_line) != 0)
- {
+ if ((i%per_line) != 0) {
int n;
n = per_line - (i%per_line);
fprintf(f, " ");
if (n>(per_line/2)) fprintf(f, " ");
- while (n--)
- {
+ while (n--) {
fprintf(f, " ");
}
n = MIN(per_line/2,i%per_line);
}
}
-void print_asc(int level, unsigned char *buf,int len)
+void print_asc(int level, const unsigned char *buf,int len)
{
int i;
for (i=0;i<len;i++)
DEBUG(level,("%c", isprint(buf[i])?buf[i]:'.'));
}
-void dump_data(int level,char *buf1,int len)
+void dump_data(int level, const char *buf1,int len)
{
- unsigned char *buf = (unsigned char *)buf1;
+ const unsigned char *buf = (const unsigned char *)buf1;
int i=0;
if (len<=0) return;
void zero_free(void *p, size_t size)
{
memset(p, 0, size);
- free(p);
+ SAFE_FREE(p);
}
return False;
}
- if (next_token(NULL, tmp, "\n\r", sizeof(tmp)))
+ if (next_token(&full_keyname, tmp, "\n\r", sizeof(tmp)))
{
fstrcpy(key_name, tmp);
}
#endif
}
+/*****************************************************************
+ malloc that aborts with smb_panic on fail or zero size.
+ *****************************************************************/
+
+void *smb_xmalloc(size_t size)
+{
+ void *p;
+ if (size == 0)
+ smb_panic("smb_xmalloc: called with zero size.\n");
+ if ((p = malloc(size)) == NULL)
+ smb_panic("smb_xmalloc: malloc fail.\n");
+ return p;
+}
+
+/**
+ Memdup with smb_panic on fail.
+**/
+void *smb_xmemdup(const void *p, size_t size)
+{
+ void *p2;
+ p2 = smb_xmalloc(size);
+ memcpy(p2, p, size);
+ return p2;
+}
+
+/**
+ strdup that aborts on malloc fail.
+**/
+char *smb_xstrdup(const char *s)
+{
+ char *s1 = strdup(s);
+ if (!s1)
+ smb_panic("smb_xstrdup: malloc fail\n");
+ return s1;
+}
+
+/*
+ vasprintf that aborts on malloc fail
+*/
+int smb_xvasprintf(char **ptr, const char *format, va_list ap)
+{
+ int n;
+ va_list ap2;
+#if defined(HAVE_VA_COPY)
+ __va_copy(ap2, ap);
+#else
+ ap2 = ap;
+#endif
+ n = vasprintf(ptr, format, ap2);
+ if (n == -1 || ! *ptr) {
+ smb_panic("smb_xvasprintf: out of memory");
+ }
+ return n;
+}
+
/*****************************************************************
like strdup but for memory
*****************************************************************/
-void *memdup(void *p, size_t size)
+void *memdup(const void *p, size_t size)
{
void *p2;
if (size == 0) return NULL;
return fname;
}
+/*****************************************************************
+a useful function for returning a path in the Samba pid directory
+ *****************************************************************/
+char *pid_path(char *name)
+{
+ static pstring fname;
+
+ pstrcpy(fname,lp_piddir());
+ trim_string(fname,"","/");
+
+ if (!directory_exist(fname,NULL)) {
+ mkdir(fname,0755);
+ }
+
+ pstrcat(fname,"/");
+ pstrcat(fname,name);
+
+ return fname;
+}
+
+
+/**
+ * @brief Returns an absolute path to a file in the Samba lib directory.
+ *
+ * @param name File to find, relative to LIBDIR.
+ *
+ * @retval Pointer to a static #pstring containing the full path.
+ **/
+char *lib_path(char *name)
+{
+ static pstring fname;
+ snprintf(fname, sizeof(fname), "%s/%s", dyn_LIBDIR, name);
+ return fname;
+}
+
/*******************************************************************
Given a filename - get its directory name
NB: Returned in static storage. Caveats:
return(NULL);
pstrcpy(dirpath, path);
- p = strrchr(dirpath, '/'); /* Find final '/', if any */
+ p = strrchr_m(dirpath, '/'); /* Find final '/', if any */
if (!p) {
pstrcpy(dirpath, "."); /* No final "/", so dir is "." */
} else {
return False;
}
+BOOL ms_has_wild_w(const smb_ucs2_t *s)
+{
+ smb_ucs2_t c;
+ if (!s) return False;
+ while ((c = *s++)) {
+ switch (c) {
+ case UCS2_CHAR('*'):
+ case UCS2_CHAR('?'):
+ case UCS2_CHAR('<'):
+ case UCS2_CHAR('>'):
+ case UCS2_CHAR('"'):
+ return True;
+ }
+ }
+ return False;
+}
+
/*******************************************************************
a wrapper that handles case sensitivity and the special handling
of the ".." name
BOOL mask_match(char *string, char *pattern, BOOL is_case_sensitive)
{
fstring p2, s2;
+
if (strcmp(string,"..") == 0) string = ".";
if (strcmp(pattern,".") == 0) return False;
if (is_case_sensitive) {
- return ms_fnmatch(pattern, string) == 0;
+ return ms_fnmatch(pattern, string, Protocol) == 0;
}
fstrcpy(p2, pattern);
fstrcpy(s2, string);
strlower(p2);
strlower(s2);
- return ms_fnmatch(p2, s2) == 0;
+ return ms_fnmatch(p2, s2, Protocol) == 0;
}
+/*********************************************************
+ Recursive routine that is called by unix_wild_match.
+*********************************************************/
+
+static BOOL unix_do_match(char *regexp, char *str)
+{
+ 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 && (*p != *str))
+ str++;
+
+ /*
+ * Patch from weidel@multichart.de. In the case of the regexp
+ * '*XX*' we want to ensure there are at least 2 'X' characters
+ * in the string after the '*' for a match to be made.
+ */
+
+ {
+ int matchcount=0;
+
+ /*
+ * Eat all the characters that match, but count how many there were.
+ */
+
+ while(*str && (*p == *str)) {
+ str++;
+ matchcount++;
+ }
+
+ /*
+ * Now check that if the regexp had n identical characters that
+ * matchcount had at least that many matches.
+ */
+
+ while ( *(p+1) && (*(p+1) == *p)) {
+ p++;
+ matchcount--;
+ }
+
+ if ( matchcount <= 0 )
+ return False;
+ }
+
+ str--; /* We've eaten the match char after the '*' */
+
+ if(unix_do_match(p, str))
+ return True;
+
+ if(!*str)
+ return False;
+ else
+ str++;
+ }
+ return False;
+
+ default:
+ if(*str != *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;
+}
+
+/*******************************************************************
+ Simple case insensitive interface to a UNIX wildcard matcher.
+*******************************************************************/
+
+BOOL unix_wild_match(char *pattern, char *string)
+{
+ pstring p2, s2;
+ char *p;
+
+ pstrcpy(p2, pattern);
+ pstrcpy(s2, string);
+ strlower(p2);
+ strlower(s2);
+
+ /* Remove any *? and ** from the pattern as they are meaningless */
+ for(p = p2; *p; p++)
+ while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
+ pstrcpy( &p[1], &p[2]);
+
+ if (strequal(p2,"*"))
+ return True;
+
+ return unix_do_match(p2, s2) == 0;
+}
#ifdef __INSURE__
static int (*fn)();
int ret;
char pidstr[10];
- pstring cmd = "/usr/X11R6/bin/xterm -display :0 -T Panic -n Panic -e /bin/sh -c 'cat /tmp/ierrs.*.%d ; gdb /proc/%d/exe %d'";
+ /* you can get /usr/bin/backtrace from
+ http://samba.org/ftp/unpacked/junkcode/backtrace */
+ pstring cmd = "/usr/bin/backtrace %d";
slprintf(pidstr, sizeof(pidstr)-1, "%d", sys_getpid());
pstring_sub(cmd, "%d", pidstr);
static void *h;
h = dlopen("/usr/local/parasoft/insure++lite/lib.linux2/libinsure.so", RTLD_LAZY);
fn = dlsym(h, "_Insure_trap_error");
+
+ if (!h || h == _Insure_trap_error) {
+ h = dlopen("/usr/local/parasoft/lib.linux2/libinsure.so", RTLD_LAZY);
+ fn = dlsym(h, "_Insure_trap_error");
+ }
}
ret = fn(a1, a2, a3, a4, a5, a6);