Skip to main content
fix typo
Source Link
/*web_api.h*/

#ifndef WEB_API_H
#define WEB_API_H

#define MAX_NAME_LEN 128
#define MAX_VALUE_LEN 128

struct web_http_nv
{
    char name[MAX_NAME_LEN];
    char value[MAX_VALUE_LEN];
};

#define MAX_NAME_VALUE_LEN 512

typedef struct web_t web_t;
struct web_t
{
    struct web_http_nv nameval[MAX_NAME_VALUE_LEN]; /* (name, value) pair from web */
    int nv_ct; /* (name, value) pair count */
};

void web_get(web_t* web); /* get (name, value) pair from web */

#endif

/*andy_web.c*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "web_api.h"
#include "andy_cfg.h"

#define MIN_HEIGHT 150
#define MAX_HEIGHT 250

#define MIN_WEIGHT 50
#define MAX_WEIGHT 150

void printMsg(char *msg); //forward declartiondeclaration

static andy_config_t* andy_config = NULL;
static web_t web = {0};

static void andy_web_page_show(void);
static int andy_web_page_setting_check_then_save(char Msg[], uint16_t MsgSize);

int main(void)
{
    andy_config = andy_config_init(180, 80);
    if (ANDY_CFG_FAILED == andy_config)
    {
        return -1;
    }
    
    web_get(&web);
    const uint8_t METHOD = web.nv_ct - 1;
    
    if (!strcmp(web.nameval[METHOD].name, "get"))
    {
        if (!strcmp(web.nameval[METHOD].value, "setting"))
        {
            andy_web_page_show();
        }
        
        goto DONE;
    }
    
    char Msg[100] = {0};
    if (!strcmp(web.nameval[METHOD].name, "post"))
    {
        if (!strcmp(web.nameval[METHOD].value, "setting"))
        {
            if (andy_web_page_setting_check_then_save(Msg, sizeof(Msg)) == -1)
            {
                goto SETTING_CHECK_ERROR;
            }
        }
        
        andy_web_page_show();
        
        goto DONE;
    }
    
SETTING_CHECK_ERROR:
    
    printMsg(Msg);

DONE:

    andy_config_close(andy_config);
    return 0;
}

static void andy_web_page_show(void)
{
    printf("Content-Type: text/html\n\n");
    printf("<html>\n");
    printf("<head>\n");
    printf("<meta http-equiv=\"Content-Type\" content=\"text/html;\" />\n");
    printf("<title>andy Setting</title>\n");
    printf("</head>\n");
    printf("<body>\n");
    printf("<fieldset>\n");
    printf("<legend>andy Setting</legend>\n");
    printf("<form  name=\"andyPage\" method=\"post\" action=\"/cgi-bin/andy_web.cgi\" >\n");
    printf("  <table id=\"table1\" border=\"0\" cellpadding=\"1\" cellspacing=\"1\">\n");
    
    uint16_t height = 0;
    if (andy_config_retrive_heightandy_config_retrieve_height(andy_config, &height) != -1)
    {
        printf("    <tr>\n");
        printf("      <td height=\"20\" width=\"150\" style=\"padding-left:10px\">andy height</td>\n");
        printf("      <td height=\"20\" ><input type=\"text\" name=\"height\" style=\"width: 100;\" value=\"%d\" />(%d~%d)</td>\n", height, MIN_HEIGHT, MAX_HEIGHT);
        printf("    </tr>\n");
    }
    
    uint16_t weight = 0;
    if (andy_config_retrive_weightandy_config_retrieve_weight(andy_config, &weight) != -1)
    {
        printf("    <tr>\n");
        printf("      <td height=\"20\" width=\"150\" style=\"padding-left:10px\">andy weight</td>\n");
        printf("      <td height=\"20\" ><input type=\"text\" name=\"weight\" style=\"width: 100;\" value=\"%d\" />(%d~%d)</td>\n", weight, MIN_WEIGHT, MAX_WEIGHT);
        printf("    </tr>\n");
    }
    
    printf("  </table>\n");
    printf("  <p align=\"center\">\n");
    printf("  <input type=\"submit\" value=\"   Update   \" />\n");
    printf("  <input type=\"hidden\" name=\"post\" value=\"setting\" />\n");
    printf("  </p>\n");
    printf("</form>\n");
    printf("</body>\n");
    printf("</html>\n");
}

static int andy_web_page_setting_check_then_save(char Msg[], uint16_t MsgSize)
{   
    int count = 0;
    for (; count < web.nv_ct-1; count++)
    {
        if (!strcmp(web.nameval[count].name, "height"))
        {
            uint16_t height = atoi(web.nameval[count].value);
            if ((height < MIN_HEIGHT) || (height >= MAX_HEIGHT))
            {
                snprintf(Msg, MsgSize, "height <%d> should be between %d and %d", height, MIN_HEIGHT, MAX_HEIGHT);
                return -1;
            }
            
            andy_config_set_height(andy_config, height);
        }
        else if (!strcmp(web.nameval[count].name, "weight"))
        {
            uint16_t weight = atoi(web.nameval[count].value);
            if ((weight < MIN_WEIGHT) || (weight >= MAX_WEIGHT))
            {
                snprintf(Msg, MsgSize, "wieght"weight <%d> should be between %d and %d", weight, MIN_WEIGHT, MAX_WEIGHT);
                return -1;
            }
            
            andy_config_set_weight(andy_config, weight);
        }
        else
        {

        }
    }

    andy_config_save(andy_config);
    return 0;
}
/*andy_cfg.h*/

