|
7 | 7 | * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
|
8 | 8 | * Portions Copyright (c) 1994, Regents of the University of California
|
9 | 9 | *
|
10 |
| - * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.390 2010/04/0706:12:52 heikki Exp $ |
| 10 | + * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.391 2010/04/0710:58:49 heikki Exp $ |
11 | 11 | *
|
12 | 12 | *-------------------------------------------------------------------------
|
13 | 13 | */
|
@@ -4893,6 +4893,100 @@ str_time(pg_time_t tnow)
|
4893 | 4893 | returnbuf;
|
4894 | 4894 | }
|
4895 | 4895 |
|
| 4896 | +/* |
| 4897 | + * Parse one line from recovery.conf. 'cmdline' is the raw line from the |
| 4898 | + * file. If the line is parsed successfully, returns true, false indicates |
| 4899 | + * syntax error. On success, *key_p and *value_p are set to the parameter |
| 4900 | + * name and value on the line, respectively. If the line is an empty line, |
| 4901 | + * consisting entirely of whitespace and comments, function returns true |
| 4902 | + * and *keyp_p and *value_p are set to NULL. |
| 4903 | + * |
| 4904 | + * The pointers returned in *key_p and *value_p point to an internal buffer |
| 4905 | + * that is valid only until the next call of parseRecoveryCommandFile(). |
| 4906 | + */ |
| 4907 | +staticbool |
| 4908 | +parseRecoveryCommandFileLine(char*cmdline,char**key_p,char**value_p) |
| 4909 | +{ |
| 4910 | +char*ptr; |
| 4911 | +char*bufp; |
| 4912 | +char*key; |
| 4913 | +char*value; |
| 4914 | +staticchar*buf=NULL; |
| 4915 | + |
| 4916 | +*key_p=*value_p=NULL; |
| 4917 | + |
| 4918 | +/* |
| 4919 | + * Allocate the buffer on first use. It's used to hold both the |
| 4920 | + * parameter name and value. |
| 4921 | + */ |
| 4922 | +if (buf==NULL) |
| 4923 | +buf=malloc(MAXPGPATH+1); |
| 4924 | +bufp=buf; |
| 4925 | + |
| 4926 | +/* Skip any whitespace at the beginning of line */ |
| 4927 | +for (ptr=cmdline;*ptr;ptr++) |
| 4928 | +{ |
| 4929 | +if (!isspace((unsignedchar)*ptr)) |
| 4930 | +break; |
| 4931 | +} |
| 4932 | +/* Ignore empty lines */ |
| 4933 | +if (*ptr=='\0'||*ptr=='#') |
| 4934 | +return true; |
| 4935 | + |
| 4936 | +/* Read the parameter name */ |
| 4937 | +key=bufp; |
| 4938 | +while (*ptr&& !isspace((unsignedchar)*ptr)&& |
| 4939 | +*ptr!='='&&*ptr!='\'') |
| 4940 | +*(bufp++)=*(ptr++); |
| 4941 | +*(bufp++)='\0'; |
| 4942 | + |
| 4943 | +/* Skip to the beginning quote of the parameter value */ |
| 4944 | +ptr=strchr(ptr,'\''); |
| 4945 | +if (!ptr) |
| 4946 | +return false; |
| 4947 | +ptr++; |
| 4948 | + |
| 4949 | +/* Read the parameter value to *bufp. Collapse any '' escapes as we go. */ |
| 4950 | +value=bufp; |
| 4951 | +for (;;) |
| 4952 | +{ |
| 4953 | +if (*ptr=='\'') |
| 4954 | +{ |
| 4955 | +ptr++; |
| 4956 | +if (*ptr=='\'') |
| 4957 | +*(bufp++)='\''; |
| 4958 | +else |
| 4959 | +{ |
| 4960 | +/* end of parameter */ |
| 4961 | +*bufp='\0'; |
| 4962 | +break; |
| 4963 | +} |
| 4964 | +} |
| 4965 | +elseif (*ptr=='\0') |
| 4966 | +return false;/* unterminated quoted string */ |
| 4967 | +else |
| 4968 | +*(bufp++)=*ptr; |
| 4969 | + |
| 4970 | +ptr++; |
| 4971 | +} |
| 4972 | +*(bufp++)='\0'; |
| 4973 | + |
| 4974 | +/* Check that there's no garbage after the value */ |
| 4975 | +while (*ptr) |
| 4976 | +{ |
| 4977 | +if (*ptr=='#') |
| 4978 | +break; |
| 4979 | +if (!isspace((unsignedchar)*ptr)) |
| 4980 | +return false; |
| 4981 | +ptr++; |
| 4982 | +} |
| 4983 | + |
| 4984 | +/* Success! */ |
| 4985 | +*key_p=key; |
| 4986 | +*value_p=value; |
| 4987 | +return true; |
| 4988 | +} |
| 4989 | + |
4896 | 4990 | /*
|
4897 | 4991 | * See if there is a recovery command file (recovery.conf), and if so
|
4898 | 4992 | * read in parameters for archive recovery and XLOG streaming.
|
@@ -4926,39 +5020,16 @@ readRecoveryCommandFile(void)
|
4926 | 5020 | */
|
4927 | 5021 | while (fgets(cmdline,sizeof(cmdline),fd)!=NULL)
|
4928 | 5022 | {
|
4929 |
| -/* skip leading whitespace and check for # comment */ |
4930 |
| -char*ptr; |
4931 | 5023 | char*tok1;
|
4932 | 5024 | char*tok2;
|
4933 | 5025 |
|
4934 |
| -for (ptr=cmdline;*ptr;ptr++) |
4935 |
| -{ |
4936 |
| -if (!isspace((unsignedchar)*ptr)) |
4937 |
| -break; |
4938 |
| -} |
4939 |
| -if (*ptr=='\0'||*ptr=='#') |
4940 |
| -continue; |
4941 |
| - |
4942 |
| -/* identify the quoted parameter value */ |
4943 |
| -tok1=strtok(ptr,"'"); |
4944 |
| -if (!tok1) |
4945 |
| -{ |
4946 |
| -syntaxError= true; |
4947 |
| -break; |
4948 |
| -} |
4949 |
| -tok2=strtok(NULL,"'"); |
4950 |
| -if (!tok2) |
4951 |
| -{ |
4952 |
| -syntaxError= true; |
4953 |
| -break; |
4954 |
| -} |
4955 |
| -/* reparse to get just the parameter name */ |
4956 |
| -tok1=strtok(ptr," \t="); |
4957 |
| -if (!tok1) |
| 5026 | +if (!parseRecoveryCommandFileLine(cmdline,&tok1,&tok2)) |
4958 | 5027 | {
|
4959 | 5028 | syntaxError= true;
|
4960 | 5029 | break;
|
4961 | 5030 | }
|
| 5031 | +if (tok1==NULL) |
| 5032 | +continue; |
4962 | 5033 |
|
4963 | 5034 | if (strcmp(tok1,"restore_command")==0)
|
4964 | 5035 | {
|
|