X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fafb-session.c;h=2cfbff9981d7f5466461111f919bf06ea67d109c;hb=refs%2Fheads%2Fsandbox%2FDDTLK%2Fpakage;hp=16fc69bbccd574071c39a966c64fe7e52f3e8d25;hpb=4521c1e7ae5371ab9d639adc617d17fb4e8ded0c;p=src%2Fapp-framework-binder.git diff --git a/src/afb-session.c b/src/afb-session.c index 16fc69bb..2cfbff99 100644 --- a/src/afb-session.c +++ b/src/afb-session.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "afb-session.h" #include "afb-hook.h" @@ -59,11 +60,12 @@ struct cookie struct afb_session { struct afb_session *next; /**< link to the next */ - unsigned refcount; /**< external reference count of the session */ + unsigned refcount; /**< count of reference to the session */ int timeout; /**< timeout of the session */ time_t expiration; /**< expiration time of the token */ pthread_mutex_t mutex; /**< mutex of the session */ struct cookie *cookies[COOKIECOUNT]; /**< cookies of the session */ + char *lang; /**< current language setting for the session */ uint8_t closed: 1; /**< is the session closed ? */ uint8_t autoclose: 1; /**< close the session when unreferenced */ uint8_t notinset: 1; /**< session removed from the set of sessions */ @@ -106,7 +108,56 @@ static inline time_t time_now() static void new_uuid(char uuid[SIZEUUID]) { uuid_t newuuid; + +#if defined(USE_UUID_GENERATE) uuid_generate(newuuid); +#else + struct timespec ts; + static uint16_t pid; + static uint16_t counter; + static char state[32]; + static struct random_data rdata; + + int32_t x; + clock_gettime(CLOCK_MONOTONIC_RAW, &ts); + if (pid == 0) { + pid = (uint16_t)getpid(); + counter = (uint16_t)(ts.tv_nsec >> 8); + rdata.state = NULL; + initstate_r((((unsigned)pid) << 16) + ((unsigned)counter), + state, sizeof state, &rdata); + } + ts.tv_nsec ^= (long)ts.tv_sec; + if (++counter == 0) + counter = 1; + + newuuid[0] = (char)(ts.tv_nsec >> 24); + newuuid[1] = (char)(ts.tv_nsec >> 16); + newuuid[2] = (char)(ts.tv_nsec >> 8); + newuuid[3] = (char)(ts.tv_nsec); + + newuuid[4] = (char)(pid >> 8); + newuuid[5] = (char)(pid); + + random_r(&rdata, &x); + newuuid[6] = (char)(((x >> 16) & 0x0f) | 0x40); /* pseudo-random version */ + newuuid[7] = (char)(x >> 8); + + random_r(&rdata, &x); + newuuid[8] = (char)(((x >> 16) & 0x3f) | 0x80); /* variant RFC4122 */ + newuuid[9] = (char)(x >> 8); + + random_r(&rdata, &x); + newuuid[10] = (char)(x >> 16); + newuuid[11] = (char)(x >> 8); + + random_r(&rdata, &x); + newuuid[12] = (char)(x >> 16); + newuuid[13] = (char)(x >> 8); + + newuuid[14] = (char)(counter >> 8); + newuuid[15] = (char)(counter); +#endif uuid_unparse_lower(newuuid, uuid); } @@ -209,6 +260,7 @@ static void session_destroy (struct afb_session *session) { afb_hook_session_destroy(session); pthread_mutex_destroy(&session->mutex); + free(session->lang); free(session); } @@ -524,7 +576,7 @@ int afb_session_check_token (struct afb_session *session, const char *token) { int r; - session_unlock(session); + session_lock(session); r = !session->closed && session->expiration >= NOW && !(session->token[0] && strcmp (token, session->token)); @@ -535,7 +587,7 @@ int afb_session_check_token (struct afb_session *session, const char *token) /* generate a new token and update client context */ void afb_session_new_token (struct afb_session *session) { - session_unlock(session); + session_lock(session); new_uuid(session->token); session_update_expiration(session, NOW); afb_hook_session_renew(session); @@ -688,3 +740,37 @@ int afb_session_set_cookie(struct afb_session *session, const void *key, void *v return -(value != afb_session_cookie(session, key, NULL, freecb, value, 1)); } +/** + * Set the language attached to the session + * + * @param session the session to set + * @param lang the language specifiction to set to session + * + * @return 0 in case of success or -1 in case of error + */ +int afb_session_set_language(struct afb_session *session, const char *lang) +{ + char *oldl, *newl; + + newl = strdup(lang); + if (newl == NULL) + return -1; + + oldl = session->lang; + session->lang = newl; + free(oldl); + return 0; +} + +/** + * Get the language attached to the session + * + * @param session the session to query + * @param lang a default language specifiction + * + * @return the langauage specification to use for session + */ +const char *afb_session_get_language(struct afb_session *session, const char *lang) +{ + return session->lang ?: lang; +}