#ifndef ANDY_CFG_H
#define ANDY_CFG_H

#include <stdint.h>

typedef struct andy_config_t andy_config_t;

#define ANDY_CFG_FAILED (andy_config_t*)NULL


andy_config_t* andy_config_init(uint16_t height, uint16_t weight);
void andy_config_close(andy_config_t* me);

void andy_config_save(andy_config_t* me);

void andy_config_set_height(andy_config_t* me, uint16_t height);
void andy_config_set_weight(andy_config_t* me, uint16_t weight);

int andy_config_retrive_heightandy_config_retrieve_height(andy_config_t* me, uint16_t* height);
int andy_config_retrive_weightandy_config_retrieve_weight(andy_config_t* me, uint16_t* weight);

#endif

/*andy_cfg.c*/

#include <stdbool.h>
#include "iniparser.h"
#include "andy_cfg.h"

#define ANDY_STARTUP_DIR "/mnt/jffs2/cfg/"
#define ANDY_RUNNING_DIR "/var/"
#define ANDY_CFG_FILE "andy.ini"

bool file_is_existing(const char* file_path); //forward declartiondeclaration

andy_config_t* andy_config_init(uint16_t height, uint16_t weight)
{
    if (!file_is_existing(ANDY_STARTUP_DIR""ANDY_CFG_FILE))
    {   
        FILE* andy_startup_file = fopen(ANDY_STARTUP_DIR""ANDY_CFG_FILE, "w");
        if (NULL == andy_startup_file)
        {
            return ANDY_CFG_FAILED;
        }
        
        fprintf(andy_startup_file,
        "\n"
        "[Info]\n"
        "\n"
        "height = %d ; 150 ~ 250\n"
        "wieght"weight = %d ; 50 ~ 150\n"
        "\n", height, weight);
        
        fclose(andy_startup_file);
    }
    
    dictionary* andy_running_config = iniparser_load(ANDY_STARTUP_DIR""ANDY_CFG_FILE);
    if (NULL == andy_running_config)
    {
        return ANDY_CFG_FAILED;
    }

    return (andy_config_t*)andy_running_config;
}

void andy_config_close(andy_config_t* me)
{
    if (NULL != me)
    {
        andy_config_save(me);
        iniparser_freedict((dictionary*)me);
    }
}

void andy_config_save(andy_config_t* me)
{
    FILE* andy_startup_file = fopen(ANDY_STARTUP_DIR""ANDY_CFG_FILE, "w");
    iniparser_dump_ini((dictionary*)me, andy_startup_file);
    fclose(andy_startup_file);
}

void andy_config_set_height(andy_config_t* me, uint16_t height)
{   
    char str[10] = {0};
    snprintf(str, sizeof(str), "%d", height);
    iniparser_set((dictionary*)me, "Info:height", str);
}

void andy_config_set_weight(andy_config_t* me, uint16_t weight)
{   
    char str[10] = {0};
    snprintf(str, sizeof(str), "%d", weight);
    iniparser_set((dictionary*)me, "Info:weight", str);
}

int andy_config_retrive_heightandy_config_retrieve_height(andy_config_t* me, uint16_t* height)
{
    int ret = iniparser_getint((dictionary*)me, "Info:height", -1);
    if (ret == -1)
    {
        return -1;
    }

    *height = (uint16_t)ret;
    return 0;
}

int andy_config_retrive_weightandy_config_retrieve_weight(andy_config_t* me, uint16_t* weight)
{
    int ret = iniparser_getint((dictionary*)me, "Info:weight", -1);
    if (ret == -1)
    {
        return -1;
    }

    *weight = (uint16_t)ret;
    return 0;
}
/*amy_cfg.h*/

#ifndef AMY_CFG_H
#define AMY_CFG_H

#include <stdint.h>

typedef struct amy_config_t amy_config_t;

#define AMY_CFG_FAILED (amy_config_t*)NULL


amy_config_t* amy_config_init(uint16_t height, uint16_t weight);
void amy_config_close(amy_config_t* me);

void amy_config_save(amy_config_t* me);

void amy_config_set_height(amy_config_t* me, uint16_t height);
void amy_config_set_weight(amy_config_t* me, uint16_t weight);

int amy_config_retrive_heightamy_config_retrieve_height(amy_config_t* me, uint16_t* height);
int amy_config_retrive_weightamy_config_retrieve_weight(amy_config_t* me, uint16_t* weight);

#endif

/*amy_cfg.c*/

#include <stdbool.h>
#include "iniparser.h"
#include "amy_cfg.h"

#define AMY_STARTUP_DIR "/mnt/jffs2/cfg/"
#define AMY_RUNNING_DIR "/var/"
#define AMY_CFG_FILE "amy.ini"

bool file_is_existing(const char* file_path); //forward declartiondeclaration

amy_config_t* amy_config_init(uint16_t height, uint16_t weight)
{
    if (!file_is_existing(AMY_STARTUP_DIR""AMY_CFG_FILE))
    {   
        FILE* amy_startup_file = fopen(AMY_STARTUP_DIR""AMY_CFG_FILE, "w");
        if (NULL == amy_startup_file)
        {
            return AMY_CFG_FAILED;
        }

        fprintf(amy_startup_file,
        "\n"
        "[Info]\n"
        "\n"
        "height = %d ; 150 ~ 250\n"
        "wieght"weight = %d ; 50 ~ 150\n"
        "\n", height, weight);

        fclose(amy_startup_file);
    }

    dictionary* amy_running_config = iniparser_load(AMY_STARTUP_DIR""AMY_CFG_FILE);
    if (NULL == amy_running_config)
    {
        return AMY_CFG_FAILED;
    }

    return (amy_config_t*)amy_running_config;
}

void amy_config_close(amy_config_t* me)
{
    if (NULL != me)
    {
        amy_config_save(me);
        iniparser_freedict((dictionary*)me);
    }
}

void amy_config_save(amy_config_t* me)
{
    FILE* amy_startup_file = fopen(AMY_STARTUP_DIR""AMY_CFG_FILE, "w");
    iniparser_dump_ini((dictionary*)me, amy_startup_file);
    fclose(amy_startup_file);
}

void amy_config_set_height(amy_config_t* me, uint16_t height)
{   
    char str[10] = {0};
    snprintf(str, sizeof(str), "%d", height);
    iniparser_set((dictionary*)me, "Info:height", str);
}

void amy_config_set_weight(amy_config_t* me, uint16_t weight)
{   
    char str[10] = {0};
    snprintf(str, sizeof(str), "%d", weight);
    iniparser_set((dictionary*)me, "Info:weight", str);
}

int amy_config_retrive_heightamy_config_retrieve_height(amy_config_t* me, uint16_t* height)
{
    int ret = iniparser_getint((dictionary*)me, "Info:height", -1);
    if (ret == -1)
    {
        return -1;
    }

    *height = (uint16_t)ret;
    return 0;
}

int amy_config_retrive_weightamy_config_retrieve_weight(amy_config_t* me, uint16_t* weight)
{
    int ret = iniparser_getint((dictionary*)me, "Info:weight", -1);
    if (ret == -1)
    {
        return -1;
    }

    *weight = (uint16_t)ret;
    return 0;
}
/*web_api.h*/

#ifndef WEB_API_H
#define WEB_API_H

#define MAX_NAME_LEN 128
#define MAX_VALUE_LEN 128

struct web_http_nv
{
    char name[MAX_NAME_LEN];
    char value[MAX_VALUE_LEN];
};

#define MAX_NAME_VALUE_LEN 512

typedef struct web_t web_t;
struct web_t
{
    struct web_http_nv nameval[MAX_NAME_VALUE_LEN]; /* (name, value) pair from web */
    int nv_ct; /* (name, value) pair count */
};

void web_get(web_t* web); /* get (name, value) pair from web */

#endif

