Пример #1
0
static int registry_remove_value_recursive(struct JsonNode *root, const char *key) {
	logprintf(LOG_STACK, "%s(...)", __FUNCTION__);

	char *sub = strstr(key, ".");
	char *buff = MALLOC(strlen(key)+1);
	strcpy(buff, key);
	if(sub != NULL) {
		int pos = sub-key;
		buff[pos] = '\0';
	}
	struct JsonNode *member = json_find_member(root, buff);
	if(member != NULL) {
		if(sub == NULL) {
			json_remove_from_parent(member);
			json_delete(member);
			registry_remove_empty_parent(root);
			FREE(buff);
			return 0;
		}
		if(member->tag == JSON_OBJECT) {
			if(sub != NULL) {
				int pos = sub-key;
				strcpy(buff, &key[pos+1]);
			}
			int ret = registry_remove_value_recursive(member, buff);
			FREE(buff);
			return ret;
		}
	}
	FREE(buff);
	return -1;
}
Пример #2
0
static void registry_remove_empty_parent(struct JsonNode *root) {
	logprintf(LOG_STACK, "%s(...)", __FUNCTION__);

	struct JsonNode *parent = root->parent;
	if(json_first_child(root) == NULL) {
		if(parent != NULL) {
			json_remove_from_parent(root);
			registry_remove_empty_parent(parent);
			json_delete(root);
		}
	}
}
Пример #3
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;
}
Пример #4
0
static void test_array(void)
{
    JsonNode *array;
    JsonNode *children[5 + 1];

    array = json_mkarray();
    should_be(array, "[]");

    children[1] = json_mknumber(1);
    children[2] = json_mknumber(2);
    children[3] = json_mknumber(3);
    children[4] = json_mknumber(4);
    children[5] = json_mknumber(5);

    json_append_element(array, children[3]);
    should_be(array, "[3]");

    json_remove_from_parent(children[3]);
    should_be(array, "[]");

    json_prepend_element(array, children[3]);
    should_be(array, "[3]");

    json_prepend_element(array, children[2]);
    should_be(array, "[2,3]");

    json_append_element(array, children[4]);
    should_be(array, "[2,3,4]");

    json_delete(children[3]);
    should_be(array, "[2,4]");

    json_prepend_element(array, children[1]);
    should_be(array, "[1,2,4]");

    json_delete(children[1]);
    should_be(array, "[2,4]");

    json_delete(children[4]);
    should_be(array, "[2]");

    ok1(json_find_element(array, 0) == children[2]);
    ok1(json_find_element(array, -1) == NULL);
    ok1(json_find_element(array, 1) == NULL);

    json_append_element(array, children[5]);
    should_be(array, "[2,5]");

    ok1(json_find_element(array, 0) == children[2]);
    ok1(json_find_element(array, 1) == children[5]);
    ok1(json_find_element(array, -1) == NULL);
    ok1(json_find_element(array, 2) == NULL);

    json_delete(children[2]);
    json_delete(children[5]);
    should_be(array, "[]");

    ok1(json_find_element(array, -1) == NULL);
    ok1(json_find_element(array, 0) == NULL);
    ok1(json_find_element(array, 1) == NULL);

    json_delete(array);
}
Пример #5
0
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;
}
Пример #6
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;
}