diff --git a/.gitignore b/.gitignore index a63190d..00b3a62 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ main log.log err.log -pam_udaem.so \ No newline at end of file +pam_udaem.so +logs/* \ No newline at end of file diff --git a/config/example.daem.conf b/config/example.daem.conf index 5864ff9..96c577f 100644 --- a/config/example.daem.conf +++ b/config/example.daem.conf @@ -7,7 +7,7 @@ exec = /bin/sleep #the following settings are optional! #arguments (not optional if program requires them) -argv = 20 +argv = 52 #restart program when enabled and crashed restartcrash = true diff --git a/config/udaem.conf b/config/udaem.conf index 20b3917..81f8c75 100644 --- a/config/udaem.conf +++ b/config/udaem.conf @@ -3,7 +3,7 @@ loopInterval = 500 #uint # what to log -logLevel = 3 #int +logLevel = 3 #int # path to log own log to selfLog = udaem.log #char* @@ -14,8 +14,11 @@ logdbdir = logs/ #char* # directory where .daem files are stored daemondb = config/ -# weather to seperate the errf and logf files +# weather to seperate the errf and logf files by default seperateLogs = false #short (bool) # (NOT YET SUPPORTED) save logs for a program in a seperate directory +# like: +# logdir/sleep/log.log +# logdir/tree/log.log # seperateLogDirs \ No newline at end of file diff --git a/makefile b/makefile index 95318b7..dec0e1f 100644 --- a/makefile +++ b/makefile @@ -1,5 +1,6 @@ -all: compile +all: daemon client -compile: - gcc src/*.c -o main - gcc src/client/*.c -o client +daemon: + clang -g src/*.c -o main +client: + clang -g src/client/*.c -o client diff --git a/src/config_struct.h b/src/config_struct.h index 243217a..4878a96 100644 --- a/src/config_struct.h +++ b/src/config_struct.h @@ -7,6 +7,7 @@ struct Config{ char* selflog; char* logdir; char* daemdir; + char* shell; int seperatelogs; // bool }; diff --git a/src/configs.c b/src/configs.c index 3e0ec34..998b2d4 100644 --- a/src/configs.c +++ b/src/configs.c @@ -1,14 +1,29 @@ #include "configs.h" #include "daem.h" #include "helpers.h" -#include #include -#include #include #include #include #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){ errno=0; @@ -66,7 +81,7 @@ int setValueCfg(char *property, char *value, void *c){ cfg->daemdir = value; return 1; case 5:{ - cfg->seperatelogs = strcmp(value, "true")==0; + cfg->seperatelogs = strcmp(value, "true") == 0; return 0; } default:{ @@ -101,39 +116,39 @@ int setValueDaemon(char *property, char *value, void* d){ } switch (v) { - case 0:{ - daemon->name=value; + case 0:{ // name + daemon->name = value; break; } - case 1:{ - daemon->exec=value; + case 1:{ // exec + daemon->exec = value; break; } - case 2:{ - daemon->argv=value; + case 2:{ // argv + daemon->argv = value; break; } - case 3:{ - daemon->logf=value; + case 3:{ // logf + daemon->logf = makePathRelative(value, cfgptr->logdir); break; } - case 4:{ - daemon->errf=value; + case 4:{ // errf + daemon->errf = makePathRelative(value, cfgptr->logdir); break; } - case 5:{ + case 5:{ // restartcrash if(strcmp(value, "true")==0){ daemon->configflags|=RESTART_ON_CRASH; } return 0; } - case 6:{ + case 6:{ // restartexit if(strcmp(value, "true")==0){ daemon->configflags|=RESTART_ON_EXIT; } return 0; } - case 7:{ + case 7:{ // restartinterval daemon->restartinterval = strtol(value, NULL, 10); 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){ - char* c; + char* c = 0; char* property=c; char* value=0; + + // property name length and value length int pl=0, vl=0; + // space counter + int spctr = 0; + //0:readproperty //1:ignorespace //2:readvalue @@ -168,10 +188,15 @@ void parseCfg(char*cf, int (setVal)(char*,char*,void*), void *v){ state=0; //process read property and value if(property && value){ + // remove trailing spaces + vl -= spctr; + + // property char string char pc[pl+1]; strncpy(pc, property, pl); pc[pl]=0; + // value char string char *vc = malloc(sizeof(char)*(vl+1)); strncpy(vc, value, vl); vc[vl]=0; @@ -207,6 +232,9 @@ void parseCfg(char*cf, int (setVal)(char*,char*,void*), void *v){ state=2; 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; return d; } - d.errf="log.log"; d.logf="log.log"; d.argv=""; parseCfg(cf, setValueDaemon, &d); + if(!d.errf) d.errf = d.logf; + free(cf); if(d.exec != NULL){ @@ -242,6 +271,7 @@ struct Config readSelfCfg(const char *path, int *err){ sc.loglevel = 0; sc.selflog = "log/udaem.log"; sc.logdir = "log"; + sc.shell = "/bin/sh"; // TODO: implement overriding this var sc.seperatelogs = 0; char *cf =readFileC(path); diff --git a/src/configs.h b/src/configs.h index 8fe98dd..8346291 100644 --- a/src/configs.h +++ b/src/configs.h @@ -1,8 +1,11 @@ #ifndef __CONFIGS_H__ #define __CONFIGS_H__ +#include "config_struct.h" #include "daem.h" +extern struct Config *cfgptr; + enum state{ RUNNING=1, EXITED=2, diff --git a/src/daem.c b/src/daem.c index 1c4ad28..285370e 100644 --- a/src/daem.c +++ b/src/daem.c @@ -1,7 +1,10 @@ #include "daem.h" #include "configs.h" +#include +#include #include #include +#include #include #include #include @@ -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 res = fork(); if(res==0){ sleep(sleepd); 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); - if(loglevel>1) printf("==== STARTING PROGRAM %s ====\n", path); - int ret = execl(path, arg); - if(loglevel>1) printf("==== PROGRAM EXITED WITH CODE %i ====\n", ret); + + // redirect output to file and (TODO: ) input to fifo + FILE *fp; + errno = 0; + 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); }else if (res < 0){ - if(loglevel>0)printf("fork failed.\n"); + if(loglevel>0) printf("fork failed.\n"); return -1; }else { return res; diff --git a/src/daem.h b/src/daem.h index c425a35..962afcb 100644 --- a/src/daem.h +++ b/src/daem.h @@ -5,6 +5,8 @@ #include #include +#define SHELL "/bin/sh"; + extern int loglevel; struct Daemon{ diff --git a/src/helpers.c b/src/helpers.c index af33b64..d66a890 100644 --- a/src/helpers.c +++ b/src/helpers.c @@ -13,12 +13,15 @@ char *readFileC(const char *filename){ long len = ftell(fp); //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 fseek(fp, 0, SEEK_SET); fread(ret, 1, len, fp); + // make sure NULL terminator is there + ret[len] = 0; + //close the stream fclose(fp); @@ -37,11 +40,14 @@ char *readFileCl(const char *filename, unsigned long* length){ *length=len; //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 fseek(fp, 0, SEEK_SET); fread(ret, 1, len, fp); + + // make sure NULL terminator is there + ret[len] = 0; //close the stream fclose(fp); diff --git a/src/main.c b/src/main.c index 39ea605..02a5485 100644 --- a/src/main.c +++ b/src/main.c @@ -9,6 +9,7 @@ #include "helpers.h" struct Daemon *daemonlist; +struct Config *cfgptr; unsigned int daemonNum; @@ -37,14 +38,20 @@ void onterm(int sig){ exit(EXIT_SUCCESS); } +void sigpipe(int sig){ + printf("sigpipe ):\n"); +} int main(){ signal(SIGTERM, onterm); signal(SIGINT, onterm); + signal(SIGPIPE, sigpipe); struct Config cfg = readSelfCfg("config/udaem.conf", NULL); + cfgptr = &cfg; loglevel = cfg.loglevel; + printf("loglevel: %i\n", loglevel); readDirs(&daemonlist, &daemonNum, cfg.daemdir); commloop(&daemonlist, &daemonNum, &sockfd, &cfg); diff --git a/src/net.c b/src/net.c index 805da95..033b7cd 100644 --- a/src/net.c +++ b/src/net.c @@ -110,6 +110,7 @@ void commhandler(int cfd, char *buffer, enum msgtype type, unsigned long bufferl len+=sizeof(daem->exitreason); char buf[len]; + memset(buf, 0, len * sizeof(char)); char *p; p=buf; @@ -179,7 +180,7 @@ void handleconn(int cfd, struct Daemon **daemonlist, unsigned int *daemonNum, st char buffer[message.datalength]; long rl = recv(cfd, buffer, message.datalength, 0); if(buffer[message.datalength-1]==0 && rl==message.datalength){ - currupt=0; + currupt = 0; commhandler(cfd, buffer, message.type, message.datalength, daemonlist, daemonNum, conf); } }else if(message.datalength == 0){