/*andy_web.c*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "web_api.h"
#include "andy_cfg.h"

#define MIN_HEIGHT 150
#define MAX_HEIGHT 250

#define MIN_WEIGHT 50
#define MAX_WEIGHT 150

void printMsg(char *msg); //forward declartion

static andy_config_t* andy_config = NULL;
static web_t web = {0};

static void andy_web_page_show(void);
static int andy_web_page_setting_check_then_save(char Msg[], uint16_t MsgSize);

int main(void)
{
    andy_config = andy_config_init(180, 80);
    if (ANDY_CFG_FAILED == andy_config)
    {
        return -1;
    }
    
    web_get(&web);
    const uint8_t METHOD = web.nv_ct - 1;
    
    if (!strcmp(web.nameval[METHOD].name, "get"))
    {
        if (!strcmp(web.nameval[METHOD].value, "setting"))
        {
            andy_web_page_show();
        }
        
        goto DONE;
    }
    
    char Msg[100] = {0};
    if (!strcmp(web.nameval[METHOD].name, "post"))
    {
        if (!strcmp(web.nameval[METHOD].value, "setting"))
        {
            if (andy_web_page_setting_check_then_save(Msg, sizeof(Msg)) == -1)
            {
                goto SETTING_CHECK_ERROR;
            }
        }
        
        andy_web_page_show();
        
        goto DONE;
    }
    
SETTING_CHECK_ERROR:
    
    printMsg(Msg);

DONE:

    andy_config_close(andy_config);
    return 0;
}

static void andy_web_page_show(void)
{
    printf("Content-Type: text/html\n\n");
    printf("<html>\n");
    printf("<head>\n");
    printf("<meta http-equiv=\"Content-Type\" content=\"text/html;\" />\n");
    printf("<title>andy Setting</title>\n");
    printf("</head>\n");
    printf("<body>\n");
    printf("<fieldset>\n");
    printf("<legend>andy Setting</legend>\n");
    printf("<form  name=\"andyPage\" method=\"post\" action=\"/cgi-bin/andy_web.cgi\" >\n");
    printf("  <table id=\"table1\" border=\"0\" cellpadding=\"1\" cellspacing=\"1\">\n");
    
    uint16_t height = 0;
    if (andy_config_retrive_height(andy_config, &height) != -1)
    {
        printf("    <tr>\n");
        printf("      <td height=\"20\" width=\"150\" style=\"padding-left:10px\">andy height</td>\n");
        printf("      <td height=\"20\" ><input type=\"text\" name=\"height\" style=\"width: 100;\" value=\"%d\" />(%d~%d)</td>\n", height, MIN_HEIGHT, MAX_HEIGHT);
        printf("    </tr>\n");
    }
    
    uint16_t weight = 0;
    if (andy_config_retrive_weight(andy_config, &weight) != -1)
    {
        printf("    <tr>\n");
        printf("      <td height=\"20\" width=\"150\" style=\"padding-left:10px\">andy weight</td>\n");
        printf("      <td height=\"20\" ><input type=\"text\" name=\"weight\" style=\"width: 100;\" value=\"%d\" />(%d~%d)</td>\n", weight, MIN_WEIGHT, MAX_WEIGHT);
        printf("    </tr>\n");
    }
    
    printf("  </table>\n");
    printf("  <p align=\"center\">\n");
    printf("  <input type=\"submit\" value=\"   Update   \" />\n");
    printf("  <input type=\"hidden\" name=\"post\" value=\"setting\" />\n");
    printf("  </p>\n");
    printf("</form>\n");
    printf("</body>\n");
    printf("</html>\n");
}

static int andy_web_page_setting_check_then_save(char Msg[], uint16_t MsgSize)
{   
    int count = 0;
    for (; count < web.nv_ct-1; count++)
    {
        if (!strcmp(web.nameval[count].name, "height"))
        {
            uint16_t height = atoi(web.nameval[count].value);
            if ((height < MIN_HEIGHT) || (height >= MAX_HEIGHT))
            {
                snprintf(Msg, MsgSize, "height <%d> should be between %d and %d", height, MIN_HEIGHT, MAX_HEIGHT);
                return -1;
            }
            
            andy_config_set_height(andy_config, height);
        }
        else if (!strcmp(web.nameval[count].name, "weight"))
        {
            uint16_t weight = atoi(web.nameval[count].value);
            if ((weight < MIN_WEIGHT) || (weight >= MAX_WEIGHT))
            {
                snprintf(Msg, MsgSize, "wieght <%d> should be between %d and %d", weight, MIN_WEIGHT, MAX_WEIGHT);
                return -1;
            }
            
            andy_config_set_weight(andy_config, weight);
        }
        else
        {

        }
    }

    andy_config_save(andy_config);
    return 0;
}
/*andy_cfg.h*/

#ifndef ANDY_CFG_H
#define ANDY_CFG_H

#include <stdint.h>

typedef struct andy_config_t andy_config_t;

#define ANDY_CFG_FAILED (andy_config_t*)NULL


andy_config_t* andy_config_init(uint16_t height, uint16_t weight);
void andy_config_close(andy_config_t* me);

void andy_config_save(andy_config_t* me);

void andy_config_set_height(andy_config_t* me, uint16_t height);
void andy_config_set_weight(andy_config_t* me, uint16_t weight);

int andy_config_retrive_height(andy_config_t* me, uint16_t* height);
int andy_config_retrive_weight(andy_config_t* me, uint16_t* weight);

#endif

/*andy_cfg.c*/

#include <stdbool.h>
#include "iniparser.h"
#include "andy_cfg.h"

#define ANDY_STARTUP_DIR "/mnt/jffs2/cfg/"
#define ANDY_RUNNING_DIR "/var/"
#define ANDY_CFG_FILE "andy.ini"

bool file_is_existing(const char* file_path); //forward declartion

