extern char **environ;
extern char **uc_environ;
#include <stdlib.h>
#define SP_SIZE sizeof(char *) // sizeof string pointer
/* get the sizeof environment table
* return the sizeof env tab
*/
int get_envtab_size()
{
char **p;
int items; // number of variants in the table
p = environ;
items = 0;
while (*p != NULL)
{
items++;
p++;
}
items++; // contain the space of NULL
return (items * SP_SIZE);
}
/* expend the name with '='
* return:pointer of the name,false NULL
*/
char *expnam(const char *name)
{
char *newnam;
if ((newnam = (char *)malloc
(strlen((name + 1) + 1))) == NULL)
{
return NULL;
}
strcpy(newnam, name);
strcat(newnam, "=");
return newnam;
}
/* make a new one to expend the env table
* return:new uc_environ,else NULL
*/
char **new_env()
{
char **old_p, **new_env_p, **new_p;
int old_size, new_size;
old_p = uc_environ;
old_size = get_envtab_size();
new_size = old_size + (1 * SP_SIZE);
if ((new_env_p = (char **)malloc(new_size)) == NULL)
{// failed to alloc
return NULL;
}
new_p = new_env_p;
// copy the old table's values to the new one
while (*old_p != NULL)
{
*new_p = *old_p;
new_p++;
old_p++;
}
*new_p = *old_p;
new_p++;
*new_p = NULL;
old_p = uc_environ;
uc_environ = new_env_p;
free(old_p);
return uc_environ;
}
/* get the environment variant's value
* return:the name relate with value's pointer,false NULL
*/
char *uc_getenv(const char *name)
{
char **p, *buf_nam;
int nam_len; // lenth of name
char *vp; // point to value
p = uc_environ;
if ((buf_nam = expnam(name)) == NULL)
{// expend '=' for name
return NULL;
}
nam_len = strlen(buf_nam);
while(*p != NULL)
{
if (strncmp(*p, buf_nam, nam_len) == 0)
{
vp = *p + nam_len;
free(buf_nam);
return vp;
}
p++;
}
free(buf_nam);
return NULL;
}
/* put the string's(name=value) pointer into the table
* overwrite if the name exist
* return:0 success,else not 0
*/
int uc_putenv(char *str)
{
char **p;
int nam_len, i;
p = uc_environ;
nam_len = 0;
i = 0;
// get the lenth of name
while (*(str + i) != '\0')
{
nam_len++;
if (*(str + i) == '=')
{
break;
}
i++;
}
if (*(str + i) == '\0')
{// the error string
return 1;
}
// is the name exist?
while (*p != NULL)
{
if(strncmp(*p, str, nam_len) == 0)
{// exist,just overwrite
free(*p);
*p = str;
return 0;
}
p++;
}
// isn't exist,realloc the env tab and add the str to the tail
if ((p = new_env()) == NULL)
{// failer to realloc
return 1;
}
while (*p != NULL)
{// move to the tail
p++;
}
*p = str; // add to the tail
return 0;
}
/* set the new environment variant (name=value)
* if name exist and rewrite is not 0,just rewrite it
* else rewrite is 0, just retuen
* else if name is not exist,add it as a new variant
* return:0 success,else not 0
*/
int uc_setenv(const char *name, const char *value, int rewrite)
{
char **p, *buf_nam;
int nam_len, len_str;
p = uc_environ;
if ((buf_nam = expnam(name)) == NULL)
{// expend '=' for name
return 1;
}
nam_len = strlen(buf_nam); // get the lenth of name
len_str = nam_len + strlen(value); // get the lenth of string
// is the name exist?
while (*p != NULL)
{
if(strncmp(*p, buf_nam, nam_len) == 0)
{// exist
// don't rewrite
if (rewrite == 0)
{
free(buf_nam);
return 0;
}
// rewrite it
if (strlen(*p) < len_str)
{// out of lenth, get a new space
*p = realloc(*p, len_str + 1);
}
strcpy(*p, buf_nam);
strcat(*p, value);
free(buf_nam);
return 0;
}
p++;
}
// isn't exist,realloc the env tab and add the str to the tail
if ((p = new_env()) == NULL)
{// failer to realloc
free(buf_nam);
return 1;
}
// add to the tail
while (*p != NULL)
{
p++;
}
*p = realloc(*p, len_str + 1);
strcpy(*p, buf_nam);
strcat(*p, value);
free(buf_nam);
return 0;
}
/* unset the variant which relate to the name
* return:0 success,else not 0
*/
int uc_unsetenv(const char *name)
{
char **p, *save_p, *buf_nam;
int nam_len;
p = uc_environ;
if ((buf_nam = expnam(name)) == NULL)
{// expend '=' for name
return 1;
}
nam_len = strlen(buf_nam);
while (*p != NULL)
{
if (strncmp(*p, buf_nam, nam_len) == 0)
{// find the name
save_p = *p;
while (*p != NULL)
{
*p = *(p + 1);
p++;
}
free(save_p); // delete the name
free(buf_nam);
return 0;
}
p++;
}
// not find
free(buf_nam);
return 1;
}
|