| --- dhcp-4.2.2/client/clparse.c |
| +++ dhcp-4.2.2/client/clparse.c |
| @@ -182,6 +182,10 @@ isc_result_t read_client_conf () |
| #endif |
| } |
| |
| + /* Read any extra configuration from stdin */ |
| + extern int read_client_conf_stdin (struct interface_info *ip, struct client_config *client); |
| + read_client_conf_stdin (NULL, &top_level_config); |
| + |
| /* Set up state and config structures for clients that don't |
| have per-interface configuration statements. */ |
| config = (struct client_config *)0; |
| @@ -211,23 +215,13 @@ isc_result_t read_client_conf () |
| return status; |
| } |
| |
| -int read_client_conf_file (const char *name, struct interface_info *ip, |
| +int read_client_conf_actual (struct parse *cfile, struct interface_info *ip, |
| struct client_config *client) |
| { |
| - int file; |
| - struct parse *cfile; |
| const char *val; |
| int token; |
| isc_result_t status; |
| |
| - if ((file = open (name, O_RDONLY)) < 0) |
| - return uerr2isc (errno); |
| - |
| - cfile = NULL; |
| - status = new_parse(&cfile, file, NULL, 0, path_dhclient_conf, 0); |
| - if (status != ISC_R_SUCCESS || cfile == NULL) |
| - return status; |
| - |
| do { |
| token = peek_token (&val, (unsigned *)0, cfile); |
| if (token == END_OF_FILE) |
| @@ -238,10 +232,74 @@ int read_client_conf_file (const char *name, struct interface_info *ip, |
| status = (cfile -> warnings_occurred |
| ? DHCP_R_BADPARSE |
| : ISC_R_SUCCESS); |
| + return status; |
| +} |
| + |
| +int read_client_conf_file (const char *name, struct interface_info *ip, |
| + struct client_config *client) |
| +{ |
| + int file; |
| + struct parse *cfile; |
| + isc_result_t status; |
| + |
| + if ((file = open (name, O_RDONLY)) < 0) |
| + return uerr2isc (errno); |
| + |
| + cfile = (struct parse *)0; |
| + new_parse (&cfile, file, (char *)0, 0, path_dhclient_conf, 0); |
| + status = read_client_conf_actual(cfile, ip, client); |
| end_parse (&cfile); |
| return status; |
| } |
| |
| +int read_client_conf_stdin (struct interface_info *ip, |
| + struct client_config *client) |
| +{ |
| + int file; |
| + char *buffer = NULL, *p; |
| + unsigned buflen, len = 0; |
| + struct parse *cfile; |
| + size_t bytes; |
| + isc_result_t status; |
| + |
| + file = fileno(stdin); |
| + if (isatty (file)) |
| + return ISC_R_NOTFOUND; |
| + if (fcntl (file, F_SETFL, O_NONBLOCK) < 0) |
| + log_fatal ("could not set stdin to non blocking!"); |
| + |
| + buflen = BUFSIZ; |
| + buffer = malloc (BUFSIZ + 1); |
| + p = buffer; |
| + do { |
| + bytes = read (file, p, BUFSIZ); |
| + if (bytes == 0) |
| + break; |
| + if (bytes == -1) |
| + log_fatal ("failed to read stdin!"); |
| + if (bytes >= BUFSIZ) { |
| + buflen += BUFSIZ; |
| + len += BUFSIZ; |
| + buffer = realloc (buffer, buflen + 1); |
| + if (!buffer) |
| + log_fatal ("not enough buffer to read stdin!"); |
| + p = buffer + len; |
| + } else { |
| + len += bytes; |
| + break; |
| + } |
| + } while(1); |
| + buffer[len] = '\0'; |
| + |
| + cfile = (struct parse *)0; |
| + status = new_parse (&cfile, -1, buffer, len, "stdin", 0); |
| + if (status == ISC_R_SUCCESS) { |
| + status = read_client_conf_actual (cfile, ip, client); |
| + end_parse (&cfile); |
| + } |
| + free(buffer); |
| + return status; |
| +} |
| |
| /* lease-file :== client-lease-statements END_OF_FILE |
| client-lease-statements :== <nil> |