/* If STRING includes known @FOO@ macros, replace these macros and return a new static string. Warning: STRING must have been allocated statically. Note that this function allocates memory which will not be released (similar to gettext). */ const char * map_static_macro_string (const char *string) { const char *s, *s2, *s3, *value; membuf_t mb; char *p; if ((s = already_mapped (string))) return s; s = string; value = find_macro (s, &s2, &s3); if (!value) return string; /* No macros at all. */ init_membuf (&mb, strlen (string) + 100); do { put_membuf (&mb, s, s2 - s); put_membuf_str (&mb, value); s = s3 + 1; } while ((value = find_macro (s, &s2, &s3))); put_membuf_str (&mb, s); put_membuf (&mb, "", 1); p = get_membuf_shrink (&mb, NULL); if (!p) log_fatal ("map_static_macro_string failed: %s\n", strerror (errno)); return store_mapping (string, p); }
/* Expands %i and %o in the args to the full temp files within the temp directory. */ static int expand_args(struct exec_info *info,const char *args_in) { const char *ch = args_in; membuf_t command; info->flags.use_temp_files=0; info->flags.keep_temp_files=0; if(DBG_EXTPROG) log_debug("expanding string \"%s\"\n",args_in); init_membuf (&command, 100); while(*ch!='\0') { if(*ch=='%') { char *append=NULL; ch++; switch(*ch) { case 'O': info->flags.keep_temp_files=1; /* fall through */ case 'o': /* out */ if(!info->flags.madedir) { if(make_tempdir(info)) goto fail; } append=info->tempfile_out; info->flags.use_temp_files=1; break; case 'I': info->flags.keep_temp_files=1; /* fall through */ case 'i': /* in */ if(!info->flags.madedir) { if(make_tempdir(info)) goto fail; } append=info->tempfile_in; info->flags.use_temp_files=1; break; case '%': append="%"; break; } if(append) put_membuf_str (&command, append); } else put_membuf (&command, ch, 1); ch++; } put_membuf (&command, "", 1); /* Terminate string. */ info->command = get_membuf (&command, NULL); if (!info->command) return gpg_error_from_syserror (); if(DBG_EXTPROG) log_debug("args expanded to \"%s\", use %u, keep %u\n",info->command, info->flags.use_temp_files,info->flags.keep_temp_files); return 0; fail: xfree (get_membuf (&command, NULL)); return G10ERR_GENERAL; }
/* Try to find KEY in the file FNAME. */ static char * findkey_fname (const char *key, const char *fname) { gpg_error_t err = 0; FILE *fp; int lnr = 0; int c; char *p, line[256]; int in_item = 0; membuf_t mb = MEMBUF_ZERO; fp = fopen (fname, "r"); if (!fp) { if (errno != ENOENT) { err = gpg_error_from_syserror (); log_error (_("can't open `%s': %s\n"), fname, gpg_strerror (err)); } return NULL; } while (fgets (line, DIM(line)-1, fp)) { lnr++; if (!*line || line[strlen(line)-1] != '\n') { /* Eat until end of line. */ while ( (c=getc (fp)) != EOF && c != '\n') ; err = gpg_error (*line? GPG_ERR_LINE_TOO_LONG : GPG_ERR_INCOMPLETE_LINE); log_error (_("file `%s', line %d: %s\n"), fname, lnr, gpg_strerror (err)); } else line[strlen(line)-1] = 0; /* Chop the LF. */ again: if (!in_item) { /* Allow for empty lines and spaces while not in an item. */ for (p=line; spacep (p); p++) ; if (!*p || *p == '#') continue; if (*line != '.' || spacep(line+1)) { log_info (_("file `%s', line %d: %s\n"), fname, lnr, _("ignoring garbage line")); continue; } trim_trailing_spaces (line); in_item = 1; if (!strcmp (line+1, key)) { /* Found. Start collecting. */ init_membuf (&mb, 1024); } continue; } /* If in an item only allow for comments in the first column and provide ". " as an escape sequence to allow for leading dots and hash marks in the actual text. */ if (*line == '#') continue; if (*line == '.') { if (spacep(line+1)) p = line + 2; else { trim_trailing_spaces (line); in_item = 0; if (is_membuf_ready (&mb)) break; /* Yep, found and collected the item. */ if (!line[1]) continue; /* Just an end of text dot. */ goto again; /* A new key line. */ } } else p = line; if (is_membuf_ready (&mb)) { put_membuf_str (&mb, p); put_membuf (&mb, "\n", 1); } } if ( !err && ferror (fp) ) { err = gpg_error_from_syserror (); log_error (_("error reading `%s', line %d: %s\n"), fname, lnr, gpg_strerror (err)); } fclose (fp); if (is_membuf_ready (&mb)) { /* We have collected something. */ if (err) { xfree (get_membuf (&mb, NULL)); return NULL; } else { put_membuf (&mb, "", 1); /* Terminate string. */ return get_membuf (&mb, NULL); } } else return NULL; }
/* Search for keys on the keyservers. The patterns are given in the string list TOKENS. */ gpg_error_t keyserver_search (ctrl_t ctrl, strlist_t tokens) { gpg_error_t err; char *searchstr; struct search_line_handler_parm_s parm; memset (&parm, 0, sizeof parm); if (!tokens) return 0; /* Return success if no patterns are given. */ if (!opt.keyserver) { log_error (_("no keyserver known (use option --keyserver)\n")); return gpg_error (GPG_ERR_NO_KEYSERVER); } /* Write global options */ /* for(temp=opt.keyserver_options.other;temp;temp=temp->next) */ /* fprintf(spawn->tochild,"OPTION %s\n",temp->d); */ /* Write per-keyserver options */ /* for(temp=keyserver->options;temp;temp=temp->next) */ /* fprintf(spawn->tochild,"OPTION %s\n",temp->d); */ { membuf_t mb; strlist_t item; init_membuf (&mb, 1024); for (item = tokens; item; item = item->next) { if (item != tokens) put_membuf (&mb, " ", 1); put_membuf_str (&mb, item->d); } put_membuf (&mb, "", 1); /* Append Nul. */ searchstr = get_membuf (&mb, NULL); if (!searchstr) { err = gpg_error_from_syserror (); goto leave; } } /* FIXME: Enable the next line */ /* log_info (_("searching for \"%s\" from %s\n"), searchstr, keyserver->uri); */ parm.ctrl = ctrl; if (searchstr) parm.searchstr_disp = utf8_to_native (searchstr, strlen (searchstr), 0); err = gpg_dirmngr_ks_search (ctrl, searchstr, search_line_handler, &parm); if (parm.not_found) { if (parm.searchstr_disp) log_info (_("key \"%s\" not found on keyserver\n"), parm.searchstr_disp); else log_info (_("key not found on keyserver\n")); } if (gpg_err_code (err) == GPG_ERR_NO_KEYSERVER) log_error (_("no keyserver known (use option --keyserver)\n")); else if (err) log_error ("error searching keyserver: %s\n", gpg_strerror (err)); /* switch(ret) */ /* { */ /* case KEYSERVER_SCHEME_NOT_FOUND: */ /* log_error(_("no handler for keyserver scheme '%s'\n"), */ /* opt.keyserver->scheme); */ /* break; */ /* case KEYSERVER_NOT_SUPPORTED: */ /* log_error(_("action '%s' not supported with keyserver " */ /* "scheme '%s'\n"), "search", opt.keyserver->scheme); */ /* break; */ /* case KEYSERVER_TIMEOUT: */ /* log_error(_("keyserver timed out\n")); */ /* break; */ /* case KEYSERVER_INTERNAL_ERROR: */ /* default: */ /* log_error(_("keyserver internal error\n")); */ /* break; */ /* } */ /* return gpg_error (GPG_ERR_KEYSERVER); */ leave: xfree (parm.desc); xfree (parm.searchstr_disp); xfree(searchstr); return err; }