Author: elliss
Update of /cvs/docs/rpm-guide In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv860
Added Files: rpm-guide-programming-c-en.xml Log Message:
--- NEW FILE rpm-guide-programming-c-en.xml --- <!-- $Id: --> <chapter id="ch-programming-c"> <title>Programming RPM with C</title>
<para> Copyright (c) 2005 by Eric Foster-Johnson. This material may be distributed only subject to the terms and conditions set forth in the Open Publication License, v1.0 or later (the latest version is presently available at http://www.opencontent.org/openpub/). </para>
<para/>
<para> In This Chapter </para>
<para> *Using the RPM C library </para>
<para> *Setting up a development environment </para>
<para> *Programming with the RPM C library </para>
<para> *The power of popt for command-line argument processing </para>
<para> *Comparing package files to installed packages </para>
<para> The RPM C library allows you to perform all the operations of the rpm command from within your own C or C++ programs. </para>
<para> The reason is simple: The rpm command was created using the RPM libraries. These same libraries are available for you to use in your own programs. </para>
<para> The rpm command itself is quick and, for the most part, simple. So, why would you want to write RPM programs? </para>
<para> There are many reasons, some of which are listed here: </para>
<para> *Speed: If you need to perform a task on many RPM files such as verifying a large set of files, then performing the task from one program will be a lot faster than launching the rpm command for each file. </para>
<para> *Custom options: If you need to do something the rpm command doesn't offer, or doesn't make easy, then you may want to write your own program. </para>
<para> *Convenience: If you need to make many packages quickly, with custom options, your best bet may be to create a program suited for your tasks. Before doing this, though, be sure to look into whether writing a shell script will handle your task adequately. You'll find writing RPM shell scripts goes much faster than writing whole programs. </para>
<para> *Installation programs: The Windows world has standardized on graphical installation programs such as InstallShield or InstallAnywhere. The RPM system, on the other hand, has focused on automated installation with the rpm command. You can combine the best of both worlds by writing a graphical installation program on top of the RPM system. </para>
<para> *Integration with environments: You may want to better integrate RPM with a Linux desktop environment such as GNOME or KDE. </para>
<para> *Working with other languages: This book covers programming RPM with C, the core language for the library, as well as the Python and Perl scripting languages. You can use the RPM library, though, to help bind with other languages such as Tcl, Ruby, or even C# (especially one of the C# implementations for Linux). </para>
<para> This chapter and the next cover RPM programming. This chapter covers the RPM C programming library, which provides low-level access to RPM functionality. The next chapter covers the RPM Python programming library, which provides a much higher-level of abstraction. If you are attempting to write a complex RPM program, your best bet is to try the Python API first. Even so, there is a lot you can do with the RPM C library. </para>
<sect1> <title>Programming with the C Library</title> <para> RPM C programs are C programs that call on functions in the RPM library, often called rpmlib. To use the rpmlib, you need to set up a C programming environment and install the rpm-devel package. </para> <sect2> <title>Setting Up a C Programming Environment</title> <para> At the very least, you���ll need a C compiler, gcc, and a text editor. The easiest way to get the C compiler is to install the packages grouped under Software Development with the Red Hat package management tool. </para> <para> Cross Reference </para> <para> See Chapter 8 for more on the Red Hat package management tool. </para> <para> The gcc package requires a number of capabilities. Make sure you install all the necessary packages. Just about every Linux distribution includes gcc and everything you need to develop C programs, so this should not be a problem. </para> <para> For text editors, you can use the vi or emacs text editors, or any of a number of graphical editors such as gedit. </para> <para> Cross Reference </para> <para> Appendix F covers Linux text editors and development tools. </para> <para> Once you have a C programming environment set up, you next need to get the RPM library for an RPM development environment. </para> </sect2> <sect2> <title>Setting Up the RPM Programming Environment</title> <para> To program with the RPM library, you need to install the rpm-devel package. You must have a version of rpm-devel that matches your version of the rpm package. If you have Red Hat Linux, your installation CDs will also have the version of the RPM development package that corresponds to your system. </para> <para> Your program should link against the same libraries that are used by the rpm command itself in order to insure compatibility, so make sure that the version of the rpm-devel package matches the rpm package itself. In most cases, the best bet is to use the RPM programs and libraries that come with your version of Linux. </para> <para> Cross Reference </para> <para> You can also download the rpm packages from ftp://ftp.rpm.org/pub/rpm/dist/. This site includes versions of the RPM libraries going back to 1996, ancient history in terms of Linux. </para> <para> The package you need is rpm-devel. If you installed Red Hat Linux 8.0, the package is rpm-devel-4.1-1.06. This package includes header files, documentation, and libraries. </para> </sect2> <sect2> <title>Using the RPM Library</title> <para> All C programs using the RPM library need to include the file rpmlib.h, which defines the core data structures, constants, and functions. One thing you���ll quickly note is that the RPM C library accesses RPM data at a very low level. This is one reason why many developers are moving to Python for their RPM programs, since the Python RPM API presents a higher level of abstraction. </para> <para> Cross Reference </para> [...3592 lines suppressed...] <para/> <para> ts = rpmtsCreate(); </para> <para/> <para> /* Check for query mode. */ </para> <para> if (qva->qva_mode == 'q') { </para> <para> /* Make sure there's something to do. */ </para> <para> if (qva->qva_source != RPMQV_ALL && !poptPeekArg(context)) { </para> <para> fprintf(stderr, "no arguments given for --query"); </para> <para> exit(EXIT_FAILURE); </para> <para> } </para> <para/> <para> ec = rpmcliQuery(ts, qva, (const char **) poptGetArgs(context)); </para> <para> } </para> <para> /* Check for verify mode. */ </para> <para> else if (qva->qva_mode == 'V') { </para> <para> rpmVerifyFlags verifyFlags = VERIFY_ALL; </para> <para/> <para> /* Verify flags are negated from query flags. */ </para> <para> verifyFlags &= ~qva->qva_flags; </para> <para> qva->qva_flags = (rpmQueryFlags) verifyFlags; </para> <para/> <para> /* Make sure there's something to do. */ </para> <para> if (qva->qva_source != RPMQV_ALL && !poptPeekArg(context)) { </para> <para> fprintf(stderr, "no arguments given for --verify"); </para> <para> exit(EXIT_FAILURE); </para> <para> } </para> <para/> <para> ec = rpmcliVerify(ts, qva, (const char **) poptGetArgs(context)); </para> <para> } </para> <para> else { </para> <para> poptPrintUsage(context, stderr, 0); </para> <para> exit(EXIT_FAILURE); </para> <para> } </para> <para/> <para> ts = rpmtsFree(ts); </para> <para/> <para> context = rpmcliFini(context); </para> <para/> <para> return ec; </para> <para> } </para> <para> There is not a lot of code in rpmq.c, as this program is mostly calling the high-level functions for the rpm command-line interface. </para> <para> When you run the rpmq program, it performs the same tasks as the rpm command with the --query (or -q) and --verify (or -V) command-line options. </para> <para> For example, rpmq supports query formats: </para> <para> $ ./rpmq -q --qf "%{NAME} %{INSTALLTID:date}\n" jikes </para> <para> jikes Fri 25 Oct 2002 06:49:38 PM CDT </para> </sect1>
<sect1> <title>Where to Go from Here</title> <para> There is a lot more you can do with the RPM library; you're limited only by your imagination. The best way to get started is to follow the examples in this chapter and then try out some RPM programs on your own. After working with the RPM library for a while, you can delve into other RPM topics. </para> <para> The RPM Web site, at www.rpm.org, has most of the available documentation on the RPM system. This site also includes official RPM released software. </para> <para> One of the best ways to help find out about how to perform RPM tasks is to look at the source code for the rpm program itself. For this, download the rpm-src source RPM, too. To see the rpm command-line interface functions in action, look especially at tools/rpmcache.c and tools/rpmgraph.c, two relatively short RPM files that show how to take advantage of a number of short cuts. The source code for the Python and Perl bindings can also provide extra hints about the purposes of the RPM API calls. </para> <para> The RPM Web site also has a cross-referenced set of HTML pages on the RPM programming API. The pages for version 4.1 of RPM are available at www.rpm.org/rpmapi-4.1/. A good starting page is www.rpm.org/rpmapi-4.1/modules.html, which lists a number of modules within the overall RPM library. This extra level of organization can help you locate the functions you need. </para> </sect1>
<sect1> <title>Summary</title> <para> Everything you can do with RPM you can program in C. That���s because the source code for the entire RPM system is available. In addition, the rpm and rpmbuild programs make use of a published API, called rpmlib, to access RPM functionality. You can use this library yourself. </para> <para> The popt library, short for parse options, provides a lot of handy utilities for parsing very complex command-line options. You can use popt inside your own programs, even if you don���t use the rest of the RPM functionality. </para> <para> Most RPM programs start up by calling rpmcliInit, which sets up RPM variables for the large set of command-line options supported by most RPM commands. </para> <para> Call rpmReadPackageFile to read in the Header object from a package file. You can also get Header objects for the packages installed in a system by initializing an iterator to iterate over a set of packages that meet a certain criteria. </para> <para> This chapter covers a fairly low level of access to RPM functionality. The next chapter, on Python programming, shows a higher level of abstraction for working with RPM. </para> </sect1> </chapter> <!-- Local variables: mode: xml sgml-parent-document:("rpm-guide-en.xml" "book" "chapter") fill-column: 72 End: -->
docs-commits@lists.fedoraproject.org