1
0
mirror of https://github.com/Llewellynvdm/conky.git synced 2025-02-05 13:38:33 +00:00

Parse quoted execgraph cmd before parsing options (#232)

When parsing the argument string for graph objects, check if there is a
double-quoted command in the beginning of the string and extract it
before parsing any options. This prevents items in a command from being
improperly recognized as graph options. It should also eliminate the
need to place commands with spaces into a separate script.

Also, fall back on default_graph_{height,width} instead of using
hard-coded values so that the default values set in a user's config will
work.
This commit is contained in:
marcpayne 2016-05-03 06:04:57 -06:00 committed by Brenden Matthews
parent 48122dcf82
commit 8dda4c3995
2 changed files with 65 additions and 56 deletions

View File

@ -1184,20 +1184,17 @@
default_graph_width config settings.</para> default_graph_width config settings.</para>
<para>If you need to execute a command with spaces, you <para>If you need to execute a command with spaces, you
have a couple options: 1) put your command into a have a couple options: 1) wrap your command in
separate file, such as ~/bin/myscript.sh, and use that double-quotes, or 2) put your command into a separate
as your execgraph command. Remember to make your script file, such as ~/bin/myscript.sh, and use that as your
executable! 2) Wrap your command in double-quotes. If execgraph command. Remember to make your script
you go for this option, do not try to pass the extra executable!</para>
parameters for height, width, etc., as the results may
be unexpected.</para>
<para>Option 1 is preferred. In the following example, we <para>In the following example, we set up execgraph to
set up execgraph to display seconds (0-59) on a graph that display seconds (0-59) on a graph that is 50px high and 200px
is 50px high and 200px wide, using a temperature gradient wide, using a temperature gradient with colors ranging from red
with colors ranging from red for small values (FF0000) to for small values (FF0000) to yellow for large values (FFFF00).
yellow for large values (FFFF00). We set the scale to We set the scale to 60.</para>
60.</para>
<para><command>${execgraph ~/seconds.sh 50,200 FF0000 <para><command>${execgraph ~/seconds.sh 50,200 FF0000
FFFF00 60 -t}</command></para> FFFF00 60 -t}</command></para>

View File

