rpm-guide rpm-guide-programming-c-en.xml,NONE,1.1

Stuart Ellis (elliss) fedora-docs-commits at redhat.com
Tue Oct 4 01:57:53 UTC 2005


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:
-->





More information about the Fedora-docs-commits mailing list