这是配置文件的格式:
[ server ]
#ip = 127.0.0.1
ip = 192.168.1.245
port = 1989
user = root
passwd = root
[ client ]
ip = 1.168.1.245
port = 10000
user = leptune
passwd = lep
读写配置文件的代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/time.h>
#include <assert.h>
#define MAX_BUF_LEN 4096
#define DBG printf(" [%s:%d] \n", __FILE__, __LINE__);
void remove_line_break(char *buf)
{/*{{{*/
char *p = NULL;
p = strrchr(buf, '\n');
if (p != NULL)
{
*p = '\0';
}
}/*}}}*/
void remove_space(char *buf)
{/*{{{*/
char *p_buf = NULL;
char *p_tmp = NULL;
char tmp_buf[MAX_BUF_LEN + 1] = "\0";
p_tmp = tmp_buf;
p_buf = buf;
while (*p_buf != '\0')
{
if (*p_buf != ' ')
{
*p_tmp++ = *p_buf;
}
p_buf++;
}
*p_buf = '\0';
strcpy(buf, tmp_buf);
}/*}}}*/
/* 如果lines为-1,则复制整个文件 */
int file_copy_nlines(FILE *fp_dest, FILE *fp_src, int start_flag, int lines)
{/*{{{*/
int i;
char tmp_buf[MAX_BUF_LEN + 1] = "\0";
fseek(fp_src, 0L, start_flag);
if (lines != -1)
{
for (i = 0; i < lines; i++)
{
fgets(tmp_buf, MAX_BUF_LEN, fp_src);
fputs(tmp_buf, fp_dest);
}
}
else
{
while (NULL != fgets(tmp_buf, MAX_BUF_LEN, fp_src))
{
fputs(tmp_buf, fp_dest);
}
}
return 0;
}/*}}}*/
int get_uniq_name(char *name, int len)
{/*{{{*/
struct timeval tv;
gettimeofday(&tv, NULL);
snprintf(name, len, ".%ld_%ld.tmp", tv.tv_sec, tv.tv_usec);
return 0;
}/*}}}*/
/* 如果没找到则返回-1,找到则返回该key在文件在第几行(从1开始) */
int ini_find_key(FILE *fp_ini, const char *key, char *value)
{/*{{{*/
int lines = 0;
long last_loc = 0L;
char *p = NULL;
char tmp_buf[MAX_BUF_LEN + 1] = "\0";
last_loc = ftell(fp_ini);
while (NULL != fgets(tmp_buf, MAX_BUF_LEN, fp_ini))
{
lines++;
remove_space(tmp_buf);
if ('[' == tmp_buf[0])
{ /* 说明到了下一个段了 */
break;
}
if ('#' == tmp_buf[0])
{ /* 说明是注释行 */
continue;
}
remove_line_break(tmp_buf);
p = strchr(tmp_buf, '=');
if (NULL == p)
{ /* 非法的配置行 */
continue;
}
*p = '\0';
if (0 == strcmp(key, tmp_buf))
{
if (value != NULL)
{
strcpy(value, p+1);
}
fseek(fp_ini, last_loc, SEEK_SET);
return lines;
}
last_loc = ftell(fp_ini);
}
DBG
return -1;
}/*}}}*/
/* 如果没找到则返回-1,找到则返回该seg在文件在第几行(从1开始) */
int ini_find_seg(FILE *fp_ini, const char *seg_name)
{/*{{{*/
int lines = 0;
char *p = NULL;
char tmp_buf[MAX_BUF_LEN + 1] = "\0";
char tmp_segname[BUFSIZ + 1] = "\0";
while (NULL != fgets(tmp_buf, MAX_BUF_LEN, fp_ini))
{
lines++;
remove_space(tmp_buf);
/* 段名是用[]包起来的,且放在行首 */
if (tmp_buf[0] != '[')
{
continue;
}
p = strchr(tmp_buf, ']');
if (NULL == p)
{ /* 不合法段名 */
continue;
}
*p = '\0';
strcpy(tmp_segname, &tmp_buf[1]);
if (0 == strcmp(seg_name, tmp_segname))
{
return lines;
}
}
DBG
return -1;
}/*}}}*/
void ini_buf_set_value(char *buf, const char *value)
{/*{{{*/
char *p = NULL;
p = strrchr(buf, '=');
assert(p != NULL); /* p == NULL could never be happen */
p++;
/* 保留空白 */
while ((*p != '\0') && (' ' == *p))
p++;
strcpy(p, value);
strcat(p, "\n");
}/*}}}*/
int ini_get(const char *ini_file, const char *seg_name, const char *key, char *value)
{/*{{{*/
int ret = 0;
FILE *fp_ini = NULL;
fp_ini = fopen(ini_file, "rb");
if (NULL == fp_ini)
{
DBG
return -1;
}
ret = ini_find_seg(fp_ini, seg_name);
if (ret < 0)
{
fclose(fp_ini);
DBG
return -2;
}
ret = ini_find_key(fp_ini, key, value);
if (ret < 0)
{
fclose(fp_ini);
DBG
return -3;
}
fclose(fp_ini);
return 0;
}/*}}}*/
int ini_set(const char *ini_file, const char *seg_name, const char *key, const char *value)
{/*{{{*/
int ret = 0;
int lines = 0;
char tmp_ini_file[BUFSIZ + 1] = "\0";
char tmp_buf[MAX_BUF_LEN + 1] = "\0";
FILE *fp_ini = NULL;
FILE *fp_tmp_ini = NULL;
fp_ini = fopen(ini_file, "rb");
if (NULL == fp_ini)
{
DBG
return -1;
}
get_uniq_name(tmp_ini_file, BUFSIZ);
fp_tmp_ini = fopen(tmp_ini_file, "wb");
if (NULL == fp_tmp_ini)
{
fclose(fp_ini);
DBG
return -4;
}
ret = ini_find_seg(fp_ini, seg_name);
if (ret < 0)
{
fclose(fp_tmp_ini);
fclose(fp_ini);
DBG
return -2;
}
lines += ret;
ret = ini_find_key(fp_ini, key, NULL);
if (ret < 0)
{
fclose(fp_ini);
fclose(fp_tmp_ini);
DBG
return -3;
}
lines += ret;
ret = file_copy_nlines(fp_tmp_ini, fp_ini, SEEK_SET, lines-1);
if (ret < 0)
{
fclose(fp_ini);
fclose(fp_tmp_ini);
DBG
return -5;
}
fgets(tmp_buf, MAX_BUF_LEN, fp_ini);
ini_buf_set_value(tmp_buf, value);
fputs(tmp_buf, fp_tmp_ini);
file_copy_nlines(fp_tmp_ini, fp_ini, SEEK_CUR, -1);
fclose(fp_ini);
fclose(fp_tmp_ini);
ret = rename(tmp_ini_file, ini_file);
if (ret < 0)
{
DBG
return -7;
}
return 0;
}/*}}}*/
int main(int argc, char *argv[])
{/*{{{*/
int ret = 0;
char value[BUFSIZ] = "\0";
if (argc != 4)
{
printf("Usage: %s ini_file seg_name key\n", argv[0]);
return -1;
}
ret = ini_get(argv[1], argv[2], argv[3], value);
if (ret < 0)
{
printf("ini_get err[%d]\n", ret);
DBG
return -1;
}
printf("[%s][%s]: [%s]\n", argv[2], argv[3], value);
ret = ini_set(argv[1], argv[2], argv[3], "newvalue");
if (ret < 0)
{
printf("ini_set err:[%d]\n", ret);
DBG
return -1;
}
printf("succeed to set value: [newvalue]\n");
ret = ini_get(argv[1], argv[2], argv[3], value);
if (ret < 0)
{
printf("ini_get err[%d]\n", ret);
DBG
return -1;
}
printf("[%s][%s]: [%s]\n", argv[2], argv[3], value);
return 0;
}/*}}}*/
CFLAGS = -Werror -Wall -g
all: clean ini
clean:
rm -f ini