1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License").  You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*
23 * Copyright 1999-2002 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27#pragma ident	"%Z%%M%	%I%	%E% SMI"
28
29#include <libintl.h>
30#include <limits.h>
31#include <string.h>
32#include <stdlib.h>
33#include <stdarg.h>
34#include <stdio.h>
35#include <errno.h>
36#include <wchar.h>
37
38#include <utils.h>
39
40static const char PNAME_FMT[] = "%s: ";
41static const char ERRNO_FMT[] = ": %s\n";
42
43static const char *pname;
44
45/*PRINTFLIKE1*/
46void
47warn(const char *format, ...)
48{
49	int err = errno;
50	va_list alist;
51
52	if (pname != NULL)
53		(void) fprintf(stderr, gettext(PNAME_FMT), pname);
54
55	va_start(alist, format);
56	(void) vfprintf(stderr, format, alist);
57	va_end(alist);
58
59	if (strrchr(format, '\n') == NULL)
60		(void) fprintf(stderr, gettext(ERRNO_FMT), strerror(err));
61}
62
63/*PRINTFLIKE1*/
64void
65die(const char *format, ...)
66{
67	int err = errno;
68	va_list alist;
69
70	if (pname != NULL)
71		(void) fprintf(stderr, gettext(PNAME_FMT), pname);
72
73	va_start(alist, format);
74	(void) vfprintf(stderr, format, alist);
75	va_end(alist);
76
77	if (strrchr(format, '\n') == NULL)
78		(void) fprintf(stderr, gettext(ERRNO_FMT), strerror(err));
79
80	exit(E_ERROR);
81}
82
83const char *
84getpname(const char *arg0)
85{
86	const char *p = strrchr(arg0, '/');
87
88	if (p == NULL)
89		p = arg0;
90	else
91		p++;
92
93	pname = p;
94	return (p);
95}
96
97void *
98safe_malloc(size_t size)
99{
100	void *a;
101
102	if ((a = malloc(size)) == NULL)
103		die(gettext("out of memory\n"));
104
105	return (a);
106}
107
108/*
109 * getdefault() reads from one of the /etc/default files. It takes
110 * input of the filename, a variable name to search for, and a
111 * prefix to prepend to the result.
112 *
113 * The file and varname arguments are required. The varname argument
114 * must be of the form "VAR=". If the prefix argument
115 * is non-null, it will be prepended to the returned string.
116 * Double and single quotes are stripped from the result.
117 *
118 * getdefault() returns NULL if the file cannot be opened, or the
119 * variable cannot be found.
120 */
121char *
122getdefault(char *file, char *varname, char *prefix)
123{
124	FILE *fp;
125	char cp[PATH_MAX];
126	char *tmp_cp, *ret_str = NULL;
127	size_t varlen;
128
129	if ((fp = fopen(file, "r")) == NULL)
130		return (ret_str);
131	varlen = strlen(varname);
132	while (fgets(cp, PATH_MAX, fp) != NULL) {
133		size_t len;
134
135		if (cp[0] == '#' || cp[0] == '\n')
136			continue;
137		len = strlen(cp);
138		if (cp[len - 1] == '\n') {
139			len--;
140			cp[len] = '\0';
141		}
142		/* Find line containing varname */
143		if (strncmp(varname, cp, varlen) == 0) {
144			char *cp2, *strip_ptr = NULL;
145			size_t tlen;
146			int inquotes = 0;
147
148			cp2 = tmp_cp = cp + varlen;
149			/*
150			 * Remove extra characters after any space,
151			 * tab, or unquoted semicolon, and strip quotes.
152			 */
153			while ((*cp2 != '\0') &&
154			    (*cp2 != ' ') && (*cp2 != '\t') &&
155			    !((*cp2 == ';') && (inquotes == 0))) {
156				if (*cp2 == '\"' || *cp2 == '\'') {
157					if (*cp2 == '\"') {
158						inquotes =
159						    inquotes == 0 ? 1 : 0;
160					}
161					if (strip_ptr == NULL) {
162						strip_ptr = cp2;
163					}
164				} else {
165					if (strip_ptr != NULL) {
166						*strip_ptr++ = *cp2;
167					}
168				}
169				cp2++;
170			}
171			if (strip_ptr != NULL) {
172				*strip_ptr = '\0';
173			}
174			len = cp2 - tmp_cp;
175			if (prefix) {
176				tlen = len + strlen(prefix) + 1;
177				ret_str = safe_malloc(tlen);
178				(void) snprintf(ret_str, tlen, "%s%s",
179				    prefix, tmp_cp);
180			} else {
181				tlen = len + 1;
182				ret_str = safe_malloc(tlen);
183				(void) snprintf(ret_str, tlen, "%s", tmp_cp);
184			}
185			break;
186		}
187	}
188	(void) fclose(fp);
189	return (ret_str);
190}
191