xref: /minix3/external/bsd/pkg_install/dist/lib/var.c (revision a824f5a1008ee67499d167f8c48e64aae26960ca)
1*a824f5a1SJean-Baptiste Boric /*	$NetBSD: var.c,v 1.2 2013/05/16 19:19:44 martin Exp $	*/
2*a824f5a1SJean-Baptiste Boric 
3*a824f5a1SJean-Baptiste Boric /*-
4*a824f5a1SJean-Baptiste Boric  * Copyright (c) 2005, 2008 The NetBSD Foundation, Inc.
5*a824f5a1SJean-Baptiste Boric  * All rights reserved.
6*a824f5a1SJean-Baptiste Boric  *
7*a824f5a1SJean-Baptiste Boric  * This code is derived from software contributed to The NetBSD Foundation
8*a824f5a1SJean-Baptiste Boric  * by Dieter Baron, Thomas Klausner, Johnny Lam, and Joerg Sonnenberger.
9*a824f5a1SJean-Baptiste Boric  *
10*a824f5a1SJean-Baptiste Boric  * Redistribution and use in source and binary forms, with or without
11*a824f5a1SJean-Baptiste Boric  * modification, are permitted provided that the following conditions
12*a824f5a1SJean-Baptiste Boric  * are met:
13*a824f5a1SJean-Baptiste Boric  * 1. Redistributions of source code must retain the above copyright
14*a824f5a1SJean-Baptiste Boric  *    notice, this list of conditions and the following disclaimer.
15*a824f5a1SJean-Baptiste Boric  * 2. Redistributions in binary form must reproduce the above copyright
16*a824f5a1SJean-Baptiste Boric  *    notice, this list of conditions and the following disclaimer in the
17*a824f5a1SJean-Baptiste Boric  *    documentation and/or other materials provided with the distribution.
18*a824f5a1SJean-Baptiste Boric  * 3. Neither the name of The NetBSD Foundation nor the names of its
19*a824f5a1SJean-Baptiste Boric  *    contributors may be used to endorse or promote products derived
20*a824f5a1SJean-Baptiste Boric  *    from this software without specific prior written permission.
21*a824f5a1SJean-Baptiste Boric  *
22*a824f5a1SJean-Baptiste Boric  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
23*a824f5a1SJean-Baptiste Boric  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24*a824f5a1SJean-Baptiste Boric  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25*a824f5a1SJean-Baptiste Boric  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
26*a824f5a1SJean-Baptiste Boric  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27*a824f5a1SJean-Baptiste Boric  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28*a824f5a1SJean-Baptiste Boric  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29*a824f5a1SJean-Baptiste Boric  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30*a824f5a1SJean-Baptiste Boric  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31*a824f5a1SJean-Baptiste Boric  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32*a824f5a1SJean-Baptiste Boric  * POSSIBILITY OF SUCH DAMAGE.
33*a824f5a1SJean-Baptiste Boric  */
34*a824f5a1SJean-Baptiste Boric 
35*a824f5a1SJean-Baptiste Boric #if HAVE_CONFIG_H
36*a824f5a1SJean-Baptiste Boric #include "config.h"
37*a824f5a1SJean-Baptiste Boric #endif
38*a824f5a1SJean-Baptiste Boric #include <nbcompat.h>
39*a824f5a1SJean-Baptiste Boric #if HAVE_SYS_CDEFS_H
40*a824f5a1SJean-Baptiste Boric #include <sys/cdefs.h>
41*a824f5a1SJean-Baptiste Boric #endif
42*a824f5a1SJean-Baptiste Boric __RCSID("$NetBSD: var.c,v 1.2 2013/05/16 19:19:44 martin Exp $");
43*a824f5a1SJean-Baptiste Boric 
44*a824f5a1SJean-Baptiste Boric #if HAVE_SYS_STAT_H
45*a824f5a1SJean-Baptiste Boric #include <sys/stat.h>
46*a824f5a1SJean-Baptiste Boric #endif
47*a824f5a1SJean-Baptiste Boric #if HAVE_ERR_H
48*a824f5a1SJean-Baptiste Boric #include <err.h>
49*a824f5a1SJean-Baptiste Boric #endif
50*a824f5a1SJean-Baptiste Boric #if HAVE_ERRNO_H
51*a824f5a1SJean-Baptiste Boric #include <errno.h>
52*a824f5a1SJean-Baptiste Boric #endif
53*a824f5a1SJean-Baptiste Boric #if HAVE_STDIO_H
54*a824f5a1SJean-Baptiste Boric #include <stdio.h>
55*a824f5a1SJean-Baptiste Boric #endif
56*a824f5a1SJean-Baptiste Boric 
57*a824f5a1SJean-Baptiste Boric #include "lib.h"
58*a824f5a1SJean-Baptiste Boric 
59*a824f5a1SJean-Baptiste Boric static const char *var_cmp(const char *, size_t, const char *, size_t);
60*a824f5a1SJean-Baptiste Boric static void var_print(FILE *, const char *, const char *);
61*a824f5a1SJean-Baptiste Boric 
62*a824f5a1SJean-Baptiste Boric /*
63*a824f5a1SJean-Baptiste Boric  * Copy the specified varibales from the file fname to stdout.
64*a824f5a1SJean-Baptiste Boric  */
65*a824f5a1SJean-Baptiste Boric int
var_copy_list(const char * buf,const char ** variables)66*a824f5a1SJean-Baptiste Boric var_copy_list(const char *buf, const char **variables)
67*a824f5a1SJean-Baptiste Boric {
68*a824f5a1SJean-Baptiste Boric 	const char *eol, *next;
69*a824f5a1SJean-Baptiste Boric 	size_t len;
70*a824f5a1SJean-Baptiste Boric 	int i;
71*a824f5a1SJean-Baptiste Boric 
72*a824f5a1SJean-Baptiste Boric 	for (; *buf; buf = next) {
73*a824f5a1SJean-Baptiste Boric 		if ((eol = strchr(buf, '\n')) != NULL) {
74*a824f5a1SJean-Baptiste Boric 			next = eol + 1;
75*a824f5a1SJean-Baptiste Boric 			len = eol - buf;
76*a824f5a1SJean-Baptiste Boric 		} else {
77*a824f5a1SJean-Baptiste Boric 			next = eol;
78*a824f5a1SJean-Baptiste Boric 			len = strlen(buf);
79*a824f5a1SJean-Baptiste Boric 		}
80*a824f5a1SJean-Baptiste Boric 
81*a824f5a1SJean-Baptiste Boric 		for (i=0; variables[i]; i++) {
82*a824f5a1SJean-Baptiste Boric 			if (var_cmp(buf, len, variables[i],
83*a824f5a1SJean-Baptiste Boric 				       strlen(variables[i])) != NULL) {
84*a824f5a1SJean-Baptiste Boric 				printf("%.*s\n", (int)len, buf);
85*a824f5a1SJean-Baptiste Boric 				break;
86*a824f5a1SJean-Baptiste Boric 			}
87*a824f5a1SJean-Baptiste Boric 		}
88*a824f5a1SJean-Baptiste Boric 	}
89*a824f5a1SJean-Baptiste Boric 	return 0;
90*a824f5a1SJean-Baptiste Boric }
91*a824f5a1SJean-Baptiste Boric 
92*a824f5a1SJean-Baptiste Boric /*
93*a824f5a1SJean-Baptiste Boric  * Print the value of variable from the file fname to stdout.
94*a824f5a1SJean-Baptiste Boric  */
95*a824f5a1SJean-Baptiste Boric char *
var_get(const char * fname,const char * variable)96*a824f5a1SJean-Baptiste Boric var_get(const char *fname, const char *variable)
97*a824f5a1SJean-Baptiste Boric {
98*a824f5a1SJean-Baptiste Boric 	FILE   *fp;
99*a824f5a1SJean-Baptiste Boric 	char   *line;
100*a824f5a1SJean-Baptiste Boric 	size_t  len;
101*a824f5a1SJean-Baptiste Boric 	size_t  varlen;
102*a824f5a1SJean-Baptiste Boric 	char   *value;
103*a824f5a1SJean-Baptiste Boric 	size_t  valuelen;
104*a824f5a1SJean-Baptiste Boric 	size_t  thislen;
105*a824f5a1SJean-Baptiste Boric 	const char *p;
106*a824f5a1SJean-Baptiste Boric 
107*a824f5a1SJean-Baptiste Boric 	varlen = strlen(variable);
108*a824f5a1SJean-Baptiste Boric 	if (varlen == 0)
109*a824f5a1SJean-Baptiste Boric 		return NULL;
110*a824f5a1SJean-Baptiste Boric 
111*a824f5a1SJean-Baptiste Boric 	fp = fopen(fname, "r");
112*a824f5a1SJean-Baptiste Boric 	if (!fp) {
113*a824f5a1SJean-Baptiste Boric 		if (errno != ENOENT)
114*a824f5a1SJean-Baptiste Boric 			warn("var_get: can't open '%s' for reading", fname);
115*a824f5a1SJean-Baptiste Boric 		return NULL;
116*a824f5a1SJean-Baptiste Boric 	}
117*a824f5a1SJean-Baptiste Boric 
118*a824f5a1SJean-Baptiste Boric 	value = NULL;
119*a824f5a1SJean-Baptiste Boric 	valuelen = 0;
120*a824f5a1SJean-Baptiste Boric 
121*a824f5a1SJean-Baptiste Boric 	while ((line = fgetln(fp, &len)) != (char *) NULL) {
122*a824f5a1SJean-Baptiste Boric 		if (line[len - 1] == '\n')
123*a824f5a1SJean-Baptiste Boric 			--len;
124*a824f5a1SJean-Baptiste Boric 		if ((p=var_cmp(line, len, variable, varlen)) == NULL)
125*a824f5a1SJean-Baptiste Boric 			continue;
126*a824f5a1SJean-Baptiste Boric 
127*a824f5a1SJean-Baptiste Boric 		thislen = line+len - p;
128*a824f5a1SJean-Baptiste Boric 		if (value) {
129*a824f5a1SJean-Baptiste Boric 			value = xrealloc(value, valuelen+thislen+2);
130*a824f5a1SJean-Baptiste Boric 			value[valuelen++] = '\n';
131*a824f5a1SJean-Baptiste Boric 		}
132*a824f5a1SJean-Baptiste Boric 		else {
133*a824f5a1SJean-Baptiste Boric 			value = xmalloc(thislen+1);
134*a824f5a1SJean-Baptiste Boric 		}
135*a824f5a1SJean-Baptiste Boric 		sprintf(value+valuelen, "%.*s", (int)thislen, p);
136*a824f5a1SJean-Baptiste Boric 		valuelen += thislen;
137*a824f5a1SJean-Baptiste Boric 	}
138*a824f5a1SJean-Baptiste Boric 	(void) fclose(fp);
139*a824f5a1SJean-Baptiste Boric 	return value;
140*a824f5a1SJean-Baptiste Boric }
141*a824f5a1SJean-Baptiste Boric 
142*a824f5a1SJean-Baptiste Boric /*
143*a824f5a1SJean-Baptiste Boric  * Print the value of variable from the memory buffer to stdout.
144*a824f5a1SJean-Baptiste Boric  */
145*a824f5a1SJean-Baptiste Boric char *
var_get_memory(const char * buf,const char * variable)146*a824f5a1SJean-Baptiste Boric var_get_memory(const char *buf, const char *variable)
147*a824f5a1SJean-Baptiste Boric {
148*a824f5a1SJean-Baptiste Boric 	const char *eol, *next, *data;
149*a824f5a1SJean-Baptiste Boric 	size_t len, varlen, thislen, valuelen;
150*a824f5a1SJean-Baptiste Boric 	char *value;
151*a824f5a1SJean-Baptiste Boric 
152*a824f5a1SJean-Baptiste Boric 	varlen = strlen(variable);
153*a824f5a1SJean-Baptiste Boric 	if (varlen == 0)
154*a824f5a1SJean-Baptiste Boric 		return NULL;
155*a824f5a1SJean-Baptiste Boric 
156*a824f5a1SJean-Baptiste Boric 	value = NULL;
157*a824f5a1SJean-Baptiste Boric 	valuelen = 0;
158*a824f5a1SJean-Baptiste Boric 
159*a824f5a1SJean-Baptiste Boric 	for (; buf && *buf; buf = next) {
160*a824f5a1SJean-Baptiste Boric 		if ((eol = strchr(buf, '\n')) != NULL) {
161*a824f5a1SJean-Baptiste Boric 			next = eol + 1;
162*a824f5a1SJean-Baptiste Boric 			len = eol - buf;
163*a824f5a1SJean-Baptiste Boric 		} else {
164*a824f5a1SJean-Baptiste Boric 			next = eol;
165*a824f5a1SJean-Baptiste Boric 			len = strlen(buf);
166*a824f5a1SJean-Baptiste Boric 		}
167*a824f5a1SJean-Baptiste Boric 		if ((data = var_cmp(buf, len, variable, varlen)) == NULL)
168*a824f5a1SJean-Baptiste Boric 			continue;
169*a824f5a1SJean-Baptiste Boric 
170*a824f5a1SJean-Baptiste Boric 		thislen = buf + len - data;
171*a824f5a1SJean-Baptiste Boric 		if (value) {
172*a824f5a1SJean-Baptiste Boric 			value = xrealloc(value, valuelen+thislen+2);
173*a824f5a1SJean-Baptiste Boric 			value[valuelen++] = '\n';
174*a824f5a1SJean-Baptiste Boric 		}
175*a824f5a1SJean-Baptiste Boric 		else {
176*a824f5a1SJean-Baptiste Boric 			value = xmalloc(thislen+1);
177*a824f5a1SJean-Baptiste Boric 		}
178*a824f5a1SJean-Baptiste Boric 		sprintf(value + valuelen, "%.*s", (int)thislen, data);
179*a824f5a1SJean-Baptiste Boric 		valuelen += thislen;
180*a824f5a1SJean-Baptiste Boric 	}
181*a824f5a1SJean-Baptiste Boric 	return value;
182*a824f5a1SJean-Baptiste Boric }
183*a824f5a1SJean-Baptiste Boric 
184*a824f5a1SJean-Baptiste Boric /*
185*a824f5a1SJean-Baptiste Boric  * Add given variable with given value to file, overwriting any
186*a824f5a1SJean-Baptiste Boric  * previous occurrence.
187*a824f5a1SJean-Baptiste Boric  */
188*a824f5a1SJean-Baptiste Boric int
var_set(const char * fname,const char * variable,const char * value)189*a824f5a1SJean-Baptiste Boric var_set(const char *fname, const char *variable, const char *value)
190*a824f5a1SJean-Baptiste Boric {
191*a824f5a1SJean-Baptiste Boric 	FILE   *fp;
192*a824f5a1SJean-Baptiste Boric 	FILE   *fout;
193*a824f5a1SJean-Baptiste Boric 	char   *tmpname;
194*a824f5a1SJean-Baptiste Boric 	int     fd;
195*a824f5a1SJean-Baptiste Boric 	char   *line;
196*a824f5a1SJean-Baptiste Boric 	size_t  len;
197*a824f5a1SJean-Baptiste Boric 	size_t  varlen;
198*a824f5a1SJean-Baptiste Boric 	Boolean done;
199*a824f5a1SJean-Baptiste Boric 	struct stat st;
200*a824f5a1SJean-Baptiste Boric 
201*a824f5a1SJean-Baptiste Boric 	varlen = strlen(variable);
202*a824f5a1SJean-Baptiste Boric 	if (varlen == 0)
203*a824f5a1SJean-Baptiste Boric 		return 0;
204*a824f5a1SJean-Baptiste Boric 
205*a824f5a1SJean-Baptiste Boric 	fp = fopen(fname, "r");
206*a824f5a1SJean-Baptiste Boric 	if (fp == NULL) {
207*a824f5a1SJean-Baptiste Boric 		if (errno != ENOENT) {
208*a824f5a1SJean-Baptiste Boric 			warn("var_set: can't open '%s' for reading", fname);
209*a824f5a1SJean-Baptiste Boric 			return -1;
210*a824f5a1SJean-Baptiste Boric 		}
211*a824f5a1SJean-Baptiste Boric 		if (value == NULL)
212*a824f5a1SJean-Baptiste Boric 			return 0; /* Nothing to do */
213*a824f5a1SJean-Baptiste Boric 	}
214*a824f5a1SJean-Baptiste Boric 
215*a824f5a1SJean-Baptiste Boric 	tmpname = xasprintf("%s.XXXXXX", fname);
216*a824f5a1SJean-Baptiste Boric 	if ((fd = mkstemp(tmpname)) < 0) {
217*a824f5a1SJean-Baptiste Boric 		free(tmpname);
218*a824f5a1SJean-Baptiste Boric 		if (fp != NULL)
219*a824f5a1SJean-Baptiste Boric 			fclose(fp);
220*a824f5a1SJean-Baptiste Boric 		warn("var_set: can't open temp file for '%s' for writing",
221*a824f5a1SJean-Baptiste Boric 		      fname);
222*a824f5a1SJean-Baptiste Boric 		return -1;
223*a824f5a1SJean-Baptiste Boric 	}
224*a824f5a1SJean-Baptiste Boric 	if (chmod(tmpname, 0644) < 0) {
225*a824f5a1SJean-Baptiste Boric 		close(fd);
226*a824f5a1SJean-Baptiste Boric 		if (fp != NULL)
227*a824f5a1SJean-Baptiste Boric 			fclose(fp);
228*a824f5a1SJean-Baptiste Boric 		free(tmpname);
229*a824f5a1SJean-Baptiste Boric 		warn("var_set: can't set permissions for temp file for '%s'",
230*a824f5a1SJean-Baptiste Boric 		      fname);
231*a824f5a1SJean-Baptiste Boric 		return -1;
232*a824f5a1SJean-Baptiste Boric 	}
233*a824f5a1SJean-Baptiste Boric 	if ((fout=fdopen(fd, "w")) == NULL) {
234*a824f5a1SJean-Baptiste Boric 		close(fd);
235*a824f5a1SJean-Baptiste Boric 		remove(tmpname);
236*a824f5a1SJean-Baptiste Boric 		free(tmpname);
237*a824f5a1SJean-Baptiste Boric 		if (fp != NULL)
238*a824f5a1SJean-Baptiste Boric 			fclose(fp);
239*a824f5a1SJean-Baptiste Boric 		warn("var_set: can't open temp file for '%s' for writing",
240*a824f5a1SJean-Baptiste Boric 		      fname);
241*a824f5a1SJean-Baptiste Boric 		return -1;
242*a824f5a1SJean-Baptiste Boric 	}
243*a824f5a1SJean-Baptiste Boric 
244*a824f5a1SJean-Baptiste Boric 	done = FALSE;
245*a824f5a1SJean-Baptiste Boric 
246*a824f5a1SJean-Baptiste Boric 	if (fp) {
247*a824f5a1SJean-Baptiste Boric 		while ((line = fgetln(fp, &len)) != (char *) NULL) {
248*a824f5a1SJean-Baptiste Boric 			if (var_cmp(line, len, variable, varlen) == NULL)
249*a824f5a1SJean-Baptiste Boric 				fprintf(fout, "%.*s", (int)len, line);
250*a824f5a1SJean-Baptiste Boric 			else {
251*a824f5a1SJean-Baptiste Boric 				if (!done && value) {
252*a824f5a1SJean-Baptiste Boric 					var_print(fout, variable, value);
253*a824f5a1SJean-Baptiste Boric 					done = TRUE;
254*a824f5a1SJean-Baptiste Boric 				}
255*a824f5a1SJean-Baptiste Boric 			}
256*a824f5a1SJean-Baptiste Boric 		}
257*a824f5a1SJean-Baptiste Boric 		(void) fclose(fp);
258*a824f5a1SJean-Baptiste Boric 	}
259*a824f5a1SJean-Baptiste Boric 
260*a824f5a1SJean-Baptiste Boric 	if (!done && value)
261*a824f5a1SJean-Baptiste Boric 		var_print(fout, variable, value);
262*a824f5a1SJean-Baptiste Boric 
263*a824f5a1SJean-Baptiste Boric 	if (fclose(fout) < 0) {
264*a824f5a1SJean-Baptiste Boric 		free(tmpname);
265*a824f5a1SJean-Baptiste Boric 		warn("var_set: write error for '%s'", fname);
266*a824f5a1SJean-Baptiste Boric 		return -1;
267*a824f5a1SJean-Baptiste Boric 	}
268*a824f5a1SJean-Baptiste Boric 
269*a824f5a1SJean-Baptiste Boric 	if (stat(tmpname, &st) < 0) {
270*a824f5a1SJean-Baptiste Boric 		free(tmpname);
271*a824f5a1SJean-Baptiste Boric 		warn("var_set: cannot stat tempfile for '%s'", fname);
272*a824f5a1SJean-Baptiste Boric 		return -1;
273*a824f5a1SJean-Baptiste Boric 	}
274*a824f5a1SJean-Baptiste Boric 
275*a824f5a1SJean-Baptiste Boric 	if (st.st_size == 0) {
276*a824f5a1SJean-Baptiste Boric 		if (remove(tmpname) < 0) {
277*a824f5a1SJean-Baptiste Boric 			free(tmpname);
278*a824f5a1SJean-Baptiste Boric 			warn("var_set: cannot remove tempfile for '%s'",
279*a824f5a1SJean-Baptiste Boric 			     fname);
280*a824f5a1SJean-Baptiste Boric 			return -1;
281*a824f5a1SJean-Baptiste Boric 		}
282*a824f5a1SJean-Baptiste Boric 		free(tmpname);
283*a824f5a1SJean-Baptiste Boric 		if (remove(fname) < 0) {
284*a824f5a1SJean-Baptiste Boric 			warn("var_set: cannot remove '%s'", fname);
285*a824f5a1SJean-Baptiste Boric 			return -1;
286*a824f5a1SJean-Baptiste Boric 		}
287*a824f5a1SJean-Baptiste Boric 		return 0;
288*a824f5a1SJean-Baptiste Boric 	}
289*a824f5a1SJean-Baptiste Boric 
290*a824f5a1SJean-Baptiste Boric 	if (rename(tmpname, fname) < 0) {
291*a824f5a1SJean-Baptiste Boric 		free(tmpname);
292*a824f5a1SJean-Baptiste Boric 		warn("var_set: cannot move tempfile to '%s'", fname);
293*a824f5a1SJean-Baptiste Boric 		return -1;
294*a824f5a1SJean-Baptiste Boric 	}
295*a824f5a1SJean-Baptiste Boric 	free(tmpname);
296*a824f5a1SJean-Baptiste Boric 	return 0;
297*a824f5a1SJean-Baptiste Boric }
298*a824f5a1SJean-Baptiste Boric 
299*a824f5a1SJean-Baptiste Boric /*
300*a824f5a1SJean-Baptiste Boric  * Check if line contains variable var, return pointer to its value or NULL.
301*a824f5a1SJean-Baptiste Boric  */
302*a824f5a1SJean-Baptiste Boric static const char *
var_cmp(const char * line,size_t linelen,const char * var,size_t varlen)303*a824f5a1SJean-Baptiste Boric var_cmp(const char *line, size_t linelen, const char *var, size_t varlen)
304*a824f5a1SJean-Baptiste Boric {
305*a824f5a1SJean-Baptiste Boric 	/*
306*a824f5a1SJean-Baptiste Boric 	 * We expect lines to look like one of the following
307*a824f5a1SJean-Baptiste Boric 	 * forms:
308*a824f5a1SJean-Baptiste Boric 	 *      VAR=value
309*a824f5a1SJean-Baptiste Boric 	 *      VAR= value
310*a824f5a1SJean-Baptiste Boric 	 * We print out the value of VAR, or nothing if it
311*a824f5a1SJean-Baptiste Boric 	 * doesn't exist.
312*a824f5a1SJean-Baptiste Boric 	 */
313*a824f5a1SJean-Baptiste Boric 	if (linelen < varlen+1)
314*a824f5a1SJean-Baptiste Boric 		return NULL;
315*a824f5a1SJean-Baptiste Boric 	if (strncmp(var, line, varlen) != 0)
316*a824f5a1SJean-Baptiste Boric 		return NULL;
317*a824f5a1SJean-Baptiste Boric 
318*a824f5a1SJean-Baptiste Boric 	line += varlen;
319*a824f5a1SJean-Baptiste Boric 	if (*line != '=')
320*a824f5a1SJean-Baptiste Boric 		return NULL;
321*a824f5a1SJean-Baptiste Boric 
322*a824f5a1SJean-Baptiste Boric 	++line;
323*a824f5a1SJean-Baptiste Boric 	linelen -= varlen+1;
324*a824f5a1SJean-Baptiste Boric 	if (linelen > 0 && *line == ' ')
325*a824f5a1SJean-Baptiste Boric 		++line;
326*a824f5a1SJean-Baptiste Boric 	return line;
327*a824f5a1SJean-Baptiste Boric }
328*a824f5a1SJean-Baptiste Boric 
329*a824f5a1SJean-Baptiste Boric /*
330*a824f5a1SJean-Baptiste Boric  * Print given variable with value to file f.
331*a824f5a1SJean-Baptiste Boric  */
332*a824f5a1SJean-Baptiste Boric static void
var_print(FILE * f,const char * variable,const char * value)333*a824f5a1SJean-Baptiste Boric var_print(FILE *f, const char *variable, const char *value)
334*a824f5a1SJean-Baptiste Boric {
335*a824f5a1SJean-Baptiste Boric 	const char *p;
336*a824f5a1SJean-Baptiste Boric 
337*a824f5a1SJean-Baptiste Boric 	while ((p=strchr(value, '\n')) != NULL) {
338*a824f5a1SJean-Baptiste Boric 		if (p != value)
339*a824f5a1SJean-Baptiste Boric 			fprintf(f, "%s=%.*s\n", variable, (int)(p-value), value);
340*a824f5a1SJean-Baptiste Boric 		value = p+1;
341*a824f5a1SJean-Baptiste Boric 	}
342*a824f5a1SJean-Baptiste Boric 
343*a824f5a1SJean-Baptiste Boric 	if (*value)
344*a824f5a1SJean-Baptiste Boric 		fprintf(f, "%s=%s\n", variable, value);
345*a824f5a1SJean-Baptiste Boric }
346