On Tue, Mar 27, 2007 at 11:53:42PM +0200, Jeroen van Wolffelaar wrote:
> On Tue, Mar 27, 2007 at 10:54:58PM +0200, José Luis Tallón wrote:
> > Jeroen van Wolffelaar wrote:
> > > Package: imapproxy
> > > Version: 1.2.4-10
> > > Severity: important
> > >
> > > The pid-handling of imapproxy is pretty fragile, as documented in
> > > #369020 amongst others. The current workaround of writing a new pidfile
> > > after start based on 'ps ax' output is, eh, fragile at best, and
> > > actually pretty bad.
> > >
> > > The proper solution would be to patch imapproxy so that it writes out a
> > > pidfile itself, like proper daemons should. 
> > Fixed. Will submit the patch ASAP
> 
> Why didn't you attach it? I'm pretty busy tomorrow, and want to get this
> fixed ASAP. I mean, the plan is to release this weekend...

NMU'd, based on your patch. See attachment for diff.

--Jeroen

-- 
Jeroen van Wolffelaar
[EMAIL PROTECTED] (also for Jabber & MSN; ICQ: 33944357)
http://Jeroen.A-Eskwadraat.nl
diff -u up-imapproxy-1.2.4/include/imapproxy.h up-imapproxy-1.2.4/include/imapproxy.h
--- up-imapproxy-1.2.4/include/imapproxy.h
+++ up-imapproxy-1.2.4/include/imapproxy.h
@@ -172,6 +172,10 @@
 #define DEFAULT_CONFIG_FILE     "/etc/imapproxy.conf"
 #endif
 
+#ifndef DEFAULT_PID_FILE
+#define DEFAULT_PID_FILE	"/var/run/imapproxy.pid"
+#endif
+
 #define LITERAL_PASSWORD        1
 #define NON_LITERAL_PASSWORD    0
 #define UNSELECT_SUPPORTED      1
diff -u up-imapproxy-1.2.4/src/main.c up-imapproxy-1.2.4/src/main.c
--- up-imapproxy-1.2.4/src/main.c
+++ up-imapproxy-1.2.4/src/main.c
@@ -242,6 +242,7 @@
 static int ParseBannerAndCapability( char *, unsigned int,
 				      char *, unsigned int );
 static void ServerInit( void );
+static void Daemonize( const char* );
 static void Usage( void );
 
 
@@ -265,13 +266,13 @@
     pthread_attr_t attr;               /* generic thread attribute struct */
     int rc, i, fd;
     unsigned int ui;
-    pid_t pid;                         /* used just for a fork call */
     struct linger lingerstruct;        /* for the socket reuse stuff */
     int flag;                          /* for the socket reuse stuff */
     ICC_Struct *ICC_tptr;             
     extern char *optarg;
     extern int optind;
     char ConfigFile[ MAXPATHLEN ];     /* path to our config file */
+    char PidFile[ MAXPATHLEN ];		/* path to our pidfile */
 #ifdef HAVE_LIBWRAP
     struct request_info r;             /* request struct for libwrap */
 #endif
@@ -279,6 +280,9 @@
     flag = 1;
     ConfigFile[0] = '\0';
 
+    /* initialize to default */
+    strncpy( PidFile, DEFAULT_PID_FILE, sizeof PidFile -1 );
+
     /*
      * Ignore signals we don't want to die from but we don't care enough
      * about to catch.
@@ -287,7 +291,7 @@
     signal( SIGHUP, SIG_IGN );
     
 
-    while (( i = getopt( argc, argv, "f:h" ) ) != EOF )
+    while (( i = getopt( argc, argv, "f:p:h" ) ) != EOF )
     {
 	switch( i )
 	{
@@ -298,7 +302,14 @@
 	    syslog( LOG_INFO, "%s: Using configuration file '%s'",
 		    fn, ConfigFile );
 	    break;
-	    
+        case 'p':
+            /* user specified a pidfile */
+            strncpy( PidFile, optarg, sizeof PidFile -1 );
+            PidFile[ sizeof PidFile - 1 ] = '\0';
+            syslog( LOG_INFO, "%s: Using pidfile '%s'",
+                    fn, PidFile );
+            break;
+            
 	case 'h':
 	    Usage();
 	    exit( 0 );
@@ -403,58 +414,7 @@
 
     ServerInit();
 