andy_config_t* andy_config_init(uint16_t height, uint16_t weight)
{
    if (!file_is_existing(ANDY_STARTUP_DIR""ANDY_CFG_FILE))
    {   
        FILE* andy_startup_file = fopen(ANDY_STARTUP_DIR""ANDY_CFG_FILE, "w");
        if (NULL == andy_startup_file)
        {
            return ANDY_CFG_FAILED;
        }
        
        fprintf(andy_startup_file,
        "\n"
        "[Info]\n"
        "\n"
        "height = %d ; 150 ~ 250\n"
        "wieght = %d ; 50 ~ 150\n"
        "\n", height, weight);
        
        fclose(andy_startup_file);
    }
    
    dictionary* andy_running_config = iniparser_load(ANDY_STARTUP_DIR""ANDY_CFG_FILE);
    if (NULL == andy_running_config)
    {
        return ANDY_CFG_FAILED;
    }

    return (andy_config_t*)andy_running_config;
}

void andy_config_close(andy_config_t* me)
{
    if (NULL != me)
    {
        andy_config_save(me);
        iniparser_freedict((dictionary*)me);
    }
}

void andy_config_save(andy_config_t* me)
{
    FILE* andy_startup_file = fopen(ANDY_STARTUP_DIR""ANDY_CFG_FILE, "w");
    iniparser_dump_ini((dictionary*)me, andy_startup_file);
    fclose(andy_startup_file);
}

void andy_config_set_height(andy_config_t* me, uint16_t height)
{   
    char str[10] = {0};
    snprintf(str, sizeof(str), "%d", height);
    iniparser_set((dictionary*)me, "Info:height", str);
}

void andy_config_set_weight(andy_config_t* me, uint16_t weight)
{   
    char str[10] = {0};
    snprintf(str, sizeof(str), "%d", weight);
    iniparser_set((dictionary*)me, "Info:weight", str);
}

int andy_config_retrive_height(andy_config_t* me, uint16_t* height)
{
    int ret = iniparser_getint((dictionary*)me, "Info:height", -1);
    if (ret == -1)
    {
        return -1;
    }

    *height = (uint16_t)ret;
    return 0;
}

int andy_config_retrive_weight(andy_config_t* me, uint16_t* weight)
{
    int ret = iniparser_getint((dictionary*)me, "Info:weight", -1);
    if (ret == -1)
    {
        return -1;
    }

    *weight = (uint16_t)ret;
    return 0;
}
/*amy_cfg.h*/

#ifndef AMY_CFG_H
#define AMY_CFG_H

#include <stdint.h>

typedef struct amy_config_t amy_config_t;

#define AMY_CFG_FAILED (amy_config_t*)NULL


amy_config_t* amy_config_init(uint16_t height, uint16_t weight);
void amy_config_close(amy_config_t* me);

void amy_config_save(amy_config_t* me);

void amy_config_set_height(amy_config_t* me, uint16_t height);
void amy_config_set_weight(amy_config_t* me, uint16_t weight);

int amy_config_retrive_height(amy_config_t* me, uint16_t* height);
int amy_config_retrive_weight(amy_config_t* me, uint16_t* weight);

#endif

/*amy_cfg.c*/

#include <stdbool.h>
#include "iniparser.h"
#include "amy_cfg.h"

#define AMY_STARTUP_DIR "/mnt/jffs2/cfg/"
#define AMY_RUNNING_DIR "/var/"
#define AMY_CFG_FILE "amy.ini"

bool file_is_existing(const char* file_path); //forward declartion

amy_config_t* amy_config_init(uint16_t height, uint16_t weight)
{
    if (!file_is_existing(AMY_STARTUP_DIR""AMY_CFG_FILE))
    {   
        FILE* amy_startup_file = fopen(AMY_STARTUP_DIR""AMY_CFG_FILE, "w");
        if (NULL == amy_startup_file)
        {
            return AMY_CFG_FAILED;
        }

        fprintf(amy_startup_file,
        "\n"
        "[Info]\n"
        "\n"
        "height = %d ; 150 ~ 250\n"
        "wieght = %d ; 50 ~ 150\n"
        "\n", height, weight);

        fclose(amy_startup_file);
    }

    dictionary* amy_running_config = iniparser_load(AMY_STARTUP_DIR""AMY_CFG_FILE);
    if (NULL == amy_running_config)
    {
        return AMY_CFG_FAILED;
    }

    return (amy_config_t*)amy_running_config;
}

void amy_config_close(amy_config_t* me)
{
    if (NULL != me)
    {
        amy_config_save(me);
        iniparser_freedict((dictionary*)me);
    }
}

void amy_config_save(amy_config_t* me)
{
    FILE* amy_startup_file = fopen(AMY_STARTUP_DIR""AMY_CFG_FILE, "w");
    iniparser_dump_ini((dictionary*)me, amy_startup_file);
    fclose(amy_startup_file);
}

void amy_config_set_height(amy_config_t* me, uint16_t height)
{   
    char str[10] = {0};
    snprintf(str, sizeof(str), "%d", height);
    iniparser_set((dictionary*)me, "Info:height", str);
}

void amy_config_set_weight(amy_config_t* me, uint16_t weight)
{   
    char str[10] = {0};
    snprintf(str, sizeof(str), "%d", weight);
    iniparser_set((dictionary*)me, "Info:weight", str);
}

