// trim trailing and trailing whitespace std::string trim( const std::string& str ) { return trim_trailing_ws( trim_leading_ws(str) ) ; }
/* Returns a keyrec (which must be freed) once a key is complete, and NULL otherwise. Call with a NULL keystring once key parsing is complete to return any unfinished keys. */ static struct keyrec * parse_keyrec(char *keystring) { /* FIXME: Remove the static and put the data into the parms we use for the caller anyway. */ static struct keyrec *work=NULL; struct keyrec *ret=NULL; char *record; int i; if(keystring==NULL) { if(work==NULL) return NULL; else if(work->desc.mode==KEYDB_SEARCH_MODE_NONE) { xfree(work); return NULL; } else { ret=work; work=NULL; return ret; } } if(work==NULL) { work=xmalloc_clear(sizeof(struct keyrec)); work->uidbuf=iobuf_temp(); } trim_trailing_ws (keystring, strlen (keystring)); if((record=strsep(&keystring,":"))==NULL) return ret; if(ascii_strcasecmp("pub",record)==0) { char *tok; gpg_error_t err; if(work->desc.mode) { ret=work; work=xmalloc_clear(sizeof(struct keyrec)); work->uidbuf=iobuf_temp(); } if((tok=strsep(&keystring,":"))==NULL) return ret; err = classify_user_id (tok, &work->desc, 1); if (err || (work->desc.mode != KEYDB_SEARCH_MODE_SHORT_KID && work->desc.mode != KEYDB_SEARCH_MODE_LONG_KID && work->desc.mode != KEYDB_SEARCH_MODE_FPR16 && work->desc.mode != KEYDB_SEARCH_MODE_FPR20)) { work->desc.mode=KEYDB_SEARCH_MODE_NONE; return ret; } /* Note all items after this are optional. This allows us to have a pub line as simple as pub:keyid and nothing else. */ work->lines++; if((tok=strsep(&keystring,":"))==NULL) return ret; work->type=atoi(tok); if((tok=strsep(&keystring,":"))==NULL) return ret; work->size=atoi(tok); if((tok=strsep(&keystring,":"))==NULL) return ret; if(atoi(tok)<=0) work->createtime=0; else work->createtime=atoi(tok); if((tok=strsep(&keystring,":"))==NULL) return ret; if(atoi(tok)<=0) work->expiretime=0; else { work->expiretime=atoi(tok); /* Force the 'e' flag on if this key is expired. */ if(work->expiretime<=make_timestamp()) work->flags|=4; } if((tok=strsep(&keystring,":"))==NULL) return ret; while(*tok) switch(*tok++) { case 'r': case 'R': work->flags|=1; break; case 'd': case 'D': work->flags|=2; break; case 'e': case 'E': work->flags|=4; break; } } else if(ascii_strcasecmp("uid",record)==0 && work->desc.mode) { char *userid,*tok,*decoded; if((tok=strsep(&keystring,":"))==NULL) return ret; if(strlen(tok)==0) return ret; userid=tok; /* By definition, de-%-encoding is always smaller than the original string so we can decode in place. */ i=0; while(*tok) if(tok[0]=='%' && tok[1] && tok[2]) { int c; userid[i] = (c=hextobyte(&tok[1])) == -1 ? '?' : c; i++; tok+=3; } else userid[i++]=*tok++; /* We don't care about the other info provided in the uid: line since no keyserver supports marking userids with timestamps or revoked/expired/disabled yet. */ /* No need to check for control characters, as utf8_to_native does this for us. */ decoded=utf8_to_native(userid,i,0); if(strlen(decoded)>opt.screen_columns-10) decoded[opt.screen_columns-10]='\0'; iobuf_writestr(work->uidbuf,decoded); xfree(decoded); iobuf_writestr(work->uidbuf,"\n\t"); work->lines++; } /* Ignore any records other than "pri" and "uid" for easy future growth. */ return ret; }