linux c数据库备份第四版

该版本算是比较成熟的啦,欢迎大伙拿来试用!!!
1.新增数据库连接和备份时间配置文件conf
2.新增日志文件,程序运行的一些异常会记录在log文件下

后续的工作:
1.将代码切割为多个文件,分类存放代码
2.加入自动后台运行的支持
3.加入开机自动运行的支持
完成上面3个之后,我的linux c数据库备份程序就暂时靠一段落了。

使用提醒:
编译:gcc -o main main.c
后台启动:./main &
停止程序:./main stop

#include<sys/types.h>
#include<sys/wait.h>
#include<ctype.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include<signal.h>
#include<time.h>
#include<stdio.h>

//程序运行的pid信息
#define PID_FILE "./pid.db"
//记录待备份的数据库信息文件
#define DB_FILE "./db_list"
//配置文件信息
#define CONF_FILE "./conf"
//日志文件
#define LOG_FILE "./log"
//最大备份的数据库数量
#define NUM 20
//数据库名字长度的限制
#define LEN 128
//程序轮询时间间隔
#define ALARM_TIME 10

//从文件读取到的数据库信息保存至该数组中
char *db_list[NUM];
//当前待备份的数据库数量
int read_num;
//是否用户终止备份
int isbreak = 0;

//数据库连接信息
typedef struct db_conf {
    char *host;
    char *user;
    char *pass;
}CONF;
//数据库备份时间
typedef struct bat_t {
    int hour;
    int min;
}BAT_T;

//malloc
void malloc_dblist();
//free
void free_dblist();
//读取待备份的数据库信息
int readDbFile();
//读取配置文件信息(数据库连接信息,备份时间等)
CONF readConfFile();
//读取备份的时间信息
BAT_T readBatTFile();
//记录日志信息
void recordLog(char *);
//信号处理函数
void signHandler(int sig);
//记录程序运行的pid信息
int recordPid(int pid);
//获取程序运行时的pid信息
int readPid(void);
//移除程序运行时的pid信息
void delPid(void);