int amy_config_retrive_height(amy_config_t* me, uint16_t* height)
{
    int ret = iniparser_getint((dictionary*)me, "Info:height", -1);
    if (ret == -1)
    {
        return -1;
    }

    *height = (uint16_t)ret;
    return 0;
}

int amy_config_retrive_weight(amy_config_t* me, uint16_t* weight)
{
    int ret = iniparser_getint((dictionary*)me, "Info:weight", -1);
    if (ret == -1)
    {
        return -1;
    }

    *weight = (uint16_t)ret;
    return 0;
}
/*web_api.h*/

#ifndef WEB_API_H
#define WEB_API_H

#define MAX_NAME_LEN 128
#define MAX_VALUE_LEN 128

struct web_http_nv
{
    char name[MAX_NAME_LEN];
    char value[MAX_VALUE_LEN];
};

#define MAX_NAME_VALUE_LEN 512

typedef struct web_t web_t;
struct web_t
{
    struct web_http_nv nameval[MAX_NAME_VALUE_LEN]; /* (name, value) pair from web */
    int nv_ct; /* (name, value) pair count */
};

void web_get(web_t* web); /* get (name, value) pair from web */

#endif

/*andy_web.c*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "web_api.h"
#include "andy_cfg.h"

#define MIN_HEIGHT 150
#define MAX_HEIGHT 250

#define MIN_WEIGHT 50
#define MAX_WEIGHT 150

void printMsg(char *msg); //forward declaration

static andy_config_t* andy_config = NULL;
static web_t web = {0};

static void andy_web_page_show(void);
static int andy_web_page_setting_check_then_save(char Msg[], uint16_t MsgSize);

int main(void)
{
    andy_config = andy_config_init(180, 80);
    if (ANDY_CFG_FAILED == andy_config)
    {
        return -1;
    }
    
    web_get(&web);
    const uint8_t METHOD = web.nv_ct - 1;
    
    if (!strcmp(web.nameval[METHOD].name, "get"))
    {
        if (!strcmp(web.nameval[METHOD].value, "setting"))
        {
            andy_web_page_show();
        }
        
        goto DONE;
    }
    
    char Msg[100] = {0};
    if (!strcmp(web.nameval[METHOD].name, "post"))
    {
        if (!strcmp(web.nameval[METHOD].value, "setting"))
        {
            if (andy_web_page_setting_check_then_save(Msg, sizeof(Msg)) == -1)
            {
                goto SETTING_CHECK_ERROR;
            }
        }
        
        andy_web_page_show();
        
        goto DONE;
    }
    
SETTING_CHECK_ERROR:
    
    printMsg(Msg);

DONE:

    andy_config_close(andy_config);
    return 0;
}

static void andy_web_page_show(void)
{
    printf("Content-Type: text/html\n\n");
    printf("<html>\n");
    printf("<head>\n");
    printf("<meta http-equiv=\"Content-Type\" content=\"text/html;\" />\n");
    printf("<title>andy Setting</title>\n");
    printf("</head>\n");
    printf("<body>\n");
    printf("<fieldset>\n");
    printf("<legend>andy Setting</legend>\n");
    printf("<form  name=\"andyPage\" method=\"post\" action=\"/cgi-bin/andy_web.cgi\" >\n");
    printf("  <table id=\"table1\" border=\"0\" cellpadding=\"1\" cellspacing=\"1\">\n");
    
    uint16_t height = 0;
    if (andy_config_retrieve_height(andy_config, &height) != -1)
    {
        printf("    <tr>\n");
        printf("      <td height=\"20\" width=\"150\" style=\"padding-left:10px\">andy height</td>\n");
        printf("      <td height=\"20\" ><input type=\"text\" name=\"height\" style=\"width: 100;\" value=\"%d\" />(%d~%d)</td>\n", height, MIN_HEIGHT, MAX_HEIGHT);
        printf("    </tr>\n");
    }
    
    uint16_t weight = 0;
    if (andy_config_retrieve_weight(andy_config, &weight) != -1)
    {
        printf("    <tr>\n");
        printf("      <td height=\"20\" width=\"150\" style=\"padding-left:10px\">andy weight</td>\n");
        printf("      <td height=\"20\" ><input type=\"text\" name=\"weight\" style=\"width: 100;\" value=\"%d\" />(%d~%d)</td>\n", weight, MIN_WEIGHT, MAX_WEIGHT);
        printf("    </tr>\n");
    }
    
    printf("  </table>\n");
    printf("  <p align=\"center\">\n");
    printf("  <input type=\"submit\" value=\"   Update   \" />\n");
    printf("  <input type=\"hidden\" name=\"post\" value=\"setting\" />\n");
    printf("  </p>\n");
    printf("</form>\n");
    printf("</body>\n");
    printf("</html>\n");
}

static int andy_web_page_setting_check_then_save(char Msg[], uint16_t MsgSize)
{   
    int count = 0;
    for (; count < web.nv_ct-1; count++)
    {
        if (!strcmp(web.nameval[count].name, "height"))
        {
            uint16_t height = atoi(web.nameval[count].value);
            if ((height < MIN_HEIGHT) || (height >= MAX_HEIGHT))
            {
                snprintf(Msg, MsgSize, "height <%d> should be between %d and %d", height, MIN_HEIGHT, MAX_HEIGHT);
                return -1;
            }
            
            andy_config_set_height(andy_config, height);
        }
        else if (!strcmp(web.nameval[count].name, "weight"))
        {
            uint16_t weight = atoi(web.nameval[count].value);
            if ((weight < MIN_WEIGHT) || (weight >= MAX_WEIGHT))
            {
                snprintf(Msg, MsgSize, "weight <%d> should be between %d and %d", weight, MIN_WEIGHT, MAX_WEIGHT);
                return -1;
            }
            
            andy_config_set_weight(andy_config, weight);
        }
        else
        {

        }
    }

    andy_config_save(andy_config);
    return 0;
}
/*andy_cfg.h*/

