..
processnameN(char*),cmdlineN(char*),pathN(char*),actionN(int)
eg:
bash,bash,./,0 //意味着允许bash自由操作
a.out,/usr/a.out &,/usr,2 //意味着阻止a.out运行
//mon_task_list文件
procmon,./procmon,./,0
bash,bash,.,0
test1,/mnt/hgfs/share/test/test1 &,/mnt/hgfs/share/test/test1,1
//procmon.c文件
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAX_THREAD_NUM 1024
#define MON_IDLE_TIME 2
//action
#define CONFIG_ACTION_ALLOW 0x0
#define CONFIG_ACTION_RESTART 0x1
#define CONFIG_ACTION_FORBIDDEN 0x2
#define CONFIG_ACTION_KILL_ZOMBIE 0x4
//process state
#define TASK_STATUS_NOT_RUN 0x0
#define TASK_STATUS_SLEEPING 0x1
#define TASK_STATUS_RUNNING 0x2
#define TASK_STATUS_ZOMBIE 0x3
#define CONFIG_STRING_DELIMITER ","
typedef struct mon_proc_thread
{
pthread_t tid;
int taskid;
int threadstatus;
int taskstatus;
int action;
char procname[128];
char cmdline[512];
char path[255];
}mon_proc_thread_t;
int displayver();
int displayhlp(char* pszAppname);
int create_mon_task_list(char* filename);
int getprocstatus(mon_proc_thread_t* pmon_proc_thread);
void getprocname(char* src,char*dst);
void handleproc(mon_proc_thread_t* pmon_proc_thread);
void* pthread_fn(void* arg);
pthread_mutex_t g_mutex;
mon_proc_thread_t mon_proc_thread[MAX_THREAD_NUM];
int displayver()
{
printf("******************************\n");
printf("* Application : APP *\n");
printf("* module : procmon *\n");
printf("* version : 1.0.0 *\n");
printf("* company : company *\n");
printf("******************************\n");
return(0);
}
void getprocname(char* src,char*dst)
{
int i;
int endstart = 0;
printf("%s\n",src);
for(i = strlen(src) -1 ; i >=0; i--)
{
if(endstart > 0)
{
dst[i] = src[i];
}
else
{
if(endstart == 0 &&(src[i] == ' ' || src[i] == '\n' || src[i] == '\r'))
{
continue;
}
else if(endstart == 0)
{
endstart = i;
dst[i] = src[i];
}
}
}
}
void handleproc(mon_proc_thread_t* pmon_proc_thread)
{
int ret ;
if(pmon_proc_thread->taskid <= -1)
{
return;
}
switch(pmon_proc_thread->action)
{
case CONFIG_ACTION_ALLOW:
printf("%s are allowed to run\n",pmon_proc_thread->procname);
break;
case CONFIG_ACTION_RESTART:
printf("%s are allowed to run and restart automaticly\n",pmon_proc_thread->procname);
break;
case CONFIG_ACTION_FORBIDDEN:
printf("%s are forbidden to run\n",pmon_proc_thread->procname);
break;
case CONFIG_ACTION_KILL_ZOMBIE:
printf("%s are allowed to run and will be killed when zombie\n",pmon_proc_thread->procname);
break;
default:
printf("%s are forbidden to run\n",pmon_proc_thread->procname);
break;
}
switch(pmon_proc_thread->taskstatus)
{
case TASK_STATUS_NOT_RUN:
if(pmon_proc_thread->action == CONFIG_ACTION_RESTART)
{
ret = system(pmon_proc_thread->cmdline);
}
break;
case TASK_STATUS_SLEEPING:
if(pmon_proc_thread->action == CONFIG_ACTION_FORBIDDEN)
{
printf("killing name=%s pid=%d\n",pmon_proc_thread->procname,pmon_proc_thread->taskid);
kill(pmon_proc_thread->taskid,SIGTERM);
}
break;
case TASK_STATUS_RUNNING:
if(pmon_proc_thread->action == CONFIG_ACTION_FORBIDDEN)
{
printf("killing name=%s pid=%d\n",pmon_proc_thread->procname,pmon_proc_thread->taskid);
kill(pmon_proc_thread->taskid,SIGTERM);
}
break;
case TASK_STATUS_ZOMBIE:
if(pmon_proc_thread->action == CONFIG_ACTION_FORBIDDEN || pmon_proc_thread->action == CONFIG_ACTION_KILL_ZOMBIE)
{
printf("killing name=%s pid=%d\n",pmon_proc_thread->procname,pmon_proc_thread->taskid);
kill(pmon_proc_thread->taskid,SIGTERM);
}
else if(pmon_proc_thread->action == CONFIG_ACTION_RESTART)
{
ret = system(pmon_proc_thread->cmdline);
}
break;
default:
break;
}
}
int create_mon_task_list(char* filename)
{
int i;
int index;
int ret;
FILE* fd;
char err[255] = {0};
char buf[128] = {0};
char* delim = CONFIG_STRING_DELIMITER;
if ((fd = fopen(filename, "r")) < 0) {
sprintf(err,"open %s",filename);
perror(err);
exit(-1);
}
index = 0;
ret = pthread_mutex_init(&g_mutex,NULL);
while(fgets(buf, sizeof(buf),fd)!= NULL)
{
bzero(&mon_proc_thread[index],sizeof(mon_proc_thread[index]));
if(buf[strlen(buf) -1] == '\n')
{
buf[strlen(buf) -1] = '\0';
}
strcpy(mon_proc_thread[index].procname,strtok(buf,delim)); //name
strcpy(mon_proc_thread[index].cmdline,strtok(NULL,delim)); //cmdline
strcpy(mon_proc_thread[index].path,strtok(NULL,delim)); //path
mon_proc_thread[index].action = atoi(strtok(NULL,delim)); //action
ret = pthread_create(&mon_proc_thread[index].tid,NULL,pthread_fn,&mon_proc_thread[index]);
if(ret != 0)
{
perror("create thread");
}
while(mon_proc_thread[index].threadstatus == 0)
{
//printf("waitting for...\n");
usleep(100);
}
bzero(buf,sizeof(buf));
index ++;
}
fclose(fd);
return 1;
}
int getprocstatus(mon_proc_thread_t* pmon_proc_thread)
{
struct dirent * ptr;
DIR * dd;
int i;
FILE* fd;
int len;
int namestart ;
char buf[128];
char name[128];
char status[20];
char* procName = pmon_proc_thread->procname;
if ((dd = opendir("/proc")) == NULL) {
perror("open");
exit(1);
}
while((ptr=readdir(dd))!=NULL)
{
if(atoi(ptr->d_name))
{
buf[0] = '\0';
sprintf(buf,"%s%s%s","/proc/",ptr->d_name,"/status");
if((fd = fopen(buf,"r")) < 0)
{
perror("open");
continue;
}
buf[0] = '\0';
if (fgets(buf, sizeof(buf),fd) == NULL)
{
closedir(dd);
return -1;
}
buf[strlen(buf) -1] = '\0'; /*remove ctrl*/
namestart = 0;
for(i = 0; i< strlen(buf); i++)
{
if(buf[i] == ':')
{
namestart = i;
continue;
}
else if(namestart == 0)
{
continue;
}
else if(isgraph(buf[i]) && namestart > 0)
{
namestart = i;
break;
}
}
strcpy(name,buf + namestart);
for(i = namestart ; i>0; i--)
{
if(isgraph(buf[i]))
{
break;
}
}
buf[i] = '\0';
if(strcmp(name ,procName))
{
fclose(fd) ;
continue;
}
else
{
pmon_proc_thread->taskid = atoi(ptr->d_name);
printf("Name : %s\n",name);
buf[0] = '\0';
if (fgets(buf, sizeof(buf),fd) == NULL)
{
printf("read status failed\n");
fclose(fd);
closedir(dd);
return -1;
}
else
{
buf[strlen(buf)] = '\0';
char* pleft = strtok(buf,"(");
char left[20] ;
strcpy(left,pleft);
char* pstatus = strtok(left,":");
strcpy(status,strtok(NULL,":") + 1);
status[strlen(status) -1] = '\0';
if(strcmp("R",status) == 0)
{
pmon_proc_thread->taskstatus = TASK_STATUS_RUNNING;
}
else if(strcmp("S",status) == 0)
{
pmon_proc_thread->taskstatus = TASK_STATUS_SLEEPING;
}
printf("%s\n",buf);
fclose(fd);
break;
}
}
}
}
closedir(dd);
handleproc(pmon_proc_thread);
pmon_proc_thread->taskstatus = TASK_STATUS_NOT_RUN;
return 1;
}
int displayhlp(char* pszAppname)
{
printf("用法:%s [ver|help]\n",pszAppname);
return(0);
}
void* pthread_fn(void* arg)
{
int ret;
char buf[128] = {0};
mon_proc_thread_t* pmon_proc_thread =(mon_proc_thread_t*)arg;
strcpy(buf,pmon_proc_thread->procname);
pmon_proc_thread->threadstatus = 0;
while(1)
{
pthread_mutex_lock(&g_mutex);
ret = getprocstatus(pmon_proc_thread);
pmon_proc_thread->threadstatus = 1;
pthread_mutex_unlock(&g_mutex);
sleep(MON_IDLE_TIME);
}
return ((void *)0);
}
int main(int argc, char** argv)
{
int ret ;
if(argc >= 2)
{
if(strcmp(argv[1],"help")==0)
{
displayhlp(argv[0]);
return 0;
}
else if(strcmp(argv[1],"ver")==0)
{
displayver();
return 0;
}
else
{
displayhlp(argv[0]);
return 0;
}
}
ret = create_mon_task_list("mon_task_list");
while(1)
{
sleep(10);
}
return 0;
}