-    /* detach from our parent if necessary */
-    if (! (getppid() == 1) && ( ! PC_Struct.foreground_mode ) )
-    {
-	syslog( LOG_INFO, "%s: Configured to run in background mode.", fn );
-	
-	if ( (pid = fork()) < 0)
-	{
-	    syslog(LOG_ERR, "%s: initial call to fork() failed: %s", fn, strerror(errno));
-	    exit( 1 );
-	}
-	else if ( pid > 0)
-	{
-	    exit( 0 );
-	}
-	
-	if (setsid() == -1)
-	{
-	    syslog(LOG_WARNING, "%s: setsid() failed: %s", 
-		   fn, strerror(errno));
-	}
-	if ( (pid = fork()) < 0)
-	{
-	    syslog(LOG_ERR, "%s: secondary call to fork() failed: %s", fn, 
-		   strerror(errno));
-	    exit( 1 );
-	}
-	else if ( pid > 0)
-	{
-	    exit( 0 );
-	}
-	if( chdir("/") < 0 )
-	{
-	    syslog(LOG_ERR, "%s: chdir(\"/\") failed: %s", fn,
-	      strerror(errno));
-            exit( 1 );
-	}
-	if( (i=open("/dev/null",O_RDWR)) < 0 )
-	{
-	    syslog(LOG_ERR, "%s: open(\"/dev/null\") failed: %s", fn,
-	      strerror(errno));
-            exit( 1 );
-	}
-	close(2); dup(i);
-	close(1); dup(i);
-	close(0); dup(i);
-	close(i);
-    }
-    else
-    {
-	syslog( LOG_INFO, "%s: Configured to run in foreground mode.", fn );
-    }
-    
+    Daemonize( PidFile );
 
     SetBannerAndCapability();
     
@@ -723,7 +683,96 @@
  * Function definitions.
  */
 
+/*++
+ * Function:	Daemonize
+ *
+ * Purpose:	Daemonize, closing all unneeded descriptors.
+ *		Write the daemon's PID into 'pidfile'
+ *
+ * Parameters:	pidfile -- where to write our PID.
+ *
+ * Returns:	nada -- exits on error
+ * 
+ * Authors:	Jose Luis Tallon <[EMAIL PROTECTED]>
+ * 
+ * Notes:
+ *--
+ */
+void Daemonize( const char* pidfile )
+{
+ const char* fn="Daemonize()";
+ FILE* fp=NULL;
+ pid_t pid;                         /* used just for a fork call */
+ int i;
+  
+    if ( PC_Struct.foreground_mode ) {
+	syslog( LOG_INFO, "%s: Configured to run in foreground mode.", fn );
+	return;
+    }
+
+    /* detach from our parent */
+    syslog( LOG_INFO, "%s: Configured to run in background mode.", fn );
 
+    if (getppid() == 1) {
+	syslog( LOG_INFO, "%s: Forking unneeded, continuing in foreground mode anyway", fn );
+    } else {
+    
+	if ( (pid = fork()) < 0)
+	{
+	    syslog(LOG_ERR, "%s: initial call to fork() failed: %s", fn, strerror(errno));
+	    exit( 1 );
+	}
+	else if ( pid > 0)
+	{
+	    exit( 0 );
+	}
+	
+	if (setsid() == -1)
+	{
+	    syslog(LOG_WARNING, "%s: setsid() failed: %s", 
+		   fn, strerror(errno));
+	}
+	if ( (pid = fork()) < 0)
+	{
+	    syslog(LOG_ERR, "%s: secondary call to fork() failed: %s", fn, 
+		   strerror(errno));
+	    exit( 1 );
+	}
+	else if ( pid > 0)
+	{
+	    exit( 0 );
+	}
+    }
+    if ( (fp=fopen(pidfile,"wt")) == NULL )
+    {
+       syslog(LOG_ERR, "%s: creating pidfile '%s' failed: %s", fn,
+	   pidfile, strerror(errno));
+       exit(1);
+    }
+    if( fprintf(fp, "%u\n", (unsigned)getpid()) < 0 )
+    {
+      syslog(LOG_ERR, "%s: fprintf on pidfile failed: %s", fn,
+	  strerror(errno));
+      exit(1);
+    }
+    fclose(fp);
+    if( chdir("/") < 0 )
+    {
+	syslog(LOG_ERR, "%s: chdir(\"/\") failed: %s", fn,
+	  strerror(errno));
+	exit( 1 );
+    }
+    if( (i=open("/dev/null",O_RDWR)) < 0 )
+    {
+	syslog(LOG_ERR, "%s: open(\"/dev/null\") failed: %s", fn,
+	  strerror(errno));
+	exit( 1 );
+    }
+    close(2); dup(i);
+    close(1); dup(i);
+    close(0); dup(i);
+    close(i);
+}
 
 /*++
  * Function:	Usage
@@ -741,7 +790,7 @@
  */
 void Usage( void )
 {
-    printf("Usage: %s [-f config filename] [-h]\n", PGM );
+    printf("Usage: %s [-f config filename] [-p pidfile] [-h]\n", PGM );
     return;
 }
 
