#include #include #include #include #include #include #include #include #include #include"config.h" #define HELP_TEXT "requires a command\n--\ngetSendStatus [objectpath]\nlistUnits\nconfig [configfile / -d]\nset token with GOTIFY_TOKEN=\"sjdfoiasfd\"\n--\n" typedef struct service { char *name; char *targetPath; char *host; bool alerted; int priority; } Service; int gotify_message(char *,char *,char *); int systemdCall(DBusConnection *,char *, char *); int checkIsActive(DBusConnection *connection, char *service_name); int systemdUnitCall(DBusConnection *connection,char *target,char *method,char *param,char **result); int GetSendStatus(DBusConnection *connection,char *objectpath); int ServiceGetSendStatus(DBusConnection *connection,Service *service); int checkState(char *ServiceName,char *result,Service *service); int getPath(char *configPath,int size); /* *sytemctl show gotify-server | grep PID *sudo busctl tree org.freedesktop.systemd1 > get object paths //org/freedesktop/systemd1 //gotify_message("https://5ccppi.org:4433/message?token=","anothertitle","anothermessage"); * */ int main(int argc,char *argv[]) { DBusConnection *connection=NULL; DBusError error; clock_t time; char *str_entry[64]={'\0'}; char *host=NULL; int i=0; int intervall=10; Service services[64]={'\0'}; char *ptr_name=NULL; char path[256]; time = clock(); curl_global_init(CURL_GLOBAL_DEFAULT); printf("time:%f\n",(float)time / CLOCKS_PER_SEC); dbus_error_init(&error); connection = dbus_bus_get(DBUS_BUS_SYSTEM,&error);//DBUS_BUS_SYSTEM DBUS_BUS_SESSION if(dbus_error_is_set(&error)) { fprintf(stderr,"%s",error.message); dbus_error_free(&error); return -1; } printf("This is my unique dbus name: %s\n",dbus_bus_get_unique_name(connection)); if(argc>1) { if(strcmp(argv[1],"getSendStatus")==0) { if(argc>2) { if(argv[2][0]=='/') { GetSendStatus(connection,argv[2]); } else { fprintf(stderr,"\n must be in the form of /org.freedesktop.systemd1/...\n"); return 1; } } else { fprintf(stderr,"%s needs 1 argument\n",argv[1]); return 2; } } else if(strcmp(argv[1],"listUnits")==0) { systemdCall(connection,"ListUnits",NULL); } else if(strcmp(argv[1],"config")==0) { if(argc==3 && strcmp(argv[2],"-d")!=0) { loadConfig(argv[2],str_entry,&host,&intervall,64); printf("[main]intervall:%d\n",intervall); for(i=0;str_entry[i];i++) { printf("entry in config:%s\n",str_entry[i]); GetSendStatus(connection,str_entry[i]); } } else if(argc==3 && strcmp(argv[2],"-d")==0) { printf("Running as a daemon\n"); getPath(path,256); printf("[main]configPath:%s\n",path); loadConfig(path,str_entry,&host,&intervall,64); printf("[main]host:%s\n",host); printf("[main]intervall:%d\n",intervall); for(i=0;str_entry[i];i++) { services[i].targetPath = strdup(str_entry[i]); ptr_name = strrchr(services[i].targetPath,'/'); if(ptr_name!=NULL) { services[i].name = strdup(ptr_name); services[i].name = services[i].name + 1; } else{ fprintf(stderr,"does not seem to be a valid target\n"); services[i].name = strdup("Undefined"); } services[i].alerted = false; services[i].priority = 6; services[i].host = host; printf("Name:%s\ntarget:%s\n",services[i].name,services[i].targetPath); } if(services[0].name) { while(true) { for(i=0;services[i].name;i++) { printf("entry in config:%s\n",services[i].name); ServiceGetSendStatus(connection,&services[i]); } sleep(intervall); } }else { fprintf(stderr,"No service found in config file, please check %s\n",path); } } else { fprintf(stderr,"config requires a config file as argument\nAppend -d for daemonizing\n"); } } else { fprintf(stderr,"Unknown command\n%s",HELP_TEXT); } } else { fprintf(stderr,HELP_TEXT); } curl_global_cleanup(); return 0; } int getPath(char *configPath,int size) { uid_t myid = getuid(); printf("My uid:%d\n",myid); struct passwd *info = getpwuid(myid); printf("My dir:%s\n",info->pw_dir); snprintf(configPath,size,"%s/.config/systemd-gotify/config",info->pw_dir); printf("ConfigPath:%s\n",configPath); return 0; } int DBusOptions(DBusConnection *connection,DBusError **error) //not tested check pointer of error!! { int ret=0,i=0; dbus_bool_t allow_user=0; char **objects = NULL; unsigned long uid; ret = dbus_bus_request_name(connection,"test.method.client",DBUS_NAME_FLAG_REPLACE_EXISTING,*error); if(dbus_error_is_set(*error)) { fprintf(stderr,"%s",(**error).message); dbus_error_free(*error); return -1; }else { printf("name requested from dbus: %d\n",ret); } dbus_connection_set_allow_anonymous(connection,allow_user); printf("user auth dbus requ: %d\n",allow_user); if(!dbus_connection_list_registered(connection,"/",&objects)) { for(i=0;objects[i];i++) { printf("\nobject dbus: %s",objects[i]); } }else{ printf("dbus_connection_list_registered error\n"); } if((ret=dbus_connection_get_unix_user(connection,&uid))==1) { printf("found USERID:%ld",uid); }else { printf("NO userID set in dbus session, servers normali do not authenthicate against users/slaves: %d\n",ret); } return 0; } int GetSendStatus(DBusConnection *connection,char *objectpath) { char *result=0; int ret = systemdUnitCall(connection,objectpath,"Get","SubState",&result); if(ret == 0) { //checkState(objectpath,result,NULL); } else { fprintf(stderr,"could not call systemdunit\n"); } return ret; } int ServiceGetSendStatus(DBusConnection *connection,Service *service) { char *result=0; char *objectpath = service->targetPath; int ret = systemdUnitCall(connection,objectpath,"Get","SubState",&result); if(ret == 0) { checkState(service->name,result,service); } else { fprintf(stderr,"could not call systemdunit\n"); } return ret; } int checkState(char *ServiceName,char *result,Service *service) { int i=0; char *error_strings[]={"dead","inactive","exited"}; printf("result systemdUnitCall: %s\n",result); for(i=0;i<(sizeof(error_strings)/sizeof(error_strings[0]));i++) { //printf("%s %ld\n",error_strings[i],sizeof(error_strings)/sizeof(error_strings[0])); if(strcmp(result,error_strings[i])==0 && service->alerted == false) { service->alerted=true; gotify_message(service->host,ServiceName,"is not running"); printf("!!system unit died!! Alert gotify server!\n"); } else if(strcmp(result,"active")==0 || strcmp(result,"running")==0) { if(service->alerted == true) { gotify_message(service->host,ServiceName,"Running again, after crash"); } service->alerted=false; printf("service seems okay!!\n"); return 0; } } return 1; } int gotify_message(char *url,char *title,char *message) { int ret; CURL *curl; CURLcode res,res2; char post_buffer[128]; char url_buffer[128]; long response_code; curl = curl_easy_init(); const char* token = NULL; if(NULL==(token = getenv("GOTIFY_TOKEN"))) { fprintf(stderr,"Pleas set a token using GOTIFY_TOKEN=\"abcde123\"\n"); } else { printf("Got token from env\n"); ret = snprintf(url_buffer,sizeof(url_buffer),"%s/message?token=%s",url,token); if(ret < sizeof(url_buffer)) { printf("url:%s",url); } else { fprintf(stderr,"error connecting strings for url and token\n"); } } ret = snprintf(post_buffer,sizeof(post_buffer),"title=%s&message=%s&priority=6",title,message); if(ret < sizeof(post_buffer)) { printf("%s %d\n",post_buffer,ret); if(curl) { curl_easy_setopt(curl,CURLOPT_URL,url_buffer); curl_easy_setopt(curl,CURLOPT_POSTFIELDS,post_buffer); curl_easy_setopt(curl,CURLOPT_FOLLOWLOCATION,1L); res = curl_easy_perform(curl); if(res != CURLE_OK) { fprintf(stderr,"curl_easy_perform failed: %s\n",curl_easy_strerror(res)); } res2 = curl_easy_getinfo(curl,CURLINFO_RESPONSE_CODE,&response_code); if((res2 == CURLE_OK) && response_code) { printf("Server returned:%ld\n",response_code); }else { fprintf(stderr,"Error getting info; %ld\n",(long int)res2); } curl_easy_cleanup(curl); }else { fprintf(stderr,"Error initializing curl context\n"); } }else { printf("Error on string concelblalbla: %d\n",ret); } curl_easy_cleanup(curl); return 0; } int systemdCall(DBusConnection *connection,char *method,char *param) { DBusError error; DBusMessage *msg; DBusMessage *ret_msg; DBusMessageIter iter; DBusMessageIter array_iter; char *reply_msg=NULL; int ret1,ret2; dbus_error_init(&error); msg = dbus_message_new_method_call("org.freedesktop.systemd1","/org/freedesktop/systemd1","org.freedesktop.systemd1.Manager",method); if(NULL == msg) { fprintf(stderr,"Message null, no message created\n"); return 1; } else { printf("message created!\n"); } if(param != NULL) { dbus_message_iter_init_append(msg,&iter); if(!dbus_message_iter_append_basic(&iter,DBUS_TYPE_STRING,¶m)) { fprintf(stderr,"Error appending\n"); return -1; } } ret_msg = dbus_connection_send_with_reply_and_block(connection,msg,DBUS_TIMEOUT_INFINITE,&error); if(ret_msg == NULL) { fprintf(stderr,"error on receiving message from peer\n"); } else { DBusMessageIter reply_iter; dbus_message_iter_init(ret_msg,&reply_iter); ret1=dbus_message_iter_get_arg_type(&reply_iter); while(ret1 != DBUS_TYPE_INVALID) { if(ret1 == *DBUS_TYPE_OBJECT_PATH_AS_STRING) { printf("succesfull received message\narg type %c\n",ret1); dbus_message_iter_get_basic(&reply_iter,&reply_msg); printf("returned value: %s\n",reply_msg); } if(ret1 == DBUS_TYPE_STRING) { printf("succesfull received message\narg type %c\n",ret1); dbus_message_iter_get_basic(&reply_iter,&reply_msg); printf("Received message:%s\n",reply_msg); } if(ret1 == DBUS_TYPE_ARRAY) { int element_count = dbus_message_iter_get_element_count(&reply_iter); printf("Array:Elem count %d\n",element_count); //ret2 = dbus_message_iter_get_element_type(&reply_iter); dbus_message_iter_recurse(&reply_iter,&array_iter); int i2=0; ret2 = dbus_message_iter_get_arg_type(&array_iter); while(ret2 != DBUS_TYPE_INVALID) { DBusMessageIter sub_iter; int ret3; ret2 = dbus_message_iter_get_arg_type(&array_iter); dbus_message_iter_recurse(&array_iter,&sub_iter); ret3 = dbus_message_iter_get_arg_type(&sub_iter); while(ret3 != DBUS_TYPE_INVALID) { ret3 = dbus_message_iter_get_arg_type(&sub_iter); //printf("arr_sub_iter:%c\n",ret3); if(ret3 == DBUS_TYPE_STRING) { dbus_message_iter_get_basic(&sub_iter,&reply_msg); printf("%s\n",reply_msg); } ret3=dbus_message_iter_next(&sub_iter); } ret2=dbus_message_iter_next(&array_iter); i2++; } } ret1=dbus_message_iter_next(&reply_iter); } } if(dbus_error_is_set(&error)) { fprintf(stderr,"%s\n",error.message); dbus_error_free(&error); return -1; } return 0; } int systemdUnitCall(DBusConnection *connection,char *target,char *method,char *param,char **result) { DBusError error; DBusMessage *msg; DBusMessage *ret_msg; DBusMessageIter iter; DBusMessageIter array_iter; DBusMessageIter variant_iter; DBusMessageIter sub_iter; int ret3; char *reply_msg=NULL; int ret1,ret2; char *param2 = "org.freedesktop.systemd1.Unit"; dbus_error_init(&error); //dest(servcice/bus) ,path(object) ,iface method msg = dbus_message_new_method_call("org.freedesktop.systemd1",target,"org.freedesktop.DBus.Properties",method); if(NULL == msg) { fprintf(stderr,"Message null, no message created\n"); dbus_message_unref(msg); return 1; } if(param2 != NULL) { dbus_message_iter_init_append(msg,&iter); if(!dbus_message_iter_append_basic(&iter,DBUS_TYPE_STRING,¶m2)) { fprintf(stderr,"Error appending\n"); dbus_message_unref(msg); return -1; } if(!dbus_message_iter_append_basic(&iter,DBUS_TYPE_STRING,¶m)) { fprintf(stderr,"Error appending\n"); dbus_message_unref(msg); return -1; } } ret_msg = dbus_connection_send_with_reply_and_block(connection,msg,DBUS_TIMEOUT_INFINITE,&error); if(ret_msg == NULL) { fprintf(stderr,"error ond receiving message from peer\n"); dbus_message_unref(msg); dbus_message_unref(ret_msg); return 1; } else { DBusMessageIter reply_iter; dbus_message_iter_init(ret_msg,&reply_iter); ret1=dbus_message_iter_get_arg_type(&reply_iter); while(ret1 != DBUS_TYPE_INVALID) { if(ret1 == DBUS_TYPE_OBJECT_PATH) { printf("succesfull received message\narg type %c\n",ret1); dbus_message_iter_get_basic(&reply_iter,&reply_msg); printf("returned value: %s\n",reply_msg); } if(ret1 == DBUS_TYPE_STRING) { printf("succesfull received message\narg type %c\n",ret1); printf("[func]reply_msg:%p , &reply_msg:%p , *reply_msg:%d\n", reply_msg,&reply_msg,*reply_msg); dbus_message_iter_get_basic(&reply_iter,&reply_msg); printf("Received message:%s\n",reply_msg); } if(ret1 == DBUS_TYPE_VARIANT) { dbus_message_iter_recurse(&reply_iter,&variant_iter); char *type = dbus_message_iter_get_signature(&variant_iter); //printf("str_val:%s\n",type); if(type[0] == DBUS_TYPE_STRING) { //printf("[func]&result:%p , result:%p\n",&result,result); dbus_message_iter_get_basic(&variant_iter,result); //printf("*result:%s\n",*result); } dbus_free(type); } if(ret1 == DBUS_TYPE_ARRAY) { int element_count = dbus_message_iter_get_element_count(&reply_iter); printf("Array:Elem count %d\n",element_count); dbus_message_iter_recurse(&reply_iter,&array_iter); ret2 = dbus_message_iter_get_arg_type(&array_iter); while(ret2 != DBUS_TYPE_INVALID) { ret2 = dbus_message_iter_get_arg_type(&array_iter); dbus_message_iter_recurse(&array_iter,&sub_iter); ret3 = dbus_message_iter_get_arg_type(&sub_iter); while(ret3 != DBUS_TYPE_INVALID) { ret3 = dbus_message_iter_get_arg_type(&sub_iter); if(ret3 == DBUS_TYPE_STRING) { dbus_message_iter_get_basic(&sub_iter,&reply_msg); //printf("%s\n",reply_msg); } ret3=dbus_message_iter_next(&sub_iter); } ret2=dbus_message_iter_next(&array_iter); } } ret1=dbus_message_iter_next(&reply_iter); } } if(dbus_error_is_set(&error)) { fprintf(stderr,"%s\n",error.message); dbus_error_free(&error); dbus_message_unref(msg); dbus_message_unref(ret_msg); return 1; } dbus_message_unref(msg); dbus_message_unref(ret_msg); return 0; }