int main(int argc, char *argv[]) 
{
    CONF conf;
    BAT_T bt;
    pid_t pid, old_pid;
    int i, prs;
    char buf[LEN];
    time_t t;
    struct tm *tm_ptr;
    
    struct sigaction act, oldact;
    sigset_t newmask, suspmask, oldmask;
    
    if (argc >= 2) {
        old_pid = (pid_t)readPid();
        //停止掉备份程序
        if (strcmp(argv[1], "stop") == 0) {
            kill(old_pid, SIGINT);
            return 0;
        }
        else if (strcmp(argv[1], "restart") == 0) {
            kill(old_pid, SIGINT);
            sleep(5);
        }
    }
    old_pid = (pid_t)readPid();
    //检测程序是否已经在运行
    if (old_pid > 0) {
        fprintf(stderr, "Progress is running.
");
        return -1;
    }
    
    //记录程序运行的pid信息
    prs = recordPid((int)getpid());
    if (prs == -1) {
        fprintf(stderr, "Open pid.db file error.
");
        return -1;
    }
    //读取待备份的数据库
    int rs = readDbFile();
    if (rs) {
        delPid();
        return rs;
    }
    //读取数据配置信息
    conf = readConfFile();
    //读取备份时间
    bt = readBatTFile();
    
    //信号接管
    act.sa_handler = signHandler;
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;
    sigaction(SIGALRM, &act, 0);
    sigaction(SIGINT, &act, 0);
    
    while (1) {
        time(&t);
        tm_ptr = localtime(&t);
        
        //备份时间内进行备份
        if (bt.hour == (int)tm_ptr->tm_hour && bt.min == (int)tm_ptr->tm_min) {
            for (i = 0; i < read_num; i++) {
                memset(buf, '', LEN);
                //密码为空
                if (!strlen(conf.pass)) {
                    sprintf(buf, "mysqldump -h%s -u%s %s > %s_%02d%02d%02d.sql", 
                        conf.host, conf.user, db_list[i], db_list[i], 
                        tm_ptr->tm_year+1900, tm_ptr->tm_mon+1, tm_ptr->tm_mday);
                }
                else {
                    sprintf(buf, "mysqldump -h%s -u%s -p%s %s > %s_%02d%02d%02d.sql", 
                        conf.host, conf.user, conf.pass, db_list[i], db_list[i], 
                        tm_ptr->tm_year+1900, tm_ptr->tm_mon+1, tm_ptr->tm_mday);
                }
                system(buf);
            }
        }
        
        alarm(ALARM_TIME);
        pause();
        
        if (isbreak) {
            recordLog("User break progress.");
            break;
        }
    }
    
    free_dblist();
    
    delPid();
    
    exit(0);
    
}

void malloc_dblist()
{
    int i = 0;
    //malloc for db_list
    for (i = 0; i < NUM; i++) {
        db_list[i] = malloc(LEN);
        memset(db_list[i], '', LEN);
    }
}
void free_dblist()
{
    int i;
    //free db_list's memory
    for (i = 0; i < NUM; i++) {
        free(db_list[i]);
    }
}

int readDbFile()
{
    FILE *fp;
    
    fp = fopen(DB_FILE, "r");
    if (!fp) {
        char buf[128];
        sprintf(buf, "%s not found
", DB_FILE);
        recordLog(buf);
        fprintf(stderr, "%s not found
", DB_FILE);
        return 1;
    }
    else {
        malloc_dblist();
        
        read_num = 0;
        while (fscanf(fp, "%127[^
]
", db_list[read_num]) == 1) {
            read_num++;
        }
        
        fclose(fp);    
        
        return 0;
    }
    
}

CONF readConfFile()
{
    FILE *fp;
    CONF conf;
    
    if (!(fp = fopen(CONF_FILE, "r"))) {
        conf.host = "localhost";
        conf.user = "root";
        conf.pass = "";
        return conf;
    }
    
    char buf[128];
    while ((fscanf(fp, "%127[^
]
", buf)) == 1) {
        char *tmp1 = strtok(buf, "=");
        char *tmp2 = strtok(NULL, "=");
        
        if (strstr(tmp1, "HOST")) {
            if (tmp2) {
                conf.host = strdup(tmp2);
            }
            else {
                conf.host = "localhost";
            }
        }
        else if (strstr(tmp1, "USER")) {
            if (tmp2) {
                conf.user = strdup(tmp2);
            }
            else {
                conf.host = "root";
            }
        }
        else if (strstr(tmp1, "PASS")) {
            if (tmp2) {
                conf.pass = strdup(tmp2);
            }
            else {
                conf.pass = "";
            }
        }
    }
    
    return conf;
}

BAT_T readBatTFile()
{
    FILE *fp;
    BAT_T bat_time;
    
    if (!(fp = fopen(CONF_FILE, "r"))) {
        bat_time.hour = 02;
        bat_time.min = 00;
        return bat_time;
    }
    
    char buf[128];
    while ((fscanf(fp, "%127[^
]
", buf)) == 1) {
        if (!strstr(buf, "BAT_TIME"))
            continue;
        
        //获取到备份数据数据
        char *tmp1 = strtok(buf, "=");
        char *tmp2 = strtok(NULL, "=");
        //对备份时间数据进行分割
        char *hour = strtok(tmp2, " ");
        char *min = strtok(NULL, " ");
        
        if (hour) {
            bat_time.hour = atoi(hour);
        }
        else {
            bat_time.hour = 02;
        }
        
        if (min) {
            bat_time.min = atoi(min);
        }
        else {
            bat_time.min = 02;
        }
    }
    
    return bat_time;
}

void recordLog(char *msg)
{
    FILE *fp;
    fp = fopen(LOG_FILE, "a");
    if (fp) {
        time_t t;
        struct tm *tm_ptr;
        time(&t);
        tm_ptr = localtime(&t);
        
        fprintf(fp, "%d-%d-%d %d:%d:%d: %s
", (tm_ptr->tm_year+1900), tm_ptr->tm_mon, tm_ptr->tm_mday,
            tm_ptr->tm_hour, tm_ptr->tm_min, tm_ptr->tm_sec, msg);
        fclose(fp);
    }
}

void signHandler(int sig)
{
    char buf[128];
    switch (sig) {
        case SIGALRM:
            //fprintf(stdout, "alarm signal comming:%d.
", sig);
            break;
        case SIGINT:
            //fprintf(stdout, "sigint signal comming:%d.
", sig);
            isbreak = 1;
            break;
        default:
            //fprintf(stdout, "uncatched signal comming:%d.
", sig);
            sprintf(buf, "uncatched signal comming:%d.
", sig);
            recordLog(buf);
    }
}

int recordPid(int pid)
{
    FILE *fp = NULL;
    
    if (!(fp = fopen(PID_FILE, "w")))
        return -1;
    
    pid = getpid();
    fprintf(fp, "%d", (int)pid);
    fclose(fp);
    
    return 0;
}

int readPid(void)
{
    FILE *fp = NULL;
    
    if (!(fp = fopen(PID_FILE, "r")))
        return -1;
    
    int pid;
    if (fscanf(fp, "%d", &pid) != 1) {
        fclose(fp);
        return -2;
    }
    
    fclose(fp);
    
    return pid;
}

void delPid(void)
{
    unlink(PID_FILE);
}
mian.c

conf

#数据库服务器地址
HOST=localhost
#数据库账号
USER=root
#数据库密码
PASS=
#备份时间 :小时 分钟
BAT_TIME=17 25

db_list

mkbl
ck_book
原文地址:https://www.cnblogs.com/qizexi/p/4676290.html