diff -u up-imapproxy-1.2.4/debian/manpages/imapproxyd.8 up-imapproxy-1.2.4/debian/manpages/imapproxyd.8
--- up-imapproxy-1.2.4/debian/manpages/imapproxyd.8
+++ up-imapproxy-1.2.4/debian/manpages/imapproxyd.8
@@ -15,6 +15,11 @@
 .B -f
 .RI
 <config file name> ]
+.RI
+[
+.B -p
+.RI
+<pidfile name> ]
 .br
 .SH DESCRIPTION
 This manual page documents briefly the
@@ -41,6 +46,12 @@
 This can be changed by using the 
 .I -f
 option
+.PP
+Unless foreground_mode has been enabled, UP-ImapProxy will write its PID to to
+a PID-file. It defaults to /var/run/imapproxy.pid, but can be overridden with
+the 
+.I -p
+option
 .SH SEE ALSO
 .BR pimpstat (8),
 .br
@@ -53 +64 @@
- 
\ No newline at end of file
+ 
diff -u up-imapproxy-1.2.4/debian/changelog up-imapproxy-1.2.4/debian/changelog
--- up-imapproxy-1.2.4/debian/changelog
+++ up-imapproxy-1.2.4/debian/changelog
@@ -1,3 +1,20 @@
+up-imapproxy (1.2.4-10.1) unstable; urgency=high
+
+  * NMU to fix RC bug
+
+  [ Jose Luis Tallon ]
+  * Re-starting imapproxy failed when it was already running.
+    - Fixed imapproxy to write a pidfile itself
+    Start-stop-daemon can now interact with it properly (Closes: #415954)
+
+  [ Jeroen van Wolffelaar ]
+  * Document -p in manpage
+  * Patch cleanup
+  * Add code to initscript to not attempt to start a second version if already
+    running, and to not fail if imapproxy is no longer running (also #415954)
+
+ -- Jeroen van Wolffelaar <[EMAIL PROTECTED]>  Wed, 28 Mar 2007 04:04:55 +0200
+
 up-imapproxy (1.2.4-10) unstable; urgency=high
 
   * Bashism in initscript made upgrade sequence fail when sh was not bash
diff -u up-imapproxy-1.2.4/debian/imapproxy.init.d up-imapproxy-1.2.4/debian/imapproxy.init.d
--- up-imapproxy-1.2.4/debian/imapproxy.init.d
+++ up-imapproxy-1.2.4/debian/imapproxy.init.d
@@ -43,59 +43,41 @@
 	exit 0;
 fi
 
-check_running ()
-{
- proc_cmdline="/proc/`cat $PIDFILE`/cmdline"
-
-	if [ -r $proc_cmdline ]; then
-		grep -q $DAEMON $proc_cmdline >/dev/null \
-		&& return 0
-	else
-		sleep 1
-		psline="`ps ax | grep imapproxyd | grep -v grep`"
-		if [ -n $psline ]; then
-			echo `echo $psline | cut -d ' ' -f 1` > $PIDFILE
-			return 0
-		else
-			return 1
-		fi
-	fi
-	return 1
-}
 
 case "$1" in
   start)
+	if [ -f $PIDFILE ] && [ -e /proc/`cat $PIDFILE`/status ]; then
+		echo "Already started: $NAME."
+		exit 0
+	fi
 	echo -n "Starting $DESC: "
-	start-stop-daemon --start --quiet --background \
-		--make-pidfile --pidfile=$PIDFILE \
+	start-stop-daemon --start --quiet --pidfile=$PIDFILE \
 		--exec $DAEMON -- $ARGS
-	ssd_ret=$?
 	sleep 1
-	if [ $ssd_ret==0 ] && check_running ; then
-		echo "$NAME."
-	else
-		echo "Failed to start $NAME. Check logs for details."
-		exit 1
-	fi
+	echo "$NAME."
 	;;
-	
+
   stop)
+	if [ ! -f $PIDFILE ]; then
+		echo "Not running: $NAME."
+		exit 0
+	fi
+	if [ ! -e /proc/`cat $PIDFILE`/status ]; then
+		rm -f $PIDFILE
+		echo "Not running: $NAME."
+		exit 0
+	fi
 	echo -n "Stopping $DESC: "
 	start-stop-daemon --oknodo --stop --quiet --pidfile=$PIDFILE \
 		--exec $DAEMON -- $ARGS 2>&1 | grep warning || true > /dev/null
-	sleep 1
-	if [ -n "`ps ax | grep imapproxyd | grep -v grep`" ]; then
-		test -r $PIDFILE && kill -15 `cat $PIDFILE` 2>&1 \
-			&& rm -f $PIDFILE
-	fi
-	echo "$NAME."
-	
+	rm -f $PIDFILE
+	echo "$NAME."	
 	;;
 
   restart|force-reload)
 	echo "Restarting $DESC: "
 	$0 stop
-	sleep 1
+	sleep 2		# not gratuituous
 	$0 start
 	;;
   *)

Reply via email to