(CC to [email protected], the new home for RPM development discussions)
On Dec 14, 2007 11:49 AM, Vento Neicapelli <[EMAIL PROTECTED]>
wrote:
> Dear All,
>
> I'm trying to use the librpm in a custom application, I use rpm 4.4.2.1and I
> need your help about tag querying...
>
Hmmm, I'll try to make suggestions appropriate for rpm-4.4.2.1, but
that's not a rpm code base I have any control over).
FYI: Note that rpm-5.0 has rewritten all the header code. E.g.
there is already a 10x (that's 10 times, not 10%) faster array
lookups using --query.
>
> 1) Have you got any snip of code to use the headerSprintf probably I'm
> doing it wrong...
>
I have many snippets using headerSprintf ...
>
> 2) given the prototype:
> char * headerSprintf(Header h, const char * fmt, const struct
> headerTagTableEntry_s * tags, const struct headerSprintfExtension_s *
> extensions, /[EMAIL PROTECTED]@*/ /[EMAIL PROTECTED]@*/ errmsg_t * errmsg)
> if I understand the tag fmt should have the same format of the rpm tool
> (cli version) with --queryformat switch....or not?
>
Yes, headerSprintf is the recipient of the format passed by the
--queryformat option.
> Below you find the code I wrote just to get familiar with rpmlib
> functions: it tries to search a package (by name) and then prints some
> tags....
>
> Thx for your help
>
> vento
>
>
> ----
>
> int dumpPkgHeader(const char *pkgName){
> Header h;
> rpmdb db;
> int rc;
>
> rpmReadConfigFiles( NULL, NULL );
>
> if( rpmdbOpen( "", &db, O_RDONLY, 0644 ) != 0 ) {
> fprintf( stderr, "cannot open RPM database.\n" );
> return ( -1 );
> }
>
>
You likely do _NOT_ want to open a rpmdb directly.
Instead see Chapter 15 of "The RedHat RPM Guide" at
http://docs.fedoraproject.org/drafts/rpm-guide-en/ch-programming-c.html
(aside) Hmmm, the example code I sent to Eric Foster-Johnson years
ago seems not to have survived editing by Eric or Fedora or ...
Gimme a couple hours and I'll post a better example ...
>
> rpmdbMatchIterator mi = rpmdbInitIterator(db, RPMTAG_NAME, pkgName,
> 0);
> while( (h=rpmdbNextIterator(mi) )!=NULL ) {
> char *name;
> char *ver;
> char *rel;
> char *sResult;
> char *errMsg=NULL;
>
> const char * qfmt = "[%{*:xml}\n]";
> struct headerTagTableEntry_s hTTE;
> struct headerSprintfExtension_s hSE;
> sResult = (hdrVec->hdrsprintf)(h, qfmt, &hTTE, &hSE, &errMsg);
>
Here's your problem: You need to use the tables from rpmlib. This snippet
(from rpm-4.3.x python/header-py.c) shows how to make a headerSprintf() call
r = headerSprintf(s->h, fmt, rpmTagTable, rpmHeaderFormats, &err);
You want to use _EXACTLY_ "... rpmTagTable, rpmHeaderFormats, ..."
as arguments.
>
> printf("ALLTAGS:\n %s",sResult);
> free(sResult); sResult=NULL; errMsg=NULL;
>
> const char *qSummary="%{NAME}";
> sResult = (hdrVec->hdrsprintf)(h, qSummary, &hTTE, &hSE, &errMsg);
>
>
Hmmm, you can go through the hdrVec vector, but headerSprintf() instead is
recommended.
Both rpm-4.4.2.2 and rpm-5.0 have nuked hdrVec AFAIK.
>
> if(!errMsg){
> if(sResult){
> printf("NAME:\n %s",sResult);
> free(sResult); sResult=NULL; errMsg=NULL;
> }
> }else printf("ERROR: %s\n",errMsg);
>
> const char *qFiles="[%{DIRNAMES}%{BASENAMES}\n]";
>
> sResult = (hdrVec->hdrsprintf)(h, qFiles, &hTTE, &hSE, &errMsg);
> if(!errMsg){
> printf("FILES:\n %s",sResult);
> free(sResult); sResult=NULL; errMsg=NULL;
> }else printf("ERROR: %s\n",errMsg);
>
> headerNVR(h,(const char **)&name, (const char **)&ver, (const char
> **) &rel );
> printf("Name %s; Version %s; Release %s", name, ver ,rel);
>
> (hdrVec->hdrfree)(h);
> }
>
> //rpmdbFreeIterator(mi);
> rpmdbClose( db );
>
> return 0;
> }
>
Lemme hack up a "tqa.c" program that uses --queryformat and headerSprintf()
as in rpm-5.0. I'll post to <[email protected]> in a couple of hours ...
hth
73 de Jeff