A couple of coding syle updates to follow the re-indent.
[ira/wip.git] / source / lib / util_sock.c
index 340a83cf13f560ff406ebb512feafeccbd8ef6b1..8e7b69cac8860bc7bc5bb95ed061389e7eb0620c 100644 (file)
@@ -1,8 +1,9 @@
 /* 
    Unix SMB/Netbios implementation.
-   Version 1.9.
+   Version 3.0.
    Samba utility functions
    Copyright (C) Andrew Tridgell 1992-1998
+   Copyright (C) Tim Potter      2000-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
@@ -202,109 +203,109 @@ ssize_t read_udp_socket(int fd,char *buf,size_t len)
 
 static ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned int time_out)
 {
-  fd_set fds;
-  int selrtn;
-  ssize_t readret;
-  size_t nread = 0;
-  struct timeval timeout;
-
-  /* just checking .... */
-  if (maxcnt <= 0)
-    return(0);
-
-  smb_read_error = 0;
-
-  /* Blocking read */
-  if (time_out <= 0) {
-    if (mincnt == 0) mincnt = maxcnt;
-
-    while (nread < mincnt) {
+       fd_set fds;
+       int selrtn;
+       ssize_t readret;
+       size_t nread = 0;
+       struct timeval timeout;
+       
+       /* just checking .... */
+       if (maxcnt <= 0)
+               return(0);
+       
+       smb_read_error = 0;
+       
+       /* Blocking read */
+       if (time_out <= 0) {
+               if (mincnt == 0) mincnt = maxcnt;
+               
+               while (nread < mincnt) {
 #ifdef WITH_SSL
-      if(fd == sslFd){
-        readret = SSL_read(ssl, buf + nread, maxcnt - nread);
-      }else{
-        readret = read(fd, buf + nread, maxcnt - nread);
-      }
+                       if (fd == sslFd) {
+                               readret = SSL_read(ssl, buf + nread, maxcnt - nread);
+                       } else {
+                               readret = read(fd, buf + nread, maxcnt - nread);
+                       }
 #else /* WITH_SSL */
-      readret = read(fd, buf + nread, maxcnt - nread);
+                       readret = read(fd, buf + nread, maxcnt - nread);
 #endif /* WITH_SSL */
-
-      if (readret == 0) {
-        DEBUG(5,("read_socket_with_timeout: blocking read. EOF from client.\n"));
-        smb_read_error = READ_EOF;
-        return -1;
-      }
-
-      if (readret == -1) {
-        DEBUG(0,("read_socket_with_timeout: read error = %s.\n", strerror(errno) ));
-        smb_read_error = READ_ERROR;
-        return -1;
-      }
-      nread += readret;
-    }
-    return((ssize_t)nread);
-  }
-  
-  /* Most difficult - timeout read */
-  /* If this is ever called on a disk file and 
-     mincnt is greater then the filesize then
-     system performance will suffer severely as 
-     select always returns true on disk files */
-
-  /* Set initial timeout */
-  timeout.tv_sec = (time_t)(time_out / 1000);
-  timeout.tv_usec = (long)(1000 * (time_out % 1000));
-
-  for (nread=0; nread < mincnt; ) {      
-    FD_ZERO(&fds);
-    FD_SET(fd,&fds);
-      
-    selrtn = sys_select_intr(fd+1,&fds,&timeout);
-
-    /* Check if error */
-    if(selrtn == -1) {
-      /* something is wrong. Maybe the socket is dead? */
-      DEBUG(0,("read_socket_with_timeout: timeout read. select error = %s.\n", strerror(errno) ));
-      smb_read_error = READ_ERROR;
-      return -1;
-    }
-
-    /* Did we timeout ? */
-    if (selrtn == 0) {
-      DEBUG(10,("read_socket_with_timeout: timeout read. select timed out.\n"));
-      smb_read_error = READ_TIMEOUT;
-      return -1;
-    }
-      
+                       
+                       if (readret == 0) {
+                               DEBUG(5,("read_socket_with_timeout: blocking read. EOF from client.\n"));
+                               smb_read_error = READ_EOF;
+                               return -1;
+                       }
+                       
+                       if (readret == -1) {
+                               DEBUG(0,("read_socket_with_timeout: read error = %s.\n", strerror(errno) ));
+                               smb_read_error = READ_ERROR;
+                               return -1;
+                       }
+                       nread += readret;
+               }
+               return((ssize_t)nread);
+       }
+       
+       /* Most difficult - timeout read */
+       /* If this is ever called on a disk file and 
+          mincnt is greater then the filesize then
+          system performance will suffer severely as 
+          select always returns true on disk files */
+       
+       /* Set initial timeout */
+       timeout.tv_sec = (time_t)(time_out / 1000);
+       timeout.tv_usec = (long)(1000 * (time_out % 1000));
+       
+       for (nread=0; nread < mincnt; ) {      
+               FD_ZERO(&fds);
+               FD_SET(fd,&fds);
+               
+               selrtn = sys_select_intr(fd+1,&fds,&timeout);
+               
+               /* Check if error */
+               if (selrtn == -1) {
+                       /* something is wrong. Maybe the socket is dead? */
+                       DEBUG(0,("read_socket_with_timeout: timeout read. select error = %s.\n", strerror(errno) ));
+                       smb_read_error = READ_ERROR;
+                       return -1;
+               }
+               
+               /* Did we timeout ? */
+               if (selrtn == 0) {
+                       DEBUG(10,("read_socket_with_timeout: timeout read. select timed out.\n"));
+                       smb_read_error = READ_TIMEOUT;
+                       return -1;
+               }
+               
 #ifdef WITH_SSL
-    if(fd == sslFd){
-      readret = SSL_read(ssl, buf + nread, maxcnt - nread);
-    }else{
-      readret = read(fd, buf + nread, maxcnt - nread);
-    }
+               if (fd == sslFd) {
+                       readret = SSL_read(ssl, buf + nread, maxcnt - nread);
+               }else{
+                       readret = read(fd, buf + nread, maxcnt - nread);
+               }
 #else /* WITH_SSL */
-    readret = read(fd, buf+nread, maxcnt-nread);
+               readret = read(fd, buf+nread, maxcnt-nread);
 #endif /* WITH_SSL */
-
-    if (readret == 0) {
-      /* we got EOF on the file descriptor */
-      DEBUG(5,("read_socket_with_timeout: timeout read. EOF from client.\n"));
-      smb_read_error = READ_EOF;
-      return -1;
-    }
-
-    if (readret == -1) {
-      /* the descriptor is probably dead */
-      DEBUG(0,("read_socket_with_timeout: timeout read. read error = %s.\n", strerror(errno) ));
-      smb_read_error = READ_ERROR;
-      return -1;
-    }
-      
-    nread += readret;
-  }
-
-  /* Return the number we got */
-  return((ssize_t)nread);
+               
+               if (readret == 0) {
+                       /* we got EOF on the file descriptor */
+                       DEBUG(5,("read_socket_with_timeout: timeout read. EOF from client.\n"));
+                       smb_read_error = READ_EOF;
+                       return -1;
+               }
+               
+               if (readret == -1) {
+                       /* the descriptor is probably dead */
+                       DEBUG(0,("read_socket_with_timeout: timeout read. read error = %s.\n", strerror(errno) ));
+                       smb_read_error = READ_ERROR;
+                       return -1;
+               }
+               
+               nread += readret;
+       }
+       
+       /* Return the number we got */
+       return (ssize_t)nread;
 }
 
 /****************************************************************************
@@ -316,76 +317,76 @@ static ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t ma
 
 ssize_t read_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned int time_out)
 {
-  fd_set fds;
-  int selrtn;
-  ssize_t readret;
-  size_t nread = 0;
-  struct timeval timeout;
-
-  /* just checking .... */
-  if (maxcnt <= 0)
-    return(0);
-
-  /* Blocking read */
-  if (time_out <= 0) {
-    if (mincnt == 0) mincnt = maxcnt;
-
-    while (nread < mincnt) {
+       fd_set fds;
+       int selrtn;
+       ssize_t readret;
+       size_t nread = 0;
+       struct timeval timeout;
+       
+       /* just checking .... */
+       if (maxcnt <= 0)
+               return(0);
+       
+       /* Blocking read */
+       if (time_out <= 0) {
+               if (mincnt == 0) mincnt = maxcnt;
+               
+               while (nread < mincnt) {
 #ifdef WITH_SSL
-      if(fd == sslFd){
-        readret = SSL_read(ssl, buf + nread, maxcnt - nread);
-      }else{
-        readret = read(fd, buf + nread, maxcnt - nread);
-      }
+                       if(fd == sslFd){
+                               readret = SSL_read(ssl, buf + nread, maxcnt - nread);
+                       }else{
+                               readret = read(fd, buf + nread, maxcnt - nread);
+                       }
 #else /* WITH_SSL */
-      readret = read(fd, buf + nread, maxcnt - nread);
+                       readret = read(fd, buf + nread, maxcnt - nread);
 #endif /* WITH_SSL */
-
-      if (readret <= 0)
-       return readret;
-
-      nread += readret;
-    }
-    return((ssize_t)nread);
-  }
-  
-  /* Most difficult - timeout read */
-  /* If this is ever called on a disk file and 
-     mincnt is greater then the filesize then
-     system performance will suffer severely as 
-     select always returns true on disk files */
-
-  /* Set initial timeout */
-  timeout.tv_sec = (time_t)(time_out / 1000);
-  timeout.tv_usec = (long)(1000 * (time_out % 1000));
-
-  for (nread=0; nread < mincnt; ) {      
-    FD_ZERO(&fds);
-    FD_SET(fd,&fds);
-      
-    selrtn = sys_select_intr(fd+1,&fds,&timeout);
-
-    if(selrtn <= 0)
-      return selrtn;
-      
+                       
+                       if (readret <= 0)
+                               return readret;
+                       
+                       nread += readret;
+               }
+               return((ssize_t)nread);
+       }
+       
+       /* Most difficult - timeout read */
+       /* If this is ever called on a disk file and 
+          mincnt is greater then the filesize then
+          system performance will suffer severely as 
+          select always returns true on disk files */
+       
+       /* Set initial timeout */
+       timeout.tv_sec = (time_t)(time_out / 1000);
+       timeout.tv_usec = (long)(1000 * (time_out % 1000));
+       
+       for (nread=0; nread < mincnt; ) {      
+               FD_ZERO(&fds);
+               FD_SET(fd,&fds);
+               
+               selrtn = sys_select_intr(fd+1,&fds,&timeout);
+               
+               if(selrtn <= 0)
+                       return selrtn;
+               
 #ifdef WITH_SSL
-    if(fd == sslFd){
-      readret = SSL_read(ssl, buf + nread, maxcnt - nread);
-    }else{
-      readret = read(fd, buf + nread, maxcnt - nread);
-    }
+               if(fd == sslFd){
+                       readret = SSL_read(ssl, buf + nread, maxcnt - nread);
+               }else{
+                       readret = read(fd, buf + nread, maxcnt - nread);
+               }
 #else /* WITH_SSL */
-    readret = read(fd, buf+nread, maxcnt-nread);
+               readret = read(fd, buf+nread, maxcnt-nread);
 #endif /* WITH_SSL */
-
-    if (readret <= 0)
-      return readret;
-
-    nread += readret;
-  }
-
-  /* Return the number we got */
-  return((ssize_t)nread);
+               
+               if (readret <= 0)
+                       return readret;
+               
+               nread += readret;
+       }
+       
+       /* Return the number we got */
+       return((ssize_t)nread);
 }
 
 /****************************************************************************
@@ -814,7 +815,7 @@ int open_socket_in( int type, int port, int dlevel, uint32 socket_addr, BOOL reb
                if( setsockopt(res,SOL_SOCKET,SO_REUSEPORT,(char *)&val,sizeof(val)) == -1 ) {
                        if( DEBUGLVL( dlevel ) ) {
                                dbgtext( "open_socket_in(): setsockopt: ");
-                               dbgtext( "SO_REUSEPORT = %d ", val?"True":"False" );
+                               dbgtext( "SO_REUSEPORT = %s ", val?"True":"False" );
                                dbgtext( "on port %d failed ", port );
                                dbgtext( "with error = %s\n", strerror(errno) );
                        }
@@ -905,6 +906,37 @@ connect_again:
   return res;
 }
 
+/*
+  open a connected UDP socket to host on port
+*/
+int open_udp_socket(const char *host, int port)
+{
+       int type = SOCK_DGRAM;
+       struct sockaddr_in sock_out;
+       int res;
+       struct in_addr *addr;
+
+       addr = interpret_addr2(host);
+
+       res = socket(PF_INET, type, 0);
+       if (res == -1) {
+               return -1;
+       }
+
+       memset((char *)&sock_out,'\0',sizeof(sock_out));
+       putip((char *)&sock_out.sin_addr,(char *)addr);
+       sock_out.sin_port = htons(port);
+       sock_out.sin_family = PF_INET;
+
+       if (connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out))) {
+               close(res);
+               return -1;
+       }
+
+       return res;
+}
+
+
 /* the following 3 client_*() functions are nasty ways of allowing
    some generic functions to get info that really should be hidden in
    particular modules */
