Cleanups!
[kai/samba.git] / source3 / lib / util.c
index 61da9eb230697f0753a61992aa9679e199f4227c..a23ef91a31e194a833aaec7dc09ecd385075c355 100644 (file)
@@ -1,9 +1,9 @@
 /* 
-   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 <openssl/ssl.h>
-#undef Realloc  /* SSLeay defines this and samba has a function of this name */
-extern SSL  *ssl;
-extern int  sslFd;
-#endif  /* WITH_SSL */
-
 int Protocol = PROTOCOL_COREPLUS;
 
 /* a default finfo structure to ensure all fields are sensible */
@@ -91,27 +84,28 @@ char **my_netbios_names;
 
 
 /****************************************************************************
-  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])
@@ -120,14 +114,13 @@ BOOL in_group(gid_t group, gid_t current_gid, int ngroups, gid_t *groups)
        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;
        }
@@ -135,9 +128,7 @@ char *Atoic(char *p, int *n, char *c)
        (*n) = atoi(p);
 
        while ((*p) && isdigit((int)*p))
-       {
                p++;
-       }
 
        if (strchr_m(c, *p) == NULL)
        {
@@ -149,22 +140,20 @@ char *Atoic(char *p, int *n, char *c)
 }
 
 /*************************************************************************
- 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) != ':')
-       {
+       while ((p = Atoic(p, &val, ":,")) != NULL && (*p) != ':') {
                uint32 *tn;
                
                tn = Realloc((*num), ((*count)+1) * sizeof(uint32));
@@ -172,8 +161,8 @@ char *get_numlist(char *p, uint32 **num, int *count)
                {
                        SAFE_FREE(*num);
                        return NULL;
-               }
-               else (*num) = tn;
+               } else
+                       (*num) = tn;
                (*num)[(*count)] = val;
                (*count)++;
                p++;
@@ -182,25 +171,27 @@ char *get_numlist(char *p, uint32 **num, int *count)
        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)));
 }
 
 /*******************************************************************
-check a files mod time
+ Check a files mod time.
 ********************************************************************/
-time_t file_modtime(char *fname)
+
+time_t file_modtime(const char *fname)
 {
   SMB_STRUCT_STAT st;
   
@@ -211,8 +202,9 @@ time_t file_modtime(char *fname)
 }
 
 /*******************************************************************
-  check if a directory exists
+ Check if a directory exists.
 ********************************************************************/
+
 BOOL directory_exist(char *dname,SMB_STRUCT_STAT *st)
 {
   SMB_STRUCT_STAT st2;
@@ -312,10 +304,10 @@ void smb_setlen(char *buf,int len)
 {
   _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');
 }
 
 /*******************************************************************
@@ -325,7 +317,7 @@ int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
 {
        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);
@@ -418,6 +410,60 @@ void unix_clean_name(char *s)
   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
 ****************************************************************************/
@@ -443,7 +489,7 @@ void make_dir_struct(char *buf,char *mask,char *fname,SMB_OFF_T size,int mode,ti
       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);
@@ -500,13 +546,13 @@ int set_blocking(int fd, BOOL set)
 #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
 }
 
@@ -514,81 +560,104 @@ int set_blocking(int fd, BOOL set)
  Transfer some data between two fd's.
 ****************************************************************************/
 
+#ifndef TRANSFER_BUF_SIZE
+#define TRANSFER_BUF_SIZE 65536
+#endif
+
 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))
 {
-       static char buf[16384];
+       char *buf;
        size_t total = 0;
        ssize_t read_ret;
-       size_t write_total = 0;
-    ssize_t write_ret;
+       ssize_t write_ret;
+       size_t num_to_read_thistime;
+       size_t num_written = 0;
+
+       if ((buf = malloc(TRANSFER_BUF_SIZE)) == NULL)
+               return -1;
 
        while (total < n) {
-               size_t num_to_read_thistime = MIN((n - total), sizeof(buf));
+               num_to_read_thistime = MIN((n - total), TRANSFER_BUF_SIZE);
 
-               read_ret = (*read_fn)(infd, buf + total, num_to_read_thistime);
+               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;
 
-               write_total = 0;
+               num_written = 0;
  
-               while (write_total < read_ret) {
-                       write_ret = (*write_fn)(outfd,buf + total, read_ret);
+               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;
  
-                       write_total += (size_t)write_ret;
+                       num_written += (size_t)write_ret;
                }
 
                total += (size_t)read_ret;
        }
 
+       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, read, write);
+       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()) {
@@ -614,7 +683,7 @@ void become_daemon(void)
 
 
 /****************************************************************************
-put up a yes/no prompt
+ Put up a yes/no prompt
 ****************************************************************************/
 BOOL yesno(char *p)
 {
@@ -631,8 +700,9 @@ BOOL yesno(char *p)
 }
 
 /****************************************************************************
-expand a pointer to be a particular size
+ Expand a pointer to be a particular size.
 ****************************************************************************/
+
 void *Realloc(void *p,size_t size)
 {
   void *ret=NULL;
@@ -654,20 +724,21 @@ void *Realloc(void *p,size_t size)
   return(ret);
 }
 
-
 /****************************************************************************
-free memory, checks for NULL and set to 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)
 {
        SAFE_FREE(p);
 }
 
 /****************************************************************************
-get my own name and IP
+ Get my own name and IP.
 ****************************************************************************/
+
 BOOL get_myname(char *my_name)
 {
        pstring hostname;
@@ -686,7 +757,9 @@ BOOL get_myname(char *my_name)
        if (my_name) {
                /* split off any parts after an initial . */
                char *p = strchr_m(hostname,'.');
-               if (p) *p = 0;
+
+               if (p)
+                       *p = 0;
                
                fstrcpy(my_name,hostname);
        }
@@ -695,8 +768,9 @@ BOOL get_myname(char *my_name)
 }
 
 /****************************************************************************
-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"))
@@ -782,15 +856,31 @@ struct in_addr *interpret_addr2(const char *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))
 /******************************************************************
@@ -824,7 +914,7 @@ static void strip_mount_options( pstring *str)
 *******************************************************************/
 
 #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 = "";
@@ -872,7 +962,7 @@ char *automount_lookup(char *user_name)
   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 = "";
@@ -951,6 +1041,9 @@ check if a process exists. Does this work on all unixes?
 
 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);
 }
 
