session.c

来自「这是我自己写的用于嵌入式设备的CGI程序」· C语言 代码 · 共 441 行

C
441
字号
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <sys/types.h>#include <dirent.h>#include "cgi_config.h"#include "session.h"#include "cgic.h"#include "multi-language.h"//SESSION_DATA* _current_session_data = NULL;//char * _current_session_id = NULL;const char* _sess_filename_prefix = "sess_";char tag_string[512];int sessionCheckOnHead( char * current_session_id ){    int result;    char cur_session_id[24];    SESSION_DATA cur_session_data;    int language_selected=1;    char msg1[24], msg2[24], msg3[24];    result = sessionCheck ( cur_session_id, &cur_session_data );    read_prev_selectd (&language_selected);    printf ( "result:%d\n", result );    if (result == SessionNotExist)    {        cgiHeaderContentType("text/html");        //strcpy ( msg1, language_tag (language_selected, "public", "NOT_EXIST"));        strcpy ( msg1, language_section_public [ language_selected -1 ][ L_ID_PUBLIC_NOT_EXIST ]);        alert_redirect ( msg1, "login.cgi");        return -1;    }    else if (result == CookieNotConform)    {        cgiHeaderContentType("text/html");        //strcpy ( msg2, language_tag (language_selected, "public", "AUTH_FAIL"));        strcpy ( msg1, language_section_public [ language_selected -1 ][ L_ID_PUBLIC_AUTH_FAIL ]);        alert_redirect ( msg2, "login.cgi");        return -2;    }    else if (result == SessionTimeOut)    {        cgiHeaderContentType("text/html");        //strcpy ( msg3, language_tag (language_selected, "public", "TIME_OUT"));        strcpy ( msg1, language_section_public [ language_selected -1 ][ L_ID_PUBLIC_TIMEOUT ]);        alert_redirect ( msg3, "login.cgi");        return -3;    }    else if (result == SessionCheckSuccess)    {        sessionUpdate( &cur_session_data );    }    strcpy ( current_session_id, cur_session_id );    return 0;}/*---------------------------------------------------------------------------------------* * 检查session,读出current_session_id和current_session_data *---------------------------------------------------------------------------------------*/sessionCheckResult sessionCheck ( char* current_session_id, SESSION_DATA* current_session_data ){    char cookie_session_id[24];    char cookie_auth_str[48];    int result;    time_t now;    result = cgiCookieString("COOKIE_SESSION_ID",cookie_session_id,24);    if (result != cgiFormSuccess) // 没有找到有效的 cookie session_id    {        return SessionNotExist;    }    else    {        result = sess_load ( cookie_session_id, SESS_DIRECTORY, current_session_data );        //根据cookie中的session_id读取session data。如果读取错误,也返回SessionNotExist        if (result != 0)        {            return SessionNotExist;        }        //result = cgiCookieString("COOKIE_AUTH_STR", cookie_auth_str, 48);        //读取cookie的auth_str,如果不存在,返回CookieNotConform        //if (result != cgiFormSuccess)        //{        //    return CookieNotConform;        //}        //result = strcmp( cookie_auth_str, current_session_data->auth_str );        //if ( result!=0)//auth_str不一致,返回返回CookieNotConform        //{        //    return CookieNotConform;        //}        time(&now);        if ((now - current_session_data->update_time) > SESS_LIVE_TIME )//超时            return SessionTimeOut;    }    strcpy ( current_session_id, cookie_session_id );    return SessionCheckSuccess;}/*---------------------------------------------------------------------------------------* * 初始化session,生成current_session_id和current_session_data,发送Cookie并生成session文件 *---------------------------------------------------------------------------------------*/int sessionInit ( char *current_session_id, SESSION_DATA * current_session_data ){    char cookie_session_id[24]="";    char cookie_auth_str[48]="";    char sess_filename[29];    char *client_ip;    time_t update_time;    int i;    FILE* sessfile;    char sessfilepath[128]="";    time(&update_time);    rand_str(23, cookie_session_id);    strcpy (current_session_id, cookie_session_id);    rand_str(47, cookie_auth_str);    init_sess_filename ( sess_filename, cookie_session_id );    strcat(sessfilepath, SESS_DIRECTORY);    strcat(sessfilepath, sess_filename);    client_ip = getenv ("REMOTE_ADDR");    strcpy (current_session_data -> session_filename, sess_filename );    strcpy (current_session_data -> session_id, cookie_session_id );    strcpy (current_session_data -> auth_str, cookie_auth_str );    current_session_data -> client_ip = (dword) ntohl( inet_addr (client_ip));    current_session_data -> update_time = update_time;    if ((sessfile = fopen(sessfilepath, "w")) == NULL)    {        return -1;    }    fwrite(current_session_data, sizeof (SESSION_DATA), 1, sessfile);    fclose(sessfile);    cgiHeaderCookieSetString("COOKIE_SESSION_ID", cookie_session_id, -1, "/", SERVER_NAME);    cgiHeaderCookieSetString("COOKIE_AUTH_STR", cookie_auth_str, -1, "/", SERVER_NAME);    //设置cookie。如果超时时间设置为负值,cookie在浏览器关闭后即失效。    //如果设置有效的超时时间,关闭浏览器后会话依然有效,只有超时或者退出登录会话才会失效。    //这里将其设置为负值    //cgiHeaderCookieSetString("COOKIE_SESSION_ID", cookie_session_id, SESS_LIVE_TIME, "/", SERVER_NAME);    //cgiHeaderCookieSetString("COOKIE_AUTH_STR", cookie_auth_str, SESS_LIVE_TIME, "/", SERVER_NAME);    return 0;}/*---------------------------------------------------------------------------------------* * 更新session,更新current_session_data,重新发送Cookie并更新session文件 *---------------------------------------------------------------------------------------*/int sessionUpdate ( SESSION_DATA * current_session_data ){    time_t update_time;    char sessfilepath[128]="";    char sess_filename[29];    char cookie_auth_str[48]="";    FILE* sessfile;    strcpy (sess_filename, current_session_data -> session_filename );    strcat(sessfilepath, SESS_DIRECTORY);    strcat(sessfilepath, sess_filename);    time(&update_time);    current_session_data -> update_time = update_time;    rand_str(47, cookie_auth_str);    strcpy (current_session_data -> auth_str, cookie_auth_str );    if ((sessfile = fopen(sessfilepath, "w")) == NULL)    {        return -1;    }    fwrite(current_session_data, sizeof (SESSION_DATA), 1, sessfile);    fclose(sessfile);    cgiHeaderCookieSetString("COOKIE_SESSION_ID", current_session_data -> session_id, -1, "/", SERVER_NAME);    cgiHeaderCookieSetString("COOKIE_AUTH_STR", cookie_auth_str, -1, "/", SERVER_NAME);    //设置cookie。如果超时时间设置为负值,cookie在浏览器关闭后即失效。    //如果设置有效的超时时间,关闭浏览器后会话依然有效,只有超时或者退出登录会话才会失效。    //这里将其设置为负值    //cgiHeaderCookieSetString("COOKIE_SESSION_ID", current_session_data -> session_id, SESS_LIVE_TIME, "/", SERVER_NAME);    //cgiHeaderCookieSetString("COOKIE_AUTH_STR", cookie_auth_str, SESS_LIVE_TIME, "/", SERVER_NAME);    return 0;}/*---------------------------------------------------------------------------------------* * session清除 *---------------------------------------------------------------------------------------*/int sessionDestroy( char *current_session_id){    char sessfilepath[128]="";    SESSION_DATA cur_session_data;    cgiHeaderCookieSetString("COOKIE_SESSION_ID", current_session_id, 0, "/", SERVER_NAME);    sess_load ( current_session_id, SESS_DIRECTORY, &cur_session_data );    strcat(sessfilepath, SESS_DIRECTORY);    strcat(sessfilepath, cur_session_data.session_filename);    unlink(sessfilepath);    return 0;}/*---------------------------------------------------------------------------------------* * 清除所有过期的session文件 * 因为只有正常退出登录的时候才会清除session文件,所以在很多情况下session文件会被遗留下来, *     使用此函数来清除所有过期的session文件 *---------------------------------------------------------------------------------------*/int oldSessionClean ( void ){    DIR *dir;    struct dirent *ent;    FILE *sessfile;    char sessfilepath[128]="";    SESSION_DATA session_data;    time_t now;    if ((dir = opendir (SESS_DIRECTORY)) ==NULL)    {        //出错,退出        return -1;    }    while (( ent = readdir(dir)) != NULL)    {        memset ( sessfilepath, '\0', 128 );        strcat(sessfilepath, SESS_DIRECTORY);        strncat(sessfilepath, ent->d_name, 128);        if ((strcmp(ent->d_name, ".") !=0) && (strcmp(ent->d_name, "..")!=0))        {            time(&now);            if ((sessfile = fopen(sessfilepath, "r")) != NULL)            {                fread(&session_data, sizeof (SESSION_DATA), 1, sessfile);                if ((now - session_data.update_time)>SESS_LIVE_TIME )                {                    unlink(sessfilepath);                }                fclose(sessfile);            }        }    }    if (closedir(dir)!=0)    {        //无法关闭目录        return -1;    }    return 0;}/*---------------------------------------------------------------------------------------* * 获取当前登录的用户名 *---------------------------------------------------------------------------------------*/int get_current_user ( char * current_session_id, char * username ){    SESSION_DATA cur_session_data;    int result;    result = sess_load ( current_session_id, SESS_DIRECTORY, &cur_session_data );    if (result != 0)    {        return -1;    }    strcpy ( username, cur_session_data.username );    return 0;}/*---------------------------------------------------------------------------------------* * 返回当前会话用户的权限级别 *---------------------------------------------------------------------------------------*/int get_user_authority ( char * current_session_id, int* authority ){    SESSION_DATA cur_session_data;    int result;    result = sess_load ( current_session_id, SESS_DIRECTORY, &cur_session_data );    if (result != 0)    {        return -1;    }    *authority = cur_session_data.authority;    return 0;}/*---------------------------------------------------------------------------------------* * 返回当前会话用户的界面语言选择 *---------------------------------------------------------------------------------------*/int get_language_selected ( char * current_session_id, int* language_selected ){    SESSION_DATA cur_session_data;    int result;    result = sess_load ( current_session_id, SESS_DIRECTORY, &cur_session_data );    if (result != 0)    {        return -1;    }    *language_selected = cur_session_data.language_selected;    return 0;}/*---------------------------------------------------------------------------------------* * 返回当前会话用户的上一次界面语言选择 *---------------------------------------------------------------------------------------*/void read_prev_selectd (int* language_selected){    cgiCookieInteger ("COOKIE_LANGUAGE_SELECTED", language_selected, 1);    return;}/*---------------------------------------------------------------------------------------* * 从语言文件中读取语言标签对应的值 *---------------------------------------------------------------------------------------*/char* language_tag (int language_selected, char* cgi_section, char* tag_name){    char * language_file;    int result_size=512;    //char tag_string[512];    //char * tag_string;    //tag_strig = (char *)malloc(512*sizeof(char));    switch (language_selected)    {        case EN://1            language_file = LANGUAGEFILE_EN;            break;        case GB://2            language_file = LANGUAGEFILE_GB;            break;        case BIG5://3            language_file = LANGUAGEFILE_BIG5;            break;        default://1            language_file = LANGUAGEFILE_EN;    }    //printf("language_selected:%d\n", language_selected);    //printf("language_file:%s\n", language_file);    _IniReadStr(cgi_section, tag_name, "NONE", language_file, tag_string, result_size);    //printf("tag_string:%s\n", tag_string);    return tag_string;}/*///////////////////////////////////////////////////////////////////////////////////////*//*---------------------------------------------------------------------------------------* * 生成随机字符串,用法:char str[20]=""; rand_str(20-1, str); *---------------------------------------------------------------------------------------*/void rand_str(int n, char * str){    int i=0;    time_t t;    char ss[2];    struct timeval tv;    int utime;    gettimeofday(&tv,NULL);    utime = (int)tv.tv_sec * 1000000 + tv.tv_usec;    srandom((unsigned) utime);    for(i=0;i<n;i++)    {        sprintf(ss, "%c",(random()%2) ? (random()%26) +65 : (random()%26) + 97);        strcat(str,ss);    }}/*---------------------------------------------------------------------------------------* * 生成session文件名 *---------------------------------------------------------------------------------------*/void init_sess_filename ( char * sess_filename, char * session_id ){    strcpy(sess_filename, _sess_filename_prefix);    strcat(sess_filename, session_id);}/*---------------------------------------------------------------------------------------* * 根据session_id读取session文件 *---------------------------------------------------------------------------------------*/int sess_load( const char* session_id, const char* datadir, SESSION_DATA * current_session_data ){    char sessfilepath[128]="";    FILE* sessfile;    strcat (sessfilepath, datadir);    strcat (sessfilepath, _sess_filename_prefix);    strcat (sessfilepath, session_id);    if ((sessfile = fopen(sessfilepath, "r")) == NULL)    {        return -1;    }    fread(current_session_data, sizeof (SESSION_DATA), 1, sessfile);    fclose(sessfile);    return 0;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?