Exemple #1
0
static void options_parse_toplevel(GQParserData *parser_data, GMarkupParseContext *context, const gchar *element_name, const gchar **attribute_names, const gchar **attribute_values, gpointer data, GError **error)
{
	if (g_ascii_strcasecmp(element_name, "gq") == 0)
		{
		/* optional top-level node */
		options_parse_func_push(parser_data, options_parse_toplevel, NULL, NULL);
		return;
		}
	if (g_ascii_strcasecmp(element_name, "global") == 0)
		{
		load_global_params(attribute_names, attribute_values);
		options_parse_func_push(parser_data, options_parse_global, options_parse_global_end, NULL);
		return;
		}

	if (g_ascii_strcasecmp(element_name, "layout") == 0)
		{
		LayoutWindow *lw;
		lw = layout_find_by_layout_id(options_get_id(attribute_names, attribute_values));
		if (lw)
			{
			layout_update_from_config(lw, attribute_names, attribute_values);
			}
		else
			{
			lw = layout_new_from_config(attribute_names, attribute_values, parser_data->startup);
			}
		options_parse_func_push(parser_data, options_parse_layout, options_parse_layout_end, lw);
		}
	else
		{
		log_printf("unexpected in <toplevel>: <%s>\n", element_name);
		options_parse_func_push(parser_data, options_parse_leaf, NULL, NULL);
		}
}
Exemple #2
0
/* Add a new option to the options struct */
void options_add(struct options_t **opt, int id, const char *name, int argtype, int conftype, const char *mask) {
	char *ctmp = NULL;
	int itmp;
	if(!(argtype >= 0 && argtype <= 3)) {
		logprintf(LOG_ERR, "tying to add an invalid option type");
	} else if(!(conftype >= 0 && conftype <= 5)) {
		logprintf(LOG_ERR, "trying to add an option with an invalid config type");
	} else if(name == NULL) {
		logprintf(LOG_ERR, "trying to add an option without name");
	} else if(options_get_name(opt, id, &ctmp) == 0) {
		logprintf(LOG_ERR, "duplicate option id: %c", id);
	} else if(options_get_id(opt, strdup(name), &itmp) == 0) {
		logprintf(LOG_ERR, "duplicate option name: %s", name);
	} else {
		if(*opt == NULL) {
			*opt = malloc(sizeof(struct options_t));
		}
		struct options_t *optnode = malloc(sizeof(struct options_t));
		optnode->id = id;
		strcpy(optnode->name, name);
		memset(optnode->value, '\0', sizeof(optnode->value));
		optnode->argtype = argtype;
		optnode->conftype = conftype;
		if(mask == NULL)
			memset(optnode->value, '\0', sizeof(optnode->mask));
		else
			strcpy(optnode->mask, mask);
		optnode->next = *opt;
		*opt = optnode;
	}
}
Exemple #3
0
/* Add a new option to the options struct */
void options_add(struct options_t **opt, int id, const char *name, int argtype, int conftype, const char *mask) {
	char *ctmp = NULL;
	char *nname = malloc(strlen(name)+1);
	strcpy(nname, name);
	int itmp;
	if(!(argtype >= 0 && argtype <= 3)) {
		logprintf(LOG_ERR, "tying to add an invalid option type");
		sfree((void *)&nname);
		exit(EXIT_FAILURE);
	} else if(!(conftype >= 0 && conftype <= 5)) {
		logprintf(LOG_ERR, "trying to add an option with an invalid config type");
		sfree((void *)&nname);
		exit(EXIT_FAILURE);
	} else if(!name) {
		logprintf(LOG_ERR, "trying to add an option without name");
		sfree((void *)&nname);
		exit(EXIT_FAILURE);
	} else if(options_get_name(opt, id, &ctmp) == 0) {
		logprintf(LOG_ERR, "duplicate option id: %c", id);
		sfree((void *)&nname);
		exit(EXIT_FAILURE);
	} else if(options_get_id(opt, nname, &itmp) == 0) {
		logprintf(LOG_ERR, "duplicate option name: %s", name);
		sfree((void *)&nname);
		exit(EXIT_FAILURE);
	} else {
		struct options_t *optnode = malloc(sizeof(struct options_t));
		optnode->id = id;
		optnode->name = malloc(strlen(name)+1);
		strcpy(optnode->name, name);
		optnode->argtype = argtype;
		optnode->conftype = conftype;
		optnode->value = malloc(4);
		memset(optnode->value, '\0', 4);
		if(mask) {
			optnode->mask = malloc(strlen(mask)+1);
			strcpy(optnode->mask, mask);
		} else {
			optnode->mask = malloc(4);
			memset(optnode->mask, '\0', 4);
		}
		optnode->next = *opt;
		*opt = optnode;
		sfree((void *)&nname);
	}
}
Exemple #4
0
/* Parse all CLI arguments */
int options_parse(struct options_t **opt, int argc, char **argv, int error_check) {
	int c = 0;
	char *ctmp = NULL;
	int itmp;
#ifndef __FreeBSD__	
	char *mask;
	regex_t regex;
	int reti;
#endif
	
	/* Reservate enough memory to store all variables */
	longarg = malloc(sizeof(char)*255);
	shortarg = malloc(sizeof(char)*3);
	optarg = malloc(sizeof(char)*255);

	/* Clear the argument holders */
	memset(longarg, '\0', sizeof(char)*255);
	memset(shortarg, '\0', sizeof(char)*3);
	memset(optarg, '\0', sizeof(char)*255);

	/* If have readed all arguments, exit and reset */
	if(getOptPos>=(argc-1)) {
		getOptPos=0;
		return -1;
	} else {
		getOptPos++;

		/* Check if the CLI character contains an equals to (=) sign.
		   If it does, we have probably encountered a long argument */
		if(strchr(argv[getOptPos],'=') != NULL) {
			/* Copy all characters until the equals to sign.
			   This will probably be the name of the argument */
			memcpy(longarg, &argv[getOptPos][0], strcspn(argv[getOptPos],"="));
			longarg[strcspn(argv[getOptPos],"=")]='\0';

			/* Then copy everything after the equals sign.
			   This will probably be the value of the argument */
			memcpy(optarg, &argv[getOptPos][strcspn(argv[getOptPos],"=")+1], strlen(argv[getOptPos]));
			optarg[strlen(argv[getOptPos])-(strcspn(argv[getOptPos],"=")+1)]='\0';
		} else {
			/* If the argument does not contain a equals sign.
			   Store the argument to check later if it's a long argument */
			longarg=strdup(argv[getOptPos]);
		}

		/* A short argument only contains of two characters.
		   So only store the first two characters */
		memcpy(shortarg, &argv[getOptPos][0], 2);

		/* Check if the short argument and the long argument are equal,
		   then we probably encountered a short argument. Only store the
		   identifier character. If there are more CLI characters
		   after the current one, store it as the CLI value. However, only
		   do this if the first character of the argument doesn't contain*/
		if(strcmp(longarg,shortarg) == 0 && (getOptPos+1)<argc && argv[getOptPos+1][0] != '-') {
			optarg=strdup(argv[getOptPos+1]);
			c=shortarg[1];
			getOptPos++;
		} else {
			/* If the short argument and the long argument are not equal,
			    then we probably encountered a long argument. */
			ctmp = malloc(strlen(longarg));
			if(longarg[0] == '-' && longarg[1] == '-') {
				memcpy(ctmp, &longarg[2], strlen(longarg));
				ctmp[strlen(longarg)] = '\0';

				/* Retrieve the short identifier for the logn argument */
				if(options_get_id(opt, ctmp, &itmp) == 0) {
					c=itmp;
				} else if(argv[getOptPos][0] == '-') {
					c=shortarg[1];
				}
			} else if(argv[getOptPos][0] == '-' && strstr(shortarg, longarg) != 0) {
				c=shortarg[1];
			}
		}

		/* Check if the argument was expected */
		if(options_get_name(opt, c, &ctmp) != 0 && c > 0) {
			if(error_check == 1) {
				if(strcmp(longarg,shortarg) == 0) {
					if(shortarg[0] == '-') {
						logprintf(LOG_ERR, "invalid option -- '-%c'", c);
					} else {
						logprintf(LOG_ERR, "invalid option -- '%s'", longarg);
					}
				} else {
					logprintf(LOG_ERR, "invalid option -- '%s'", longarg);
				}
				exit(EXIT_FAILURE);
			} else {
				return 0;
			}
		/* Check if an argument cannot have an argument that was set */
		} else if(strlen(optarg) != 0 && options_get_argtype(opt, c, &itmp) == 0 && itmp == 1) {
			if(error_check == 1) {
				if(strcmp(longarg,shortarg) == 0) {
					logprintf(LOG_ERR, "option '-%c' doesn't take an argument", c);
				} else {
					logprintf(LOG_ERR, "option '%s' doesn't take an argument", longarg);
				}
				exit(EXIT_FAILURE);
			} else {
				return 0;
			}
		/* Check if an argument required a value that wasn't set */
		} else if(strlen(optarg) == 0 && options_get_argtype(opt, c, &itmp) == 0 && itmp == 2) {
			if(error_check == 1) {
				if(strcmp(longarg, shortarg) == 0) {
					logprintf(LOG_ERR, "option '-%c' requires an argument", c);
				} else {
					logprintf(LOG_ERR, "option '%s' requires an argument", longarg);
				}
				exit(EXIT_FAILURE);
			} else {
				return 0;
			}
		/* Check if we have a valid argument */
		} else if(c == 0) {
			if(error_check == 1) {
				if(shortarg[0] == '-' && strstr(shortarg, longarg) != 0) {
					logprintf(LOG_ERR, "invalid option -- '-%c'", c);
				} else {
					logprintf(LOG_ERR, "invalid option -- '%s'", longarg);
				}
				exit(EXIT_FAILURE);
			} else {
				return 0;
			}
		} else {
			/* If the argument didn't have a value, set it to 1 */
			if(strlen(optarg) == 0)
				options_set_value(opt, c, "1");
			else {
#ifndef __FreeBSD__			
				/* If the argument has a regex mask, check if it passes */
				if(options_get_mask(opt, c, &mask) == 0) {
					reti = regcomp(&regex, mask, REG_EXTENDED);
					if(reti) {
						logprintf(LOG_ERR, "could not compile regex");
						exit(EXIT_FAILURE);
					}
					reti = regexec(&regex, optarg, 0, NULL, 0);
					if(reti == REG_NOMATCH || reti != 0) {
						if(shortarg[0] == '-') {
							logprintf(LOG_ERR, "invalid format -- '-%c'", c);
						} else {
							logprintf(LOG_ERR, "invalid format -- '%s'", longarg);
						}
						logprintf(LOG_ERR, "requires %s", mask);
						exit(EXIT_FAILURE);
					}
				}
#endif
				options_set_value(opt, c, optarg);
			}
			return c;
		}
	}
}
Exemple #5
0
static void options_parse_bar(GQParserData *parser_data, GMarkupParseContext *context, const gchar *element_name, const gchar **attribute_names, const gchar **attribute_values, gpointer data, GError **error)
{
	GtkWidget *bar = data;
	if (g_ascii_strcasecmp(element_name, "pane_comment") == 0)
		{
		GtkWidget *pane = bar_find_pane_by_id(bar, PANE_COMMENT, options_get_id(attribute_names, attribute_values));
		if (pane)
			{
			bar_pane_comment_update_from_config(pane, attribute_names, attribute_values);
			}
		else
			{
			pane = bar_pane_comment_new_from_config(attribute_names, attribute_values);
			bar_add(bar, pane);
			}
		options_parse_func_push(parser_data, options_parse_leaf, NULL, NULL);
		}
#ifdef HAVE_LIBCHAMPLAIN
#ifdef HAVE_LIBCHAMPLAIN_GTK
	else if (g_ascii_strcasecmp(element_name, "pane_gps") == 0)
		{
		GtkWidget *pane = bar_find_pane_by_id(bar, PANE_GPS, options_get_id(attribute_names, attribute_values));
		if (pane)
			{
			bar_pane_gps_update_from_config(pane, attribute_names, attribute_values);
			}
		else
			{
			pane = bar_pane_gps_new_from_config(attribute_names, attribute_values);
			bar_add(bar, pane);
			}
		options_parse_func_push(parser_data, options_parse_leaf, NULL, NULL);
		}
#endif
#endif
	else if (g_ascii_strcasecmp(element_name, "pane_exif") == 0)
		{
		GtkWidget *pane = bar_find_pane_by_id(bar, PANE_EXIF, options_get_id(attribute_names, attribute_values));
		if (pane)
			{
			bar_pane_exif_update_from_config(pane, attribute_names, attribute_values);
			}
		else
			{
			pane = bar_pane_exif_new_from_config(attribute_names, attribute_values);
			bar_add(bar, pane);
			}
		options_parse_func_push(parser_data, options_parse_pane_exif, NULL, pane);
		}
	else if (g_ascii_strcasecmp(element_name, "pane_histogram") == 0)
		{
		GtkWidget *pane = bar_find_pane_by_id(bar, PANE_HISTOGRAM, options_get_id(attribute_names, attribute_values));
		if (pane)
			{
			bar_pane_histogram_update_from_config(pane, attribute_names, attribute_values);
			}
		else
			{
			pane = bar_pane_histogram_new_from_config(attribute_names, attribute_values);
			bar_add(bar, pane);
			}
		options_parse_func_push(parser_data, options_parse_leaf, NULL, NULL);
		}
	else if (g_ascii_strcasecmp(element_name, "pane_keywords") == 0)
		{
		GtkWidget *pane = bar_find_pane_by_id(bar, PANE_KEYWORDS, options_get_id(attribute_names, attribute_values));
		if (pane)
			{
			bar_pane_keywords_update_from_config(pane, attribute_names, attribute_values);
			}
		else
			{
			pane = bar_pane_keywords_new_from_config(attribute_names, attribute_values);
			bar_add(bar, pane);
			}
		options_parse_func_push(parser_data, options_parse_leaf, NULL, NULL);
		}
	else if (g_ascii_strcasecmp(element_name, "clear") == 0)
		{
		bar_clear(bar);
		options_parse_func_push(parser_data, options_parse_leaf, NULL, NULL);
		}
	else
		{
		log_printf("unexpected in <bar>: <%s>\n", element_name);
		options_parse_func_push(parser_data, options_parse_leaf, NULL, NULL);
		}
}
Exemple #6
0
/* Add a new option to the options struct */
void options_add(struct options_t **opt, int id, const char *name, int argtype, int conftype, int vartype, void *def, const char *mask) {
	logprintf(LOG_STACK, "%s(...)", __FUNCTION__);

	char *ctmp = NULL;
	char *nname = MALLOC(strlen(name)+1);
	int sid = 0;
	if(!nname) {
		logprintf(LOG_ERR, "out of memory");
		exit(EXIT_FAILURE);
	}
	strcpy(nname, name);
	int itmp = 0;
	if(!(argtype >= 0 && argtype <= 3)) {
		logprintf(LOG_ERR, "tying to add an invalid option type");
		FREE(nname);
		exit(EXIT_FAILURE);
	} else if(!(conftype >= 0 && conftype <= NROPTIONTYPES)) {
		logprintf(LOG_ERR, "trying to add an option of an invalid type");
		FREE(nname);
		exit(EXIT_FAILURE);
	} else if(!name) {
		logprintf(LOG_ERR, "trying to add an option without name");
		FREE(nname);
		exit(EXIT_FAILURE);
	} else if(id != 0 && options_get_name(opt, id, &ctmp) == 0) {
		logprintf(LOG_ERR, "duplicate option id: %c", id);
		FREE(nname);
		exit(EXIT_FAILURE);
	} else if(options_get_id(opt, nname, &sid) == 0 &&
			((options_get_conftype(opt, sid, &itmp) == 0 && itmp == conftype) ||
			(options_get_conftype(opt, sid, &itmp) != 0))) {
		logprintf(LOG_ERR, "duplicate option name: %s", name);
		FREE(nname);
		exit(EXIT_FAILURE);
	} else {
		struct options_t *optnode = MALLOC(sizeof(struct options_t));
		if(!optnode) {
			logprintf(LOG_ERR, "out of memory");
			exit(EXIT_FAILURE);
		}
		optnode->id = id;
		optnode->name = MALLOC(strlen(name)+1);
		if(!optnode->name) {
			logprintf(LOG_ERR, "out of memory");
			exit(EXIT_FAILURE);
		}
		strcpy(optnode->name, name);
		optnode->argtype = argtype;
		optnode->conftype = conftype;
		optnode->vartype = vartype;
		optnode->def = def;
		optnode->string_ = NULL;
		if(mask) {
			optnode->mask = MALLOC(strlen(mask)+1);
			if(!optnode->mask) {
				logprintf(LOG_ERR, "out of memory");
				exit(EXIT_FAILURE);
			}
			strcpy(optnode->mask, mask);
		} else {
			optnode->mask = NULL;
		}
		optnode->next = *opt;
		*opt = optnode;
		FREE(nname);
	}
}
Exemple #7
0
/* Parse all CLI arguments */
int options_parse(struct options_t **opt, int argc, char **argv, int error_check, char **optarg) {
	logprintf(LOG_STACK, "%s(...)", __FUNCTION__);

	int c = 0;
	int itmp = 0;
#ifndef __FreeBSD__
	char *mask;
	regex_t regex;
	int reti;
#endif

	char *ctmp = NULL;

	/* If have read all arguments, exit and reset */
	if(getOptPos>=(argc-1)) {
		getOptPos=0;
		if(*optarg) {
			FREE(*optarg);
			*optarg = NULL;
		}
		return -1;
	} else {
		getOptPos++;
		/* Reserve enough memory to store all variables */
		longarg = REALLOC(longarg, 4);
		shortarg = REALLOC(shortarg, 2);
		*optarg = REALLOC(*optarg, 4);

		if(!longarg) {
			logprintf(LOG_ERR, "out of memory");
			exit(EXIT_FAILURE);
		}
		if(!shortarg) {
			logprintf(LOG_ERR, "out of memory");
			exit(EXIT_FAILURE);
		}
		if(!*optarg) {
			logprintf(LOG_ERR, "out of memory");
			exit(EXIT_FAILURE);
		}

		/* The memory to null */
		memset(*optarg, '\0', 4);
		memset(shortarg, '\0', 2);
		memset(longarg, '\0', 4);

		/* Check if the CLI character contains an equals to (=) sign.
		   If it does, we have probably encountered a long argument */
		if(strchr(argv[getOptPos],'=')) {
			/* Copy all characters until the equals to sign.
			   This will probably be the name of the argument */
			longarg = REALLOC(longarg, strcspn(argv[getOptPos],"=")+1);
			if(!longarg) {
				logprintf(LOG_ERR, "out of memory");
				exit(EXIT_FAILURE);
			}
			memset(longarg, '\0', strcspn(argv[getOptPos],"=")+1);
			memcpy(longarg, &argv[getOptPos][0], strcspn(argv[getOptPos],"="));

			/* Then copy everything after the equals sign.
			   This will probably be the value of the argument */
			size_t i = strlen(&argv[getOptPos][strcspn(argv[getOptPos],"=")+1]);
			*optarg = REALLOC(*optarg, i+1);
			if(!*optarg) {
				logprintf(LOG_ERR, "out of memory");
				exit(EXIT_FAILURE);
			}
			memset(*optarg, '\0', i+1);
			memcpy(*optarg, &argv[getOptPos][strcspn(argv[getOptPos],"=")+1], i);
		} else {
			/* If the argument does not contain a equals sign.
			   Store the argument to check later if it's a long argument */
			longarg = REALLOC(longarg, strlen(argv[getOptPos])+1);
			if(!longarg) {
				logprintf(LOG_ERR, "out of memory");
				exit(EXIT_FAILURE);
			}
			strcpy(longarg, argv[getOptPos]);
		}

		/* A short argument only contains of two characters.
		   So only store the first two characters */
		shortarg = REALLOC(shortarg, strlen(argv[getOptPos])+1);
		if(!shortarg) {
			logprintf(LOG_ERR, "out of memory");
			exit(EXIT_FAILURE);
		}
		memset(shortarg, '\0', 3);
		strncpy(shortarg, argv[getOptPos], 2);

		/* Check if the short argument and the long argument are equal,
		   then we probably encountered a short argument. Only store the
		   identifier character. If there are more CLI characters
		   after the current one, store it as the CLI value. However, only
		   do this if the first character of the argument doesn't contain*/
		if(strcmp(longarg, shortarg) == 0 && (getOptPos+1)<argc && argv[getOptPos+1][0] != '-') {
			*optarg = REALLOC(*optarg, strlen(argv[getOptPos+1])+1);
			if(!*optarg) {
				logprintf(LOG_ERR, "out of memory");
				exit(EXIT_FAILURE);
			}
			strcpy(*optarg, argv[getOptPos+1]);
			c = shortarg[1];
			getOptPos++;
		} else {
			/* If the short argument and the long argument are not equal,
			    then we probably encountered a long argument. */
			if(longarg[0] == '-' && longarg[1] == '-') {
				if((gctmp = REALLOC(gctmp, strlen(&longarg[2])+1)) == NULL) {
					logprintf(LOG_ERR, "out of memory");
					exit(EXIT_FAILURE);
				}
				strcpy(gctmp, &longarg[2]);

				/* Retrieve the short identifier for the long argument */
				if(options_get_id(opt, gctmp, &itmp) == 0) {
					c = itmp;
				} else if(argv[getOptPos][0] == '-') {
					c = shortarg[1];
				}
			} else if(argv[getOptPos][0] == '-' && strstr(shortarg, longarg) != 0) {
				c = shortarg[1];
			}
		}

		/* Check if the argument was expected */
		if(options_get_name(opt, c, &ctmp) != 0 && c > 0) {
			if(error_check == 1) {
				if(strcmp(longarg,shortarg) == 0) {
					if(shortarg[0] == '-') {
						logprintf(LOG_ERR, "invalid option -- '-%c'", c);
					} else {
						logprintf(LOG_ERR, "invalid option -- '%s'", longarg);
					}
				} else {
					logprintf(LOG_ERR, "invalid option -- '%s'", longarg);
				}
				goto gc;
			} else {
				return 0;
			}
		/* Check if an argument cannot have an argument that was set */
		} else if(strlen(*optarg) != 0 && options_get_argtype(opt, c, &itmp) == 0 && itmp == 1) {
			if(error_check == 1) {
				if(strcmp(longarg,shortarg) == 0) {
					logprintf(LOG_ERR, "option '-%c' doesn't take an argument", c);
				} else {
					logprintf(LOG_ERR, "option '%s' doesn't take an argument", longarg);
				}
				goto gc;
			} else {
				return 0;
			}
		/* Check if an argument required a value that wasn't set */
		} else if(strlen(*optarg) == 0 && options_get_argtype(opt, c, &itmp) == 0 && itmp == 2) {
			if(error_check == 1) {
				if(strcmp(longarg, shortarg) == 0) {
					logprintf(LOG_ERR, "option '-%c' requires an argument", c);
				} else {
					logprintf(LOG_ERR, "option '%s' requires an argument", longarg);
				}
				goto gc;
			} else {
				return 0;
			}
		/* Check if we have a valid argument */
		} else if(c == 0) {
			if(error_check == 1) {
				if(shortarg[0] == '-' && strstr(shortarg, longarg) != 0) {
					logprintf(LOG_ERR, "invalid option -- '-%c'", c);
				} else {
					logprintf(LOG_ERR, "invalid option -- '%s'", longarg);
				}
				goto gc;
			} else {
				return 0;
			}
		} else {
			/* If the argument didn't have a value, set it to 1 */
			if(strlen(*optarg) == 0) {
				options_set_string(opt, c, "1");
			} else {
#ifndef __FreeBSD__
				if(error_check != 2) {
					/* If the argument has a regex mask, check if it passes */
					if(options_get_mask(opt, c, &mask) == 0) {
						reti = regcomp(&regex, mask, REG_EXTENDED);
						if(reti) {
							logprintf(LOG_ERR, "could not compile regex");
							goto gc;
						}
						reti = regexec(&regex, *optarg, 0, NULL, 0);
						if(reti == REG_NOMATCH || reti != 0) {
							if(error_check == 1) {
								if(shortarg[0] == '-') {
									logprintf(LOG_ERR, "invalid format -- '-%c'", c);
								} else {
									logprintf(LOG_ERR, "invalid format -- '%s'", longarg);
								}
								logprintf(LOG_ERR, "requires %s", mask);
							}
							regfree(&regex);
							goto gc;
						}
						regfree(&regex);
					}
				}
#endif
				options_set_string(opt, c, *optarg);
			}
			return c;
		}
	}

gc:
	getOptPos=0;
	FREE(*optarg);

	return -2;
}
Exemple #8
0
int main(int argc, char **argv) {

	log_file_disable();
	log_shell_enable();
	log_level_set(LOG_NOTICE);

	progname = malloc(13);
	strcpy(progname, "pilight-send");

	struct options_t *options = NULL;

	int sockfd = 0;
    char *recvBuff = NULL;
    char *message;
	char *args = NULL;
	steps_t steps = WELCOME;

	/* Hold the name of the protocol */
	char protobuffer[25] = "\0";
	/* 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 *server = malloc(17);
	strcpy(server, "127.0.0.1");
	unsigned short port = PORT;
	
	/* Hold the final protocol struct */
	protocol_t *protocol = NULL;

	JsonNode *json = json_mkobject();
	JsonNode *code = json_mkobject();

	/* Define all CLI arguments of this program */
	options_add(&options, 'H', "help", no_value, 0, NULL);
	options_add(&options, 'V', "version", no_value, 0, NULL);
	options_add(&options, 'p', "protocol", has_value, 0, NULL);
	options_add(&options, 'S', "server", has_value, 0, "^(([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", has_value, 0, "[0-9]{1,4}");

	/* Initialize peripheral modules */
	hw_init();

	/* Get the protocol to be used */
	while (1) {
		int c;
		c = options_parse(&options, argc, argv, 0, &args);

		if (c == -1)
			break;
		switch(c) {
			case 'p':
				if(strlen(args) == 0) {
					logprintf(LOG_ERR, "options '-p' and '--protocol' require an argument");
					exit(EXIT_FAILURE);
				} else {
					strcpy(protobuffer, args);
				}
			break;
			case 'V':
				version = 1;
			break;
			case 'H':
				help = 1;
			break;
			case 'S':
				server = realloc(server, strlen(args)+1);
				strcpy(server, args);
			break;
			case 'P':
				port = (unsigned short)atoi(args);
			break;
			default:;
		}
	}	
	
	/* Check if a protocol was given */
	if(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_has_device(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");
			}
		}
	}

	/* Display help or version information */
	if(version == 1) {
		printf("%s %s\n", progname, "1.0");
		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 -S --server=%s\t\tconnect to server address\n", server);
			printf("\t -P --port=%d\t\t\tconnect to server port\n", port);
			printf("\t -p --protocol=protocol\t\tthe protocol that you want to control\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) {
					while(protocol->devices) {
						printf("\t %s\t\t",protocol->devices->id);
						if(strlen(protocol->devices->id)<7)
							printf("\t");
						if(strlen(protocol->devices->id)<14)
							printf("\t");
						printf("%s\n", protocol->devices->desc);
						protocol->devices = protocol->devices->next;
					}
				}
				pnode = pnode->next;
			}
		}
		goto close;
	}

	/* 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;
	}

	int itmp;
	/* 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 || strcmp(tmp->name, "protocol") == 0)
			&& strlen(tmp->value) > 0) {
				json_append_member(code, tmp->name, json_mkstring(tmp->value));
			}
		}
		tmp = tmp->next;
	}

	if(protocol->createCode(code) == 0) {
		if(protocol->message) {
			json_delete(protocol->message);
		}
		if((sockfd = socket_connect(server, port)) == -1) {
			logprintf(LOG_ERR, "could not connect to pilight-daemon");
			goto close;
		}

		while(1) {
			if(steps > WELCOME) {
				/* Clear the receive buffer again and read the welcome message */
				if((recvBuff = socket_read(sockfd))) {
					json = json_decode(recvBuff);
					json_find_string(json, "message", &message);
				} else {
					goto close;
				}
				usleep(100);
			}
			switch(steps) {
				case WELCOME:
					socket_write(sockfd, "{\"message\":\"client sender\"}");
					steps=IDENTIFY;
				case IDENTIFY:
					if(strcmp(message, "accept client") == 0) {
						steps=SEND;
					}
					if(strcmp(message, "reject client") == 0) {
						steps=REJECT;
					}
				case SEND:
					json_delete(json);
					json = json_mkobject();
					json_append_member(json, "message", json_mkstring("send"));
					json_append_member(json, "code", code);
					char *output = json_stringify(json, NULL);
					socket_write(sockfd, output);
					free(output);
					goto close;
				break;
				case REJECT:
				default:
					goto close;
				break;
			}
		}
	}
close:
	if(json) {
		json_delete(json);
	}
	if(sockfd) {
		socket_close(sockfd);
	}
	log_shell_disable();
	free(server);
	protocol_gc();
	options_delete(options);
	options_gc();
	free(progname);

return EXIT_SUCCESS;
}
Exemple #9
0
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;
}