1 /* $NetBSD: var.c,v 1.8 2009/08/02 17:56:45 joerg Exp $ */
4 * Copyright (c) 2005, 2008 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Dieter Baron, Thomas Klausner, Johnny Lam, and Joerg Sonnenberger.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of The NetBSD Foundation nor the names of its
19 * contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
23 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
40 #include <sys/cdefs.h>
42 __RCSID("$NetBSD: var.c,v 1.8 2009/08/02 17:56:45 joerg Exp $");
59 static const char *var_cmp(const char *, size_t, const char *, size_t);
60 static void var_print(FILE *, const char *, const char *);
63 * Copy the specified varibales from the file fname to stdout.
66 var_copy_list(const char *buf
, const char **variables
)
68 const char *eol
, *next
;
72 for (; *buf
; buf
= next
) {
73 if ((eol
= strchr(buf
, '\n')) != NULL
) {
81 for (i
=0; variables
[i
]; i
++) {
82 if (var_cmp(buf
, len
, variables
[i
],
83 strlen(variables
[i
])) != NULL
) {
84 printf("%.*s\n", (int)len
, buf
);
93 * Print the value of variable from the file fname to stdout.
96 var_get(const char *fname
, const char *variable
)
107 varlen
= strlen(variable
);
111 fp
= fopen(fname
, "r");
114 warn("var_get: can't open '%s' for reading", fname
);
121 while ((line
= fgetln(fp
, &len
)) != (char *) NULL
) {
122 if (line
[len
- 1] == '\n')
124 if ((p
=var_cmp(line
, len
, variable
, varlen
)) == NULL
)
127 thislen
= line
+len
- p
;
129 value
= xrealloc(value
, valuelen
+thislen
+2);
130 value
[valuelen
++] = '\n';
133 value
= xmalloc(thislen
+1);
135 sprintf(value
+valuelen
, "%.*s", (int)thislen
, p
);
143 * Print the value of variable from the memory buffer to stdout.
146 var_get_memory(const char *buf
, const char *variable
)
148 const char *eol
, *next
, *data
;
149 size_t len
, varlen
, thislen
, valuelen
;
152 varlen
= strlen(variable
);
159 for (; *buf
; buf
= next
) {
160 if ((eol
= strchr(buf
, '\n')) != NULL
) {
167 if ((data
= var_cmp(buf
, len
, variable
, varlen
)) == NULL
)
170 thislen
= buf
+ len
- data
;
172 value
= xrealloc(value
, valuelen
+thislen
+2);
173 value
[valuelen
++] = '\n';
176 value
= xmalloc(thislen
+1);
178 sprintf(value
+ valuelen
, "%.*s", (int)thislen
, data
);
185 * Add given variable with given value to file, overwriting any
186 * previous occurrence.
189 var_set(const char *fname
, const char *variable
, const char *value
)
201 varlen
= strlen(variable
);
205 fp
= fopen(fname
, "r");
207 if (errno
!= ENOENT
) {
208 warn("var_set: can't open '%s' for reading", fname
);
212 return 0; /* Nothing to do */
215 tmpname
= xasprintf("%s.XXXXXX", fname
);
216 if ((fd
= mkstemp(tmpname
)) < 0) {
220 warn("var_set: can't open temp file for '%s' for writing",
224 if (chmod(tmpname
, 0644) < 0) {
229 warn("var_set: can't set permissions for temp file for '%s'",
233 if ((fout
=fdopen(fd
, "w")) == NULL
) {
239 warn("var_set: can't open temp file for '%s' for writing",
247 while ((line
= fgetln(fp
, &len
)) != (char *) NULL
) {
248 if (var_cmp(line
, len
, variable
, varlen
) == NULL
)
249 fprintf(fout
, "%.*s", (int)len
, line
);
251 if (!done
&& value
) {
252 var_print(fout
, variable
, value
);
261 var_print(fout
, variable
, value
);
263 if (fclose(fout
) < 0) {
265 warn("var_set: write error for '%s'", fname
);
269 if (stat(tmpname
, &st
) < 0) {
271 warn("var_set: cannot stat tempfile for '%s'", fname
);
275 if (st
.st_size
== 0) {
276 if (remove(tmpname
) < 0) {
278 warn("var_set: cannot remove tempfile for '%s'",
283 if (remove(fname
) < 0) {
284 warn("var_set: cannot remove '%s'", fname
);
290 if (rename(tmpname
, fname
) < 0) {
292 warn("var_set: cannot move tempfile to '%s'", fname
);
300 * Check if line contains variable var, return pointer to its value or NULL.
303 var_cmp(const char *line
, size_t linelen
, const char *var
, size_t varlen
)
306 * We expect lines to look like one of the following
310 * We print out the value of VAR, or nothing if it
313 if (linelen
< varlen
+1)
315 if (strncmp(var
, line
, varlen
) != 0)
324 if (linelen
> 0 && *line
== ' ')
330 * Print given variable with value to file f.
333 var_print(FILE *f
, const char *variable
, const char *value
)
337 while ((p
=strchr(value
, '\n')) != NULL
) {
339 fprintf(f
, "%s=%.*s\n", variable
, (int)(p
-value
), value
);
344 fprintf(f
, "%s=%s\n", variable
, value
);