#ifndef ANDY_CFG_H
#define ANDY_CFG_H

#include <stdint.h>

typedef struct andy_config_t andy_config_t;

#define ANDY_CFG_FAILED (andy_config_t*)NULL


andy_config_t* andy_config_init(uint16_t height, uint16_t weight);
void andy_config_close(andy_config_t* me);

void andy_config_save(andy_config_t* me);

void andy_config_set_height(andy_config_t* me, uint16_t height);
void andy_config_set_weight(andy_config_t* me, uint16_t weight);

int andy_config_retrieve_height(andy_config_t* me, uint16_t* height);
int andy_config_retrieve_weight(andy_config_t* me, uint16_t* weight);

#endif

/*andy_cfg.c*/

#include <stdbool.h>
#include "iniparser.h"
#include "andy_cfg.h"

#define ANDY_STARTUP_DIR "/mnt/jffs2/cfg/"
#define ANDY_RUNNING_DIR "/var/"
#define ANDY_CFG_FILE "andy.ini"

bool file_is_existing(const char* file_path); //forward declaration

andy_config_t* andy_config_init(uint16_t height, uint16_t weight)
{
    if (!file_is_existing(ANDY_STARTUP_DIR""ANDY_CFG_FILE))
    {   
        FILE* andy_startup_file = fopen(ANDY_STARTUP_DIR""ANDY_CFG_FILE, "w");
        if (NULL == andy_startup_file)
        {
            return ANDY_CFG_FAILED;
        }
        
        fprintf(andy_startup_file,
        "\n"
        "[Info]\n"
        "\n"
        "height = %d ; 150 ~ 250\n"
        "weight = %d ; 50 ~ 150\n"
        "\n", height, weight);
        
        fclose(andy_startup_file);
    }
    
    dictionary* andy_running_config = iniparser_load(ANDY_STARTUP_DIR""ANDY_CFG_FILE);
    if (NULL == andy_running_config)
    {
        return ANDY_CFG_FAILED;
    }

    return (andy_config_t*)andy_running_config;
}

void andy_config_close(andy_config_t* me)
{
    if (NULL != me)
    {
        andy_config_save(me);
        iniparser_freedict((dictionary*)me);
    }
}

void andy_config_save(andy_config_t* me)
{
    FILE* andy_startup_file = fopen(ANDY_STARTUP_DIR""ANDY_CFG_FILE, "w");
    iniparser_dump_ini((dictionary*)me, andy_startup_file);
    fclose(andy_startup_file);
}

void andy_config_set_height(andy_config_t* me, uint16_t height)
{   
    char str[10] = {0};
    snprintf(str, sizeof(str), "%d", height);
    iniparser_set((dictionary*)me, "Info:height", str);
}

void andy_config_set_weight(andy_config_t* me, uint16_t weight)
{   
    char str[10] = {0};
    snprintf(str, sizeof(str), "%d", weight);
    iniparser_set((dictionary*)me, "Info:weight", str);
}

int andy_config_retrieve_height(andy_config_t* me, uint16_t* height)
{
    int ret = iniparser_getint((dictionary*)me, "Info:height", -1);
    if (ret == -1)
    {
        return -1;
    }

    *height = (uint16_t)ret;
    return 0;
}

int andy_config_retrieve_weight(andy_config_t* me, uint16_t* weight)
{
    int ret = iniparser_getint((dictionary*)me, "Info:weight", -1);
    if (ret == -1)
    {
        return -1;
    }

    *weight = (uint16_t)ret;
    return 0;
}
/*amy_cfg.h*/

#ifndef AMY_CFG_H
#define AMY_CFG_H

#include <stdint.h>

typedef struct amy_config_t amy_config_t;

#define AMY_CFG_FAILED (amy_config_t*)NULL


