#include <string.h>
#include <uuid/uuid.h>
#include <errno.h>
+#include <unistd.h>
#include "afb-session.h"
#include "afb-hook.h"
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 */
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);
}
{
afb_hook_session_destroy(session);
pthread_mutex_destroy(&session->mutex);
+ free(session->lang);
free(session);
}
{
int r;
- session_unlock(session);
+ session_lock(session);
r = !session->closed
&& session->expiration >= NOW
&& !(session->token[0] && strcmp (token, session->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);
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;
+}