void *events_clientize(void *param) { logprintf(LOG_STACK, "%s(...)", __FUNCTION__); unsigned int failures = 0; while(loop && failures <= 5) { struct ssdp_list_t *ssdp_list = NULL; int standalone = 0; settings_find_number("standalone", &standalone); if(ssdp_seek(&ssdp_list) == -1 || standalone == 1) { logprintf(LOG_DEBUG, "no pilight ssdp connections found"); char server[16] = "127.0.0.1"; if((sockfd = socket_connect(server, (unsigned short)socket_get_port())) == -1) { logprintf(LOG_DEBUG, "could not connect to pilight-daemon"); failures++; continue; } } else { if((sockfd = socket_connect(ssdp_list->ip, ssdp_list->port)) == -1) { logprintf(LOG_DEBUG, "could not connect to pilight-daemon"); failures++; continue; } } if(ssdp_list) { ssdp_free(ssdp_list); } struct JsonNode *jclient = json_mkobject(); struct JsonNode *joptions = json_mkobject(); json_append_member(jclient, "action", json_mkstring("identify")); json_append_member(joptions, "config", json_mknumber(1, 0)); json_append_member(jclient, "options", joptions); json_append_member(jclient, "media", json_mkstring("all")); char *out = json_stringify(jclient, NULL); socket_write(sockfd, out); json_free(out); json_delete(jclient); if(socket_read(sockfd, &recvBuff, 0) != 0 || strcmp(recvBuff, "{\"status\":\"success\"}") != 0) { failures++; continue; } failures = 0; while(loop) { if(socket_read(sockfd, &recvBuff, 0) != 0) { break; } else { events_queue(recvBuff); } } } if(recvBuff) { FREE(recvBuff); recvBuff = NULL; } socket_close(sockfd); return 0; }
int main(int argc, char **argv) { // memtrack(); atomicinit(); gc_attach(main_gc); /* Catch all exit signals for gc */ gc_catch(); log_shell_enable(); log_file_disable(); log_level_set(LOG_NOTICE); if((progname = MALLOC(16)) == NULL) { fprintf(stderr, "out of memory\n"); exit(EXIT_FAILURE); } strcpy(progname, "pilight-receive"); struct options_t *options = NULL; struct ssdp_list_t *ssdp_list = NULL; char *server = NULL; unsigned short port = 0; unsigned short stats = 0; char *args = NULL; options_add(&options, 'H', "help", OPTION_NO_VALUE, 0, JSON_NULL, NULL, NULL); options_add(&options, 'V', "version", OPTION_NO_VALUE, 0, JSON_NULL, NULL, NULL); options_add(&options, 'S', "server", OPTION_HAS_VALUE, 0, JSON_NULL, NULL, "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"); options_add(&options, 'P', "port", OPTION_HAS_VALUE, 0, JSON_NULL, NULL, "[0-9]{1,4}"); options_add(&options, 's', "stats", OPTION_NO_VALUE, 0, JSON_NULL, NULL, "[0-9]{1,4}"); /* Store all CLI arguments for later usage and also check if the CLI arguments where used correctly by the user. This will also fill all necessary values in the options struct */ while(1) { int c; c = options_parse(&options, argc, argv, 1, &args); if(c == -1) break; if(c == -2) c = 'H'; switch(c) { case 'H': printf("\t -H --help\t\t\tdisplay this message\n"); printf("\t -V --version\t\t\tdisplay version\n"); printf("\t -S --server=x.x.x.x\t\tconnect to server address\n"); printf("\t -P --port=xxxx\t\t\tconnect to server port\n"); printf("\t -s --stats\t\t\tshow CPU and RAM statistics\n"); exit(EXIT_SUCCESS); break; case 'V': printf("%s v%s\n", progname, PILIGHT_VERSION); exit(EXIT_SUCCESS); break; case 'S': if((server = MALLOC(strlen(args)+1)) == NULL) { fprintf(stderr, "out of memory\n"); exit(EXIT_FAILURE); } strcpy(server, args); break; case 'P': port = (unsigned short)atoi(args); break; case 's': stats = 1; break; default: printf("Usage: %s -l location -d device\n", progname); exit(EXIT_SUCCESS); break; } } options_delete(options); if(server != NULL && port > 0) { if((sockfd = socket_connect(server, port)) == -1) { logprintf(LOG_ERR, "could not connect to pilight-daemon"); return EXIT_FAILURE; } } else if(ssdp_seek(&ssdp_list) == -1) { logprintf(LOG_NOTICE, "no pilight ssdp connections found"); goto close; } else { if((sockfd = socket_connect(ssdp_list->ip, ssdp_list->port)) == -1) { logprintf(LOG_ERR, "could not connect to pilight-daemon"); goto close; } } if(ssdp_list != NULL) { ssdp_free(ssdp_list); } if(server != NULL) { FREE(server); } struct JsonNode *jclient = json_mkobject(); struct JsonNode *joptions = json_mkobject(); json_append_member(jclient, "action", json_mkstring("identify")); json_append_member(joptions, "receiver", json_mknumber(1, 0)); json_append_member(joptions, "stats", json_mknumber(stats, 0)); json_append_member(jclient, "options", joptions); char *out = json_stringify(jclient, NULL); socket_write(sockfd, out); json_free(out); json_delete(jclient); if(socket_read(sockfd, &recvBuff, 0) != 0 || strcmp(recvBuff, "{\"status\":\"success\"}") != 0) { goto close; } while(main_loop) { if(socket_read(sockfd, &recvBuff, 0) != 0) { goto close; } char **array = NULL; unsigned int n = explode(recvBuff, "\n", &array), i = 0; for(i=0;i<n;i++) { struct JsonNode *jcontent = json_decode(array[i]); struct JsonNode *jtype = json_find_member(jcontent, "type"); if(jtype != NULL) { json_remove_from_parent(jtype); json_delete(jtype); } char *content = json_stringify(jcontent, "\t"); printf("%s\n", content); json_delete(jcontent); json_free(content); } array_free(&array, n); } close: if(sockfd > 0) { socket_close(sockfd); } if(recvBuff != NULL) { FREE(recvBuff); recvBuff = NULL; } options_gc(); log_shell_disable(); log_gc(); FREE(progname); return EXIT_SUCCESS; }
int main(int argc, char **argv) { log_shell_enable(); log_file_disable(); log_level_set(LOG_NOTICE); progname = malloc(16); if(!progname) { logprintf(LOG_ERR, "out of memory"); exit(EXIT_FAILURE); } strcpy(progname, "pilight-receive"); struct options_t *options = NULL; struct ssdp_list_t *ssdp_list = NULL; JsonNode *json = NULL; char *server = NULL; unsigned short port = 0; int sockfd = 0; char *recvBuff = NULL; char *message = NULL; char *args = NULL; steps_t steps = WELCOME; options_add(&options, 'H', "help", OPTION_NO_VALUE, 0, JSON_NULL, NULL, NULL); options_add(&options, 'V', "version", OPTION_NO_VALUE, 0, JSON_NULL, NULL, NULL); options_add(&options, 'S', "server", OPTION_HAS_VALUE, 0, JSON_NULL, NULL, "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"); options_add(&options, 'P', "port", OPTION_HAS_VALUE, 0, JSON_NULL, NULL, "[0-9]{1,4}"); /* Store all CLI arguments for later usage and also check if the CLI arguments where used correctly by the user. This will also fill all necessary values in the options struct */ while(1) { int c; c = options_parse(&options, argc, argv, 1, &args); if(c == -1) break; if(c == -2) c = 'H'; switch(c) { case 'H': printf("\t -H --help\t\t\tdisplay this message\n"); printf("\t -V --version\t\t\tdisplay version\n"); printf("\t -S --server=x.x.x.x\t\tconnect to server address\n"); printf("\t -P --port=xxxx\t\t\tconnect to server port\n"); exit(EXIT_SUCCESS); break; case 'V': printf("%s %s\n", progname, VERSION); exit(EXIT_SUCCESS); break; case 'S': server = realloc(server, strlen(args)+1); memset(server, '\0', strlen(args)+1); if(!server) { logprintf(LOG_ERR, "out of memory"); exit(EXIT_FAILURE); } strcpy(server, args); break; case 'P': port = (unsigned short)atoi(args); break; default: printf("Usage: %s -l location -d device\n", progname); exit(EXIT_SUCCESS); break; } } options_delete(options); if(server && port > 0) { if((sockfd = socket_connect(server, port)) == -1) { logprintf(LOG_ERR, "could not connect to pilight-daemon"); return EXIT_FAILURE; } } else if(ssdp_seek(&ssdp_list) == -1) { logprintf(LOG_ERR, "no pilight ssdp connections found"); goto close; } else { if((sockfd = socket_connect(ssdp_list->ip, ssdp_list->port)) == -1) { logprintf(LOG_ERR, "could not connect to pilight-daemon"); goto close; } } if(ssdp_list) { ssdp_free(ssdp_list); } if(server) { sfree((void *)&server); } while(1) { if(steps > WELCOME) { if((recvBuff = socket_read(sockfd)) == NULL) { goto close; } } switch(steps) { case WELCOME: socket_write(sockfd, "{\"message\":\"client receiver\"}"); steps=IDENTIFY; break; case IDENTIFY: //extract the message json = json_decode(recvBuff); json_find_string(json, "message", &message); if(strcmp(message, "accept client") == 0) { steps=RECEIVE; } else if(strcmp(message, "reject client") == 0) { steps=REJECT; } //cleanup json_delete(json); sfree((void *)&recvBuff); json = NULL; message = NULL; recvBuff = NULL; break; case RECEIVE: { char *line = strtok(recvBuff, "\n"); //for each line while(line) { json = json_decode(line); char *output = json_stringify(json, "\t"); printf("%s\n", output); sfree((void *)&output); json_delete(json); line = strtok(NULL,"\n"); } sfree((void *)&recvBuff); sfree((void *)&line); recvBuff = NULL; } break; case REJECT: default: goto close; break; } } close: if(sockfd > 0) { socket_close(sockfd); } if(recvBuff) { sfree((void *)&recvBuff); } options_gc(); log_shell_disable(); log_gc(); sfree((void *)&progname); return EXIT_SUCCESS; }
int main(int argc, char **argv) { unsigned short port = 0; char* server = NULL; unsigned short stats = 0; struct ssdp_list_t *ssdp_list = NULL; atomicinit(); gc_attach(main_gc); gc_catch(); if(server != NULL && port > 0) { if((sockfd = socket_connect(server, port)) == -1){ printf("error: could not connect to pilight-daemon\n"); return EXIT_FAILURE; } } else if(ssdp_seek(&ssdp_list) == -1){ printf("error: no pilight ssdp connections found\n"); goto close; } else{ if((sockfd = socket_connect(ssdp_list->ip, ssdp_list->port)) == -1){ printf("error: could not connect to pilight-daemon\n"); goto close; } } if(ssdp_list != NULL) ssdp_free(ssdp_list); if(server != NULL) FREE(server); struct JsonNode *jclient = json_mkobject(); struct JsonNode *joptions = json_mkobject(); json_append_member(jclient, "action", json_mkstring("identify")); json_append_member(joptions, "receiver", json_mknumber(1, 0)); json_append_member(joptions, "stats", json_mknumber(stats, 0)); json_append_member(jclient, "options", joptions); char *out = json_stringify(jclient, NULL); socket_write(sockfd, out); json_free(out); json_delete(jclient); if(socket_read(sockfd, &recvBuff, 0)!=0 || strcmp(recvBuff, "{\"status\":\"success\"}")!=0) goto close; if(iniInit("config.ini")) // get values from config.ini goto close; display(0, 0, 0); // init display unsigned short filteropt = 1; int lastmin = -1, firstrx = 0; while(main_loop){ if(socket_read(sockfd, &recvBuff, 0) != 0) goto close; char **array = NULL; unsigned int n = explode(recvBuff, "\n", &array), i = 0; for(i=0; i<n; i++){ struct JsonNode *jcontent = json_decode(array[i]); struct JsonNode *jtype = json_find_member(jcontent, "type"); if(jtype != NULL){ json_remove_from_parent(jtype); json_delete(jtype); } if(filteropt == 1){ char *pr = NULL; double id = 0.0; double ch = 0.0; struct JsonNode *jmessage = json_find_member(jcontent, "message"); json_find_string(jcontent, "protocol", &pr); json_find_number(jmessage, "id", &id); json_find_number(jmessage, "channel", &ch); int j = 0; for(j=0; j<stations; j++){ // step through protocol filters if(strcmp(station[j].pr, "-")==0 || strcmp(station[j].pr, pr)==0){ // protocol not specified or found if(j == 0){ // datetime protocol is the first if(firstrx){ double min = 0.0; json_find_number(jmessage, "minute", &min); if((int)min != lastmin){ display(-1, 0.0, 0.0); lastmin = (int)min; } } } else if(strcmp(station[j].id, "-")==0 || (int)id==atoi(station[j].id)){ // id not specified or found if(strcmp(station[j].ch, "-")==0 || (int)ch==atoi(station[j].ch)){ // channel not specified or found double temp = 0.0, humi = 0.0; json_find_number(jmessage, "temperature", &temp); json_find_number(jmessage, "humidity", &humi); display(j-1, temp, humi); firstrx = 1; break; } } } } } else{ char *content = json_stringify(jcontent, "\t"); printf("%s\n", content); json_free(content); } json_delete(jcontent); } array_free(&array, n); } close: if(sockfd > 0) socket_close(sockfd); if(recvBuff != NULL){ FREE(recvBuff); recvBuff = NULL; } iniClean(); return EXIT_SUCCESS; }
int main( int argc, char **argv ) { // Read any command line arguments from our friend the user. arguments(argc, argv); // Catch some signals so can exit cleanly signal(SIGINT, exit_interrupt); #ifndef WIN32 signal(SIGHUP, exit_interrupt); signal(SIGTERM, exit_interrupt); signal(SIGPIPE, SIG_IGN); if (debug_on) setvbuf(stdout, NULL, _IONBF, 0); #endif printf("%s - Jorgen Lundman v%s %s %s\n\n", argv ? argv[0] : "llink", VERSION, VERSION_STRING, #if WITH_DVDREAD "(libdvdread)" #else #if HAVE_CLINKC "(libdvdnav, ClinkC)" #else "(libdvdnav)" #endif #endif ); lion_buffersize(conf_buffersize); //lion_buffersize(2352); if (lion_init()) { printf("Failed to initialize lion/networking\n"); exit(-1); } debugf("\n"); // Read configuration file, if any // Warning, calls lion_poll until done. conf_init(); debugf("[main] initialising...\n"); // Warning, calls lion_poll until done. mime_init(); // Warning, calls lion_poll until done. skin_init(); ssdp_init(); httpd_init(); request_init(); root_init(); llrar_init(); visited_init(); cgicmd_init(); #ifdef EXTERNAL external_init(); #endif printf("[main] ready!\n"); // Background? #ifndef WIN32 if (!foreground) { if (fork()) exit(0); setsid(); if (conf_pidfile) { FILE *fd; if ((fd = fopen(conf_pidfile, "w"))) { fprintf(fd, "%u\r\n", getpid()); fclose(fd); } } } #endif cupnp_init(); // Scan for media if (conf_xmlscan) { signal(SIGINT, SIG_DFL); xmlscan_run(); do_exit = 1; } query_init(); #ifdef WIN32 SetPriorityClass(GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS); #endif // The main loop while ( !do_exit ) { // Was 250,0 - we should probably let users control this in // conf settings. if (lion_poll(0, 1)<0) do_exit=1; request_events(); #ifdef EXTERNAL external_resume(); #endif } printf("\n[main] releasing resources...\n"); query_free(); cupnp_free(); #ifdef EXTERNAL external_free(); #endif root_free(); cgicmd_free(); visited_free(); llrar_free(); request_free(); httpd_free(); ssdp_free(); skin_free(); mime_free(); conf_free(); #ifndef WIN32 // Crashed when releasing spawned processes, until i can fix: lion_free(); #endif debugf("[main] done.\n"); return 0; }
int main(int argc, char **argv) { // memtrack(); struct options_t *options = NULL; struct ssdp_list_t *ssdp_list = NULL; struct devices_t *dev = NULL; struct JsonNode *json = NULL; struct JsonNode *tmp = NULL; char *recvBuff = NULL, *message = NULL, *output = NULL; char *device = NULL, *state = NULL, *values = NULL; char *server = NULL; int has_values = 0, sockfd = 0, hasconfarg = 0; unsigned short port = 0, showhelp = 0, showversion = 0; log_file_disable(); log_shell_enable(); log_level_set(LOG_NOTICE); if(!(progname = MALLOC(16))) { logprintf(LOG_ERR, "out of memory"); exit(EXIT_FAILURE); } strcpy(progname, "pilight-control"); /* Define all CLI arguments of this program */ options_add(&options, 'H', "help", OPTION_NO_VALUE, 0, JSON_NULL, NULL, NULL); options_add(&options, 'V', "version", OPTION_NO_VALUE, 0, JSON_NULL, NULL, NULL); options_add(&options, 'd', "device", OPTION_HAS_VALUE, 0, JSON_NULL, NULL, NULL); options_add(&options, 's', "state", OPTION_HAS_VALUE, 0, JSON_NULL, NULL, NULL); options_add(&options, 'v', "values", OPTION_HAS_VALUE, 0, JSON_NULL, NULL, NULL); options_add(&options, 'S', "server", OPTION_HAS_VALUE, 0, JSON_NULL, NULL, "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"); options_add(&options, 'P', "port", OPTION_HAS_VALUE, 0, JSON_NULL, NULL, "[0-9]{1,4}"); options_add(&options, 'C', "config", OPTION_HAS_VALUE, 0, JSON_NULL, NULL, NULL); /* Store all CLI arguments for later usage and also check if the CLI arguments where used correctly by the user. This will also fill all necessary values in the options struct */ while(1) { int c; c = options_parse(&options, argc, argv, 1, &optarg); if(c == -1) break; if(c == -2) { showhelp = 1; break; } switch(c) { case 'H': showhelp = 1; break; case 'V': showversion = 1; break; case 'd': if((device = REALLOC(device, strlen(optarg)+1)) == NULL) { logprintf(LOG_ERR, "out of memory"); exit(EXIT_FAILURE); } strcpy(device, optarg); break; case 's': if((state = REALLOC(state, strlen(optarg)+1)) == NULL) { logprintf(LOG_ERR, "out of memory"); exit(EXIT_FAILURE); } strcpy(state, optarg); break; case 'v': if((values = REALLOC(values, strlen(optarg)+1)) == NULL) { logprintf(LOG_ERR, "out of memory"); exit(EXIT_FAILURE); } strcpy(values, optarg); break; case 'C': if(config_set_file(optarg) == EXIT_FAILURE) { return EXIT_FAILURE; } hasconfarg = 1; break; case 'S': if(!(server = REALLOC(server, strlen(optarg)+1))) { logprintf(LOG_ERR, "out of memory"); exit(EXIT_FAILURE); } strcpy(server, optarg); break; case 'P': port = (unsigned short)atoi(optarg); break; default: printf("Usage: %s -l location -d device -s state\n", progname); goto close; break; } } options_delete(options); if(showversion == 1) { printf("%s %s\n", progname, PILIGHT_VERSION); goto close; } if(showhelp == 1) { printf("\t -H --help\t\t\tdisplay this message\n"); printf("\t -V --version\t\t\tdisplay version\n"); printf("\t -S --server=x.x.x.x\t\tconnect to server address\n"); printf("\t -C --config\t\t\tconfig file\n"); printf("\t -P --port=xxxx\t\t\tconnect to server port\n"); printf("\t -d --device=device\t\tthe device that you want to control\n"); printf("\t -s --state=state\t\tthe new state of the device\n"); printf("\t -v --values=values\t\tspecific comma separated values, e.g.:\n"); printf("\t\t\t\t\t-v dimlevel=10\n"); goto close; } if(device == NULL || state == NULL || strlen(device) == 0 || strlen(state) == 0) { printf("Usage: %s -d device -s state\n", progname); goto close; } if(server && port > 0) { if((sockfd = socket_connect(server, port)) == -1) { logprintf(LOG_ERR, "could not connect to pilight-daemon"); goto close; } } else if(ssdp_seek(&ssdp_list) == -1) { logprintf(LOG_ERR, "no pilight ssdp connections found"); goto close; } else { if((sockfd = socket_connect(ssdp_list->ip, ssdp_list->port)) == -1) { logprintf(LOG_ERR, "could not connect to pilight-daemon"); goto close; } } if(ssdp_list) { ssdp_free(ssdp_list); } protocol_init(); config_init(); if(hasconfarg == 1) { if(config_read() != EXIT_SUCCESS) { goto close; } } socket_write(sockfd, "{\"action\":\"identify\"}"); if(socket_read(sockfd, &recvBuff, 0) != 0 || strcmp(recvBuff, "{\"status\":\"success\"}") != 0) { goto close; } json = json_mkobject(); json_append_member(json, "action", json_mkstring("request config")); output = json_stringify(json, NULL); socket_write(sockfd, output); json_free(output); json_delete(json); if(socket_read(sockfd, &recvBuff, 0) == 0) { if(json_validate(recvBuff) == true) { json = json_decode(recvBuff); if(json_find_string(json, "message", &message) == 0) { if(strcmp(message, "config") == 0) { struct JsonNode *jconfig = NULL; if((jconfig = json_find_member(json, "config")) != NULL) { int match = 1; while(match) { struct JsonNode *jchilds = json_first_child(jconfig); match = 0; while(jchilds) { if(strcmp(jchilds->key, "devices") != 0) { json_remove_from_parent(jchilds); tmp = jchilds; match = 1; } jchilds = jchilds->next; if(tmp != NULL) { json_delete(tmp); } tmp = NULL; } } config_parse(jconfig); if(devices_get(device, &dev) == 0) { JsonNode *joutput = json_mkobject(); JsonNode *jcode = json_mkobject(); JsonNode *jvalues = json_mkobject(); json_append_member(jcode, "device", json_mkstring(device)); if(values != NULL) { char **array = NULL; unsigned int n = explode(values, ",=", &array), q = 0; for(q=0;q<n;q+=2) { char *name = MALLOC(strlen(array[q])+1); if(name == NULL) { logprintf(LOG_ERR, "out of memory\n"); exit(EXIT_FAILURE); } strcpy(name, array[q]); if(q+1 == n) { for(q=0;q<n;q++) { FREE(array[q]); } FREE(array); logprintf(LOG_ERR, "\"%s\" is missing a value for device \"%s\"", name, device); FREE(name); break; } else { char *val = MALLOC(strlen(array[q+1])+1); if(val == NULL) { logprintf(LOG_ERR, "out of memory\n"); exit(EXIT_FAILURE); } strcpy(val, array[q+1]); if(devices_valid_value(device, name, val) == 0) { if(isNumeric(val) == EXIT_SUCCESS) { char *ptr = strstr(array[q+1], "."); int decimals = 0; if(ptr != NULL) { decimals = (int)(strlen(array[q+1])-((size_t)(ptr-array[q+1])+1)); } json_append_member(jvalues, name, json_mknumber(atof(val), decimals)); } else { json_append_member(jvalues, name, json_mkstring(val)); } has_values = 1; } else { logprintf(LOG_ERR, "\"%s\" is an invalid value for device \"%s\"", name, device); for(q=0;q<n;q++) { FREE(array[q]); } FREE(array); FREE(name); json_delete(json); goto close; } } FREE(name); } unsigned int z = 0; for(z=q;z<n;z++) { FREE(array[z]); } if(n > 0) { FREE(array); } } if(devices_valid_state(device, state) == 0) { json_append_member(jcode, "state", json_mkstring(state)); } else { logprintf(LOG_ERR, "\"%s\" is an invalid state for device \"%s\"", state, device); json_delete(json); goto close; } if(has_values == 1) { json_append_member(jcode, "values", jvalues); } else { json_delete(jvalues); } json_append_member(joutput, "action", json_mkstring("control")); json_append_member(joutput, "code", jcode); output = json_stringify(joutput, NULL); socket_write(sockfd, output); json_free(output); json_delete(joutput); if(socket_read(sockfd, &recvBuff, 0) != 0 || strcmp(recvBuff, "{\"status\":\"success\"}") != 0) { logprintf(LOG_ERR, "failed to control %s", device); } } else { logprintf(LOG_ERR, "the device \"%s\" does not exist", device); json_delete(json); goto close; } } } } json_delete(json); } } close: if(recvBuff) { FREE(recvBuff); } if(sockfd > 0) { socket_close(sockfd); } if(server != NULL) { FREE(server); } if(device != NULL) { FREE(device); } if(state != NULL) { FREE(state); } if(values != NULL) { FREE(values); } log_shell_disable(); socket_gc(); config_gc(); protocol_gc(); options_gc(); event_operator_gc(); event_action_gc(); dso_gc(); log_gc(); threads_gc(); gc_clear(); FREE(progname); xfree(); return EXIT_SUCCESS; }
int main(int argc, char **argv) { // memtrack(); wiringXLog = _lognone; log_file_disable(); log_shell_enable(); log_level_set(LOG_NOTICE); if(!(progname = MALLOC(13))) { logprintf(LOG_ERR, "out of memory"); exit(EXIT_FAILURE); } strcpy(progname, "pilight-send"); struct options_t *options = NULL; struct ssdp_list_t *ssdp_list = NULL; int sockfd = 0; char *args = NULL, *recvBuff = NULL; /* Hold the name of the protocol */ char *protobuffer = NULL; /* Does this protocol exists */ int match = 0; /* Do we need to print the help */ int help = 0; /* Do we need to print the version */ int version = 0; /* Do we need to print the protocol help */ int protohelp = 0; char *uuid = NULL; char *server = NULL; unsigned short port = 0; /* Hold the final protocol struct */ protocol_t *protocol = NULL; JsonNode *code = NULL; /* Define all CLI arguments of this program */ options_add(&options, 'H', "help", OPTION_NO_VALUE, 0, JSON_NULL, NULL, NULL); options_add(&options, 'V', "version", OPTION_NO_VALUE, 0, JSON_NULL, NULL, NULL); options_add(&options, 'p', "protocol", OPTION_HAS_VALUE, 0, JSON_NULL, NULL, NULL); options_add(&options, 'S', "server", OPTION_HAS_VALUE, 0, JSON_NULL, NULL, "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"); options_add(&options, 'P', "port", OPTION_HAS_VALUE, 0, JSON_NULL, NULL, "[0-9]{1,4}"); options_add(&options, 'U', "uuid", OPTION_HAS_VALUE, 0, JSON_NULL, NULL, "[a-zA-Z0-9]{4}-[a-zA-Z0-9]{2}-[a-zA-Z0-9]{2}-[a-zA-Z0-9]{2}-[a-zA-Z0-9]{6}"); /* Get the protocol to be used */ while(1) { int c; c = options_parse(&options, argc, argv, 0, &args); if(c == -1) break; if(c == -2) c = 'H'; switch(c) { case 'p': if(strlen(args) == 0) { logprintf(LOG_ERR, "options '-p' and '--protocol' require an argument"); exit(EXIT_FAILURE); } else { if(!(protobuffer = REALLOC(protobuffer, strlen(args)+1))) { logprintf(LOG_ERR, "out of memory"); exit(EXIT_FAILURE); } strcpy(protobuffer, args); } break; case 'V': version = 1; break; case 'H': help = 1; break; case 'S': if(!(server = REALLOC(server, strlen(args)+1))) { logprintf(LOG_ERR, "out of memory"); exit(EXIT_FAILURE); } strcpy(server, args); break; case 'P': port = (unsigned short)atoi(args); break; case 'U': if(!(uuid = REALLOC(uuid, strlen(args)+1))) { logprintf(LOG_ERR, "out of memory"); exit(EXIT_FAILURE); } strcpy(uuid, args); break; default:; } } /* Initialize protocols */ protocol_init(); /* Check if a protocol was given */ if(protobuffer && strlen(protobuffer) > 0 && strcmp(protobuffer, "-V") != 0) { if(strlen(protobuffer) > 0 && version) { printf("-p and -V cannot be combined\n"); } else { struct protocols_t *pnode = protocols; /* Retrieve the used protocol */ while(pnode) { /* Check if the protocol exists */ protocol = pnode->listener; if(protocol_device_exists(protocol, protobuffer) == 0 && match == 0 && protocol->createCode != NULL) { match=1; /* Check if the protocol requires specific CLI arguments and merge them with the main CLI arguments */ if(protocol->options && help == 0) { options_merge(&options, &protocol->options); } else if(help == 1) { protohelp=1; } break; } pnode = pnode->next; } /* If no protocols matches the requested protocol */ if(!match) { logprintf(LOG_ERR, "this protocol is not supported or doesn't support sending"); } } } /* Store all CLI arguments for later usage and also check if the CLI arguments where used correctly by the user. This will also fill all necessary values in the options struct */ while(1) { int c; c = options_parse(&options, argc, argv, 2, &args); if(c == -1) break; if(c == -2) { if(match == 1) { protohelp = 1; } else { help = 1; } break; } } /* Display help or version information */ if(version == 1) { printf("%s %s\n", progname, PILIGHT_VERSION); goto close; } else if(help == 1 || protohelp == 1 || match == 0) { if(protohelp == 1 && match == 1 && protocol->printHelp) printf("Usage: %s -p %s [options]\n", progname, protobuffer); else printf("Usage: %s -p protocol [options]\n", progname); if(help == 1) { printf("\t -H --help\t\t\tdisplay this message\n"); printf("\t -V --version\t\t\tdisplay version\n"); printf("\t -p --protocol=protocol\t\tthe protocol that you want to control\n"); printf("\t -S --server=x.x.x.x\t\tconnect to server address\n"); printf("\t -P --port=xxxx\t\t\tconnect to server port\n"); printf("\t -C --config\t\t\tconfig file\n"); printf("\t -U --uuid=xxx-xx-xx-xx-xxxxxx\tUUID\n"); } if(protohelp == 1 && match == 1 && protocol->printHelp) { printf("\n\t[%s]\n", protobuffer); protocol->printHelp(); } else { printf("\nThe supported protocols are:\n"); struct protocols_t *pnode = protocols; /* Retrieve the used protocol */ while(pnode) { protocol = pnode->listener; if(protocol->createCode) { struct protocol_devices_t *tmpdev = protocol->devices; while(tmpdev) { struct pname_t *node = MALLOC(sizeof(struct pname_t)); if(!node) { logprintf(LOG_ERR, "out of memory"); exit(EXIT_FAILURE); } if(!(node->name = MALLOC(strlen(tmpdev->id)+1))) { logprintf(LOG_ERR, "out of memory"); exit(EXIT_FAILURE); } strcpy(node->name, tmpdev->id); if(!(node->desc = MALLOC(strlen(tmpdev->desc)+1))) { logprintf(LOG_ERR, "out of memory"); exit(EXIT_FAILURE); } strcpy(node->desc, tmpdev->desc); node->next = pname; pname = node; tmpdev = tmpdev->next; } } pnode = pnode->next; } sort_list(); struct pname_t *ptmp = NULL; while(pname) { ptmp = pname; printf("\t %s\t\t",ptmp->name); if(strlen(ptmp->name) < 7) printf("\t"); if(strlen(ptmp->name) < 15) printf("\t"); printf("%s\n", ptmp->desc); FREE(ptmp->name); FREE(ptmp->desc); pname = pname->next; FREE(ptmp); } FREE(pname); } goto close; } code = json_mkobject(); int itmp = 0; /* Check if we got sufficient arguments from this protocol */ struct options_t *tmp = options; while(tmp) { if(strlen(tmp->name) > 0) { /* Only send the CLI arguments that belong to this protocol, the protocol name and those that are called by the user */ if((options_get_id(&protocol->options, tmp->name, &itmp) == 0) && tmp->vartype == JSON_STRING && tmp->string_ != NULL && (strlen(tmp->string_) > 0)) { if(isNumeric(tmp->string_) == 0) { char *ptr = strstr(tmp->string_, "."); int decimals = 0; if(ptr != NULL) { decimals = (int)(strlen(tmp->string_)-((size_t)(ptr-tmp->string_)+1)); } json_append_member(code, tmp->name, json_mknumber(atof(tmp->string_), decimals)); } else { json_append_member(code, tmp->name, json_mkstring(tmp->string_)); } } if(strcmp(tmp->name, "protocol") == 0 && strlen(tmp->string_) > 0) { JsonNode *jprotocol = json_mkarray(); json_append_element(jprotocol, json_mkstring(tmp->string_)); json_append_member(code, "protocol", jprotocol); } } tmp = tmp->next; } if(protocol->createCode(code) == 0) { if(protocol->message) { json_delete(protocol->message); } if(server && port > 0) { if((sockfd = socket_connect(server, port)) == -1) { logprintf(LOG_ERR, "could not connect to pilight-daemon"); goto close; } } else if(ssdp_seek(&ssdp_list) == -1) { logprintf(LOG_ERR, "no pilight ssdp connections found"); goto close; } else { if((sockfd = socket_connect(ssdp_list->ip, ssdp_list->port)) == -1) { logprintf(LOG_ERR, "could not connect to pilight-daemon"); goto close; } } if(ssdp_list) { ssdp_free(ssdp_list); } socket_write(sockfd, "{\"action\":\"identify\"}"); if(socket_read(sockfd, &recvBuff, 0) != 0 || strcmp(recvBuff, "{\"status\":\"success\"}") != 0) { goto close; } JsonNode *json = json_mkobject(); json_append_member(json, "action", json_mkstring("send")); if(uuid != NULL) { json_append_member(code, "uuid", json_mkstring(uuid)); } json_append_member(json, "code", code); char *output = json_stringify(json, NULL); socket_write(sockfd, output); json_free(output); json_delete(json); if(socket_read(sockfd, &recvBuff, 0) != 0 || strcmp(recvBuff, "{\"status\":\"success\"}") != 0) { logprintf(LOG_ERR, "failed to send codes"); goto close; } } close: if(sockfd > 0) { socket_close(sockfd); } if(recvBuff != NULL) { FREE(recvBuff); } if(server != NULL) { FREE(server); } if(protobuffer != NULL) { FREE(protobuffer); } if(uuid != NULL) { FREE(uuid); } log_shell_disable(); protocol_gc(); options_delete(options); options_gc(); config_gc(); threads_gc(); dso_gc(); log_gc(); FREE(progname); xfree(); return EXIT_SUCCESS; }