@@ -1081,6 +1113,107 @@ int open_pipe_sock(char *path)
        return sock;
 }
 
+/*******************************************************************
+ Create protected unix domain socket.
+
+ some unixen cannot set permissions on a ux-dom-sock, so we
+ have to make sure that the directory contains the protection
+ permissions, instead.
+ ******************************************************************/
+int create_pipe_sock(const char *socket_dir,
+                                       const char *socket_name,
+                                       mode_t dir_perms)
+{
+        struct sockaddr_un sunaddr;
+        struct stat st;
+        int sock;
+        mode_t old_umask;
+        pstring path;
+        
+        /* Create the socket directory or reuse the existing one */
+        
+        if (lstat(socket_dir, &st) == -1) {
+                
+                if (errno == ENOENT) {
+                        
+                        /* Create directory */
+                        
+                        if (mkdir(socket_dir, dir_perms) == -1) {
+                                DEBUG(0, ("error creating socket directory "
+                                          "%s: %s\n", socket_dir, 
+                                          strerror(errno)));
+                                return -1;
+                        }
+                        
+                } else {
+                        
+                        DEBUG(0, ("lstat failed on socket directory %s: %s\n",
+                                  socket_dir, strerror(errno)));
+                        return -1;
+                }
+                
+        } else {
+                
+                /* Check ownership and permission on existing directory */
+                
+                if (!S_ISDIR(st.st_mode)) {
+                        DEBUG(0, ("socket directory %s isn't a directory\n",
+                                  socket_dir));
+                        return -1;
+                }
+                
+                if ((st.st_uid != sec_initial_uid()) || 
+                    ((st.st_mode & 0777) != dir_perms)) {
+                        DEBUG(0, ("invalid permissions on socket directory "
+                                  "%s\n", socket_dir));
+                        return -1;
+                }
+        }
+        
+        /* Create the socket file */
+        
+        old_umask = umask(0);
+        
+        sock = socket(AF_UNIX, SOCK_STREAM, 0);
+        
+        if (sock == -1) {
+                perror("socket");
+               umask(old_umask);
+                return -1;
+        }
+        
+        snprintf(path, sizeof(path), "%s/%s", socket_dir, socket_name);
+        
+        unlink(path);
+        memset(&sunaddr, 0, sizeof(sunaddr));
+        sunaddr.sun_family = AF_UNIX;
+        safe_strcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path)-1);
+        
+        if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) == -1) {
+                DEBUG(0, ("bind failed on pipe socket %s: %s\n",
+                          path,
+                          strerror(errno)));
+                close(sock);
+               umask(old_umask);
+                return -1;
+        }
+        
+        if (listen(sock, 5) == -1) {
+                DEBUG(0, ("listen failed on pipe socket %s: %s\n",
+                          path,
+                          strerror(errno)));
+                close(sock);
+               umask(old_umask);
+                return -1;
+        }
+        
+        umask(old_umask);
+        
+        /* Success! */
+        
+        return sock;
+}
+
 /*******************************************************************
 this is like socketpair but uses tcp. It is used by the Samba
 regression test code