Cleanups!
[kai/samba.git] / source3 / lib / util.c
index 6caa605066367e5ffef7713dfa833e36ef660f6d..a23ef91a31e194a833aaec7dc09ecd385075c355 100644 (file)
@@ -1,6 +1,5 @@
 /* 
-   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
 #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 */
@@ -92,9 +84,10 @@ char **my_netbios_names;
 
 
 /****************************************************************************
 find a suitable temporary directory. The result should be copied immediately
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;
@@ -122,10 +115,10 @@ BOOL in_group(gid_t group, gid_t current_gid, int ngroups, gid_t *groups)
 }
 
 /****************************************************************************
- 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)) {
                DEBUG(5, ("Atoic: malformed number\n"));
@@ -182,7 +175,7 @@ char *get_numlist(char *p, uint32 **num, int *count)
  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)
@@ -191,14 +184,14 @@ BOOL file_exist(char *fname,SMB_STRUCT_STAT *sbuf)
   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.
 ********************************************************************/
 
-time_t file_modtime(char *fname)
+time_t file_modtime(const char *fname)
 {
   SMB_STRUCT_STAT st;
   
@@ -311,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');
 }
 
 /*******************************************************************
@@ -324,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);
@@ -429,6 +422,7 @@ smb_ucs2_t *unix_clean_path(const smb_ucs2_t *s)
        smb_ucs2_t *p, *r, *t;
 
        DEBUG(3, ("unix_clean_path\n")); /*  [%unicode]\n")); */
+       if(!s) return NULL;
 
        /* convert '\' to '/' */
        ns = strdup_w(s);
@@ -449,19 +443,20 @@ smb_ucs2_t *unix_clean_path(const smb_ucs2_t *s)
 
        /* reduce any /../ */
        t = ns;
-       while ((r = strstr_wa(t, "/.."))) {
+       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;
-                       memmove(p, t, (strlen_w(t) + 1) * sizeof(smb_ucs2_t));
+                       if (*t == 0) *p = 0;
+                       else memmove(p, t, (strlen_w(t) + 1) * sizeof(smb_ucs2_t));
                        t = p;
                }
        }
 
-       /* remove any trailing /. */
-       trim_string_wa(ns, NULL, "/.");
+       /* remove any leading ./ trailing /. */
+       trim_string_wa(ns, "./", "/.");
 
        /* remove any leading and trailing / */
        trim_string_wa(ns, "/", "/");
@@ -494,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);
@@ -551,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
 }
 
@@ -619,33 +614,44 @@ ssize_t transfer_file_internal(int infd, int outfd, size_t n, ssize_t (*read_fn)
 
 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.
 ********************************************************************/
 
-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);
+       }
 }
 
 /****************************************************************************
@@ -677,7 +683,7 @@ void become_daemon(void)
 
 
 /****************************************************************************
-put up a yes/no prompt
+ Put up a yes/no prompt
 ****************************************************************************/
 BOOL yesno(char *p)
 {
@@ -850,7 +856,7 @@ 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 is_zero_ip(struct in_addr ip)
 {
@@ -859,7 +865,9 @@ BOOL is_zero_ip(struct in_addr ip)
   return(a == 0);
 }
 
-/* Set an IP to 0.0.0.0 */
+/*******************************************************************
+ Set an IP to 0.0.0.0
+ ******************************************************************/
 
 void zero_ip(struct in_addr *ip)
 {
@@ -1033,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);
 }
 
@@ -1046,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);
 }
@@ -1065,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)
@@ -1084,22 +1091,22 @@ 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(const char *name)
@@ -1112,9 +1119,6 @@ gid_t nametogid(const 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);
@@ -1348,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 */
@@ -1386,20 +1388,39 @@ 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)
@@ -1411,8 +1432,7 @@ BOOL is_myname_or_ipaddr(char *s)
                return True;
 
        /* maybe its an IP address? */
-       if (is_ipaddress(s))
-       {
+       if (is_ipaddress(s)) {
                struct iface_struct nics[MAX_INTERFACES];
                int i, n;
                uint32 ip;
@@ -1430,59 +1450,56 @@ BOOL is_myname_or_ipaddr(char *s)
 
        /* check for an alias */
        ptr = lp_netbios_aliases();
-       for ( ; *ptr; ptr++ )
-       {
+       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;
 }
 
 
@@ -1490,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);
@@ -1764,10 +1774,10 @@ int smb_mkstemp(char *template)
 #endif
 }
 
-
-/**
+/*****************************************************************
  malloc that aborts with smb_panic on fail or zero size.
-**/
+ *****************************************************************/  
+
 void *smb_xmalloc(size_t size)
 {
        void *p;
@@ -1806,7 +1816,13 @@ char *smb_xstrdup(const char *s)
 int smb_xvasprintf(char **ptr, const char *format, va_list ap)
 {
        int n;
-       n = vasprintf(ptr, format, ap);
+       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");
        }
@@ -1859,6 +1875,26 @@ char *lock_path(char *name)
        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.
@@ -1925,6 +1961,7 @@ BOOL ms_has_wild(char *s)
 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('*'):
@@ -2086,92 +2123,6 @@ BOOL unix_wild_match(char *pattern, char *string)
        return unix_do_match(p2, s2) == 0;      
 }
 
-/*******************************************************************
- free() a data blob
-*******************************************************************/
-static void free_data_blob(DATA_BLOB *d)
-{
-       if ((d) && (d->free)) {
-               SAFE_FREE(d->data);
-       }
-}
-
-/*******************************************************************
- construct a data blob, must be freed with data_blob_free()
- you can pass NULL for p and get a blank data blob
-*******************************************************************/
-DATA_BLOB data_blob(const void *p, size_t length)
-{
-       DATA_BLOB ret;
-
-       if (!length) {
-               ZERO_STRUCT(ret);
-               return ret;
-       }
-
-       if (p) {
-               ret.data = smb_xmemdup(p, length);
-       } else {
-               ret.data = smb_xmalloc(length);
-       }
-       ret.length = length;
-       ret.free = free_data_blob;
-       return ret;
-}
-
-/*******************************************************************
- construct a data blob, using supplied TALLOC_CTX
-*******************************************************************/
-DATA_BLOB data_blob_talloc(TALLOC_CTX *mem_ctx, const void *p, size_t length)
-{
-       DATA_BLOB ret;
-
-       if (!p || !length) {
-               ZERO_STRUCT(ret);
-               return ret;
-       }
-
-       ret.data = talloc_memdup(mem_ctx, p, length);
-       if (ret.data == NULL)
-               smb_panic("data_blob_talloc: talloc_memdup failed.\n");
-
-       ret.length = length;
-       ret.free = NULL;
-       return ret;
-}
-
-/*******************************************************************
-free a data blob
-*******************************************************************/
-void data_blob_free(DATA_BLOB *d)
-{
-       if (d) {
-               if (d->free) {
-                       (d->free)(d);
-               }
-               ZERO_STRUCTP(d);
-       }
-}
-
-/*******************************************************************
-clear a DATA_BLOB's contents
-*******************************************************************/
-void data_blob_clear(DATA_BLOB *d)
-{
-       if (d->data) {
-               memset(d->data, 0, d->length);
-       }
-}
-
-/*******************************************************************
-free a data blob and clear its contents
-*******************************************************************/
-void data_blob_clear_free(DATA_BLOB *d)
-{
-       data_blob_clear(d);
-       data_blob_free(d);
-}
-
 #ifdef __INSURE__
 
 /*******************************************************************
@@ -2195,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);