X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=common-src%2Futil.c;h=b9172ca41950fa716235833f7e2b0c2853fbd957;hb=0b384eedceb290242dbc4759ca16cbb1370c26de;hp=9ca0b4db604d249ffdbd737e614b49c60cc706df;hpb=b116e9366c7b2ea2c2eb53b0a13df4090e176235;p=debian%2Famanda diff --git a/common-src/util.c b/common-src/util.c index 9ca0b4d..b9172ca 100644 --- a/common-src/util.c +++ b/common-src/util.c @@ -438,52 +438,129 @@ quote_string_maybe( if ((str == NULL) || (*str == '\0')) { ret = stralloc("\"\""); - } else if (!always && (match("[:\'\\\"[:space:][:cntrl:]]", str)) == 0) { - /* - * String does not need to be quoted since it contains - * neither whitespace, control or quote characters. - */ - ret = stralloc(str); } else { - /* - * Allocate maximum possible string length. - * (a string of all quotes plus room for leading ", trailing " and NULL) - */ - ret = s = alloc((strlen(str) * 2) + 2 + 1); - *(s++) = '"'; - while (*str != '\0') { - if (*str == '\t') { - *(s++) = '\\'; - *(s++) = 't'; - str++; - continue; - } else if (*str == '\n') { - *(s++) = '\\'; - *(s++) = 'n'; - str++; - continue; - } else if (*str == '\r') { - *(s++) = '\\'; - *(s++) = 'r'; - str++; - continue; - } else if (*str == '\f') { - *(s++) = '\\'; - *(s++) = 'f'; - str++; - continue; - } else if (*str == '\\') { - *(s++) = '\\'; - *(s++) = '\\'; - str++; - continue; - } - if (*str == '"') - *(s++) = '\\'; - *(s++) = *(str++); + const char *r; + for (r = str; *r; r++) { + if (*r == ':' || *r == '\'' || *r == '\\' || *r == '\"' || + *r <= ' ' || *r == 0x7F ) + always = 1; + } + if (!always) { + /* + * String does not need to be quoted since it contains + * neither whitespace, control or quote characters. + */ + ret = stralloc(str); + } else { + /* + * Allocate maximum possible string length. + * (a string of all quotes plus room for leading ", trailing " and + * NULL) + */ + ret = s = alloc((strlen(str) * 2) + 2 + 1); + *(s++) = '"'; + while (*str != '\0') { + if (*str == '\t') { + *(s++) = '\\'; + *(s++) = 't'; + str++; + continue; + } else if (*str == '\n') { + *(s++) = '\\'; + *(s++) = 'n'; + str++; + continue; + } else if (*str == '\r') { + *(s++) = '\\'; + *(s++) = 'r'; + str++; + continue; + } else if (*str == '\f') { + *(s++) = '\\'; + *(s++) = 'f'; + str++; + continue; + } else if (*str == '\\') { + *(s++) = '\\'; + *(s++) = '\\'; + str++; + continue; + } + if (*str == '"') + *(s++) = '\\'; + *(s++) = *(str++); + } + *(s++) = '"'; + *s = '\0'; } - *(s++) = '"'; - *s = '\0'; + } + return (ret); +} + + +int +len_quote_string_maybe( + const char *str, + gboolean always) +{ + int ret; + + if ((str == NULL) || (*str == '\0')) { + ret = 0; + } else { + const char *r; + for (r = str; *r; r++) { + if (*r == ':' || *r == '\'' || *r == '\\' || *r == '\"' || + *r <= ' ' || *r == 0x7F ) + always = 1; + } + if (!always) { + /* + * String does not need to be quoted since it contains + * neither whitespace, control or quote characters. + */ + ret = strlen(str); + } else { + /* + * Allocate maximum possible string length. + * (a string of all quotes plus room for leading ", trailing " and + * NULL) + */ + ret = 1; + while (*str != '\0') { + if (*str == '\t') { + ret++; + ret++; + str++; + continue; + } else if (*str == '\n') { + ret++; + ret++; + str++; + continue; + } else if (*str == '\r') { + ret++; + ret++; + str++; + continue; + } else if (*str == '\f') { + ret++; + ret++; + str++; + continue; + } else if (*str == '\\') { + ret++; + ret++; + str++; + continue; + } + if (*str == '"') + ret++; + ret++; + str++; + } + ret++; + } } return (ret); } @@ -1027,7 +1104,7 @@ int copy_file( return 0; } -#ifndef HAVE_READLINE +#ifndef HAVE_LIBREADLINE /* * simple readline() replacements, used when we don't have readline * support from the system. @@ -1528,3 +1605,73 @@ debug_executing( amfree(cmdline); } +char * +get_first_line( + GPtrArray *argv_ptr) +{ + char *output_string = NULL; + int inpipe[2], outpipe[2], errpipe[2]; + int pid; + FILE *out, *err; + + assert(argv_ptr != NULL); + assert(argv_ptr->pdata != NULL); + assert(argv_ptr->len >= 1); + + if (pipe(inpipe) == -1) { + error(_("error [open pipe: %s]"), strerror(errno)); + /*NOTREACHED*/ + } + if (pipe(outpipe) == -1) { + error(_("error [open pipe: %s]"), strerror(errno)); + /*NOTREACHED*/ + } + if (pipe(errpipe) == -1) { + error(_("error [open pipe: %s]"), strerror(errno)); + /*NOTREACHED*/ + } + + fflush(stdout); + switch(pid = fork()) { + case -1: + error(_("error [fork: %s]"), strerror(errno)); + /*NOTREACHED*/ + + default: /* parent process */ + aclose(inpipe[0]); + aclose(outpipe[1]); + aclose(errpipe[1]); + break; + + case 0: /* child process */ + aclose(inpipe[1]); + aclose(outpipe[0]); + aclose(errpipe[0]); + + dup2(inpipe[0], 0); + dup2(outpipe[1], 1); + dup2(errpipe[1], 2); + + debug_executing(argv_ptr); + g_fprintf(stdout, "unknown\n"); + execv((char *)*argv_ptr->pdata, (char **)argv_ptr->pdata); + error(_("error [exec %s: %s]"), (char *)*argv_ptr->pdata, strerror(errno)); + } + + aclose(inpipe[1]); + + out = fdopen(outpipe[0],"r"); + err = fdopen(errpipe[0],"r"); + + output_string = agets(out); + if (!output_string) + output_string = agets(err); + + fclose(out); + fclose(err); + + waitpid(pid, NULL, 0); + + return output_string; +} +