Compare commits
2 commits
b7f4cb2704
...
a587ab6f8e
Author | SHA1 | Date | |
---|---|---|---|
a587ab6f8e | |||
edacc3e3db |
12 changed files with 138 additions and 35 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -3,3 +3,4 @@ main
|
||||||
log.log
|
log.log
|
||||||
err.log
|
err.log
|
||||||
pam_udaem.so
|
pam_udaem.so
|
||||||
|
logs/*
|
|
@ -7,7 +7,7 @@ exec = /bin/sleep
|
||||||
#the following settings are optional!
|
#the following settings are optional!
|
||||||
|
|
||||||
#arguments (not optional if program requires them)
|
#arguments (not optional if program requires them)
|
||||||
argv = 20
|
argv = 52
|
||||||
|
|
||||||
#restart program when enabled and crashed
|
#restart program when enabled and crashed
|
||||||
restartcrash = true
|
restartcrash = true
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
loopInterval = 500 #uint
|
loopInterval = 500 #uint
|
||||||
|
|
||||||
# what to log
|
# what to log
|
||||||
logLevel = 3 #int
|
logLevel = 3 #int
|
||||||
|
|
||||||
# path to log own log to
|
# path to log own log to
|
||||||
selfLog = udaem.log #char*
|
selfLog = udaem.log #char*
|
||||||
|
@ -14,8 +14,11 @@ logdbdir = logs/ #char*
|
||||||
# directory where .daem files are stored
|
# directory where .daem files are stored
|
||||||
daemondb = config/
|
daemondb = config/
|
||||||
|
|
||||||
# weather to seperate the errf and logf files
|
# weather to seperate the errf and logf files by default
|
||||||
seperateLogs = false #short (bool)
|
seperateLogs = false #short (bool)
|
||||||
|
|
||||||
# (NOT YET SUPPORTED) save logs for a program in a seperate directory
|
# (NOT YET SUPPORTED) save logs for a program in a seperate directory
|
||||||
|
# like:
|
||||||
|
# logdir/sleep/log.log
|
||||||
|
# logdir/tree/log.log
|
||||||
# seperateLogDirs
|
# seperateLogDirs
|
9
makefile
9
makefile
|
@ -1,5 +1,6 @@
|
||||||
all: compile
|
all: daemon client
|
||||||
|
|
||||||
compile:
|
daemon:
|
||||||
gcc src/*.c -o main
|
clang -g src/*.c -o main
|
||||||
gcc src/client/*.c -o client
|
client:
|
||||||
|
clang -g src/client/*.c -o client
|
||||||
|
|
|
@ -7,6 +7,7 @@ struct Config{
|
||||||
char* selflog;
|
char* selflog;
|
||||||
char* logdir;
|
char* logdir;
|
||||||
char* daemdir;
|
char* daemdir;
|
||||||
|
char* shell;
|
||||||
int seperatelogs; // bool
|
int seperatelogs; // bool
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,29 @@
|
||||||
#include "configs.h"
|
#include "configs.h"
|
||||||
#include "daem.h"
|
#include "daem.h"
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
#include <bits/types/cookie_io_functions_t.h>
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <limits.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "config_struct.h"
|
#include "config_struct.h"
|
||||||
|
|
||||||
|
char *makePathRelative(const char *path, const char *relativeto){
|
||||||
|
if(path[0]=='/'){
|
||||||
|
return (char*)path;
|
||||||
|
} else{
|
||||||
|
int reltolen = strlen(relativeto);
|
||||||
|
int pathlen = strlen(path);
|
||||||
|
// check if adding a slash to the relative path is necessary
|
||||||
|
int addslash = (relativeto[reltolen - 1] != '/') ? 1 : 0;
|
||||||
|
char * ret = malloc(reltolen + pathlen + addslash + 1);
|
||||||
|
|
||||||
|
strcpy(ret, relativeto);
|
||||||
|
if(addslash) ret[reltolen] = '/';
|
||||||
|
strcpy(ret + reltolen + addslash, path);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int strtoim_wdef(char *str, int min, int max, int def, int *err){
|
int strtoim_wdef(char *str, int min, int max, int def, int *err){
|
||||||
errno=0;
|
errno=0;
|
||||||
|
@ -66,7 +81,7 @@ int setValueCfg(char *property, char *value, void *c){
|
||||||
cfg->daemdir = value;
|
cfg->daemdir = value;
|
||||||
return 1;
|
return 1;
|
||||||
case 5:{
|
case 5:{
|
||||||
cfg->seperatelogs = strcmp(value, "true")==0;
|
cfg->seperatelogs = strcmp(value, "true") == 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
default:{
|
default:{
|
||||||
|
@ -101,39 +116,39 @@ int setValueDaemon(char *property, char *value, void* d){
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (v) {
|
switch (v) {
|
||||||
case 0:{
|
case 0:{ // name
|
||||||
daemon->name=value;
|
daemon->name = value;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 1:{
|
case 1:{ // exec
|
||||||
daemon->exec=value;
|
daemon->exec = value;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 2:{
|
case 2:{ // argv
|
||||||
daemon->argv=value;
|
daemon->argv = value;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 3:{
|
case 3:{ // logf
|
||||||
daemon->logf=value;
|
daemon->logf = makePathRelative(value, cfgptr->logdir);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 4:{
|
case 4:{ // errf
|
||||||
daemon->errf=value;
|
daemon->errf = makePathRelative(value, cfgptr->logdir);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 5:{
|
case 5:{ // restartcrash
|
||||||
if(strcmp(value, "true")==0){
|
if(strcmp(value, "true")==0){
|
||||||
daemon->configflags|=RESTART_ON_CRASH;
|
daemon->configflags|=RESTART_ON_CRASH;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case 6:{
|
case 6:{ // restartexit
|
||||||
if(strcmp(value, "true")==0){
|
if(strcmp(value, "true")==0){
|
||||||
daemon->configflags|=RESTART_ON_EXIT;
|
daemon->configflags|=RESTART_ON_EXIT;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case 7:{
|
case 7:{ // restartinterval
|
||||||
daemon->restartinterval = strtol(value, NULL, 10);
|
daemon->restartinterval = strtol(value, NULL, 10);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -147,12 +162,17 @@ int setValueDaemon(char *property, char *value, void* d){
|
||||||
}
|
}
|
||||||
|
|
||||||
void parseCfg(char*cf, int (setVal)(char*,char*,void*), void *v){
|
void parseCfg(char*cf, int (setVal)(char*,char*,void*), void *v){
|
||||||
char* c;
|
char* c = 0;
|
||||||
|
|
||||||
char* property=c;
|
char* property=c;
|
||||||
char* value=0;
|
char* value=0;
|
||||||
|
|
||||||
|
// property name length and value length
|
||||||
int pl=0, vl=0;
|
int pl=0, vl=0;
|
||||||
|
|
||||||
|
// space counter
|
||||||
|
int spctr = 0;
|
||||||
|
|
||||||
//0:readproperty
|
//0:readproperty
|
||||||
//1:ignorespace
|
//1:ignorespace
|
||||||
//2:readvalue
|
//2:readvalue
|
||||||
|
@ -168,10 +188,15 @@ void parseCfg(char*cf, int (setVal)(char*,char*,void*), void *v){
|
||||||
state=0;
|
state=0;
|
||||||
//process read property and value
|
//process read property and value
|
||||||
if(property && value){
|
if(property && value){
|
||||||
|
// remove trailing spaces
|
||||||
|
vl -= spctr;
|
||||||
|
|
||||||
|
// property char string
|
||||||
char pc[pl+1];
|
char pc[pl+1];
|
||||||
strncpy(pc, property, pl);
|
strncpy(pc, property, pl);
|
||||||
pc[pl]=0;
|
pc[pl]=0;
|
||||||
|
|
||||||
|
// value char string
|
||||||
char *vc = malloc(sizeof(char)*(vl+1));
|
char *vc = malloc(sizeof(char)*(vl+1));
|
||||||
strncpy(vc, value, vl);
|
strncpy(vc, value, vl);
|
||||||
vc[vl]=0;
|
vc[vl]=0;
|
||||||
|
@ -207,6 +232,9 @@ void parseCfg(char*cf, int (setVal)(char*,char*,void*), void *v){
|
||||||
state=2;
|
state=2;
|
||||||
vl++;
|
vl++;
|
||||||
}
|
}
|
||||||
|
// increment space counter
|
||||||
|
if(*c==' ') spctr++;
|
||||||
|
else spctr = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,12 +247,13 @@ struct Daemon readDaemonCfg(const char *path, int *err){
|
||||||
if(err)*err=1;
|
if(err)*err=1;
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
d.errf="log.log";
|
|
||||||
d.logf="log.log";
|
d.logf="log.log";
|
||||||
d.argv="";
|
d.argv="";
|
||||||
|
|
||||||
parseCfg(cf, setValueDaemon, &d);
|
parseCfg(cf, setValueDaemon, &d);
|
||||||
|
|
||||||
|
if(!d.errf) d.errf = d.logf;
|
||||||
|
|
||||||
free(cf);
|
free(cf);
|
||||||
|
|
||||||
if(d.exec != NULL){
|
if(d.exec != NULL){
|
||||||
|
@ -242,6 +271,7 @@ struct Config readSelfCfg(const char *path, int *err){
|
||||||
sc.loglevel = 0;
|
sc.loglevel = 0;
|
||||||
sc.selflog = "log/udaem.log";
|
sc.selflog = "log/udaem.log";
|
||||||
sc.logdir = "log";
|
sc.logdir = "log";
|
||||||
|
sc.shell = "/bin/sh"; // TODO: implement overriding this var
|
||||||
sc.seperatelogs = 0;
|
sc.seperatelogs = 0;
|
||||||
|
|
||||||
char *cf =readFileC(path);
|
char *cf =readFileC(path);
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
#ifndef __CONFIGS_H__
|
#ifndef __CONFIGS_H__
|
||||||
#define __CONFIGS_H__
|
#define __CONFIGS_H__
|
||||||
|
|
||||||
|
#include "config_struct.h"
|
||||||
#include "daem.h"
|
#include "daem.h"
|
||||||
|
|
||||||
|
extern struct Config *cfgptr;
|
||||||
|
|
||||||
enum state{
|
enum state{
|
||||||
RUNNING=1,
|
RUNNING=1,
|
||||||
EXITED=2,
|
EXITED=2,
|
||||||
|
|
60
src/daem.c
60
src/daem.c
|
@ -1,7 +1,10 @@
|
||||||
#include "daem.h"
|
#include "daem.h"
|
||||||
#include "configs.h"
|
#include "configs.h"
|
||||||
|
#include <asm-generic/errno-base.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -56,21 +59,66 @@ void readDirs(struct Daemon **edlist, unsigned int *edlen, char* daemdir){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handleReopenErr(const char *fdname, const char *file, int errnoval){
|
||||||
|
switch(errnoval){
|
||||||
|
case EACCES:{
|
||||||
|
fprintf(stderr, "FATAL: could not reroute %s to %s , Access denied\n", fdname, file);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EBADF:{
|
||||||
|
fprintf(stderr, "FATAL: could not reroute \"%s\" to \"%s\" , Bad Filename\n", fdname, file);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ENOENT:{
|
||||||
|
fprintf(stderr, "FATAL: could not reroute \"%s\" to \"%s\" , No such directory\n", fdname, file);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:{
|
||||||
|
fprintf(stderr, "FATAL: could not reroute %s to %s , Something went very wrong. errno = %i;\n", fdname, file, errnoval);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
int startProgram(const char* path, const char* arg, const char* stdoutfile, const char* stderrfile, int sleepd){
|
int startProgram(const char* path, const char* arg, const char* stdoutfile, const char* stderrfile, int sleepd){
|
||||||
int res = fork();
|
int res = fork();
|
||||||
if(res==0){
|
if(res==0){
|
||||||
sleep(sleepd);
|
sleep(sleepd);
|
||||||
|
|
||||||
if(loglevel>1)printf("starting prog with path: %s \n",path);
|
if(loglevel>1)printf("starting prog with path: %s \n",path);
|
||||||
|
if(loglevel>2)printf("starting prog with args: %s \n",arg);
|
||||||
|
|
||||||
freopen(stdoutfile, "a+", stdout);
|
|
||||||
freopen(stderrfile, "a+", stderr);
|
// redirect output to file and (TODO: ) input to fifo
|
||||||
if(loglevel>1) printf("==== STARTING PROGRAM %s ====\n", path);
|
FILE *fp;
|
||||||
int ret = execl(path, arg);
|
errno = 0;
|
||||||
if(loglevel>1) printf("==== PROGRAM EXITED WITH CODE %i ====\n", ret);
|
fp = freopen(stdoutfile, "a+", stdout);
|
||||||
|
if(fp == NULL) handleReopenErr("stdout", stdoutfile, errno);
|
||||||
|
fp = freopen(stderrfile, "a+", stderr);
|
||||||
|
if(fp == NULL) handleReopenErr("stderr", stderrfile, errno);
|
||||||
|
|
||||||
|
// log that program is starting
|
||||||
|
if(loglevel>1) printf("==== STARTING PROGRAM %s ====\n", path);
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
|
// concatenate program file path and arguments for shell
|
||||||
|
int pathlen = strlen(path);
|
||||||
|
char *combined = malloc(pathlen + strlen(arg) + 2);
|
||||||
|
strcpy(combined, path);
|
||||||
|
combined[pathlen] = ' ';
|
||||||
|
strcpy(combined + pathlen + 1, arg);
|
||||||
|
|
||||||
|
// execute the program
|
||||||
|
int ret = execl(cfgptr->shell, cfgptr->shell, "-c", combined, NULL);
|
||||||
|
|
||||||
|
// only gets executed when program fails
|
||||||
|
if(loglevel>1) printf("==== PROGRAM (%s) EXITED WITH CODE %i ====\n", path, ret);
|
||||||
|
fclose(stdout);
|
||||||
|
fclose(stderr);
|
||||||
exit(ret);
|
exit(ret);
|
||||||
}else if (res < 0){
|
}else if (res < 0){
|
||||||
if(loglevel>0)printf("fork failed.\n");
|
if(loglevel>0) printf("fork failed.\n");
|
||||||
return -1;
|
return -1;
|
||||||
}else {
|
}else {
|
||||||
return res;
|
return res;
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#define SHELL "/bin/sh";
|
||||||
|
|
||||||
extern int loglevel;
|
extern int loglevel;
|
||||||
|
|
||||||
struct Daemon{
|
struct Daemon{
|
||||||
|
|
|
@ -13,12 +13,15 @@ char *readFileC(const char *filename){
|
||||||
long len = ftell(fp);
|
long len = ftell(fp);
|
||||||
|
|
||||||
//allocate enough memory for the string on the heap
|
//allocate enough memory for the string on the heap
|
||||||
char *ret = (char*)malloc(len);
|
char *ret = (char*)calloc(1, len + 1);
|
||||||
|
|
||||||
//go back to the beginning and read everything to the string
|
//go back to the beginning and read everything to the string
|
||||||
fseek(fp, 0, SEEK_SET);
|
fseek(fp, 0, SEEK_SET);
|
||||||
fread(ret, 1, len, fp);
|
fread(ret, 1, len, fp);
|
||||||
|
|
||||||
|
// make sure NULL terminator is there
|
||||||
|
ret[len] = 0;
|
||||||
|
|
||||||
//close the stream
|
//close the stream
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
|
@ -37,12 +40,15 @@ char *readFileCl(const char *filename, unsigned long* length){
|
||||||
*length=len;
|
*length=len;
|
||||||
|
|
||||||
//allocate enough memory for the string on the heap
|
//allocate enough memory for the string on the heap
|
||||||
char *ret = (char*)malloc(len);
|
char *ret = (char*)calloc(1, len + 1);
|
||||||
|
|
||||||
//go back to the beginning and read everything to the string
|
//go back to the beginning and read everything to the string
|
||||||
fseek(fp, 0, SEEK_SET);
|
fseek(fp, 0, SEEK_SET);
|
||||||
fread(ret, 1, len, fp);
|
fread(ret, 1, len, fp);
|
||||||
|
|
||||||
|
// make sure NULL terminator is there
|
||||||
|
ret[len] = 0;
|
||||||
|
|
||||||
//close the stream
|
//close the stream
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
|
|
||||||
struct Daemon *daemonlist;
|
struct Daemon *daemonlist;
|
||||||
|
struct Config *cfgptr;
|
||||||
unsigned int daemonNum;
|
unsigned int daemonNum;
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,14 +38,20 @@ void onterm(int sig){
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sigpipe(int sig){
|
||||||
|
printf("sigpipe ):\n");
|
||||||
|
}
|
||||||
|
|
||||||
int main(){
|
int main(){
|
||||||
signal(SIGTERM, onterm);
|
signal(SIGTERM, onterm);
|
||||||
signal(SIGINT, onterm);
|
signal(SIGINT, onterm);
|
||||||
|
signal(SIGPIPE, sigpipe);
|
||||||
|
|
||||||
struct Config cfg = readSelfCfg("config/udaem.conf", NULL);
|
struct Config cfg = readSelfCfg("config/udaem.conf", NULL);
|
||||||
|
cfgptr = &cfg;
|
||||||
|
|
||||||
loglevel = cfg.loglevel;
|
loglevel = cfg.loglevel;
|
||||||
|
printf("loglevel: %i\n", loglevel);
|
||||||
|
|
||||||
readDirs(&daemonlist, &daemonNum, cfg.daemdir);
|
readDirs(&daemonlist, &daemonNum, cfg.daemdir);
|
||||||
commloop(&daemonlist, &daemonNum, &sockfd, &cfg);
|
commloop(&daemonlist, &daemonNum, &sockfd, &cfg);
|
||||||
|
|
|
@ -110,6 +110,7 @@ void commhandler(int cfd, char *buffer, enum msgtype type, unsigned long bufferl
|
||||||
len+=sizeof(daem->exitreason);
|
len+=sizeof(daem->exitreason);
|
||||||
|
|
||||||
char buf[len];
|
char buf[len];
|
||||||
|
memset(buf, 0, len * sizeof(char));
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
p=buf;
|
p=buf;
|
||||||
|
@ -179,7 +180,7 @@ void handleconn(int cfd, struct Daemon **daemonlist, unsigned int *daemonNum, st
|
||||||
char buffer[message.datalength];
|
char buffer[message.datalength];
|
||||||
long rl = recv(cfd, buffer, message.datalength, 0);
|
long rl = recv(cfd, buffer, message.datalength, 0);
|
||||||
if(buffer[message.datalength-1]==0 && rl==message.datalength){
|
if(buffer[message.datalength-1]==0 && rl==message.datalength){
|
||||||
currupt=0;
|
currupt = 0;
|
||||||
commhandler(cfd, buffer, message.type, message.datalength, daemonlist, daemonNum, conf);
|
commhandler(cfd, buffer, message.type, message.datalength, daemonlist, daemonNum, conf);
|
||||||
}
|
}
|
||||||
}else if(message.datalength == 0){
|
}else if(message.datalength == 0){
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue