1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
--- 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>
|