Mailing List Archive

[PATCH] terminate config reading on 0x1A instead of just on pipe close
vpnc's config file processing logic uses EOF to determine when to stop
processing the config input, but if stdin is actually a pipe from a
controlling process, EOF only happens if the pipe is closed. Which
means the controlling process can't respond to any interactive requests
for information. So we need to add some other mechanism to indicate
that config processing is done that does not rely on closing stdin to
indicate this.

Also, getline() only returns on EOF (which has the problems described
above) or when it encounters sufficient newline characters;
unfortunately this precludes using getline() to handle single bytes.
Switch to fgetc() and build up the line ourselves so that we can
recognize a custom EOF character, 0x1A (Ctl-Z).

---
Index: config.c
===================================================================
--- config.c (revision 527)
+++ config.c (working copy)
@@ -484,8 +484,7 @@
static void read_config_file(const char *name, const char **configs, int missingok)
{
FILE *f;
- char *line = NULL;
- size_t line_length = 0;
+ char line[200];
int linenum = 0;
char *realname;

@@ -508,14 +507,27 @@
error(1, errno, "couldn't open `%s'", realname);
}
for (;;) {
- ssize_t llen;
- int i;
+ size_t llen = 0;
+ int i, c;

- llen = getline(&line, &line_length, f);
- if (llen == -1 && feof(f))
+ /* Read a line from the input */
+ while (llen < sizeof (line) - 1) {
+ c = fgetc (f);
+ if (c == EOF) {
+ if (ferror (f))
+ error(1, errno, "reading `%s'", realname);
+ break;
+ }
+ line[llen++] = (char) c;
+ if ((char) c == '\r' || (char) c == '\n' ||
+ (char) c == '\0' || (char) c == 0x1A)
+ break;
+ }
+ line[llen] = '\0';
+
+ /* EOF or 0x1A terminate reading configuration */
+ if (feof (f) || (llen == 1 && line[0] == 0x1A))
break;
- if (llen == -1)
- error(1, errno, "reading `%s'", realname);
if (llen > 0 && line[llen - 1] == '\n')
line[--llen] = 0;
if (llen > 0 && line[llen - 1] == '\r')
@@ -541,7 +553,6 @@
error(0, 0, "warning: unknown configuration directive in %s at line %d",
realname, linenum);
}
- free(line);
free(realname);
if (strcmp(name, "-"))
fclose(f);


_______________________________________________
vpnc-devel mailing list
vpnc-devel@unix-ag.uni-kl.de
https://lists.unix-ag.uni-kl.de/mailman/listinfo/vpnc-devel
http://www.unix-ag.uni-kl.de/~massar/vpnc/
Re: [PATCH] terminate config reading on 0x1A instead of just on pipe close [ In reply to ]
On Thu, 2013-07-11 at 12:50 -0500, Dan Williams wrote:
> vpnc's config file processing logic uses EOF to determine when to stop
> processing the config input, but if stdin is actually a pipe from a
> controlling process, EOF only happens if the pipe is closed. Which
> means the controlling process can't respond to any interactive requests
> for information. So we need to add some other mechanism to indicate
> that config processing is done that does not rely on closing stdin to
> indicate this.
>
> Also, getline() only returns on EOF (which has the problems described
> above) or when it encounters sufficient newline characters;
> unfortunately this precludes using getline() to handle single bytes.
> Switch to fgetc() and build up the line ourselves so that we can
> recognize a custom EOF character, 0x1A (Ctl-Z).

Actually, scratch this patch, I'll pull the getline() re-implementation
out into its own function so we can use it from do_config() as well.

Dan

> ---
> Index: config.c
> ===================================================================
> --- config.c (revision 527)
> +++ config.c (working copy)
> @@ -484,8 +484,7 @@
> static void read_config_file(const char *name, const char **configs, int missingok)
> {
> FILE *f;
> - char *line = NULL;
> - size_t line_length = 0;
> + char line[200];
> int linenum = 0;
> char *realname;
>
> @@ -508,14 +507,27 @@
> error(1, errno, "couldn't open `%s'", realname);
> }
> for (;;) {
> - ssize_t llen;
> - int i;
> + size_t llen = 0;
> + int i, c;
>
> - llen = getline(&line, &line_length, f);
> - if (llen == -1 && feof(f))
> + /* Read a line from the input */
> + while (llen < sizeof (line) - 1) {
> + c = fgetc (f);
> + if (c == EOF) {
> + if (ferror (f))
> + error(1, errno, "reading `%s'", realname);
> + break;
> + }
> + line[llen++] = (char) c;
> + if ((char) c == '\r' || (char) c == '\n' ||
> + (char) c == '\0' || (char) c == 0x1A)
> + break;
> + }
> + line[llen] = '\0';
> +
> + /* EOF or 0x1A terminate reading configuration */
> + if (feof (f) || (llen == 1 && line[0] == 0x1A))
> break;
> - if (llen == -1)
> - error(1, errno, "reading `%s'", realname);
> if (llen > 0 && line[llen - 1] == '\n')
> line[--llen] = 0;
> if (llen > 0 && line[llen - 1] == '\r')
> @@ -541,7 +553,6 @@
> error(0, 0, "warning: unknown configuration directive in %s at line %d",
> realname, linenum);
> }
> - free(line);
> free(realname);
> if (strcmp(name, "-"))
> fclose(f);
>
>
> _______________________________________________
> vpnc-devel mailing list
> vpnc-devel@unix-ag.uni-kl.de
> https://lists.unix-ag.uni-kl.de/mailman/listinfo/vpnc-devel
> http://www.unix-ag.uni-kl.de/~massar/vpnc/


_______________________________________________
vpnc-devel mailing list
vpnc-devel@unix-ag.uni-kl.de
https://lists.unix-ag.uni-kl.de/mailman/listinfo/vpnc-devel
http://www.unix-ag.uni-kl.de/~massar/vpnc/