summaryrefslogtreecommitdiff
blob: f3068b698ec7da178305510693e6c77d86c3cc9b (plain)
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
--- udhcp/dhcpc.c
+++ udhcp/dhcpc.c
@@ -68,6 +68,8 @@
 	clientid: NULL,
 	hostname: NULL,
 	fqdn: NULL,
+ 	envList: NULL,
+ 	envListLength: 0,
 	ifindex: 0,
 	arp: "\0\0\0\0\0\0",		/* appease gcc-3.0 */
 };
@@ -78,6 +80,7 @@
 	printf(
 "Usage: udhcpc [OPTIONS]\n\n"
 "  -c, --clientid=CLIENTID         Client identifier\n"
+"  -e, --env=\"FOO=BAR\"           Environment variable passed to script\n"
 "  -H, --hostname=HOSTNAME         Client hostname\n"
 "  -h                              Alias for -H\n"
 "  -F, --fqdn=FQDN                 Client fully qualified domain name\n"
@@ -193,9 +196,11 @@
 	long now;
 	int max_fd;
 	int sig;
+	struct stringList *env_tmp;
 
 	static const struct option arg_options[] = {
 		{"clientid",	required_argument,	0, 'c'},
+		{"env",		required_argument,	0, 'e'},
 		{"foreground",	no_argument,		0, 'f'},
 		{"background",	no_argument,		0, 'b'},
 		{"hostname",	required_argument,	0, 'H'},
@@ -214,7 +219,7 @@
 	/* get options */
 	while (1) {
 		int option_index = 0;
-		c = getopt_long(argc, argv, "c:fbH:h:F:i:np:qr:s:v", arg_options, &option_index);
+		c = getopt_long(argc, argv, "c:e:fbH:h:F:i:np:qr:s:v", arg_options, &option_index);
 		if (c == -1) break;
 
 		switch (c) {
@@ -227,6 +232,17 @@
 			client_config.clientid[OPT_DATA] = '\0';
 			strncpy(client_config.clientid + OPT_DATA, optarg, len);
 			break;
+		case 'e':
+			env_tmp = xmalloc(strlen(optarg) + sizeof *env_tmp);
+			if (!env_tmp) {
+				DEBUG(LOG_ERR, "No memory for %s", optargs);
+				exit(1);
+			}
+			strncpy(env_tmp->string, optarg, strlen(optarg));
+			env_tmp->next=client_config.envList;
+			client_config.envList=env_tmp;
+			client_config.envListLength++;
+			break;
 		case 'f':
 			client_config.foreground = 1;
 			break;
--- udhcp/dhcpc.h
+++ udhcp/dhcpc.h
@@ -17,6 +17,12 @@
 #define RELEASED	7
 
 
+struct stringList {
+	struct stringList *next;
+	char string[1];
+};
+
+
 struct client_config_t {
 	char foreground;		/* Do not fork */
 	char quit_after_lease;		/* Quit after obtaining lease */
@@ -28,6 +34,8 @@
 	uint8_t *clientid;		/* Optional client id to use */
 	uint8_t *hostname;		/* Optional hostname to use */
 	uint8_t *fqdn;			/* Optional fully qualified domain name to use */
+	struct stringList *envList;	/* Environment variables to pass to the script */
+	int envListLength;		/* Length of the environment variable list */
 	int ifindex;			/* Index number of the interface to use */
 	uint8_t arp[6];			/* Our arp address */
 };
--- udhcp/script.c
+++ udhcp/script.c
@@ -141,6 +141,7 @@
 	uint8_t *temp;
 	struct in_addr subnet;
 	char over = 0;
+	struct stringList *sp;
 
 	if (packet == NULL)
 		num_options = 0;
@@ -158,7 +159,7 @@
 		if (!(over & SNAME_FIELD) && packet->sname[0]) num_options++;
 	}
 
-	envp = xcalloc(sizeof(char *), num_options + 5);
+	envp = xcalloc(sizeof(char *), num_options + client_config.envListLength + 5);
 	j = 0;
 	asprintf(&envp[j++], "interface=%s", client_config.interface);
 	asprintf(&envp[j++], "%s=%s", "PATH",
@@ -198,6 +199,10 @@
 		packet->sname[sizeof(packet->sname) - 1] = '\0';
 		asprintf(&envp[j++], "sname=%s", packet->sname);
 	}
+	if (client_config.envList) {
+		for (sp=client_config.envList; sp; sp=sp->next)
+			asprintf(&envp[j++], "%s", sp->string);
+	}
 	return envp;
 }
 
--- udhcp/udhcpc.8
+++ udhcp/udhcpc.8
@@ -13,6 +13,12 @@
 Send the client identifier
 .IR CLIENTID .
 .TP
+.BI \-e\  ENV=VALUE ,\ \-\-env= VARIABLE=VALUE
+Send the script the given enviroment variable
+.IR VARIABLE
+set to the value
+.IR VALUE .
+.TP
 .BR -f ,\  \-\-foreground
 Do not fork after obtaining a lease.
 .TP