@@ -964,11 +1057,9 @@ char *uidtoname(uid_t uid)
        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);
 }
@@ -983,17 +1074,15 @@ char *gidtoname(gid_t gid)
        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)
@@ -1002,25 +1091,25 @@ uid_t nametouid(char *name)
        char *p;
        uid_t u;
 
-       u = (uid_t)strtol(name, &p, 0);
-       if ((p != name) && (*p == '\0'))
+       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;
@@ -1030,9 +1119,6 @@ gid_t nametogid(char *name)
        if ((p != name) && (*p == '\0'))
                return g;
 
-       if (winbind_nametogid(&g, name))
-               return g;
-
        grp = getgrnam(name);
        if (grp)
                return(grp->gr_gid);
@@ -1266,11 +1352,9 @@ BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
   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 */
@@ -1304,62 +1388,118 @@ BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
 }
 
 /*******************************************************************
-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;
 }
 
 
@@ -1367,42 +1507,35 @@ void out_ascii(FILE *f, unsigned char *buf,int len)
 {
        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);
@@ -1645,44 +1778,61 @@ int smb_mkstemp(char *template)
  malloc that aborts with smb_panic on fail or zero size.
  *****************************************************************/  
 
-void *xmalloc(size_t size)
+void *smb_xmalloc(size_t size)
 {
        void *p;
        if (size == 0)
-               smb_panic("xmalloc: called with zero size.\n");
+               smb_panic("smb_xmalloc: called with zero size.\n");
        if ((p = malloc(size)) == NULL)
-               smb_panic("xmalloc: malloc fail.\n");
+               smb_panic("smb_xmalloc: malloc fail.\n");
        return p;
 }
 
-/*****************************************************************
+/**
  Memdup with smb_panic on fail.
- *****************************************************************/  
-
-void *xmemdup(void *p, size_t size)
+**/
+void *smb_xmemdup(const void *p, size_t size)
 {
        void *p2;
-       p2 = xmalloc(size);
+       p2 = smb_xmalloc(size);
        memcpy(p2, p, size);
        return p2;
 }
 
-/*****************************************************************
+/**
  strdup that aborts on malloc fail.
- *****************************************************************/  
-
-char *xstrdup(const char *s)
+**/
+char *smb_xstrdup(const char *s)
 {
        char *s1 = strdup(s);
        if (!s1)
-               smb_panic("xstrdup: malloc fail\n");
+               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;
@@ -1726,12 +1876,37 @@ char *lock_path(char *name)
 }
 
 /*****************************************************************
-a useful function for returning a path in the Samba lib directory
- *****************************************************************/  
+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", LIBDIR, name);
+       snprintf(fname, sizeof(fname), "%s/%s", dyn_LIBDIR, name);
        return fname;
 }
 
@@ -1783,6 +1958,23 @@ BOOL ms_has_wild(char *s)
        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
@@ -1931,32 +2123,6 @@ BOOL unix_wild_match(char *pattern, char *string)
        return unix_do_match(p2, s2) == 0;      
 }
 
-/*******************************************************************
- construct a data blob, must be freed with data_blob_free()
-*******************************************************************/
-DATA_BLOB data_blob(void *p, size_t length)
-{
-       DATA_BLOB ret;
-
-       if (!p || !length) {
-               ZERO_STRUCT(ret);
-               return ret;
-       }
-
-       ret.data = xmemdup(p, length);
-       ret.length = length;
-       return ret;
-}
-
-/*******************************************************************
-free a data blob
-*******************************************************************/
-void data_blob_free(DATA_BLOB *d)
-{
-       SAFE_FREE(d->data);
-}
-
-
 #ifdef __INSURE__
 
 /*******************************************************************
@@ -1969,7 +2135,9 @@ int _Insure_trap_error(int a1, int a2, int a3, int a4, int a5, int a6)
        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);
@@ -1978,6 +2146,11 @@ int _Insure_trap_error(int a1, int a2, int a3, int a4, int a5, int a6)
                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);