/* align to a page size */
inline static size_t pagealign( size_t size)
{
+ static size_t pagemask = 0;
/* we assume that pagesize is a power of 2 */
- size_t pagemask = (size_t)sysconf(_SC_PAGE_SIZE) - 1;
- assert( (pagemask & (pagemask+1)) == 0 );
+ if (!pagemask) {
+ pagemask = (size_t)sysconf(_SC_PAGE_SIZE) - 1;
+ assert( pagemask );
+ assert( (pagemask & (pagemask+1)) == 0 );
+ }
return (size + pagemask) & ~pagemask;
}
return result;
}
+int pw_has_uid( uid_t uid)
+{
+ if (oppw() == 0) {
+ while (rdpw()) {
+ if (lengths[iuid] && (int)uid == atoi(starts[iuid])) {
+ clpw();
+ return 1;
+ }
+ }
+ clpw();
+ }
+ return 0;
+}
+
int pw_get_uid( const char *name, uid_t *uid)
{
int result = oppw();
return 0;
}
+int pw_has_uid( uid_t uid)
+{
+ char buffer[BUFSIZE];
+ struct passwd entry, *pe;
+ int result;
+
+ result = getpwuid_r( uid, &entry, buffer, sizeof buffer, &pe);
+ return !result && pe;
+}
+
int pw_get_uid( const char *name, uid_t *uid)
{
char buffer[BUFSIZE];
int pw_get( struct heap *heap, struct pwget **items);
int pw_get_uid( const char *name, uid_t *uid);
int pw_get_gid( const char *name, gid_t *gid);
+int pw_has_uid( uid_t uid);
#endif
#define INSTANCIATE 1
#if INSTANCIATE
-#define SET_CAPACITY 97
+#define SET_CAPACITY 97
#define HASHCODE_INIT 5381
#define HASHCODE_NEXT(H,C) (((H) << 5) + (H) + (C))
-#ifndef NOT_MULTI_THREAD_SAFE
-#define NOT_MULTI_THREAD_SAFE
-#endif
#endif
#ifndef NOT_MULTI_THREAD_SAFE
#include <pthread.h>
-static pthread_key_t tlskey;
-static int key_initialized = 0;
+#endif
+
+#if !(defined(NOT_MULTI_THREAD_SAFE) || INSTANCIATE)
+static __thread void *global_scratch = NULL;
#else
static void *global_scratch = NULL;
#endif
+#if INSTANCIATE && !defined(NOT_MULTI_THREAD_SAFE)
+static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+#endif
#if INSTANCIATE
/* structure for recording items in the hash map */
struct set_item {
- struct set_item *next; /* chain to next item */
- size_t hashcode; /* hash of the string */
- size_t length; /* length of the string including null */
+ struct set_item *next; /* chain to next item */
+ size_t hashcode; /* hash of the string */
+ size_t length; /* length of the string including null */
};
/* the array of recorded strings */
hash code 'hashcode' */
static const char *instantiate(const char *string, size_t length, size_t hashcode)
{
- struct set_item **pp, *item;
- char *result;
-
- /* get first item in the table */
- pp = &global_path_set[hashcode % SET_CAPACITY];
- result = 0;
- do {
- /* inspect the item */
- item = *pp;
- if (!item) {
- /* no item: create it */
- item = malloc(length + sizeof * item);
- if (!item)
- return NULL;
- /* init it */
- item->next = 0;
- item->hashcode = hashcode;
- item->length = length;
- result = (char *)(item + 1);
- memcpy(result, string, length);
- /* record it */
- *pp = item;
- } else if (item->hashcode == hashcode
- && item->length == length
- && 0 == strcmp(string, (const char *)(item + 1))) {
- /* item found */
- result = (char *)(item + 1);
- } else {
- /* try the next */
- pp = &item->next;
- }
- } while (!result);
-
- return result;
+ struct set_item **pp, *item;
+ char *result;
+
+ /* get first item in the table */
+ pp = &global_path_set[hashcode % SET_CAPACITY];
+ result = 0;
+ do {
+ /* inspect the item */
+ item = *pp;
+ if (!item) {
+ /* no item: create it */
+ item = malloc(length + sizeof * item);
+ if (!item)
+ return NULL;
+ /* init it */
+ item->next = 0;
+ item->hashcode = hashcode;
+ item->length = length;
+ result = (char *)(item + 1);
+ memcpy(result, string, length);
+ /* record it */
+ *pp = item;
+ } else if (item->hashcode == hashcode
+ && item->length == length
+ && 0 == strcmp(string, (const char *)(item + 1))) {
+ /* item found */
+ result = (char *)(item + 1);
+ } else {
+ /* try the next */
+ pp = &item->next;
+ }
+ } while (!result);
+
+ return result;
}
#endif
If it is not the case please check for initializing 'tlskey'
only one time before use of it. */
+#if INSTANCIATE && !defined(NOT_MULTI_THREAD_SAFE)
+static const char *_scratchcat( int ispath, const char **strings);
+
const char *scratchcat( int ispath, const char **strings)
{
+ const char *result;
+ pthread_mutex_lock(&mutex);
+ result = _scratchcat( ispath, strings);
+ pthread_mutex_unlock(&mutex);
+ return result;
+}
+
+static const char *_scratchcat( int ispath, const char **strings)
+#else
+const char *scratchcat( int ispath, const char **strings)
+#endif
+{
void *scratch, *p;
char *result;
size_t length, capacity;
const char *instr;
char c, pc;
#if INSTANCIATE
- size_t hashcode = HASHCODE_INIT;
+ size_t hashcode = HASHCODE_INIT;
#endif
/* get the recorded pointer on scrtch area */
-#ifndef NOT_MULTI_THREAD_SAFE
- if (!key_initialized) {
- key_initialized = 1;
- pthread_key_create( &tlskey, (void(*)(void*))free);
- }
- scratch = pthread_getspecific( tlskey);
-#else
scratch = global_scratch;
-#endif
/* create the scratch area if needed */
if (scratch == NULL) {
return NULL;
*((size_t*)p) = capacity;
scratch = p;
-#ifndef NOT_MULTI_THREAD_SAFE
- pthread_setspecific( tlskey, p);
-#else
global_scratch = p;
-#endif
}
/* set local data for scratch area */
*((size_t*)p) = capacity;
if (p != scratch) {
scratch = p;
-#ifndef NOT_MULTI_THREAD_SAFE
- pthread_setspecific( tlskey, p);
-#else
global_scratch = p;
-#endif
result = (char*)(1+((size_t*)p));
}
}
/* append the char */
pc = result[length++] = c;
#if INSTANCIATE
- hashcode = HASHCODE_NEXT(hashcode, (size_t)c);
+ hashcode = HASHCODE_NEXT(hashcode, (size_t)c);
#endif
}
#if INSTANCIATE
- return instantiate(result, length, hashcode);
+ return instantiate(result, length, hashcode);
#else
return result;
#endif
int ispath, iter, i;
argv++;
ispath = argv[0] && argv[0][0] == '-' && argv[0][1] == 'p';
- for (i = 0 ; i < 2 ; i++) {
- iter = ispath;
- while (iter < argc) {
- const char *p = scratchcat(ispath,argv+iter++);
- printf("%p: %s\n",p,p);
- }
- }
+ for (i = 0 ; i < 2 ; i++) {
+ iter = ispath;
+ while (iter < argc) {
+ const char *p = scratchcat(ispath,argv+iter++);
+ printf("%p: %s\n",p,p);
+ }
+ }
return 0;
}
#endif
#ifndef NOT_MULTI_THREAD_SAFE
#include <pthread.h>
-static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-static inline void lock() { pthread_mutex_lock(&mutex); }
-static inline void unlock() { pthread_mutex_unlock(&mutex); }
-#else
-static inline void lock() { }
-static inline void unlock() { }
#endif
#ifndef CONFIGPATH
|| _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 {
int errcount;
+ struct tzplatform_context *context;
size_t dynvars[_FOREIGN_COUNT_];
size_t offsets[_TZPLATFORM_VARIABLES_COUNT_];
};
-/* local and static variables */
-static const char metafilepath[] = CONFIGPATH;
-static const char emptystring[] = "";
-static struct heap heap;
-static enum { RESET=0, ERROR, VALID } state = RESET;
-static const char *var_values[_TZPLATFORM_VARIABLES_COUNT_];
-static const char *var_names[_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"
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)
#if _FOREIGN_HAS_(UID)
/* set the uid */
if (reading->dynvars[UID] == HNULL) {
- n = snprintf( buffer, sizeof buffer, "%d", (int)getuid());
+ n = snprintf( buffer, sizeof buffer, "%d", (int)get_uid(reading->context));
if (0 < n && n < (int)(sizeof buffer))
- reading->dynvars[UID] = heap_strndup( &heap, buffer, (size_t)n);
+ reading->dynvars[UID] = heap_strndup( &reading->context->heap, buffer, (size_t)n);
}
#endif
#if _FOREIGN_HAS_(EUID)
/* set the euid */
if (reading->dynvars[EUID] == HNULL) {
- n = snprintf( buffer, sizeof buffer, "%d", (int)geteuid());
+ n = snprintf( buffer, sizeof buffer, "%d", (int)get_euid(reading->context));
if (0 < n && n < (int)(sizeof buffer))
- reading->dynvars[EUID] = heap_strndup( &heap, buffer, (size_t)n);
+ reading->dynvars[EUID] = heap_strndup( &reading->context->heap, buffer, (size_t)n);
}
#endif
#if _FOREIGN_HAS_(GID)
/* set the gid */
if (reading->dynvars[GID] == HNULL) {
- n = snprintf( buffer, sizeof buffer, "%d", (int)getgid());
+ n = snprintf( buffer, sizeof buffer, "%d", (int)get_gid(reading->context));
if (0 < n && n < (int)(sizeof buffer))
- reading->dynvars[GID] = heap_strndup( &heap, buffer, (size_t)n);
+ reading->dynvars[GID] = heap_strndup( &reading->context->heap, buffer, (size_t)n);
}
#endif
}
reading->dynvars[USER] == HNULL
#endif
) {
- snprintf( suid, sizeof suid, "%u", (unsigned)getuid());
+ snprintf( suid, sizeof suid, "%u", (unsigned)get_uid(reading->context));
uid.id = suid;
array[n++] = &uid;
}
reading->dynvars[EUSER] == HNULL
#endif
) {
- snprintf( seuid, sizeof seuid, "%u", (unsigned)geteuid());
+ snprintf( seuid, sizeof seuid, "%u", (unsigned)get_euid(reading->context));
euid.id = seuid;
array[n++] = &euid;
}
if (n) {
array[n] = NULL;
- if (pw_get( &heap, array) == 0) {
+ if (pw_get( &reading->context->heap, array) == 0) {
#if _FOREIGN_HAS_(HOME)
if (uid.set)
reading->dynvars[HOME] = uid.home;
return NULL;
}
offset = reading->dynvars[key];
- return offset==HNULL ? NULL : heap_address( &heap, offset);
+ return offset==HNULL ? NULL : heap_address( &reading->context->heap, offset);
}
/* callback for parsing errors */
/* found: try to use it */
offset = reading->offsets[(int)vara->id];
if (offset != HNULL)
- result = heap_address( &heap, offset);
+ result = heap_address( &reading->context->heap, offset);
else
result = NULL;
}
}
/* allocate the variable value */
- offset = heap_alloc( &heap, value_length+1);
+ offset = heap_alloc( &reading->context->heap, value_length+1);
if (offset == HNULL) {
/* error of allocation */
reading->errcount++;
else {
/* record the variable value */
reading->offsets[(int)vara->id] = offset;
- string = heap_address( &heap, offset);
+ string = heap_address( &reading->context->heap, offset);
memcpy( string, value, value_length);
string[value_length] = 0;
}
}
/* initialize the environment */
-static void initialize()
+static void initialize(struct tzplatform_context *context)
{
struct buffer buffer;
struct parsing parsing;
/* clear the variables */
reading.errcount = 0;
+ reading.context = context;
for (i = 0 ; i < (int)_FOREIGN_COUNT_ ; i++) {
reading.dynvars[i] = HNULL;
}
for (i = 0 ; i < (int)_TZPLATFORM_VARIABLES_COUNT_ ; i++) {
- var_values[i] = NULL;
+ context->values[i] = NULL;
reading.offsets[i] = HNULL;
}
result = buffer_create( &buffer, metafilepath);
if (result != 0) {
writerror( "can't read file %s",metafilepath);
- state = ERROR;
+ context->state = ERROR;
return;
}
/* create the heap */
- result = heap_create( &heap, 1);
+ result = heap_create( &context->heap, 1);
if (result != 0) {
buffer_destroy( &buffer);
writerror( "out of memory");
- state = ERROR;
+ context->state = ERROR;
return;
}
}
/* set the variables */
- heap_read_only( &heap);
+ heap_read_only( &context->heap);
for (i = 0 ; i < (int)_TZPLATFORM_VARIABLES_COUNT_ ; i++) {
offset = reading.offsets[i];
if (offset != HNULL)
- var_values[i] = heap_address( &heap, offset);
+ 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);
/* TODO undefined variable */;
}
- state = VALID;
+ 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(enum tzplatform_variable id)
+static const char *get_lock(struct tzplatform_context *context, enum tzplatform_variable id)
{
const char *result;
int offset;
- lock();
+ lock( context);
offset = (int)id;
if (offset < 0 || (int)_TZPLATFORM_VARIABLES_COUNT_ <= offset) {
/*error("invalid id"); TODO*/
result = NULL;
}
else {
- if (state == RESET)
- initialize();
- result = var_values[offset];
+ if (context->state == RESET)
+ initialize( context);
+ result = context->state == ERROR ? NULL : context->values[offset];
}
return result;
}
-/* reset the state of the environement */
+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()
{
- lock();
- if (state != RESET) {
- if (state == VALID)
- heap_destroy( &heap);
- state = 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();
+ unlock( context);
}
int tzplatform_getcount()
const char* tzplatform_getenv(enum tzplatform_variable id)
{
- const char *result = get_lock( id);
- unlock();
+ 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)
{
- const char *value = get_lock( 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();
+ 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( id);
+ const char *result = get_lock( context, id);
if (result != NULL) {
array[0] = result;
array[1] = str;
array[2] = NULL;
result = scratchcat( 0, array);
}
- unlock();
+ 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( id);
+ const char *result = get_lock( context, id);
if (result != NULL) {
array[0] = result;
array[1] = path;
array[2] = NULL;
result = scratchcat( 1, array);
}
- unlock();
+ 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( id);
+ const char *result = get_lock( context, id);
if (result != NULL) {
array[0] = result;
array[1] = path;
array[3] = NULL;
result = scratchcat( 1, array);
}
- unlock();
+ 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( id);
+ const char *result = get_lock( context, id);
if (result != NULL) {
array[0] = result;
array[1] = path;
array[4] = NULL;
result = scratchcat( 1, array);
}
- unlock();
+ 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( id);
+ const char *value = get_lock( context, id);
if (value != NULL) {
pw_get_uid( value, &result);
}
- unlock();
+ 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( id);
+ const char *value = get_lock( context, id);
if (value != NULL) {
pw_get_gid( value, &result);
}
- unlock();
+ 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 = 0;
- while(i != (int)_TZPLATFORM_VARIABLES_COUNT_) {
- enum tzplatform_variable id = (enum tzplatform_variable)i;
- const char*name = tzplatform_getname(id);
- const char*value = tzplatform_getenv(id);
- int xid = (int)tzplatform_getid(name);
- printf("%d=%d\t%s=%s\n",i,xid,name,value);
+ 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
+
+
/*
* Copyright (C) 2013 Intel Corporation.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
#include <sys/types.h>
#include <tzplatform_variables.h>
-/*
- Enforces the removal of the previously evaluated tizen platform variables.
-
- Call this function in case of changing of user inside the application.
-*/
-extern
-void tzplatform_reset();
+/*------------------------------ COMMON API (no context) ---------------*/
/*
Return the count of variables.
/*
Return the id of the variable of 'name'.
- Return _TZPLATFORM_VARIABLES_INVALID_ if 'name' doesn't match a
+ Return _TZPLATFORM_VARIABLES_INVALID_ if 'name' doesn't match a
valid variable name.
*/
extern
enum tzplatform_variable tzplatform_getid(const char *name);
+/*------------------------------ GLOBAL API (default global context) ----*/
+
+/*
+ Enforces the removal of the previously evaluated tizen platform variables.
+
+ Call this function in case of changing of user inside the application.
+*/
+extern
+void tzplatform_reset();
+
+/*
+ Set the user used for UID/EUID/USER/EUSER computations.
+ Using uid==(uid_t)-1 reset the context as if tzplatform_reset_user
+ was called.
+
+ Returns 0 if uid is valid or -1 if not valid.
+*/
+extern
+int tzplatform_set_user(uid_t uid);
+
+/*
+*/
+extern
+uid_t tzplatform_get_user();
+
+/*
+ Reset the user context to use the values returned by
+ getuid and geteuid.
+*/
+extern
+void tzplatform_reset_user();
+
/*
Return the read-only string value of the tizen plaform variable 'id'.
- The tizen global values are globals to the application.
+
+ The returned value is an allocated unique string that MUST not be freed.
+
Can return NULL in case of internal error or when 'id' isn't defined.
*/
extern
int tzplatform_getenv_int(enum tzplatform_variable id);
/*
- Return the string resulting of the concatenation of string value of the
+ Return the string resulting of the concatenation of string value of the
tizen plaform variable 'id' and the given string 'str'.
The returned value is an allocated unique string that MUST not be freed.
Example:
if TZ_SYS_HOME == "/opt/home" then calling
- tzplatform_mkstr(TZ_SYS_HOME,"-yes")
+ tzplatform_mkstr(TZ_SYS_HOME,"-yes")
will return "/opt/home-yes"
*/
const char* tzplatform_mkstr(enum tzplatform_variable id, const char *str);
/*
- Return the string resulting of the path-concatenation of string value of the
+ Return the string resulting of the path-concatenation of string value of the
tizen plaform variable 'id' and the given string 'path'.
path-concatenation is the concatenation taking care of / characters.
Example:
if TZ_SYS_HOME == "/opt/home" then calling
- tzplatform_mkpath(TZ_SYS_HOME,"yes")
+ tzplatform_mkpath(TZ_SYS_HOME,"yes")
will return "/opt/home/yes"
*/
const char* tzplatform_mkpath(enum tzplatform_variable id, const char *path);
/*
- Return the string resulting of the path-concatenation of string value of the
+ Return the string resulting of the path-concatenation of string value of the
tizen plaform variable 'id' and the given strings 'path' and 'path2'.
path-concatenation is the concatenation taking care of / characters.
will return "/opt/home/yes/no"
*/
extern
-const char* tzplatform_mkpath3(enum tzplatform_variable id, const char *path,
+const char* tzplatform_mkpath3(enum tzplatform_variable id, const char *path,
const char *path2);
/*
- Return the string resulting of the path-concatenation of string value of the
+ Return the string resulting of the path-concatenation of string value of the
tizen plaform variable 'id' and the given strings 'path', 'path2' and 'path3'.
path-concatenation is the concatenation taking care of / characters.
will return "/opt/home/yes/no/maybe"
*/
extern
-const char* tzplatform_mkpath4(enum tzplatform_variable id, const char *path,
+const char* tzplatform_mkpath4(enum tzplatform_variable id, const char *path,
const char *path2, const char *path3);
/*
Retun -1 in case of error.
Example:
- if TZ_USER_NAME=="app" then calling:
-
- tzplatform_getuid(TZ_USER_NAME)
-
- will return the uid of the user 'app'
+ if TZ_USER_NAME=="app" then calling:
+
+ tzplatform_getuid(TZ_USER_NAME)
+
+ will return the uid of the user 'app'
*/
extern
uid_t tzplatform_getuid(enum tzplatform_variable id);
Retun -1 in case of error.
Example:
- if TZ_USER_GROUP=="app" then calling:
-
- tzplatform_getuid(TZ_USER_GROUP)
-
- will return the gid of the group 'app'
+ if TZ_USER_GROUP=="app" then calling:
+
+ tzplatform_getuid(TZ_USER_GROUP)
+
+ will return the gid of the group 'app'
*/
extern
gid_t tzplatform_getgid(enum tzplatform_variable id);
+/*------------------------------ CONTEXTUAL API --------------------------*/
+
+struct tzplatform_context;
+
+/*
+ Creates a new platform 'context'.
+ Return 0 in case of success or a negative value in case of error.
+*/
+extern
+int tzplatform_context_create(struct tzplatform_context **context);
+
+/*
+ Destroys the platform 'context' previously created with 'tzplatform_context_create'.
+ The destroyed context must not be used after calling this function.
+*/
+extern
+void tzplatform_context_destroy(struct tzplatform_context *context);
+
+/*
+ Enforces the removal of the previously evaluated tizen platform variables.
+
+ Call this function in case of changing of user inside the application.
+*/
+extern
+void tzplatform_context_reset(struct tzplatform_context *context);
+
+/*
+ Set the user used for UID/EUID/USER/EUSER computations.
+ Using uid==(uid_t)-1 reset the context as if tzplatform_context_reset_user
+ was called.
+
+ Returns 0 if uid is valid or -1 if not valid.
+*/
+extern
+int tzplatform_context_set_user(struct tzplatform_context *context, uid_t uid);
+
+/*
+*/
+extern
+uid_t tzplatform_context_get_user(struct tzplatform_context *context);
+
+/*
+ Reset the user context to use the values returned by
+ getuid and geteuid.
+*/
+extern
+void tzplatform_context_reset_user(struct tzplatform_context *context);
+
+/*
+ Return the read-only string value of the tizen plaform variable 'id'.
+
+ The returned value is an allocated unique string that MUST not be freed.
+
+ Can return NULL in case of internal error or when 'id' isn't defined.
+*/
+extern
+const char* tzplatform_context_getenv(struct tzplatform_context *context, enum tzplatform_variable id);
+
+/*
+ Return the integer value of the tizen plaform variable 'id'.
+*/
+extern
+int tzplatform_context_getenv_int(struct tzplatform_context *context, enum tzplatform_variable id);
+
+/*
+ Return the string resulting of the concatenation of string value of the
+ tizen plaform variable 'id' and the given string 'str'.
+
+ The returned value is an allocated unique string that MUST not be freed.
+
+ Can return NULL in case of internal error.
+
+ Example:
+ if TZ_SYS_HOME == "/opt/home" then calling
+
+ tzplatform_context_mkstr(context, TZ_SYS_HOME,"-yes")
+
+ will return "/opt/home-yes"
+*/
+extern
+const char* tzplatform_context_mkstr(struct tzplatform_context *context, enum tzplatform_variable id, const char *str);
+
+/*
+ Return the string resulting of the path-concatenation of string value of the
+ tizen plaform variable 'id' and the given string 'path'.
+
+ path-concatenation is the concatenation taking care of / characters.
+
+ The returned value is an allocated unique string that MUST not be freed.
+
+ Can return NULL in case of internal error.
+
+ Example:
+ if TZ_SYS_HOME == "/opt/home" then calling
+
+ tzplatform_context_mkpath(context, TZ_SYS_HOME,"yes")
+
+ will return "/opt/home/yes"
+*/
+extern
+const char* tzplatform_context_mkpath(struct tzplatform_context *context, enum tzplatform_variable id, const char *path);
+
+/*
+ Return the string resulting of the path-concatenation of string value of the
+ tizen plaform variable 'id' and the given strings 'path' and 'path2'.
+
+ path-concatenation is the concatenation taking care of / characters.
+
+ The returned value is an allocated unique string that MUST not be freed.
+
+ Can return NULL in case of internal error.
+
+ Example:
+ if TZ_SYS_HOME == "/opt/home" then calling
+
+ tzplatform_context_mkpath3(context, TZ_SYS_HOME,"yes","no")
+
+ will return "/opt/home/yes/no"
+*/
+extern
+const char* tzplatform_context_mkpath3(struct tzplatform_context *context, enum tzplatform_variable id, const char *path,
+ const char *path2);
+
+/*
+ Return the string resulting of the path-concatenation of string value of the
+ tizen plaform variable 'id' and the given strings 'path', 'path2' and 'path3'.
+
+ path-concatenation is the concatenation taking care of / characters.
+
+ The returned value is an allocated unique string that MUST not be freed.
+
+ Can return NULL in case of internal error.
+
+ Example:
+ if TZ_SYS_HOME == "/opt/home" then calling
+
+ tzplatform_context_mkpath4(context, TZ_SYS_HOME,"yes","no","/maybe")
+
+ will return "/opt/home/yes/no/maybe"
+*/
+extern
+const char* tzplatform_context_mkpath4(struct tzplatform_context *context, enum tzplatform_variable id, const char *path,
+ const char *path2, const char *path3);
+
+/*
+ Return the uid for a given user name, stored in variable <id>
+ Retun -1 in case of error.
+
+ Example:
+ if TZ_USER_NAME=="app" then calling:
+
+ tzplatform_context_getuid(context, TZ_USER_NAME)
+
+ will return the uid of the user 'app'
+*/
+extern
+uid_t tzplatform_context_getuid(struct tzplatform_context *context, enum tzplatform_variable id);
+
+/*
+ Return the gid for a given group name, stored in variable <id>
+ Retun -1 in case of error.
+
+ Example:
+ if TZ_USER_GROUP=="app" then calling:
+
+ tzplatform_context_getuid(context, TZ_USER_GROUP)
+
+ will return the gid of the group 'app'
+*/
+extern
+gid_t tzplatform_context_getgid(struct tzplatform_context *context, enum tzplatform_variable id);
+
#ifdef __cplusplus
}
#endif
-#endif // _LIBTIZEN-PLATFORM-WRAPPER
+#endif /* LIBTIZEN_PLATFORM_WRAPPER */
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/types.h>
+#include <pwd.h>
#include <tzplatform_config.h>
-s --space separate with spaces instead of new-lines\n\
-q --query silently check that given variables are existing\n\
-c --continue continue to process if error\n\
+-u --user id set the user using its 'id' (name or numeric)\n\
\n\
";
int main(int argc, char **argv)
{
- char *progname = *argv++;
+ char *progname = *argv++, *user = 0;
int all = 0, not = 0, query = 0, export = 0, space = 0, list = 0, cont = 0;
int i, n, *sel, p;
enum tzplatform_variable id;
+ struct passwd *spw;
/* parse args */
while(*argv && **argv=='-') {
case 'l': x = "list"; break;
case 'c': x = "continue"; break;
case 'h': x = "help"; break;
+ case 'u': x = "user"; break;
}
if (!x || strcmp(x,opt))
c = 0;
case 's': space = 1; break;
case 'l': list = 1; break;
case 'c': cont = 1; break;
+ case 'u': user = *argv; if (user) argv++; break;
case 'h':
fprintf( stdout, help, basename(progname));
return 0;
if (query)
return 0;
+ /* set the user */
+ if (user) {
+ for (i=0 ; '0' <= user[i] && user[i] <= '9' ; i++);
+ if (user[i])
+ spw = getpwnam(user);
+ else
+ spw = getpwuid((uid_t)atoi(user));
+ if (!spw) {
+ fprintf( stderr, "error! %s isn't standing for a valid user.\n", user);
+ if (!cont)
+ return 1;
+ } else {
+ i = tzplatform_set_user(spw->pw_uid);
+ if (i) {
+ fprintf( stderr, "error! can't set the valid user %s.\n", user);
+ if (!cont)
+ return 1;
+ }
+ }
+ }
+
/* emits the result */
for (p = i = 0 ; i < n ; i++) {
if (sel[i] != not) {