Ok... Yet another round of fixes for smbmount and autofs.
[samba.git] / source / client / smbmount.c
index 51c1ee6310a947752053ba34c3815bb265cac625..3c2d2074986ee61e48bf3d7fb9ca160da1dda0e0 100644 (file)
@@ -19,9 +19,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
-#ifdef SYSLOG
-#undef SYSLOG
-#endif
+#define NO_SYSLOG
 
 #include <linux/version.h>
 #define LVERSION(major,minor,patch) (((((major)<<8)+(minor))<<8)+(patch))
@@ -30,6 +28,8 @@
 #endif
 
 #include "includes.h"
+
+#include <asm/types.h>
 #include <linux/smb_fs.h>
 static struct smb_conn_opt conn_options;
 
@@ -38,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 = "";
@@ -71,7 +71,6 @@ extern int name_type;
 extern int max_protocol;
 int port = SMB_PORT;
 
-
 time_t newer_than = 0;
 int archive_level = 0;
 
@@ -80,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;
@@ -97,7 +94,7 @@ extern BOOL tar_reset;
 /* clitar bits end */
  
 
-int myumask = 0755;
+mode_t myumask = 0755;
 
 extern pstring scope;
 
@@ -148,7 +145,7 @@ static BOOL chkpath(char *path,BOOL report)
   pstring inbuf,outbuf;
   char *p;
 
-  strcpy(path2,path);
+  fstrcpy(path2,path);
   trim_string(path2,NULL,"\\");
   if (!*path2) *path2 = '\\';
 
@@ -160,7 +157,7 @@ static BOOL chkpath(char *path,BOOL report)
 
   p = smb_buf(outbuf);
   *p++ = 4;
-  strcpy(p,path2);
+  fstrcpy(p,path2);
 
 #if 0
   {
@@ -183,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("/");
 }
 
@@ -233,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;
@@ -258,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)
@@ -279,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);
                /*
@@ -295,7 +334,7 @@ send_fs_socket(char *mount_point, char *inbuf, char *outbuf)
                /*
                 * Wait for a signal from smbfs ...
                 */
-               signal(SIGUSR1, &usr1_handler);
+               CatchSignal(SIGUSR1, &usr1_handler);
                pause();
                DEBUG(0, ("smbmount: got signal, getting new socket\n"));
 
@@ -328,7 +367,7 @@ static void cmd_mount(char *inbuf,char *outbuf)
        int retval;
        char mount_point[MAXPATHLEN+1];
 
-       if (!next_token(NULL, mpoint, NULL))
+       if (!next_token(NULL, mpoint, NULL, sizeof(mpoint)))
        {
                DEBUG(0,("You must supply a mount point\n"));
                return;
@@ -346,32 +385,32 @@ static void cmd_mount(char *inbuf,char *outbuf)
         * Build the service name to report on the Unix side,
         * converting '\' to '/' and ' ' to '_'.
         */
-       strcpy(share_name, service);  
+       pstrcpy(share_name, service);  
        string_replace(share_name, '\\', '/');
        string_replace(share_name, ' ', '_');
 
        slprintf(mount_command, sizeof(mount_command)-1,"smbmnt %s -s %s", mount_point, share_name);
 
-       while(next_token(NULL, buf, NULL))
+       while(next_token(NULL, buf, NULL, sizeof(buf)))
        {
-               strcat(mount_command, " ");
-               strcat(mount_command, buf);
+               pstrcat(mount_command, " ");
+               pstrcat(mount_command, buf);
        }
 
        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);
 }      
 
@@ -426,12 +465,12 @@ static int process_tok(fstring tok)
 /****************************************************************************
 help
 ****************************************************************************/
