/*
- * Copyright (C) 2013 Intel Corporation.
+ * Copyright (C) 2013-2014 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
#include <stdarg.h>
#include <alloca.h>
#include <pwd.h>
+#include <assert.h>
#ifndef NOT_MULTI_THREAD_SAFE
#include <pthread.h>
#include "foreign.h"
#include "scratch.h"
#include "passwd.h"
+#include "context.h"
+#include "hashing.h"
+#include "init.h"
#define _HAS_IDS_ ( _FOREIGN_HAS_(UID) \
|| _FOREIGN_HAS_(EUID) \
|| _FOREIGN_HAS_(EHOME) \
|| _FOREIGN_HAS_(EUSER) )
-#define _USER_NOT_SET_ ((uid_t)-1)
-
/* local and static variables */
static const char metafilepath[] = CONFIGPATH;
static const char emptystring[] = "";
-static const char *var_names[_TZPLATFORM_VARIABLES_COUNT_];
-
-enum STATE { RESET=0, ERROR, VALID };
-
-struct tzplatform_context {
-#ifndef NOT_MULTI_THREAD_SAFE
- pthread_mutex_t mutex;
-#endif
- enum STATE state;
- uid_t user;
- struct heap heap;
- const char *values[_TZPLATFORM_VARIABLES_COUNT_];
-};
/* structure for reading config files */
struct reading {
size_t offsets[_TZPLATFORM_VARIABLES_COUNT_];
};
-static struct tzplatform_context global_context = {
-#ifndef NOT_MULTI_THREAD_SAFE
- .mutex = PTHREAD_MUTEX_INITIALIZER,
-#endif
- .state = RESET,
- .user = _USER_NOT_SET_
-};
-
-#include "hash.inc"
-
/* write the error message */
static void writerror( const char *format, ...)
{
fprintf( stderr, "\n");
}
-static uid_t get_uid(struct tzplatform_context *context)
-{
- uid_t result;
-
- result = context->user;
- if (result == _USER_NOT_SET_)
- result = getuid();
-
- return result;
-}
-
-#if _FOREIGN_HAS_(EUID)
-static uid_t get_euid(struct tzplatform_context *context)
-{
- uid_t result;
-
- result = context->user;
- if (result == _USER_NOT_SET_)
- result = geteuid();
-
- return result;
-}
-#endif
-
-#if _FOREIGN_HAS_(GID)
-static gid_t get_gid(struct tzplatform_context *context)
-{
- return getgid();
-}
-#endif
-
#if _HAS_IDS_
/* fill the foreign variables for ids */
static void foreignid( struct reading *reading)
{
struct parsinfo info;
const char *result;
- const struct varassoc *vara;
size_t offset;
struct reading *reading = parsing->data;
+ int id;
/* try to find a tzplatform variable */
- vara = hashvar( key, length);
- if (vara) {
+ id = hashid(key, length);
+ if (id >= 0) {
/* found: try to use it */
- offset = reading->offsets[(int)vara->id];
+ offset = reading->offsets[id];
if (offset != HNULL)
result = heap_address( &reading->context->heap, offset);
else
size_t begin_pos, size_t end_pos)
{
struct parsinfo info;
- const struct varassoc *vara;
size_t offset;
char *string;
struct reading *reading = parsing->data;
+ int id;
/* try to find a tzplatform variable */
- vara = hashvar( key, key_length);
- if (vara) {
+ id = hashid( key, key_length);
+ if (id >= 0) {
/* check that the variable isn't already defined */
- offset = reading->offsets[(int)vara->id];
+ offset = reading->offsets[id];
if (offset != HNULL) {
reading->errcount++;
parse_utf8_info( parsing, &info, begin_pos);
}
else {
/* record the variable value */
- reading->offsets[(int)vara->id] = offset;
+ reading->offsets[id] = offset;
string = heap_address( &reading->context->heap, offset);
memcpy( string, value, value_length);
string[value_length] = 0;
}
/* initialize the environment */
-static void initialize(struct tzplatform_context *context)
+inline void initialize(struct tzplatform_context *context)
{
struct buffer buffer;
struct parsing parsing;
context->values[i] = heap_address( &context->heap, offset);
else
writerror( "the variable %s isn't defined in file %s",
- tzplatform_getname((enum tzplatform_variable)i), metafilepath);
+ keyname(i), metafilepath);
/* TODO undefined variable */;
}
context->state = VALID;
}
-inline static void lock(struct tzplatform_context *context)
-{
-#ifndef NOT_MULTI_THREAD_SAFE
- pthread_mutex_lock( &context->mutex);
-#endif
-}
-
-inline static void unlock(struct tzplatform_context *context)
-{
-#ifndef NOT_MULTI_THREAD_SAFE
- pthread_mutex_unlock( &context->mutex);
-#endif
-}
-
-static const char *get_lock(struct tzplatform_context *context, enum tzplatform_variable id)
-{
- const char *result;
- int offset;
-
- lock( context);
- offset = (int)id;
- if (offset < 0 || (int)_TZPLATFORM_VARIABLES_COUNT_ <= offset) {
- /*error("invalid id"); TODO*/
- result = NULL;
- }
- else {
- if (context->state == RESET)
- initialize( context);
- result = context->state == ERROR ? NULL : context->values[offset];
- }
- return result;
-}
-
-int tzplatform_context_create(struct tzplatform_context **result)
-{
- struct tzplatform_context *context;
-
- context = malloc( sizeof * context);
- *result = context;
- if (context == NULL)
- return -1;
-
- context->state = RESET;
- context->user = _USER_NOT_SET_;
-#ifndef NOT_MULTI_THREAD_SAFE
- pthread_mutex_init( &context->mutex, NULL);
-#endif
- return 0;
-}
-
-void tzplatform_context_destroy(struct tzplatform_context *context)
-{
- if (context->state == VALID)
- heap_destroy( &context->heap);
- context->state = ERROR;
- free( context);
-}
-
-void tzplatform_reset()
-{
- tzplatform_context_reset( &global_context);
-}
-
-void tzplatform_context_reset(struct tzplatform_context *context)
-{
- lock( context);
- if (context->state != RESET) {
- if (context->state == VALID)
- heap_destroy( &context->heap);
- context->state = RESET;
- }
- unlock( context);
-}
-
-int tzplatform_getcount()
-{
- return (int)_TZPLATFORM_VARIABLES_COUNT_;
-}
-
-const char* tzplatform_getname(enum tzplatform_variable id)
-{
- const struct varassoc *iter, *end;
- const char *result;
- int offset;
-
- offset = (int)id;
- if (offset < 0 || (int)_TZPLATFORM_VARIABLES_COUNT_ <= offset) {
- /*error("invalid id"); TODO*/
- result = NULL;
- }
- else {
- if (!var_names[0]) {
- iter = namassoc;
- end = iter + (sizeof namassoc / sizeof namassoc[0]);
- while (iter != end) {
- if (iter->offset >= 0)
- var_names[(int)iter->id] = varpool + iter->offset;
- iter++;
- }
- }
- result = var_names[offset];
- }
- return result;
-}
-
-enum tzplatform_variable tzplatform_getid(const char *name)
-{
- const struct varassoc *vara = hashvar( name, strlen(name));
- return vara ? vara->id : _TZPLATFORM_VARIABLES_INVALID_;
-}
-
-const char* tzplatform_getenv(enum tzplatform_variable id)
-{
- return tzplatform_context_getenv( &global_context, id);
-}
-
-const char* tzplatform_context_getenv(struct tzplatform_context *context, enum tzplatform_variable id)
-{
- const char *array[2];
- const char *result = get_lock( context, id);
- if (result != NULL) {
- array[0] = result;
- array[1] = NULL;
- result = scratchcat( 0, array);
- }
- unlock( context);
- return result;
-}
-
-int tzplatform_getenv_int(enum tzplatform_variable id)
-{
- return tzplatform_context_getenv_int( &global_context, id);
-}
-
-int tzplatform_context_getenv_int(struct tzplatform_context *context, enum tzplatform_variable id)
-{
- const char *value = get_lock( context, id);
- int result = value==NULL ? -1 : atoi(value);
- unlock( context);
- return result;
-}
-
-const char* tzplatform_mkstr(enum tzplatform_variable id, const char * str)
-{
- return tzplatform_context_mkstr( &global_context, id, str);
-}
-
-const char* tzplatform_context_mkstr(struct tzplatform_context *context, enum tzplatform_variable id, const char *str)
-{
- const char *array[3];
- const char *result = get_lock( context, id);
- if (result != NULL) {
- array[0] = result;
- array[1] = str;
- array[2] = NULL;
- result = scratchcat( 0, array);
- }
- unlock( context);
- return result;
-}
-
-const char* tzplatform_mkpath(enum tzplatform_variable id, const char * path)
-{
- return tzplatform_context_mkpath( &global_context, id, path);
-}
-
-const char* tzplatform_context_mkpath(struct tzplatform_context *context, enum tzplatform_variable id, const char *path)
-{
- const char *array[3];
- const char *result = get_lock( context, id);
- if (result != NULL) {
- array[0] = result;
- array[1] = path;
- array[2] = NULL;
- result = scratchcat( 1, array);
- }
- unlock( context);
- return result;
-}
-
-const char* tzplatform_mkpath3(enum tzplatform_variable id, const char * path,
- const char* path2)
-{
- return tzplatform_context_mkpath3( &global_context, id, path, path2);
-}
-
-const char* tzplatform_context_mkpath3(struct tzplatform_context *context, enum tzplatform_variable id, const char *path,
- const char *path2)
-{
- const char *array[4];
- const char *result = get_lock( context, id);
- if (result != NULL) {
- array[0] = result;
- array[1] = path;
- array[2] = path2;
- array[3] = NULL;
- result = scratchcat( 1, array);
- }
- unlock( context);
- return result;
-}
-
-const char* tzplatform_mkpath4(enum tzplatform_variable id, const char * path,
- const char* path2, const char *path3)
-{
- return tzplatform_context_mkpath4( &global_context, id, path, path2, path3);
-}
-
-const char* tzplatform_context_mkpath4(struct tzplatform_context *context, enum tzplatform_variable id, const char *path,
- const char *path2, const char *path3)
-{
- const char *array[5];
- const char *result = get_lock( context, id);
- if (result != NULL) {
- array[0] = result;
- array[1] = path;
- array[2] = path2;
- array[3] = path3;
- array[4] = NULL;
- result = scratchcat( 1, array);
- }
- unlock( context);
- return result;
-}
-
-uid_t tzplatform_getuid(enum tzplatform_variable id)
-{
- return tzplatform_context_getuid( &global_context, id);
-}
-
-uid_t tzplatform_context_getuid(struct tzplatform_context *context, enum tzplatform_variable id)
-{
- uid_t result = (uid_t)-1;
- const char *value = get_lock( context, id);
- if (value != NULL) {
- pw_get_uid( value, &result);
- }
- unlock( context);
- return result;
-}
-
-gid_t tzplatform_getgid(enum tzplatform_variable id)
-{
- return tzplatform_context_getgid( &global_context, id);
-}
-
-gid_t tzplatform_context_getgid(struct tzplatform_context *context, enum tzplatform_variable id)
-{
- gid_t result = (uid_t)-1;
- const char *value = get_lock( context, id);
- if (value != NULL) {
- pw_get_gid( value, &result);
- }
- unlock( context);
- return result;
-}
-
-int tzplatform_set_user(uid_t uid)
-{
- return tzplatform_context_set_user( &global_context, uid);
-}
-
-int tzplatform_context_set_user(struct tzplatform_context *context, uid_t uid)
-{
- int result;
-
- result = 0;
- lock( context);
- if (context->user != uid) {
- if (uid != _USER_NOT_SET_ && !pw_has_uid( uid))
- result = -1;
- else {
- if (context->state == VALID)
- heap_destroy( &context->heap);
- context->state = RESET;
- context->user = uid;
- }
- }
- unlock( context);
-
- return result;
-}
-
-uid_t tzplatform_get_user()
-{
- return tzplatform_context_get_user( &global_context);
-}
-
-uid_t tzplatform_context_get_user(struct tzplatform_context *context)
-{
- uid_t result;
-
- lock( context);
- result = get_uid( context);
- unlock( context);
-
- return result;
-}
-
-void tzplatform_reset_user()
-{
- tzplatform_context_reset_user( &global_context);
-}
-
-void tzplatform_context_reset_user(struct tzplatform_context *context)
-{
- tzplatform_context_set_user( context, _USER_NOT_SET_);
-}
-
-#ifdef TEST
-int main() {
- int i;
- struct tzplatform_context *context;
- enum tzplatform_variable id;
- const char *name;
- const char *value;
- int xid;
- uid_t uid;
-
- i = 0;
- while(i != tzplatform_getcount()) {
- id = (enum tzplatform_variable)i;
- name = tzplatform_getname(id);
- value = tzplatform_getenv(id);
- xid = (int)tzplatform_getid(name);
- printf("%d=%d\t%s=%s\n",i,xid,name,value?value:"<null>");
- i++;
- }
-
- printf("------------------------\n");
- i = tzplatform_context_create(&context);
- if (i) {
- printf("error while creating context %d\n",i);
- return 1;
- }
-
- uid = (uid_t)0;
- i = tzplatform_context_set_user(context, uid);
- if (i) {
- printf("error %d while switching to user %d\n",i,(int)uid);
- return 1;
- }
- i = 0;
- while(i != tzplatform_getcount()) {
- id = (enum tzplatform_variable)i;
- name = tzplatform_getname(id);
- value = tzplatform_context_getenv(context, id);
- xid = (int)tzplatform_getid(name);
- printf("%d=%d\t%s=%s\n",i,xid,name,value?value:"<null>");
- i++;
- }
- tzplatform_context_destroy(context);
-
- return 0;
-}
-#endif
-
-