portal_user/src/sessions.h

227 lines
5.7 KiB
C

#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include <string.h>
#include <time.h>
struct session_s {
char *session_id;
char *user;
struct session_s *next;
};
typedef struct session_s session_t;
struct hashtable_s {
int size;
struct session_s **table;
};
typedef struct hashtable_s hashtable_t;
static hashtable_t *ht_create( int size );
static int ht_hash( hashtable_t *hashtable, char *session_id );
static session_t *ht_newpair( char *session_id, char *user );
static session_t *ht_get( hashtable_t *hashtable, char *session_id );
static void ht_set( hashtable_t *hashtable, char *session_id, char *user );
static void ht_delete (hashtable_t *hashtable, char *key);
static char *gen_session_id(int len);
static char *set_cookie_header( const char *champ, const char separator,
const char *session_id);
/* Create a new hashtable. */
hashtable_t *ht_create( int size ) {
hashtable_t *hashtable = NULL;
int i;
if( size < 1 ) return NULL;
/* Allocate the table itself. */
if( ( hashtable = malloc( sizeof( hashtable_t ) ) ) == NULL ) {
return NULL;
}
/* Allocate pointers to the head nodes. */
if( ( hashtable->table = malloc( sizeof( session_t * ) * size ) ) == NULL ) {
return NULL;
}
for( i = 0; i < size; i++ ) {
hashtable->table[i] = NULL;
}
hashtable->size = size;
return hashtable;
}
/* Hash a string for a particular hash table. */
int ht_hash( hashtable_t *hashtable, char *session_id ) {
unsigned long int hashval = 0;
int i = 0;
/* Convert our string to an integer */
while( hashval < ULONG_MAX && i < strlen( session_id ) ) {
hashval = hashval << 8;
hashval += session_id[ i ];
i++;
}
return hashval % hashtable->size;
}
/* Create a key-value pair. */
session_t *ht_newpair( char *session_id, char *user ) {
session_t *newpair;
if( ( newpair = malloc( sizeof( session_t ) ) ) == NULL ) {
return NULL;
}
if( ( newpair->session_id = strdup( session_id ) ) == NULL ) {
return NULL;
}
if( ( newpair->user = strdup( user ) ) == NULL ) {
return NULL;
}
newpair->next = NULL;
return newpair;
}
/* Insert a key-value pair into a hash table. */
static void ht_set( hashtable_t *hashtable, char *session_id, char *user ) {
int bin = 0;
session_t *newpair = NULL;
session_t *next = NULL;
session_t *last = NULL;
bin = ht_hash( hashtable, session_id );
next = hashtable->table[ bin ];
while( next != NULL && next->session_id != NULL && strcmp( session_id, next->session_id ) > 0 ) {
last = next;
next = next->next;
}
/* There's already a pair. Let's replace that string. */
if( next != NULL && next->session_id != NULL && strcmp( session_id, next->session_id ) == 0 ) {
free( next->user );
next->user = strdup( user );
/* Nope, could't find it. Time to grow a pair. */
} else {
newpair = ht_newpair( session_id, user );
/* We're at the start of the linked list in this bin. */
if( next == hashtable->table[ bin ] ) {
newpair->next = next;
hashtable->table[ bin ] = newpair;
/* We're at the end of the linked list in this bin. */
} else if ( next == NULL ) {
last->next = newpair;
/* We're in the middle of the list. */
} else {
newpair->next = next;
last->next = newpair;
}
}
}
/* Retrieve a key-value pair from a hash table. */
static session_t *ht_get( hashtable_t *hashtable, char *session_id ) {
int bin = 0;
session_t *pair;
bin = ht_hash( hashtable, session_id );
/* Step through the bin, looking for our value. */
pair = hashtable->table[ bin ];
while( pair != NULL && pair->session_id != NULL && strcmp( session_id, pair->session_id ) > 0 ) {
pair = pair->next;
}
/* Did we actually find anything? */
if( pair == NULL || pair->session_id == NULL || strcmp( session_id, pair->session_id ) != 0 )
{
return NULL;
}
else
{
return pair;
}
}
void ht_delete (hashtable_t *hashtable, char *key){
int bin = 0;
session_t *pair;
session_t *prec;
bin = ht_hash( hashtable, key );
/* Step through the bin, looking for our value. */
pair = hashtable->table[ bin ];
while( pair != NULL && pair->session_id != NULL && strcmp( key, pair->session_id ) > 0 ) {
prec = pair;
pair = pair->next;
}
/* Did we actually find anything? */
if( pair != NULL || pair->session_id != NULL || strcmp( key, pair->session_id ) == 0 ) {
free(pair->session_id);
free(pair->user);
}
}
char *gen_session_id(int len){
int index = 0;
char session_id[len];
char char1[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789/,.-+~`<>:";
int c_tmp = 0;
char *res;
srand((unsigned int)(time(NULL)));
for(index = 0; index < len; index++)
{
c_tmp = rand() % sizeof(char1) - 1;
session_id[index] = char1[c_tmp];
}
session_id[len] = '\0';
res = strdup(session_id);
return res;
}
char *set_cookie_header( const char *champ, const char separator,
const char *session_id) {
int lch, lse;
int ls = 0;
char *result;
lch = strlen(champ);
lse = strlen(session_id);
if (separator)
ls = 1;
result = calloc(lch + ls + lse + 1, sizeof *result);
if (result != NULL) {
memcpy (result, champ, lch);
if (separator)
result[lch] = separator;
memcpy (result + lch + ls, session_id, lse + 1 );
}
return result;
}