-void cmd_help(void)
+void cmd_help(char *dum_in, char *dum_out)
 {
   int i=0,j;
   fstring buf;
 
-  if (next_token(NULL,buf,NULL))
+  if (next_token(NULL,buf,NULL,sizeof(buf)))
     {
       if ((i = process_tok(buf)) >= 0)
        DEBUG(0,("HELP %s:\n\t%s\n\n",commands[i].name,commands[i].description));                   
@@ -450,61 +489,25 @@ void cmd_help(void)
 /****************************************************************************
 wait for keyboard activity, swallowing network packets
 ****************************************************************************/
-#ifdef CLIX
-static char wait_keyboard(char *buffer)
-#else
 static void wait_keyboard(char *buffer)
-#endif
 {
   fd_set fds;
   int selrtn;
   struct timeval timeout;
   
-#ifdef CLIX
-  int delay = 0;
-#endif
-  
   while (1) 
     {
       extern int Client;
       FD_ZERO(&fds);
       FD_SET(Client,&fds);
-#ifndef CLIX
       FD_SET(fileno(stdin),&fds);
-#endif
 
       timeout.tv_sec = 20;
       timeout.tv_usec = 0;
-#ifdef CLIX
-      timeout.tv_sec = 0;
-#endif
-      selrtn = sys_select(&fds,&timeout);
+      selrtn = sys_select(MAX(Client,fileno(stdin))+1,&fds,&timeout);
       
-#ifndef CLIX
       if (FD_ISSET(fileno(stdin),&fds))
        return;
-#else
-      {
-       char ch;
-       int readret;
-
-    set_blocking(fileno(stdin), False);        
-       readret = read_data( fileno(stdin), &ch, 1);
-       set_blocking(fileno(stdin), True);
-       if (readret == -1)
-         {
-           if (errno != EAGAIN)
-             {
-               /* should crash here */
-               DEBUG(1,("readchar stdin failed\n"));
-             }
-         }
-       else if (readret != 0)
-         {
-           return ch;
-         }
-      }
-#endif
 
       /* We deliberately use receive_smb instead of
          client_receive_smb as we want to receive
@@ -513,16 +516,7 @@ static void wait_keyboard(char *buffer)
       if (FD_ISSET(Client,&fds))
        receive_smb(Client,buffer,0);
       
-#ifdef CLIX
-      delay++;
-      if (delay > 100000)
-       {
-         delay = 0;
-         chkpath("\\",False);
-       }
-#else
       chkpath("\\",False);
-#endif
     }  
 }
 
@@ -574,7 +568,7 @@ static BOOL process(char *base_directory)
       /* and get the first part of the command */
       {
        char *ptr = line;
-       if (!next_token(&ptr,tok,NULL)) continue;
+       if (!next_token(&ptr,tok,NULL,sizeof(tok))) continue;
       }
 
       if ((i = process_tok(tok)) >= 0)
@@ -593,24 +587,13 @@ static BOOL process(char *base_directory)
 
       /* display a prompt */
       DEBUG(0,("smb: %s> ", CNV_LANG(cur_dir)));
-      fflush(dbf);
+      dbgflush();
 
-#ifdef CLIX
-      line[0] = wait_keyboard(InBuffer);
-      /* this might not be such a good idea... */
-      if ( line[0] == EOF)
-       break;
-#else
       wait_keyboard(InBuffer);
-#endif
   
       /* and get a response */
-#ifdef CLIX
-      fgets( &line[1],999, stdin);
-#else
       if (!fgets(line,1000,stdin))
        break;
-#endif
 
       /* input language code to internal one */
       CNV_INPUT (line);
@@ -625,7 +608,7 @@ static BOOL process(char *base_directory)
       /* and get the first part of the command */
       {
        char *ptr = line;
-       if (!next_token(&ptr,tok,NULL)) continue;
+       if (!next_token(&ptr,tok,NULL,sizeof(tok))) continue;
       }
 
       if ((i = process_tok(tok)) >= 0)
@@ -636,7 +619,7 @@ static BOOL process(char *base_directory)
        DEBUG(0,("%s: command not found\n",CNV_LANG(tok)));
     }
   
-  cli_send_logout();
+  cli_send_logout(InBuffer,OutBuffer);
   return(True);
 }
 
@@ -683,7 +666,7 @@ static void usage(char *pname)
   char *p;
 
 #ifdef KANJI
-  strcpy(term_code, KANJI);
+  pstrcpy(term_code, KANJI);
 #else /* KANJI */
   *term_code = 0;
 #endif /* KANJI */
@@ -698,16 +681,15 @@ 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);
 
   if (getenv("USER"))
   {
-    strcpy(username,getenv("USER"));
+    pstrcpy(username,getenv("USER"));
 
     /* modification to support userid%passwd syntax in the USER var
        25.Aug.97, jdblair@uab.edu */
@@ -715,7 +697,7 @@ static void usage(char *pname)
     if ((p=strchr(username,'%')))
     {
       *p = 0;
-      strcpy(password,p+1);
+      pstrcpy(password,p+1);
       got_pass = True;
       memset(strchr(getenv("USER"),'%')+1,'X',strlen(password));
     }
@@ -726,11 +708,11 @@ static void usage(char *pname)
   25.Aug.97, jdblair@uab.edu */
 
   if (getenv("PASSWD"))
-    strcpy(password,getenv("PASSWD"));
+    pstrcpy(password,getenv("PASSWD"));
 
   if (*username == 0 && getenv("LOGNAME"))
     {
-      strcpy(username,getenv("LOGNAME"));
+      pstrcpy(username,getenv("LOGNAME"));
       strupper(username);
     }
 
@@ -743,7 +725,7 @@ static void usage(char *pname)
   if (*argv[1] != '-')
     {
 
-      strcpy(service, argv[1]);  
+      pstrcpy(service, argv[1]);  
       /* Convert any '/' characters in the service name to '\' characters */
       string_replace( service, '/','\\');
       argc--;
@@ -759,7 +741,7 @@ static void usage(char *pname)
       if (argc > 1 && (*argv[1] != '-'))
        {
          got_pass = True;
-         strcpy(password,argv[1]);  
+         pstrcpy(password,argv[1]);  
          memset(argv[1],'X',strlen(argv[1]));
          argc--;
          argv++;
@@ -774,10 +756,10 @@ static void usage(char *pname)
        max_protocol = interpret_protocol(optarg,max_protocol);
        break;
       case 'O':
-       strcpy(user_socket_options,optarg);
+       pstrcpy(user_socket_options,optarg);
        break;  
       case 'S':
-       strcpy(desthost,optarg);
+       pstrcpy(desthost,optarg);
        strupper(desthost);
        nt_domain_logon = True;
        break;
@@ -785,19 +767,19 @@ static void usage(char *pname)
        iface_set_default(NULL,optarg,NULL);
        break;
       case 'D':
-       strcpy(base_directory,optarg);
+       pstrcpy(base_directory,optarg);
        break;
       case 'i':
-       strcpy(scope,optarg);
+       pstrcpy(scope,optarg);
        break;
       case 'U':
        {
          char *lp;
-       strcpy(username,optarg);
+       pstrcpy(username,optarg);
        if ((lp=strchr(username,'%')))
          {
            *lp = 0;
-           strcpy(password,lp+1);
+           pstrcpy(password,lp+1);
            got_pass = True;
            memset(strchr(optarg,'%')+1,'X',strlen(password));
          }
@@ -805,7 +787,7 @@ static void usage(char *pname)
            
        break;
       case 'W':
-       strcpy(workgroup,optarg);
+       pstrcpy(workgroup,optarg);
        break;
       case 'E':
        dbf = stderr;
@@ -818,7 +800,7 @@ static void usage(char *pname)
        }
        break;
       case 'n':
-       strcpy(global_myname,optarg);
+       pstrcpy(global_myname,optarg);
        break;
       case 'N':
        got_pass = True;
@@ -844,10 +826,10 @@ static void usage(char *pname)
        exit(0);
        break;
       case 's':
-       strcpy(servicesf, optarg);
+       pstrcpy(servicesf, optarg);
        break;
       case 't':
-        strcpy(term_code, optarg);
+        pstrcpy(term_code, optarg);
        break;
       default:
        usage(pname);
@@ -861,7 +843,7 @@ static void usage(char *pname)
     }
 
 
-  DEBUG(3,("%s client started (version %s)\n",timestring(),VERSION));
+  DEBUG( 3, ( "Client started (version %s)\n", VERSION ) );
 
   if(!get_myname(myhostname,NULL))
   {
@@ -877,7 +859,7 @@ static void usage(char *pname)
   interpret_coding_system(term_code);
 
   if (*workgroup == 0)
-    strcpy(workgroup,lp_workgroup());
+    pstrcpy(workgroup,lp_workgroup());
 
   load_interfaces();
   get_myname((*global_myname)?NULL:global_myname,NULL);