上QQ阅读APP看书,第一时间看更新
1.4 RPM解析例程
笔者基于rpm-devel开发了一个C程序,用来读取RPM文件的基本信息并打印到标准输出。如果你对前面章节介绍的知识已经理解并掌握了,下面这段代码就比较容易阅读了。
核心代码片段如下:
char * readHeaderString (Header header,int_32 tag_id) { int_32 type; void *pointer; int_32 data_size; //获取header中的一个string int header_status = headerGetEntry (header, tag_id,&type,&pointer,&data_size); if(header_status) { if(type == RPM_STRING_TYPE) { return pointer; } } return NULL; } int samplerpm (const char *szrpm) { char g_szname[1024] = {0}; FD_t fd = Fopen (szrpm,"r"); memset (g_szname,0,1024); sprintf (g_szname,"%s",szrpm); fflush (stdin); fflush (stdout); if(!fd) { printf ("open file '%s' failed\n",szrpm); return 0; } struct rpmlead plead; int lead = readLead (fd,&plead);//读取lead结构体 if(lead) { printf ("readLead of '%s' failed\n",szrpm); Fclose (fd); return 0; } Header header; //读取第一个header structure—signature rpmRC ret = rpmReadSignature (fd,&header,plead.signature_type); if(ret != RPMRC_OK) { printf ("rpmReadSignature of '%s' failed\n",szrpm); Fclose (fd); return 0; } //读取第一个header structure—header Header newheader = headerRead (fd,(plead.major >= 3)? HEADER_MAGIC_YES :HEADER_MAGIC_NO); if(!newheader) { printf ("headerRead of '%s' failed\n",szrpm); Fclose (fd); return 0; } //读取各个TAG const char *name = readHeaderString (newheader,RPMTAG_NAME); const char *version = readHeaderString (newheader,RPMTAG_VERSION); const char *release = readHeaderString (newheader,RPMTAG_RELEASE); const char *group = readHeaderString (newheader,RPMTAG_GROUP); const char *packager = readHeaderString (newheader,RPMTAG_PACKAGER); if (!group)group = "NONE_GROUP"; if (!packager)packager = "NONE_PACKAGER"; printf ("name:%s\nversion:%s\nrelease:%s\ngroup:%s\npackager:%s\n\n", name,version,release,group,packager); Fclose (fd); return 1; }
可执行程序的编译方法如下:
gcc test.c-I/usr/include/rpm-lrpm-lrpmdb-lrpmio-lpopt-o test_rpm
可以通过以下方法进行测试:
./test_rpm ./mysql-server-5.0.77-4.el5_6.6.x86_64.rpm
输出如下:
name:mysql-server version:5.0.77 release:4.el5_6.6 group:Applications/Databases packager:Red Hat,Inc.<http://bugzilla.redhat.com/bugzilla>
可以看到,test_rpm这个程序解析并打印了指定RPM文件的基本信息,读者可以参考文档对该程序进行功能细化。
由于笔者并没阅读rpm命令或者rpmbuild的源码,因此对RPM格式的剖析只能到此深度,不过rpmbuild的实现应该也是类似的,感兴趣的读者可以参考RPM的文档和源码进一步学习。