@ -192,11 +192,11 @@ void scan_font(struct text_object *obj, const char *args)
**/ **/
char *scan_graph(struct text_object *obj, const char *args, double defscale) char *scan_graph(struct text_object *obj, const char *args, double defscale)
{ {
struct graph *g; char quoted_cmd[1024] = { '\0' }; /* double-quoted execgraph command */
char buf[1024]; char argstr[1024] = { '\0' }; /* args minus quoted_cmd */
memset(buf, 0, 1024); char buf[1024] = { '\0' }; /* first unquoted string argument in argstr */
g = (struct graph *)malloc(sizeof(struct graph)); struct graph *g = (struct graph *)malloc(sizeof(struct graph));
memset(g, 0, sizeof(struct graph)); memset(g, 0, sizeof(struct graph));
obj->special_data = g; obj->special_data = g;
@ -208,14 +208,38 @@ char *scan_graph(struct text_object *obj, const char *args, double defscale)
g->scale = defscale; g->scale = defscale;
g->tempgrad = FALSE; g->tempgrad = FALSE;
if (args) { if (args) {
/* extract double-quoted command in case of execgraph */
if (*args == '"') {
char *_ptr;
size_t _size;
if ((_ptr = const_cast<char*>(strrchr(args, '"'))) && _ptr != args) {
_size = _ptr - args - 1;
} else {
NORM_ERR("mismatched double-quote in execgraph object");
return NULL;
}
_size = _size < 1024 ? _size : 1023;
strncpy(quoted_cmd, args + 1, _size);
quoted_cmd[_size] = '\0';
/* copy everything after the last quote into argstr */
if (_size + 2 < strlen(args)) {
strncpy(argstr, args + _size + 2, 1023);
}
} else {
/* redundant, but simplifies the code below */
strncpy(argstr, args, 1023);
}
/* set tempgrad to true, if '-t' specified. /* set tempgrad to true, if '-t' specified.
* It doesn#t matter where the argument is exactly. */ * It doesn#t matter where the argument is exactly. */
if (strstr(args, " " TEMPGRAD) || strncmp(args, TEMPGRAD, strlen(TEMPGRAD)) == 0) { if (strstr(argstr, " " TEMPGRAD) || strncmp(argstr, TEMPGRAD, strlen(TEMPGRAD)) == 0) {
g->tempgrad = TRUE; g->tempgrad = TRUE;
} }
/* set showlog-flag, if '-l' specified /* set showlog-flag, if '-l' specified
* It doesn#t matter where the argument is exactly. */ * It doesn#t matter where the argument is exactly. */
if (strstr(args, " " LOGGRAPH) || strncmp(args, LOGGRAPH, strlen(LOGGRAPH)) == 0) { if (strstr(argstr, " " LOGGRAPH) || strncmp(argstr, LOGGRAPH, strlen(LOGGRAPH)) == 0) {
g->flags |= SF_SHOWLOG; g->flags |= SF_SHOWLOG;
} }
@ -226,78 +250,66 @@ char *scan_graph(struct text_object *obj, const char *args, double defscale)
/* interpret the beginning(!) of the argument string as: /* interpret the beginning(!) of the argument string as:
* '[height],[width] [color1] [color2] [scale]' * '[height],[width] [color1] [color2] [scale]'
* This means parameters like -t and -l may not be in the beginning */ * This means parameters like -t and -l may not be in the beginning */
if (sscanf(args, "%d,%d %x %x %lf", &g->height, &g->width, &g->first_colour, &g->last_colour, &g->scale) == 5) { if (sscanf(argstr, "%d,%d %x %x %lf", &g->height, &g->width, &g->first_colour, &g->last_colour, &g->scale) == 5) {
return NULL; return *quoted_cmd ? strndup(quoted_cmd, text_buffer_size.get(*state)) : NULL;
} }
/* [height],[width] [color1] [color2] */ /* [height],[width] [color1] [color2] */
g->scale = defscale; g->scale = defscale;
if (sscanf(args, "%d,%d %x %x", &g->height, &g->width, &g->first_colour, &g->last_colour) == 4) { if (sscanf(argstr, "%d,%d %x %x", &g->height, &g->width, &g->first_colour, &g->last_colour) == 4) {
return NULL; return *quoted_cmd ? strndup(quoted_cmd, text_buffer_size.get(*state)) : NULL;
} }
/* [command] [height],[width] [color1] [color2] [scale] */ /* [command] [height],[width] [color1] [color2] [scale] */
if (sscanf(args, "%1023s %d,%d %x %x %lf", buf, &g->height, &g->width, &g->first_colour, &g->last_colour, &g->scale) == 6) { if (sscanf(argstr, "%1023s %d,%d %x %x %lf", buf, &g->height, &g->width, &g->first_colour, &g->last_colour, &g->scale) == 6) {
return strndup(buf, text_buffer_size.get(*state)); return strndup(buf, text_buffer_size.get(*state));
} }
g->scale = defscale; g->scale = defscale;
if (sscanf(args, "%1023s %d,%d %x %x", buf, &g->height, &g->width, &g->first_colour, &g->last_colour) == 5) { if (sscanf(argstr, "%1023s %d,%d %x %x", buf, &g->height, &g->width, &g->first_colour, &g->last_colour) == 5) {
return strndup(buf, text_buffer_size.get(*state)); return strndup(buf, text_buffer_size.get(*state));
} }
buf[0] = '\0'; buf[0] = '\0';
g->height = 25; g->height = default_graph_height.get(*state);
g->width = 0; g->width = default_graph_width.get(*state);
if (sscanf(args, "%x %x %lf", &g->first_colour, &g->last_colour, &g->scale) == 3) { if (sscanf(argstr, "%x %x %lf", &g->first_colour, &g->last_colour, &g->scale) == 3) {
return NULL; return *quoted_cmd ? strndup(quoted_cmd, text_buffer_size.get(*state)) : NULL;
} }
g->scale = defscale; g->scale = defscale;
if (sscanf(args, "%x %x", &g->first_colour, &g->last_colour) == 2) { if (sscanf(argstr, "%x %x", &g->first_colour, &g->last_colour) == 2) {
return NULL; return *quoted_cmd ? strndup(quoted_cmd, text_buffer_size.get(*state)) : NULL;
} }
if (sscanf(args, "%1023s %x %x %lf", buf, &g->first_colour, &g->last_colour, &g->scale) == 4) { if (sscanf(argstr, "%1023s %x %x %lf", buf, &g->first_colour, &g->last_colour, &g->scale) == 4) {
return strndup(buf, text_buffer_size.get(*state)); return strndup(buf, text_buffer_size.get(*state));
} }
g->scale = defscale; g->scale = defscale;
if (sscanf(args, "%1023s %x %x", buf, &g->first_colour, &g->last_colour) == 3) { if (sscanf(argstr, "%1023s %x %x", buf, &g->first_colour, &g->last_colour) == 3) {
return strndup(buf, text_buffer_size.get(*state)); return strndup(buf, text_buffer_size.get(*state));
} }
buf[0] = '\0'; buf[0] = '\0';
g->first_colour = 0; g->first_colour = 0;
g->last_colour = 0; g->last_colour = 0;
if (sscanf(args, "%d,%d %lf", &g->height, &g->width, &g->scale) == 3) { if (sscanf(argstr, "%d,%d %lf", &g->height, &g->width, &g->scale) == 3) {
return NULL; return *quoted_cmd ? strndup(quoted_cmd, text_buffer_size.get(*state)) : NULL;
} }
g->scale = defscale; g->scale = defscale;
if (sscanf(args, "%d,%d", &g->height, &g->width) == 2) { if (sscanf(argstr, "%d,%d", &g->height, &g->width) == 2) {
return NULL; return *quoted_cmd ? strndup(quoted_cmd, text_buffer_size.get(*state)) : NULL;
} }
if (sscanf(args, "%1023s %d,%d %lf", buf, &g->height, &g->width, &g->scale) < 4) { if (sscanf(argstr, "%1023s %d,%d %lf", buf, &g->height, &g->width, &g->scale) < 4) {
g->scale = defscale; g->scale = defscale;
//TODO: check the return value and throw an error? //TODO: check the return value and throw an error?
sscanf(args, "%1023s %d,%d", buf, &g->height, &g->width); sscanf(argstr, "%1023s %d,%d", buf, &g->height, &g->width);
} }
/* escape quotes at end in case of execgraph */ if (!*quoted_cmd && !*buf) {
if (*buf == '"') {
char *_ptr;
size_t _size;
if ((_ptr = const_cast<char*>(strrchr(args, '"')))) {
_size = _ptr - args - 1;
}
_size = _size < 1024 ? _size : 1023;
strncpy(buf, args + 1, _size);
buf[_size] = 0;
}
return strndup(buf, text_buffer_size.get(*state));
}
if (buf[0] == '\0') {
return NULL; return NULL;
} else { } else {
return strndup(buf, text_buffer_size.get(*state)); return strndup(*quoted_cmd ? quoted_cmd : buf, text_buffer_size.get(*state));
} }
} }
return NULL;
}
#endif /* BUILD_X11 */ #endif /* BUILD_X11 */
/* /*