amy_config_t* amy_config_init(uint16_t height, uint16_t weight);
void amy_config_close(amy_config_t* me);

void amy_config_save(amy_config_t* me);

void amy_config_set_height(amy_config_t* me, uint16_t height);
void amy_config_set_weight(amy_config_t* me, uint16_t weight);

int amy_config_retrieve_height(amy_config_t* me, uint16_t* height);
int amy_config_retrieve_weight(amy_config_t* me, uint16_t* weight);

#endif

/*amy_cfg.c*/

#include <stdbool.h>
#include "iniparser.h"
#include "amy_cfg.h"

#define AMY_STARTUP_DIR "/mnt/jffs2/cfg/"
#define AMY_RUNNING_DIR "/var/"
#define AMY_CFG_FILE "amy.ini"

bool file_is_existing(const char* file_path); //forward declaration

amy_config_t* amy_config_init(uint16_t height, uint16_t weight)
{
    if (!file_is_existing(AMY_STARTUP_DIR""AMY_CFG_FILE))
    {   
        FILE* amy_startup_file = fopen(AMY_STARTUP_DIR""AMY_CFG_FILE, "w");
        if (NULL == amy_startup_file)
        {
            return AMY_CFG_FAILED;
        }

        fprintf(amy_startup_file,
        "\n"
        "[Info]\n"
        "\n"
        "height = %d ; 150 ~ 250\n"
        "weight = %d ; 50 ~ 150\n"
        "\n", height, weight);

        fclose(amy_startup_file);
    }

    dictionary* amy_running_config = iniparser_load(AMY_STARTUP_DIR""AMY_CFG_FILE);
    if (NULL == amy_running_config)
    {
        return AMY_CFG_FAILED;
    }

    return (amy_config_t*)amy_running_config;
}

void amy_config_close(amy_config_t* me)
{
    if (NULL != me)
    {
        amy_config_save(me);
        iniparser_freedict((dictionary*)me);
    }
}

void amy_config_save(amy_config_t* me)
{
    FILE* amy_startup_file = fopen(AMY_STARTUP_DIR""AMY_CFG_FILE, "w");
    iniparser_dump_ini((dictionary*)me, amy_startup_file);
    fclose(amy_startup_file);
}

void amy_config_set_height(amy_config_t* me, uint16_t height)
{   
    char str[10] = {0};
    snprintf(str, sizeof(str), "%d", height);
    iniparser_set((dictionary*)me, "Info:height", str);
}

void amy_config_set_weight(amy_config_t* me, uint16_t weight)
{   
    char str[10] = {0};
    snprintf(str, sizeof(str), "%d", weight);
    iniparser_set((dictionary*)me, "Info:weight", str);
}

int amy_config_retrieve_height(amy_config_t* me, uint16_t* height)
{
    int ret = iniparser_getint((dictionary*)me, "Info:height", -1);
    if (ret == -1)
    {
        return -1;
    }

    *height = (uint16_t)ret;
    return 0;
}

int amy_config_retrieve_weight(amy_config_t* me, uint16_t* weight)
{
    int ret = iniparser_getint((dictionary*)me, "Info:weight", -1);
    if (ret == -1)
    {
        return -1;
    }

    *weight = (uint16_t)ret;
    return 0;
}
added 3 characters in body
Source Link

For example: As to question 1.1. It's better to create andy_cfg to handle everything about andy.ini only if these considerations are met..., or you're doing good with this architecture so far. 

Then give insight on each consideration.

For example: As to question 1.1. It's better to create andy_cfg to handle everything about andy.ini only if these considerations are met..., or you're doing good with this architecture so far. Then give insight on each consideration.

For example: As to question 1.1. It's better to create andy_cfg to handle everything about andy.ini only if these considerations are met..., or you're doing good with this architecture so far. 

Then give insight on each consideration.

Bumped by Community user
edited tags
Link
Notice removed Canonical answer required by CommunityBot
Bounty Ended with no winning answer by CommunityBot
add a paragraph describing ideal answer
Source Link
Loading
Tweeted twitter.com/StackCodeReview/status/1415914090636226563
added 15 characters in body
Source Link
Loading
added 15 characters in body
Source Link
Loading
Notice added Canonical answer required by Andy Lin
Bounty Started worth 100 reputation by Andy Lin
added 5 characters in body
Source Link
Loading
added 127 characters in body
Source Link
Loading
Add code so it can be compiled
Source Link
Loading
replace keyword `form` with `web`, add `web_api.h`
Source Link
Loading
replace keyword `form` with `web`
Source Link
Loading
added 25 characters in body
Source Link
Loading
add text to describe program approach vs function approach
Source Link
Loading
edited body
Source Link
Loading
add andy_cfg.h, amy_cfg.h, and amy_cfg.c
Source Link
Loading
edited body; edited tags; edited title
Source Link
200_success
  • 144.2k
  • 22
  • 188
  • 473
Loading
change title
Link
Loading
Source Link
Loading