44 *
55 * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
66 *
7- * $PostgreSQL: pgsql/src/bin/pg_ctl/pg_ctl.c,v 1.92 2008/01/01 19:45:55 momjian Exp $
7+ * $PostgreSQL: pgsql/src/bin/pg_ctl/pg_ctl.c,v 1.93 2008/02/20 22:18:15 tgl Exp $
88 *
99 *-------------------------------------------------------------------------
1010 */
@@ -49,8 +49,6 @@ intoptreset;
4949typedef long pgpid_t ;
5050
5151
52- #define WHITESPACE "\f\n\r\t\v"/* as defined by isspace() */
53-
5452/* postgres version ident string */
5553#define PM_VERSIONSTR "postgres (PostgreSQL) " PG_VERSION "\n"
5654
@@ -416,33 +414,52 @@ test_postmaster_connection(bool do_checkpoint)
416414int i ;
417415char portstr [32 ];
418416char * p ;
417+ char * q ;
419418char connstr [128 ];/* Should be way more than enough! */
420419
421420* portstr = '\0' ;
422421
423- /* post_opts */
422+ /*
423+ * Look in post_opts for a -p switch.
424+ *
425+ * This parsing code is not amazingly bright; it could for instance
426+ * get fooled if ' -p' occurs within a quoted argument value. Given
427+ * that few people pass complicated settings in post_opts, it's
428+ * probably good enough.
429+ */
424430for (p = post_opts ;* p ;)
425431{
426- /* advance past whitespace/quoting */
427- while (isspace ((unsignedchar )* p )|| * p == '\'' || * p == '"' )
432+ /* advance past whitespace */
433+ while (isspace ((unsignedchar )* p ))
428434p ++ ;
429435
430- if (strncmp (p ,"-p" ,strlen ( "-p" ) )== 0 )
436+ if (strncmp (p ,"-p" ,2 )== 0 )
431437{
432- p += strlen ( "-p" ) ;
433- /* advance past whitespace/quoting */
438+ p += 2 ;
439+ /* advance pastany whitespace/quoting */
434440while (isspace ((unsignedchar )* p )|| * p == '\'' || * p == '"' )
435441p ++ ;
436- strlcpy (portstr ,p ,Min (strcspn (p ,"\"'" WHITESPACE )+ 1 ,
437- sizeof (portstr )));
442+ /* find end of value (not including any ending quote!) */
443+ q = p ;
444+ while (* q &&
445+ !(isspace ((unsignedchar )* q )|| * q == '\'' || * q == '"' ))
446+ q ++ ;
447+ /* and save the argument value */
448+ strlcpy (portstr ,p ,Min ((q - p )+ 1 ,sizeof (portstr )));
438449/* keep looking, maybe there is another -p */
450+ p = q ;
439451}
440452/* Advance to next whitespace */
441453while (* p && !isspace ((unsignedchar )* p ))
442454p ++ ;
443455}
444456
445- /* config file */
457+ /*
458+ * Search config file for a 'port' option.
459+ *
460+ * This parsing code isn't amazingly bright either, but it should be
461+ * okay for valid port settings.
462+ */
446463if (!* portstr )
447464{
448465char * * optlines ;
@@ -456,28 +473,35 @@ test_postmaster_connection(bool do_checkpoint)
456473
457474while (isspace ((unsignedchar )* p ))
458475p ++ ;
459- if (strncmp (p ,"port" ,strlen ( "port" ) )!= 0 )
476+ if (strncmp (p ,"port" ,4 )!= 0 )
460477continue ;
461- p += strlen ( "port" ) ;
478+ p += 4 ;
462479while (isspace ((unsignedchar )* p ))
463480p ++ ;
464481if (* p != '=' )
465482continue ;
466483p ++ ;
467- while (isspace ((unsignedchar )* p ))
484+ /* advance past any whitespace/quoting */
485+ while (isspace ((unsignedchar )* p )|| * p == '\'' || * p == '"' )
468486p ++ ;
469- strlcpy (portstr ,p ,Min (strcspn (p ,"#" WHITESPACE )+ 1 ,
470- sizeof (portstr )));
487+ /* find end of value (not including any ending quote/comment!) */
488+ q = p ;
489+ while (* q &&
490+ !(isspace ((unsignedchar )* q )||
491+ * q == '\'' || * q == '"' || * q == '#' ))
492+ q ++ ;
493+ /* and save the argument value */
494+ strlcpy (portstr ,p ,Min ((q - p )+ 1 ,sizeof (portstr )));
471495/* keep looking, maybe there is another */
472496}
473497}
474498}
475499
476- /* environment */
500+ /*Check environment */
477501if (!* portstr && getenv ("PGPORT" )!= NULL )
478502strlcpy (portstr ,getenv ("PGPORT" ),sizeof (portstr ));
479503
480- /* default */
504+ /*Else use compiled-in default */
481505if (!* portstr )
482506snprintf (portstr ,sizeof (portstr ),"%d" ,DEF_PGPORT );
483507