|
Packit |
8480eb |
/* ----------------------------------------------------------------------- *
|
|
Packit |
8480eb |
*
|
|
Packit |
8480eb |
* macros.c - module to handle macro substitution variables for map
|
|
Packit |
8480eb |
* entries.
|
|
Packit |
8480eb |
*
|
|
Packit |
8480eb |
* Copyright 2006 Ian Kent <raven@themaw.net>
|
|
Packit |
8480eb |
*
|
|
Packit |
8480eb |
* This program is free software; you can redistribute it and/or modify
|
|
Packit |
8480eb |
* it under the terms of the GNU General Public License as published by
|
|
Packit |
8480eb |
* the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
|
|
Packit |
8480eb |
* USA; either version 2 of the License, or (at your option) any later
|
|
Packit |
8480eb |
* version; incorporated herein by reference.
|
|
Packit |
8480eb |
*
|
|
Packit |
8480eb |
* ----------------------------------------------------------------------- */
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
#include <malloc.h>
|
|
Packit |
8480eb |
#include <stdlib.h>
|
|
Packit |
8480eb |
#include <string.h>
|
|
Packit |
8480eb |
#include <limits.h>
|
|
Packit |
8480eb |
#include <sys/utsname.h>
|
|
Packit |
8480eb |
#include <unistd.h>
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
#include "automount.h"
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
static struct utsname un;
|
|
Packit |
8480eb |
static char processor[65]; /* Not defined on Linux, so we make our own */
|
|
Packit |
8480eb |
static char hostname[HOST_NAME_MAX + 1];
|
|
Packit |
8480eb |
static char host[HOST_NAME_MAX];
|
|
Packit |
8480eb |
static char domain[HOST_NAME_MAX];
|
|
Packit |
8480eb |
static char hostd[HOST_NAME_MAX + 1];
|
|
Packit |
8480eb |
static char endian[] = "unknown";
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
/* Predefined variables: tail of link chain */
|
|
Packit |
8480eb |
static struct substvar
|
|
Packit |
8480eb |
sv_arch = {"ARCH", un.machine, 1, NULL },
|
|
Packit |
8480eb |
sv_cpu = {"CPU", processor, 1, &sv_arch},
|
|
Packit |
8480eb |
sv_host = {"HOST", un.nodename, 1, &sv_cpu},
|
|
Packit |
8480eb |
sv_osname = {"OSNAME", un.sysname, 1, &sv_host},
|
|
Packit |
8480eb |
sv_osrel = {"OSREL", un.release, 1, &sv_osname},
|
|
Packit |
8480eb |
sv_osvers = {"OSVERS", un.version, 1, &sv_osrel},
|
|
Packit |
8480eb |
sv_dollar = {"dollar", "$", 1, &sv_osvers},
|
|
Packit |
8480eb |
sv_true = {"true", "1", 1, &sv_dollar},
|
|
Packit |
8480eb |
sv_false = {"false", "0", 1, &sv_true},
|
|
Packit |
8480eb |
sv_byte = {"byte", endian, 1, &sv_false},
|
|
Packit |
8480eb |
sv_host2 = {"host", host, 1, &sv_byte},
|
|
Packit |
8480eb |
sv_xhost = {"xhost", host, 1, &sv_host2},
|
|
Packit |
8480eb |
sv_domain = {"domain", domain, 1, &sv_xhost},
|
|
Packit |
8480eb |
sv_hostd = {"hostd", hostd, 1, &sv_domain
|
|
Packit |
8480eb |
};
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
static struct substvar *system_table = &sv_hostd;
|
|
Packit |
8480eb |
static unsigned int macro_init_done = 0;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
static pthread_mutex_t table_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
Packit |
8480eb |
static pthread_mutex_t macro_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
void dump_table(struct substvar *table)
|
|
Packit |
8480eb |
{
|
|
Packit |
8480eb |
struct substvar *lv = table;
|
|
Packit |
8480eb |
int status;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
status = pthread_mutex_lock(&table_mutex);
|
|
Packit |
8480eb |
if (status)
|
|
Packit |
8480eb |
fatal(status);
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
while (lv) {
|
|
Packit |
8480eb |
logmsg("lv->def %s lv->val %s lv->next %p",
|
|
Packit |
8480eb |
lv->def, lv->val, lv->next);
|
|
Packit |
8480eb |
lv = lv->next;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
status = pthread_mutex_unlock(&table_mutex);
|
|
Packit |
8480eb |
if (status)
|
|
Packit |
8480eb |
fatal(status);
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
/* Get processor information for predefined macro definitions */
|
|
Packit |
8480eb |
void macro_init(void)
|
|
Packit |
8480eb |
{
|
|
Packit |
8480eb |
char *local_domain;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
memset(hostname, 0, HOST_NAME_MAX + 1);
|
|
Packit |
8480eb |
memset(host, 0, HOST_NAME_MAX);
|
|
Packit |
8480eb |
memset(domain, 0, HOST_NAME_MAX);
|
|
Packit |
8480eb |
memset(hostd, 0, HOST_NAME_MAX + 1);
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
macro_lock();
|
|
Packit |
8480eb |
if (macro_init_done) {
|
|
Packit |
8480eb |
macro_unlock();
|
|
Packit |
8480eb |
return;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
uname(&un;;
|
|
Packit |
8480eb |
/*
|
|
Packit |
8480eb |
* uname -p is not defined on Linux. Make it the same as
|
|
Packit |
8480eb |
* uname -m, except make it return i386 on all x86 (x >= 3)
|
|
Packit |
8480eb |
*/
|
|
Packit |
8480eb |
strcpy(processor, un.machine);
|
|
Packit |
8480eb |
if (processor[0] == 'i' && processor[1] >= '3' &&
|
|
Packit |
8480eb |
!strcmp(processor + 2, "86"))
|
|
Packit |
8480eb |
processor[1] = '3';
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
local_domain = conf_amd_get_sub_domain();
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (!gethostname(hostname, HOST_NAME_MAX)) {
|
|
Packit |
8480eb |
char *dot;
|
|
Packit |
8480eb |
dot = strchr(hostname, '.');
|
|
Packit |
8480eb |
if (dot) {
|
|
Packit |
8480eb |
*dot++ = '\0';
|
|
Packit |
8480eb |
strcpy(domain, dot);
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
strcpy(host, hostname);
|
|
Packit |
8480eb |
strcpy(hostd, host);
|
|
Packit |
8480eb |
if (*domain || local_domain) {
|
|
Packit |
8480eb |
strcat(hostd, ".");
|
|
Packit |
8480eb |
if (!local_domain)
|
|
Packit |
8480eb |
strcat(hostd, domain);
|
|
Packit |
8480eb |
else {
|
|
Packit |
8480eb |
strcat(hostd, local_domain);
|
|
Packit |
8480eb |
strcpy(domain, local_domain);
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (sizeof(short) == 2) {
|
|
Packit |
8480eb |
union { short s; char c[sizeof(short)]; } order;
|
|
Packit |
8480eb |
order.s = 0x0102;
|
|
Packit |
8480eb |
if (order.c[0] == 1 && order.c[1] == 2)
|
|
Packit |
8480eb |
strcpy(endian, "big");
|
|
Packit |
8480eb |
else if (order.c[0] == 2 && order.c[1] == 1)
|
|
Packit |
8480eb |
strcpy(endian, "little");
|
|
Packit |
8480eb |
else
|
|
Packit |
8480eb |
strcpy(endian, "unknown");
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
add_std_amd_vars(system_table);
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
macro_init_done = 1;
|
|
Packit |
8480eb |
macro_unlock();
|
|
Packit |
0f1c87 |
free(local_domain);
|
|
Packit |
8480eb |
return;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
int macro_is_systemvar(const char *str, int len)
|
|
Packit |
8480eb |
{
|
|
Packit |
8480eb |
struct substvar *sv;
|
|
Packit |
8480eb |
int found = 0;
|
|
Packit |
8480eb |
int status;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
status = pthread_mutex_lock(&table_mutex);
|
|
Packit |
8480eb |
if (status)
|
|
Packit |
8480eb |
fatal(status);
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
sv = system_table;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
while (sv) {
|
|
Packit |
8480eb |
if (!strncmp(str, sv->def, len) && sv->def[len] == '\0') {
|
|
Packit |
8480eb |
found = 1;
|
|
Packit |
8480eb |
break;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
sv = sv->next;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
status = pthread_mutex_unlock(&table_mutex);
|
|
Packit |
8480eb |
if (status)
|
|
Packit |
8480eb |
fatal(status);
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
return found;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
int macro_global_addvar(const char *str, int len, const char *value)
|
|
Packit |
8480eb |
{
|
|
Packit |
8480eb |
struct substvar *sv;
|
|
Packit |
8480eb |
int status, ret = 0;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
status = pthread_mutex_lock(&table_mutex);
|
|
Packit |
8480eb |
if (status)
|
|
Packit |
8480eb |
fatal(status);
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
sv = system_table;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
while (sv) {
|
|
Packit |
8480eb |
if (!strncmp(str, sv->def, len) && sv->def[len] == '\0')
|
|
Packit |
8480eb |
break;
|
|
Packit |
8480eb |
sv = sv->next;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (sv && !sv->readonly) {
|
|
Packit |
8480eb |
char *this = malloc(strlen(value) + 1);
|
|
Packit |
8480eb |
if (!this)
|
|
Packit |
8480eb |
goto done;
|
|
Packit |
8480eb |
strcpy(this, value);
|
|
Packit |
8480eb |
free(sv->val);
|
|
Packit |
8480eb |
sv->val = this;
|
|
Packit |
8480eb |
ret = 1;
|
|
Packit |
8480eb |
} else {
|
|
Packit |
8480eb |
struct substvar *new;
|
|
Packit |
8480eb |
char *def, *val;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
def = strdup(str);
|
|
Packit |
8480eb |
if (!def)
|
|
Packit |
8480eb |
goto done;
|
|
Packit |
8480eb |
def[len] = '\0';
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
val = strdup(value);
|
|
Packit |
8480eb |
if (!val) {
|
|
Packit |
8480eb |
free(def);
|
|
Packit |
8480eb |
goto done;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
new = malloc(sizeof(struct substvar));
|
|
Packit |
8480eb |
if (!new) {
|
|
Packit |
8480eb |
free(def);
|
|
Packit |
8480eb |
free(val);
|
|
Packit |
8480eb |
goto done;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
new->def = def;
|
|
Packit |
8480eb |
new->val = val;
|
|
Packit |
8480eb |
new->readonly = 0;
|
|
Packit |
8480eb |
new->next = system_table;
|
|
Packit |
8480eb |
system_table = new;
|
|
Packit |
8480eb |
ret =1;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
done:
|
|
Packit |
8480eb |
status = pthread_mutex_unlock(&table_mutex);
|
|
Packit |
8480eb |
if (status)
|
|
Packit |
8480eb |
fatal(status);
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
return ret;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
int macro_parse_globalvar(const char *define)
|
|
Packit |
8480eb |
{
|
|
Packit |
8480eb |
char buf[MAX_MACRO_STRING];
|
|
Packit |
8480eb |
char *pbuf, *value;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (strlen(define) >= MAX_MACRO_STRING)
|
|
Packit |
8480eb |
return 0;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
strcpy(buf, define);
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
pbuf = buf;
|
|
Packit |
8480eb |
while (pbuf) {
|
|
Packit |
8480eb |
if (*pbuf == '=') {
|
|
Packit |
8480eb |
*pbuf = '\0';
|
|
Packit |
8480eb |
value = pbuf + 1;
|
|
Packit |
8480eb |
break;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
pbuf++;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
/* Macro must have value */
|
|
Packit |
8480eb |
if (!pbuf)
|
|
Packit |
8480eb |
return 0;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
return macro_global_addvar(buf, strlen(buf), value);
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
void macro_lock(void)
|
|
Packit |
8480eb |
{
|
|
Packit |
8480eb |
int status = pthread_mutex_lock(¯o_mutex);
|
|
Packit |
8480eb |
if (status)
|
|
Packit |
8480eb |
fatal(status);
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
void macro_unlock(void)
|
|
Packit |
8480eb |
{
|
|
Packit |
8480eb |
int status = pthread_mutex_unlock(¯o_mutex);
|
|
Packit |
8480eb |
if (status)
|
|
Packit |
8480eb |
fatal(status);
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
struct substvar *
|
|
Packit |
8480eb |
macro_addvar(struct substvar *table, const char *str, int len, const char *value)
|
|
Packit |
8480eb |
{
|
|
Packit |
8480eb |
struct substvar *lv = table;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
while (lv) {
|
|
Packit |
8480eb |
if (!strncmp(str, lv->def, len) && lv->def[len] == '\0')
|
|
Packit |
8480eb |
break;
|
|
Packit |
8480eb |
lv = lv->next;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (lv) {
|
|
Packit |
8480eb |
const char *val = value ? value : "";
|
|
Packit |
8480eb |
char *this = malloc(strlen(val) + 1);
|
|
Packit |
8480eb |
if (!this) {
|
|
Packit |
8480eb |
lv = table;
|
|
Packit |
8480eb |
goto done;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
strcpy(this, val);
|
|
Packit |
8480eb |
free(lv->val);
|
|
Packit |
8480eb |
lv->val = this;
|
|
Packit |
8480eb |
if (lv != table)
|
|
Packit |
8480eb |
lv = table;
|
|
Packit |
8480eb |
} else {
|
|
Packit |
8480eb |
struct substvar *new;
|
|
Packit |
8480eb |
const char *this = value ? value : "";
|
|
Packit |
8480eb |
char *def, *val;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
def = strdup(str);
|
|
Packit |
8480eb |
if (!def) {
|
|
Packit |
8480eb |
lv = table;
|
|
Packit |
8480eb |
goto done;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
def[len] = '\0';
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
val = strdup(this);
|
|
Packit |
8480eb |
if (!val) {
|
|
Packit |
8480eb |
lv = table;
|
|
Packit |
8480eb |
free(def);
|
|
Packit |
8480eb |
goto done;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
new = malloc(sizeof(struct substvar));
|
|
Packit |
8480eb |
if (!new) {
|
|
Packit |
8480eb |
lv = table;
|
|
Packit |
8480eb |
free(def);
|
|
Packit |
8480eb |
free(val);
|
|
Packit |
8480eb |
goto done;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
new->def = def;
|
|
Packit |
8480eb |
new->val = val;
|
|
Packit |
8480eb |
new->readonly = 0;
|
|
Packit |
8480eb |
new->next = table;
|
|
Packit |
8480eb |
lv = new;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
done:
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
return lv;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
void macro_global_removevar(const char *str, int len)
|
|
Packit |
8480eb |
{
|
|
Packit |
8480eb |
struct substvar *sv;
|
|
Packit |
8480eb |
struct substvar *last = NULL;
|
|
Packit |
8480eb |
int status;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
status = pthread_mutex_lock(&table_mutex);
|
|
Packit |
8480eb |
if (status)
|
|
Packit |
8480eb |
fatal(status);
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
sv = system_table;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
while (sv) {
|
|
Packit |
8480eb |
if (!strncmp(str, sv->def, len) && sv->def[len] == '\0')
|
|
Packit |
8480eb |
break;
|
|
Packit |
8480eb |
last = sv;
|
|
Packit |
8480eb |
sv = sv->next;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (sv && !sv->readonly) {
|
|
Packit |
8480eb |
if (last)
|
|
Packit |
8480eb |
last->next = sv->next;
|
|
Packit |
8480eb |
else
|
|
Packit |
8480eb |
system_table = sv->next;
|
|
Packit |
8480eb |
if (sv->def)
|
|
Packit |
8480eb |
free(sv->def);
|
|
Packit |
8480eb |
if (sv->val)
|
|
Packit |
8480eb |
free(sv->val);
|
|
Packit |
8480eb |
free(sv);
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
status = pthread_mutex_unlock(&table_mutex);
|
|
Packit |
8480eb |
if (status)
|
|
Packit |
8480eb |
fatal(status);
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
return;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
struct substvar *
|
|
Packit |
8480eb |
macro_removevar(struct substvar *table, const char *str, int len)
|
|
Packit |
8480eb |
{
|
|
Packit |
8480eb |
struct substvar *list, *lv;
|
|
Packit |
8480eb |
struct substvar *last = NULL;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
lv = list = table;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
while (lv) {
|
|
Packit |
8480eb |
if (!strncmp(str, lv->def, len) && lv->def[len] == '\0')
|
|
Packit |
8480eb |
break;
|
|
Packit |
8480eb |
last = lv;
|
|
Packit |
8480eb |
lv = lv->next;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (lv) {
|
|
Packit |
8480eb |
if (last)
|
|
Packit |
8480eb |
last->next = lv->next;
|
|
Packit |
8480eb |
else
|
|
Packit |
8480eb |
list = lv->next;
|
|
Packit |
8480eb |
if (lv->def)
|
|
Packit |
8480eb |
free(lv->def);
|
|
Packit |
8480eb |
if (lv->val)
|
|
Packit |
8480eb |
free(lv->val);
|
|
Packit |
8480eb |
free(lv);
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
return list;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
void macro_free_global_table(void)
|
|
Packit |
8480eb |
{
|
|
Packit |
8480eb |
struct substvar *sv;
|
|
Packit |
8480eb |
struct substvar *next;
|
|
Packit |
8480eb |
int status;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
status = pthread_mutex_lock(&table_mutex);
|
|
Packit |
8480eb |
if (status)
|
|
Packit |
8480eb |
fatal(status);
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
sv = system_table;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
while (sv) {
|
|
Packit |
8480eb |
if (sv->readonly) {
|
|
Packit |
8480eb |
sv = sv->next;
|
|
Packit |
8480eb |
continue;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
next = sv->next;
|
|
Packit |
8480eb |
if (sv->def)
|
|
Packit |
8480eb |
free(sv->def);
|
|
Packit |
8480eb |
if (sv->val)
|
|
Packit |
8480eb |
free(sv->val);
|
|
Packit |
8480eb |
free(sv);
|
|
Packit |
8480eb |
sv = next;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
system_table = &sv_osvers;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
status = pthread_mutex_unlock(&table_mutex);
|
|
Packit |
8480eb |
if (status)
|
|
Packit |
8480eb |
fatal(status);
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
return;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
void macro_free_table(struct substvar *table)
|
|
Packit |
8480eb |
{
|
|
Packit |
8480eb |
struct substvar *lv = table;
|
|
Packit |
8480eb |
struct substvar *next;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (!lv)
|
|
Packit |
8480eb |
return;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
while (lv) {
|
|
Packit |
8480eb |
next = lv->next;
|
|
Packit |
8480eb |
if (lv->def)
|
|
Packit |
8480eb |
free(lv->def);
|
|
Packit |
8480eb |
if (lv->val)
|
|
Packit |
8480eb |
free(lv->val);
|
|
Packit |
8480eb |
free(lv);
|
|
Packit |
8480eb |
lv = next;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
return;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
/* Find the $-variable matching a certain string fragment */
|
|
Packit |
8480eb |
const struct substvar *
|
|
Packit |
8480eb |
macro_findvar(const struct substvar *table, const char *str, int len)
|
|
Packit |
8480eb |
{
|
|
Packit |
8480eb |
const struct substvar *sv = system_table;
|
|
Packit |
8480eb |
const struct substvar *lv = table;
|
|
Packit |
8480eb |
#ifdef ENABLE_EXT_ENV
|
|
Packit |
8480eb |
/* holds one env var */
|
|
Packit |
8480eb |
static struct substvar *lv_var;
|
|
Packit |
8480eb |
static char *value;
|
|
Packit |
8480eb |
char etmp[512];
|
|
Packit |
8480eb |
#endif
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
/* First try the passed in local table */
|
|
Packit |
8480eb |
while (lv) {
|
|
Packit |
8480eb |
if (!strncmp(str, lv->def, len) && lv->def[len] == '\0')
|
|
Packit |
8480eb |
return lv;
|
|
Packit |
8480eb |
lv = lv->next;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
/* Then look in the system wide table */
|
|
Packit |
8480eb |
while (sv) {
|
|
Packit |
8480eb |
if (!strncmp(str, sv->def, len) && sv->def[len] == '\0')
|
|
Packit |
8480eb |
return sv;
|
|
Packit |
8480eb |
sv = sv->next;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
#ifdef ENABLE_EXT_ENV
|
|
Packit |
8480eb |
/* builtin and local map failed, try the $ENV */
|
|
Packit |
8480eb |
memcpy(etmp, str, len);
|
|
Packit |
8480eb |
etmp[len]='\0';
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if ((value=getenv(etmp)) != NULL) {
|
|
Packit |
8480eb |
lv_var = macro_addvar((struct substvar *) table, str, len, value);
|
|
Packit |
8480eb |
return(lv_var);
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
#endif
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
return NULL;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
/* Set environment from macro variable table */
|
|
Packit |
8480eb |
void macro_setenv(struct substvar *table)
|
|
Packit |
8480eb |
{
|
|
Packit |
8480eb |
const struct substvar *sv = system_table;
|
|
Packit |
8480eb |
const struct substvar *lv = table;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
/*
|
|
Packit |
8480eb |
* First set environment from global table, matching local
|
|
Packit |
8480eb |
* variables will overwrite these.
|
|
Packit |
8480eb |
*/
|
|
Packit |
8480eb |
while (sv) {
|
|
Packit |
8480eb |
if (sv->def)
|
|
Packit |
8480eb |
setenv(sv->def, sv->val, 1);
|
|
Packit |
8480eb |
sv = sv->next;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
/* Next set environment from the local table */
|
|
Packit |
8480eb |
while (lv) {
|
|
Packit |
8480eb |
if (lv->def)
|
|
Packit |
8480eb |
setenv(lv->def, lv->val, 1);
|
|
Packit |
8480eb |
lv = lv->next;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
return;
|
|
Packit |
8480eb |
}
|