env.c revision 2311
12311Sjkh/* Copyright 1988,1990,1993,1994 by Paul Vixie
22311Sjkh * All rights reserved
32311Sjkh *
42311Sjkh * Distribute freely, except: don't remove my name from the source or
52311Sjkh * documentation (don't take credit for my work), mark your changes (don't
62311Sjkh * get me blamed for your possible bugs), don't alter or remove this
72311Sjkh * notice.  May be sold if buildable source is provided to buyer.  No
82311Sjkh * warrantee of any kind, express or implied, is included with this
92311Sjkh * software; use at your own risk, responsibility for damages (if any) to
102311Sjkh * anyone resulting from the use of this software rests entirely with the
112311Sjkh * user.
122311Sjkh *
132311Sjkh * Send bug reports, bug fixes, enhancements, requests, flames, etc., and
142311Sjkh * I'll try to keep a version up to date.  I can be reached as follows:
152311Sjkh * Paul Vixie          <paul@vix.com>          uunet!decwrl!vixie!paul
162311Sjkh */
172311Sjkh
182311Sjkh#if !defined(lint) && !defined(LINT)
192311Sjkhstatic char rcsid[] = "$Id: env.c,v 2.6 1994/01/15 20:43:43 vixie Exp $";
202311Sjkh#endif
212311Sjkh
222311Sjkh
232311Sjkh#include "cron.h"
242311Sjkh
252311Sjkh
262311Sjkhchar **
272311Sjkhenv_init()
282311Sjkh{
292311Sjkh	register char	**p = (char **) malloc(sizeof(char **));
302311Sjkh
312311Sjkh	p[0] = NULL;
322311Sjkh	return (p);
332311Sjkh}
342311Sjkh
352311Sjkh
362311Sjkhvoid
372311Sjkhenv_free(envp)
382311Sjkh	char	**envp;
392311Sjkh{
402311Sjkh	char	**p;
412311Sjkh
422311Sjkh	for (p = envp;  *p;  p++)
432311Sjkh		free(*p);
442311Sjkh	free(envp);
452311Sjkh}
462311Sjkh
472311Sjkh
482311Sjkhchar **
492311Sjkhenv_copy(envp)
502311Sjkh	register char	**envp;
512311Sjkh{
522311Sjkh	register int	count, i;
532311Sjkh	register char	**p;
542311Sjkh
552311Sjkh	for (count = 0;  envp[count] != NULL;  count++)
562311Sjkh		;
572311Sjkh	p = (char **) malloc((count+1) * sizeof(char *));  /* 1 for the NULL */
582311Sjkh	for (i = 0;  i < count;  i++)
592311Sjkh		p[i] = strdup(envp[i]);
602311Sjkh	p[count] = NULL;
612311Sjkh	return (p);
622311Sjkh}
632311Sjkh
642311Sjkh
652311Sjkhchar **
662311Sjkhenv_set(envp, envstr)
672311Sjkh	char	**envp;
682311Sjkh	char	*envstr;
692311Sjkh{
702311Sjkh	register int	count, found;
712311Sjkh	register char	**p;
722311Sjkh
732311Sjkh	/*
742311Sjkh	 * count the number of elements, including the null pointer;
752311Sjkh	 * also set 'found' to -1 or index of entry if already in here.
762311Sjkh	 */
772311Sjkh	found = -1;
782311Sjkh	for (count = 0;  envp[count] != NULL;  count++) {
792311Sjkh		if (!strcmp_until(envp[count], envstr, '='))
802311Sjkh			found = count;
812311Sjkh	}
822311Sjkh	count++;	/* for the NULL */
832311Sjkh
842311Sjkh	if (found != -1) {
852311Sjkh		/*
862311Sjkh		 * it exists already, so just free the existing setting,
872311Sjkh		 * save our new one there, and return the existing array.
882311Sjkh		 */
892311Sjkh		free(envp[found]);
902311Sjkh		envp[found] = strdup(envstr);
912311Sjkh		return (envp);
922311Sjkh	}
932311Sjkh
942311Sjkh	/*
952311Sjkh	 * it doesn't exist yet, so resize the array, move null pointer over
962311Sjkh	 * one, save our string over the old null pointer, and return resized
972311Sjkh	 * array.
982311Sjkh	 */
992311Sjkh	p = (char **) realloc((void *) envp,
1002311Sjkh			      (unsigned) ((count+1) * sizeof(char **)));
1012311Sjkh	p[count] = p[count-1];
1022311Sjkh	p[count-1] = strdup(envstr);
1032311Sjkh	return (p);
1042311Sjkh}
1052311Sjkh
1062311Sjkh
1072311Sjkh/* return	ERR = end of file
1082311Sjkh *		FALSE = not an env setting (file was repositioned)
1092311Sjkh *		TRUE = was an env setting
1102311Sjkh */
1112311Sjkhint
1122311Sjkhload_env(envstr, f)
1132311Sjkh	char	*envstr;
1142311Sjkh	FILE	*f;
1152311Sjkh{
1162311Sjkh	long	filepos;
1172311Sjkh	int	fileline;
1182311Sjkh	char	name[MAX_TEMPSTR], val[MAX_ENVSTR];
1192311Sjkh	int	fields;
1202311Sjkh
1212311Sjkh	filepos = ftell(f);
1222311Sjkh	fileline = LineNumber;
1232311Sjkh	skip_comments(f);
1242311Sjkh	if (EOF == get_string(envstr, MAX_ENVSTR, f, "\n"))
1252311Sjkh		return (ERR);
1262311Sjkh
1272311Sjkh	Debug(DPARS, ("load_env, read <%s>\n", envstr))
1282311Sjkh
1292311Sjkh	name[0] = val[0] = '\0';
1302311Sjkh	fields = sscanf(envstr, "%[^ =] = %[^\n#]", name, val);
1312311Sjkh	if (fields != 2) {
1322311Sjkh		Debug(DPARS, ("load_env, not 2 fields (%d)\n", fields))
1332311Sjkh		fseek(f, filepos, 0);
1342311Sjkh		Set_LineNum(fileline);
1352311Sjkh		return (FALSE);
1362311Sjkh	}
1372311Sjkh
1382311Sjkh	/* 2 fields from scanf; looks like an env setting
1392311Sjkh	 */
1402311Sjkh
1412311Sjkh	/*
1422311Sjkh	 * process value string
1432311Sjkh	 */
1442311Sjkh	/*local*/{
1452311Sjkh		int	len = strdtb(val);
1462311Sjkh
1472311Sjkh		if (len >= 2) {
1482311Sjkh			if (val[0] == '\'' || val[0] == '"') {
1492311Sjkh				if (val[len-1] == val[0]) {
1502311Sjkh					val[len-1] = '\0';
1512311Sjkh					(void) strcpy(val, val+1);
1522311Sjkh				}
1532311Sjkh			}
1542311Sjkh		}
1552311Sjkh	}
1562311Sjkh
1572311Sjkh	(void) sprintf(envstr, "%s=%s", name, val);
1582311Sjkh	Debug(DPARS, ("load_env, <%s> <%s> -> <%s>\n", name, val, envstr))
1592311Sjkh	return (TRUE);
1602311Sjkh}
1612311Sjkh
1622311Sjkh
1632311Sjkhchar *
1642311Sjkhenv_get(name, envp)
1652311Sjkh	register char	*name;
1662311Sjkh	register char	**envp;
1672311Sjkh{
1682311Sjkh	register int	len = strlen(name);
1692311Sjkh	register char	*p, *q;
1702311Sjkh
1712311Sjkh	while (p = *envp++) {
1722311Sjkh		if (!(q = strchr(p, '=')))
1732311Sjkh			continue;
1742311Sjkh		if ((q - p) == len && !strncmp(p, name, len))
1752311Sjkh			return (q+1);
1762311Sjkh	}
1772311Sjkh	return (NULL);
1782311Sjkh}
179