Minor change to bring smbmount in the main branch in line with some bzero
[samba.git] / source / client / smbmount.c
index 95aeecde3c55f21965fd024887a09bddc33ca15e..00331f36819e1518d9bb1b58b1337870d295dc79 100644 (file)
@@ -28,6 +28,8 @@
 #endif
 
 #include "includes.h"
+
+#include <asm/types.h>
 #include <linux/smb_fs.h>
 static struct smb_conn_opt conn_options;
 
@@ -36,7 +38,7 @@ static struct smb_conn_opt conn_options;
 #endif
 
 /* Uncomment this to allow debug the smbmount daemon */
-#define SMBFS_DEBUG 1
+/* #define SMBFS_DEBUG 1 */
 
 pstring cur_dir = "\\";
 pstring cd_path = "";
@@ -69,7 +71,6 @@ extern int name_type;
 extern int max_protocol;
 int port = SMB_PORT;
 
-
 time_t newer_than = 0;
 int archive_level = 0;
 
@@ -78,12 +79,10 @@ extern int DEBUGLEVEL;
 
 BOOL translation = False;
 
-extern int cnum;
-extern int mid;
-extern int pid;
-extern int tid;
-extern int gid;
-extern int uid;
+extern uint16 cnum;
+extern uint16 mid;
+extern uint16 pid;
+extern uint16 vuid;
 
 extern BOOL have_ip;
 extern int max_xmit;
@@ -95,7 +94,7 @@ extern BOOL tar_reset;
 /* clitar bits end */
  
 
-int myumask = 0755;
+mode_t myumask = 0755;
 
 extern pstring scope;
 
@@ -150,7 +149,7 @@ static BOOL chkpath(char *path,BOOL report)
   trim_string(path2,NULL,"\\");
   if (!*path2) *path2 = '\\';
 
-  bzero(outbuf,smb_size);
+  memset(outbuf,'\0',smb_size);
   set_message(outbuf,0,4 + strlen(path2),True);
   SCVAL(outbuf,smb_com,SMBchkpth);
   SSVAL(outbuf,smb_tid,cnum);
@@ -181,20 +180,51 @@ static BOOL chkpath(char *path,BOOL report)
   return(CVAL(inbuf,smb_rcls) == 0);
 }
 
+static void
+exit_parent( int sig )
+{
+       /* parent simply exits when child says go... */
+       exit(0);
+}
+
 static void
 daemonize(void)
 {
-       int i;
-       if ((i = fork()) < 0)
+       int j, status;
+       pid_t child_pid;
+
+       signal( SIGTERM, exit_parent );
+
+       if ((child_pid = fork()) < 0)
        {
                DEBUG(0, ("could not fork\n"));
        }
-       if (i > 0)
+       if (child_pid > 0)
        {
-               /* parent simply exits */
-               exit(0);
+               while( 1 ) {
+                       j = waitpid( child_pid, &status, 0 );
+                       if( j < 0 ) {
+                               if( EINTR == errno ) {
+                                       continue;
+                               }
+                               status = errno;
+                       }
+                       break;
+               }
+               /* If we get here - the child exited with some error status */
+               exit(status);
        }
-       setsid();
+       /* Programmers Note:
+               Danger Will Robinson!  Danger!
+
+               There use to be a call to setsid() here.  This does no
+               harm to normal mount operations, but it broke automounting.
+               The setsid call has been moved to just before the child
+               sends the SIGTERM to the parent.  All of our deadly embrace
+               conditions with autofs will have been cleared by then...
+               -mhw-
+       */
+       signal( SIGTERM, SIG_DFL );
        chdir("/");
 }
 
@@ -231,7 +261,7 @@ static BOOL mount_send_login(char *inbuf, char *outbuf)
   conn_options.protocol = opt.protocol;
   conn_options.case_handling = CASE_LOWER;
   conn_options.max_xmit = opt.max_xmit;
-  conn_options.server_uid = opt.server_uid;
+  conn_options.server_uid = opt.server_vuid;
   conn_options.tid = opt.tid;
   conn_options.secmode = opt.sec_mode;
   conn_options.maxmux = opt.max_mux;
@@ -256,6 +286,8 @@ send_fs_socket(char *mount_point, char *inbuf, char *outbuf)
 {
        int fd, closed = 0, res = 1;
 
+       pid_t parentpid = getppid();
+
        while (1)
        {
                if ((fd = open(mount_point, O_RDONLY)) < 0)
@@ -277,6 +309,15 @@ send_fs_socket(char *mount_point, char *inbuf, char *outbuf)
                        DEBUG(0, ("smbmount: ioctl failed, res=%d\n", res));
                }
 
+               if( parentpid ) {
+                       /* Ok...  We are going to kill the parent.  Now
+                               is the time to break the process group... */
+                       setsid();
+                       /* Send a signal to the parent to terminate */
+                       kill( parentpid, SIGTERM );
+                       parentpid = 0;
+               }
+
                close_sockets();
                close(fd);
                /*
@@ -359,17 +400,17 @@ static void cmd_mount(char *inbuf,char *outbuf)
        DEBUG(3, ("mount command: %s\n", mount_command));
 
        /*
-        * Create the background process before trying the mount.
-        * (We delay closing files to allow diagnostic messages.)
-        */
+               Set up to return as a daemon child and wait in the parent
+               until the child say it's ready...
+       */
        daemonize();
 
-       /* The parent has exited here, the child handles the connection: */
        if ((retval = system(mount_command)) != 0)
        {
                DEBUG(0,("mount failed\n"));
                exit(1);
        }
+
        send_fs_socket(mount_point, inbuf, outbuf);
 }      
 
@@ -495,7 +536,7 @@ static BOOL process(char *base_directory)
   if ((InBuffer == NULL) || (OutBuffer == NULL)) 
     return(False);
   
-  bzero(OutBuffer,smb_size);
+  memset(OutBuffer,'\0',smb_size);
 
   if (!mount_send_login(InBuffer,OutBuffer))
     return(False);
@@ -542,7 +583,7 @@ static BOOL process(char *base_directory)
       fstring tok;
       int i;
 
-      bzero(OutBuffer,smb_size);
+      memset(OutBuffer,'\0',smb_size);
 
       /* display a prompt */
       DEBUG(0,("smb: %s> ", CNV_LANG(cur_dir)));
@@ -640,9 +681,8 @@ static void usage(char *pname)
   TimeInit();
   charset_initialise();
 
-  pid = getpid();
-  uid = getuid();
-  gid = getgid();
+  pid = (uint16)getpid();
+  vuid = (uint16)getuid();
   mid = pid + 100;
   myumask = umask(0);
   umask(myumask);