xref: /titanic_41/usr/src/lib/libbc/libc/gen/common/putenv.c (revision 1ae0874509b6811fdde1dfd46f0d93fd09867a3f)
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 1987 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*      Copyright (c) 1984 AT&T */
28 /*        All Rights Reserved   */
29 
30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31 
32 /*	LINTLIBRARY	*/
33 /*	putenv - change environment variables
34  *
35  *	input - char *change = a pointer to a string of the form
36  *			       "name=value"
37  *
38  *	output - 0, if successful
39  *		 1, otherwise
40  */
41 
42 #include <stdio.h>
43 #include <stdlib.h>
44 
45 extern char **environ;		/* pointer to enviroment */
46 static int	reall;		/* flag to reallocate space, if putenv is called
47 				   more than once */
48 static int	find(char *);
49 static int	match(char *, char *);
50 
51 int
52 putenv(char *change)
53 {
54 	char **newenv;		    /* points to new environment */
55 	int which;	    /* index of variable to replace */
56 
57 	if ((which = find(change)) < 0)  {
58 		/* if a new variable */
59 		/* which is negative of table size, so invert and
60 		   count new element */
61 		which = (-which) + 1;
62 		if (reall)  {
63 			/* we have expanded environ before */
64 			newenv = (char **)realloc(environ,
65 				  which*sizeof(char *));
66 			if (newenv == NULL)  return (-1);
67 			/* now that we have space, change environ */
68 			environ = newenv;
69 		} else {
70 			/* environ points to the original space */
71 			reall++;
72 			newenv = (char **)malloc(which*sizeof(char *));
73 			if (newenv == NULL)  return (-1);
74 			(void)memcpy((char *)newenv, (char *)environ,
75  				(int)(which*sizeof(char *)));
76 			environ = newenv;
77 		}
78 		environ[which-2] = change;
79 		environ[which-1] = NULL;
80 	}  else  {
81 		/* we are replacing an old variable */
82 		environ[which] = change;
83 	}
84 	return (0);
85 }
86 
87 /*	find - find where s2 is in environ
88  *
89  *	input - str = string of form name=value
90  *
91  *	output - index of name in environ that matches "name"
92  *		 -size of table, if none exists
93 */
94 static int
95 find(char *str)
96 {
97 	int ct = 0;	/* index into environ */
98 
99 	while(environ[ct] != NULL)   {
100 		if (match(environ[ct], str)  != 0)
101 			return (ct);
102 		ct++;
103 	}
104 	return (-(++ct));
105 }
106 /*
107  *	s1 is either name, or name=value
108  *	s2 is name=value
109  *	if names match, return value of 1,
110  *	else return 0
111  */
112 
113 static int
114 match(char *s1, char *s2)
115 {
116 	while(*s1 == *s2++)  {
117 		if (*s1 == '=')
118 			return (1);
119 		s1++;
120 	}
121 	return (0);
122 }
123