Compare commits
No commits in common. "master" and "20d355a0f69fdfc229e76f14d5a6adb8b5736b69" have entirely different histories.
master
...
20d355a0f6
2
Makefile
2
Makefile
@ -5,7 +5,7 @@ CFLAGS += -g -O2 -Wall -I../libconf -L../libconf
|
|||||||
LIBS = -lconf -static
|
LIBS = -lconf -static
|
||||||
OBJ := daemon
|
OBJ := daemon
|
||||||
|
|
||||||
all: conf.o popen.o main.o
|
all: popen.o main.o
|
||||||
$(CC) $(CFLAGS) -o $(OBJ) $^ $(LIBS)
|
$(CC) $(CFLAGS) -o $(OBJ) $^ $(LIBS)
|
||||||
$(STRIP) $(OBJ)
|
$(STRIP) $(OBJ)
|
||||||
-chmod a+x $(OBJ)
|
-chmod a+x $(OBJ)
|
||||||
|
49
README.md
49
README.md
@ -1,35 +1,24 @@
|
|||||||
# Daemon
|
### Daemon
|
||||||
Process daemon
|
根据程序名称和时间为判断条件的进程守护程序.
|
||||||
|
配置文件默认 daemon.conf
|
||||||
# build
|
global {
|
||||||
git clone https://git.aixiao.me:443/aixiao/libconf.git
|
PROCESS_NAME = "frpc"; //进程名称条件变量
|
||||||
git clone https://git.aixiao.me:443/aixiao/daemon.git
|
COMMAND = "ls -al"; //进程名称条件变量不成立执行的命令
|
||||||
|
TIME = "10"; //时间条件变量, 单位秒
|
||||||
|
LOGFILE = "log.txt"; //日志记录
|
||||||
|
}
|
||||||
|
|
||||||
|
### Build
|
||||||
|
Linux编译:
|
||||||
|
git clone https://github.com/niuyuling/daemon.git
|
||||||
|
git clone https://github.com/niuyuling/libconf.git
|
||||||
cd libconf
|
cd libconf
|
||||||
make clean; make
|
make clean; make
|
||||||
cd ../daemon
|
cd ../daemon
|
||||||
make clean; make
|
make clean; make
|
||||||
|
|
||||||
# HELP
|
### Help
|
||||||
root@NIUYULING:/mnt/c/Users/niuyuling/Desktop/conf# ./daemon -?
|
#启动
|
||||||
Process daemon
|
./daemon
|
||||||
Author: AIXIAO@AIXIAO.ME
|
#关闭
|
||||||
Usage: [-?h] [-c filename]
|
killall daemon
|
||||||
|
|
||||||
Options:
|
|
||||||
-c : set configuration file, (default: daemon.conf)
|
|
||||||
-? -h : help information
|
|
||||||
|
|
||||||
root@NIUYULING:/mnt/c/Users/niuyuling/Desktop/conf#
|
|
||||||
|
|
||||||
|
|
||||||
配置文件示列:
|
|
||||||
global {
|
|
||||||
PROCESS="ls" -> "ls -al"; // 要执行的命令和进程名, 依'" -> "'为分界, '" -> "'之前的字符为进程名字, '" -> "'之后的字符串为要执行的命令.(PROCESS配置理论可以有无数个, 通过链表存储)
|
|
||||||
PROCESS="ls1" -> "ls -al"; // 同上
|
|
||||||
PROCESS="id" -> "id"; // 同上
|
|
||||||
TIME = "10"; // 循环时间, 单位秒. 大于等于1
|
|
||||||
LOGFILE = "log_daemon.txt"; // 日志文件
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
215
conf.c
215
conf.c
@ -1,215 +0,0 @@
|
|||||||
#include "conf.h"
|
|
||||||
|
|
||||||
/* 字符串预处理,设置转义字符 */
|
|
||||||
static void string_pretreatment(char *str, int *len)
|
|
||||||
{
|
|
||||||
char *lf, *p, *ori_strs[] = { "\\r", "\\n", "\\b", "\\v", "\\f", "\\t", "\\a", "\\b", "\\0" }, to_chrs[] = { '\r', '\n', '\b', '\v', '\f', '\t', '\a', '\b', '\0' };
|
|
||||||
int i;
|
|
||||||
|
|
||||||
while ((lf = strchr(str, '\n')) != NULL) {
|
|
||||||
for (p = lf + 1; *p == ' ' || *p == '\t' || *p == '\n' || *p == '\r'; p++)
|
|
||||||
*len -= 1;
|
|
||||||
strcpy(lf, p);
|
|
||||||
*len -= 1;
|
|
||||||
}
|
|
||||||
for (i = 0; i < sizeof(to_chrs); i++) {
|
|
||||||
for (p = strstr(str, ori_strs[i]); p; p = strstr(p, ori_strs[i])) {
|
|
||||||
//支持\\r
|
|
||||||
*(p - 1) == '\\' ? (*p--) : (*p = to_chrs[i]);
|
|
||||||
memmove(p + 1, p + 2, strlen(p + 2));
|
|
||||||
(*len)--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 在content中,设置变量(var)的首地址,值(val)的位置首地址和末地址,返回下一行指针 */
|
|
||||||
static char *set_var_val_lineEnd(char *content, char **var, char **val_begin, char **val_end)
|
|
||||||
{
|
|
||||||
char *p, *pn, *lineEnd;
|
|
||||||
;
|
|
||||||
int val_len;
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
if (content == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
for (; *content == ' ' || *content == '\t' || *content == '\r' || *content == '\n'; content++) ;
|
|
||||||
if (*content == '\0')
|
|
||||||
return NULL;
|
|
||||||
*var = content;
|
|
||||||
pn = strchr(content, '\n');
|
|
||||||
p = strchr(content, '=');
|
|
||||||
if (p == NULL) {
|
|
||||||
if (pn) {
|
|
||||||
content = pn + 1;
|
|
||||||
continue;
|
|
||||||
} else
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
content = p;
|
|
||||||
//将变量以\0结束
|
|
||||||
for (p--; *p == ' ' || *p == '\t'; p--) ;
|
|
||||||
*(p + 1) = '\0';
|
|
||||||
//值的首地址
|
|
||||||
for (content++; *content == ' ' || *content == '\t'; content++) ;
|
|
||||||
if (*content == '\0')
|
|
||||||
return NULL;
|
|
||||||
//双引号引起来的值支持换行
|
|
||||||
if (*content == '"') {
|
|
||||||
*val_begin = content + 1;
|
|
||||||
*val_end = strstr(*val_begin, "\";");
|
|
||||||
if (*val_end != NULL)
|
|
||||||
break;
|
|
||||||
} else
|
|
||||||
*val_begin = content;
|
|
||||||
*val_end = strchr(content, ';');
|
|
||||||
if (pn && *val_end > pn) {
|
|
||||||
content = pn + 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*val_end) {
|
|
||||||
**val_end = '\0';
|
|
||||||
val_len = *val_end - *val_begin;
|
|
||||||
lineEnd = *val_end;
|
|
||||||
} else {
|
|
||||||
val_len = strlen(*val_begin);
|
|
||||||
*val_end = lineEnd = *val_begin + val_len;
|
|
||||||
}
|
|
||||||
string_pretreatment(*val_begin, &val_len);
|
|
||||||
*val_end = *val_begin + val_len;
|
|
||||||
//printf("var[%s]\nbegin[%s]\n\n", *var, *val_begin);
|
|
||||||
return lineEnd;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 在buff中读取模块(global http https httpdns httpudp)内容 */
|
|
||||||
static char *read_module(char *buff, const char *module_name)
|
|
||||||
{
|
|
||||||
int len;
|
|
||||||
char *p, *p0;
|
|
||||||
|
|
||||||
len = strlen(module_name);
|
|
||||||
p = buff;
|
|
||||||
while (1) {
|
|
||||||
while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n')
|
|
||||||
p++;
|
|
||||||
if (strncasecmp(p, module_name, len) == 0) {
|
|
||||||
p += len;
|
|
||||||
while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n')
|
|
||||||
p++;
|
|
||||||
if (*p == '{')
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if ((p = strchr(p, '\n')) == NULL)
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if ((p0 = strchr(++p, '}')) == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return strndup(p, p0 - p);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void parse_global_module(char *content)
|
|
||||||
{
|
|
||||||
char *var, *val_begin, *val_end, *lineEnd;
|
|
||||||
conf *conf_node = NULL;
|
|
||||||
char *p1 = NULL, *s = NULL, *t = NULL;
|
|
||||||
char *p2 = NULL;
|
|
||||||
|
|
||||||
while ((lineEnd = set_var_val_lineEnd(content, &var, &val_begin, &val_end)) != NULL) {
|
|
||||||
|
|
||||||
if (strcasecmp(var, "PROCESS") == 0) {
|
|
||||||
conf_node = (conf *)malloc(sizeof(*conf_node));
|
|
||||||
conf_node->PROCESS = strdup(val_begin);
|
|
||||||
conf_node->PROCESS_len = val_end - val_begin;
|
|
||||||
|
|
||||||
p1 = strstr(val_begin, "->");
|
|
||||||
for (t = p1; *t != '"'; ++t) ;
|
|
||||||
conf_node->PROCESS_command = strdup(t + 1);
|
|
||||||
p2 = strchr(t+1, '\0');
|
|
||||||
conf_node->PROCESS_command_len = p2 - (t + 1);
|
|
||||||
|
|
||||||
for (s = p1 - 1; *s == ' '; s--) {
|
|
||||||
if (s == val_begin)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (*s == '"')
|
|
||||||
s--;
|
|
||||||
|
|
||||||
conf_node->PROCESS_name = strndup(val_begin, s - val_begin + 1);
|
|
||||||
conf_node->PROCESS_name_len = s - val_begin + 1;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
conf_node->next = NULL;
|
|
||||||
if (conf_head == NULL) {
|
|
||||||
conf_head = conf_node;
|
|
||||||
} else {
|
|
||||||
conf_node->next = conf_head;
|
|
||||||
conf_head = conf_node;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
content = strchr(lineEnd + 1, '\n');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_conf(conf * p) {
|
|
||||||
conf *temp = p; //将temp指针重新指向头结点
|
|
||||||
while (temp) { //只要temp指针指向的结点的next不是Null就执行输出
|
|
||||||
if (temp->PROCESS)
|
|
||||||
printf("%s %d\n", temp->PROCESS, temp->PROCESS_len);
|
|
||||||
if (temp->PROCESS_name)
|
|
||||||
printf("%s %d\n", temp->PROCESS_name, temp->PROCESS_name_len);
|
|
||||||
if (temp->PROCESS_command)
|
|
||||||
printf("%s %d\n", temp->PROCESS_command, temp->PROCESS_command_len);
|
|
||||||
|
|
||||||
temp = temp->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void free_conf(conf *p) {
|
|
||||||
conf *temp = p;
|
|
||||||
while (temp) {
|
|
||||||
if (temp->PROCESS)
|
|
||||||
free(temp->PROCESS);
|
|
||||||
if (temp->PROCESS_name)
|
|
||||||
free(temp->PROCESS_name);
|
|
||||||
if (temp->PROCESS_command)
|
|
||||||
free(temp->PROCESS_command);
|
|
||||||
|
|
||||||
temp = temp->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void read_conf_link(char *path)
|
|
||||||
{
|
|
||||||
char *buff, *global_content;
|
|
||||||
FILE *file;
|
|
||||||
long file_size;
|
|
||||||
|
|
||||||
/* 读取配置文件到缓冲区 */
|
|
||||||
file = fopen(path, "r");
|
|
||||||
if (file == NULL) {
|
|
||||||
printf("cannot open config file.\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
fseek(file, 0, SEEK_END);
|
|
||||||
file_size = ftell(file);
|
|
||||||
buff = (char *)alloca(file_size + 1);
|
|
||||||
if (buff == NULL)
|
|
||||||
printf("out of memory.\n");
|
|
||||||
rewind(file);
|
|
||||||
fread(buff, file_size, 1, file);
|
|
||||||
fclose(file);
|
|
||||||
buff[file_size] = '\0';
|
|
||||||
/* 读取global模块内容 */
|
|
||||||
if ((global_content = read_module(buff, "global")) == NULL)
|
|
||||||
printf("read global module error\n");
|
|
||||||
parse_global_module(global_content);
|
|
||||||
free(global_content);
|
|
||||||
|
|
||||||
}
|
|
22
conf.h
22
conf.h
@ -1,22 +0,0 @@
|
|||||||
#ifndef CONF_H
|
|
||||||
#define CONF_H
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
typedef struct conf {
|
|
||||||
char *PROCESS;
|
|
||||||
char *PROCESS_name, *PROCESS_command;
|
|
||||||
|
|
||||||
int PROCESS_len, PROCESS_name_len, PROCESS_command_len;
|
|
||||||
struct conf *next;
|
|
||||||
} conf;
|
|
||||||
|
|
||||||
|
|
||||||
extern conf *conf_head;
|
|
||||||
extern void read_conf_link(char *path);
|
|
||||||
extern void free_conf(conf *p);
|
|
||||||
extern void print_conf(conf *p);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,7 +1,6 @@
|
|||||||
global {
|
global {
|
||||||
PROCESS="ls" -> "ls -al";
|
PROCESS_NAME = "frpc";
|
||||||
PROCESS="ls1" -> "ls -al";
|
COMMAND = "ls -al";
|
||||||
PROCESS="init" -> "id";
|
|
||||||
TIME = "10";
|
TIME = "10";
|
||||||
LOGFILE = "log_daemon.txt";
|
LOGFILE = "log.txt";
|
||||||
}
|
}
|
107
main.c
107
main.c
@ -1,10 +1,8 @@
|
|||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "conf.h"
|
|
||||||
#include "libconf.h"
|
#include "libconf.h"
|
||||||
|
|
||||||
conf *conf_head = NULL;
|
int get_process_pid(char *proces_name)
|
||||||
|
{
|
||||||
int get_process_pid(char *proces_name) {
|
|
||||||
char bufer[PATH_SIZE];
|
char bufer[PATH_SIZE];
|
||||||
char comm[PATH_SIZE];
|
char comm[PATH_SIZE];
|
||||||
char proc_comm_name[PATH_SIZE];
|
char proc_comm_name[PATH_SIZE];
|
||||||
@ -43,95 +41,60 @@ int get_process_pid(char *proces_name) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *times() {
|
char *times()
|
||||||
|
{
|
||||||
time_t t;
|
time_t t;
|
||||||
struct tm *timeinfo;
|
struct tm *timeinfo;
|
||||||
|
|
||||||
time(&t);
|
time(&t);
|
||||||
timeinfo = localtime(&t);
|
timeinfo = localtime(&t);
|
||||||
return asctime(timeinfo);
|
return asctime(timeinfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
int logs(char *str, char *configfile) {
|
int logs(char *str, char *configfile)
|
||||||
|
{
|
||||||
FILE *fp = NULL;
|
FILE *fp = NULL;
|
||||||
|
|
||||||
fp = fopen(read_conf(configfile, "global", "LOGFILE"), "a+");
|
fp = fopen(read_conf(configfile, "global", "LOGFILE"), "a+");
|
||||||
fprintf(fp, str);
|
fprintf(fp, str);
|
||||||
return fclose(fp);
|
return fclose(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t copy_new_mem(char *src, int src_len, char **dest) {
|
int loop(char *configfile)
|
||||||
*dest = (char *)malloc(src_len + 1);
|
|
||||||
if (*dest == NULL)
|
|
||||||
return 1;
|
|
||||||
memcpy(*dest, src, src_len);
|
|
||||||
*((*dest)+src_len) = '\0';
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int loop(char *configfile, conf *p)
|
|
||||||
{
|
{
|
||||||
conf *conf = p;
|
|
||||||
|
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char buffer[CACHE_SIZE];
|
char buffer[PATH_SIZE];
|
||||||
char log_content[CACHE_SIZE];
|
|
||||||
memset(log_content, 0, CACHE_SIZE);
|
|
||||||
while (1) {
|
while (1) {
|
||||||
while (conf) {
|
if (get_process_pid(read_conf(configfile, "global", "PROCESS_NAME")) <= 0) {
|
||||||
if (conf->PROCESS) {
|
logs(times(), configfile);
|
||||||
if (get_process_pid(conf->PROCESS_name) <= 0) {
|
logs("没有运行\n", configfile);
|
||||||
strcpy(log_content, times());
|
fp = _popen(read_conf(configfile, "global", "COMMAND"), "r");
|
||||||
strcat(log_content, conf->PROCESS_name);
|
|
||||||
strcat(log_content, " Not running\n");
|
logs(times(), configfile);
|
||||||
logs(log_content, configfile);
|
logs("执行结果\n", configfile);
|
||||||
|
while (fgets(buffer, sizeof(buffer), fp)) {
|
||||||
fp = _popen(conf->PROCESS_command, "r");
|
//printf("%s", buffer);
|
||||||
memset(buffer, 0, CACHE_SIZE);
|
logs(buffer, configfile);
|
||||||
while (fgets(buffer, sizeof(buffer), fp)) {
|
|
||||||
//printf("%s", buffer);
|
|
||||||
logs(buffer, configfile);
|
|
||||||
}
|
|
||||||
_pclose(fp);
|
|
||||||
} else {
|
|
||||||
strcpy(log_content, times());
|
|
||||||
strcat(log_content, conf->PROCESS_name);
|
|
||||||
strcat(log_content, " Running\n");
|
|
||||||
logs(log_content, configfile);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
conf = conf->next;
|
_pclose(fp);
|
||||||
|
} else {
|
||||||
|
logs(times(), configfile);
|
||||||
|
logs("运行\n", configfile);
|
||||||
}
|
}
|
||||||
conf = p;
|
|
||||||
sleep(atoi(read_conf(configfile, "global", "TIME")));
|
sleep(atoi(read_conf(configfile, "global", "TIME")));
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[], char **env) {
|
int main(int argc, char **argv, char **env)
|
||||||
|
{
|
||||||
char configfile[PATH_SIZE];
|
char configfile[PATH_SIZE];
|
||||||
int opt;
|
int opt;
|
||||||
|
|
||||||
memset(configfile, 0, PATH_SIZE);
|
memset(configfile, 0, PATH_SIZE);
|
||||||
while ((opt = getopt(argc, argv, "c:h?")) != -1) {
|
while ((opt = getopt(argc, argv, "c:")) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'c':
|
case 'c':
|
||||||
strcpy(configfile, optarg);
|
strcpy(configfile, optarg);
|
||||||
break;
|
break;
|
||||||
case 'h':
|
|
||||||
case '?':
|
|
||||||
printf("%s\n",
|
|
||||||
"Process daemon\n"\
|
|
||||||
"Author: AIXIAO@AIXIAO.ME\n"\
|
|
||||||
"Usage: [-?h] [-c filename]\n"\
|
|
||||||
"\n"\
|
|
||||||
"Options:\n"\
|
|
||||||
"-c : set configuration file, (default: daemon.conf)\n"\
|
|
||||||
"-? -h : help information\n");
|
|
||||||
exit(1);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -140,20 +103,14 @@ int main(int argc, char *argv[], char **env) {
|
|||||||
if (strlen(configfile) == 0) {
|
if (strlen(configfile) == 0) {
|
||||||
strcpy(configfile, "daemon.conf");
|
strcpy(configfile, "daemon.conf");
|
||||||
}
|
}
|
||||||
|
printf("%s\n", configfile);
|
||||||
if (daemon(1, 1)) { // 守护, 脱离终端
|
|
||||||
|
if (daemon(1, 1)) {
|
||||||
perror("daemon");
|
perror("daemon");
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
read_conf_link(configfile);
|
loop(configfile);
|
||||||
/* Test Code
|
|
||||||
print_conf(conf_head);
|
|
||||||
free_conf(conf_head);
|
|
||||||
exit(0);
|
|
||||||
*/
|
|
||||||
loop(configfile, conf_head);
|
|
||||||
free_conf(conf_head);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10
main.h
10
main.h
@ -1,7 +1,3 @@
|
|||||||
#ifndef MAIN_H
|
|
||||||
#define MAIN_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -10,11 +6,7 @@
|
|||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#define PATH_SIZE 2700
|
#define PATH_SIZE 270
|
||||||
#define CACHE_SIZE 2700
|
|
||||||
|
|
||||||
FILE *_popen(const char *cmdstring, const char *type);
|
FILE *_popen(const char *cmdstring, const char *type);
|
||||||
int _pclose(FILE * fp);
|
int _pclose(FILE * fp);
|
||||||
int8_t copy_new_mem(char *src, int src_len, char **dest);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
Loading…
Reference in New Issue
Block a user