# AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: Fedora RPM Guide\n" "POT-Creation-Date: 2011-03-02T00:57:13\n" "PO-Revision-Date: 2011-08-21 07:58+0000\n" "Last-Translator: Automatically generated\n" "Language-Team: Ukrainian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: uk\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n" #. Tag: title #, no-c-format msgid "Programming RPM with C" msgstr "" #. Tag: para #, no-c-format msgid "This chapter covers:" msgstr "" #. Tag: para #, no-c-format msgid "Using the RPM C library" msgstr "" #. Tag: para #, no-c-format msgid "Setting up a development environment" msgstr "" #. Tag: para #, no-c-format msgid "Programming with the RPM C library" msgstr "" #. Tag: para #, no-c-format msgid "" "The power of popt for command-line argument processing" msgstr "" #. Tag: para #, no-c-format msgid "Comparing package files to installed packages" msgstr "" #. Tag: para #, no-c-format msgid "" "The RPM C library allows you to perform all the operations of the rpm " "command from within your own C or C++ programs." msgstr "" #. Tag: para #, no-c-format msgid "" "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." msgstr "" #. Tag: para #, no-c-format msgid "" "The rpm command itself is quick and, for the most part, simple. So, why " "would you want to write RPM programs?" msgstr "" #. Tag: para #, no-c-format msgid "There are many reasons, some of which are listed here:" msgstr "" #. Tag: para #, no-c-format msgid "" "*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." msgstr "" #. Tag: para #, no-c-format msgid "" "*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." msgstr "" #. Tag: para #, no-c-format msgid "" "*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." msgstr "" #. Tag: para #, no-c-format msgid "" "*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." msgstr "" #. Tag: para #, no-c-format msgid "" "*Integration with environments: You may want to better integrate RPM with a " "Linux desktop environment such as GNOME or KDE." msgstr "" #. Tag: para #, no-c-format msgid "" "*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)." msgstr "" #. Tag: para #, no-c-format msgid "" "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." msgstr "" #. Tag: title #, no-c-format msgid "Programming with the C Library" msgstr "" #. Tag: para #, no-c-format msgid "" "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." msgstr "" #. Tag: title #, no-c-format msgid "Setting Up a C Programming Environment" msgstr "" #. Tag: para #, no-c-format msgid "" "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." msgstr "" #. Tag: para #, no-c-format msgid "Cross Reference" msgstr "" #. Tag: para #, no-c-format msgid "" "See for more on the Red Hat " "package management tool." msgstr "" #. Tag: para #, no-c-format msgid "" "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." msgstr "" #. Tag: para #, no-c-format msgid "" "For text editors, you can use the vi or emacs text editors, or any of a " "number of graphical editors such as gedit." msgstr "" #. Tag: para #, no-c-format msgid "" " covers Linux text editors and " "development tools." msgstr "" #. Tag: para #, no-c-format msgid "" "Once you have a C programming environment set up, you next need to get the " "RPM library for an RPM development environment." msgstr "" #. Tag: title #, no-c-format msgid "Setting Up the RPM Programming Environment" msgstr "" #. Tag: para #, no-c-format msgid "" "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." msgstr "" #. Tag: para #, no-c-format msgid "" "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." msgstr "" #. Tag: para #, no-c-format msgid "" "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." msgstr "" #. Tag: para #, no-c-format msgid "" "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." msgstr "" #. Tag: title #, no-c-format msgid "Using the RPM Library" msgstr "" #. Tag: para #, no-c-format msgid "" "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." msgstr "" #. Tag: para #, no-c-format msgid "" " covers programming RPM with " "Python." msgstr "" #. Tag: para #, no-c-format msgid "" "In addition to rpmlib.h, the header file rpmcli.h defines a high-level API " "based on the command-line options to the rpm command. (The cli in rpmcli " "stands for command-line interface.) Table 16-1 lists other important RPM " "header files that make up the major subsystems of the RPM system." msgstr "" #. Tag: para #, no-c-format msgid "Table 16-1 RPM sub-system header files" msgstr "" #. Tag: para #, no-c-format msgid "File" msgstr "" #. Tag: para #, no-c-format msgid "Defines" msgstr "" #. Tag: para #, no-c-format msgid "rpmdb.h" msgstr "" #. Tag: para #, no-c-format msgid "RPM database access" msgstr "" #. Tag: para #, no-c-format msgid "rpmio.h" msgstr "" #. Tag: para #, no-c-format msgid "RPM input/output routines" msgstr "" #. Tag: para #, no-c-format msgid "popt.h" msgstr "" #. Tag: para #, no-c-format msgid "Command-line option processing" msgstr "" #. Tag: para #, no-c-format msgid "" "In addition, a number of header files define the major data objects in the " "RPM system and the functions that operate on these data objects. Table 16-2 " "lists these header files." msgstr "" #. Tag: para #, no-c-format msgid "Table 16-2 RPM data object header files" msgstr "" #. Tag: para #, no-c-format msgid "rpmts.h" msgstr "" #. Tag: para #, no-c-format msgid "Transaction sets" msgstr "" #. Tag: para #, no-c-format msgid "rpmte.h" msgstr "" #. Tag: para #, no-c-format msgid "Transaction elements (packages)" msgstr "" #. Tag: para #, no-c-format msgid "rpmds.h" msgstr "" #. Tag: para #, no-c-format msgid "Dependency sets" msgstr "" #. Tag: para #, no-c-format msgid "rpmfi.h" msgstr "" #. Tag: para #, no-c-format msgid "File information" msgstr "" #. Tag: para #, no-c-format msgid "header.h" msgstr "" #. Tag: para #, no-c-format msgid "Package headers" msgstr "" #. Tag: para #, no-c-format msgid "" "All the RPM include files are located in /usr/include/rpm on most versions " "of Linux." msgstr "" #. Tag: para #, no-c-format msgid "Note" msgstr "" #. Tag: para #, no-c-format msgid "" "You can use the rpm command and the queries introduced in to determine exactly where the header files are " "located. Simply execute the following command:" msgstr "" #. Tag: para #, no-c-format msgid "$ rpm –ql rpm-devel" msgstr "" #. Tag: para #, no-c-format msgid "Examine the output of this command for include files." msgstr "" #. Tag: title #, no-c-format msgid "Compiling and Linking RPM Programs" msgstr "" #. Tag: para #, no-c-format msgid "" "RPM programs using the rpmlib C API are the same as C programs everywhere. " "You need to include the proper header files that define the API calls you " "need, and link with the right set of libraries." msgstr "" #. Tag: title #, no-c-format msgid "Include Files" msgstr "" #. Tag: para #, no-c-format msgid "" "The rpm include files are located in /usr/include/rpm, so you should add " "this directory to the set of directories that the C compiler looks in for " "include files with the –I command-line option. For example:" msgstr "" #. Tag: para #, no-c-format msgid "$ gcc –I/usr/include/rpm –c rpm1.c" msgstr "" #. Tag: para #, no-c-format msgid "" "This also means that you can install the rpm header files in other " "directories as needed, and just change the –I command-line option." msgstr "" #. Tag: para #, no-c-format msgid "" "To help debug problems, you probably want to add the -Wall (output all " "warnings) and -g (compile with debugging information). For example:" msgstr "" #. Tag: para #, no-c-format msgid "$ gcc -Wall -g –I/usr/include/rpm –c rpm1.c" msgstr "" #. Tag: title #, no-c-format msgid "Libraries" msgstr "" #. Tag: para #, no-c-format msgid "" "The main rpm library is librpm.a, or a shared version of this same library. " "To do most anything with RPM programming, you need to link in the following " "libraries, as listed in Table 16-3." msgstr "" #. Tag: para #, no-c-format msgid "Table 16-3 Required rpm libraries" msgstr "" #. Tag: para #, no-c-format msgid "Library" msgstr "" #. Tag: para #, no-c-format msgid "Usage" msgstr "" #. Tag: para #, no-c-format msgid "rpm" msgstr "" #. Tag: para #, no-c-format msgid "Main RPM library" msgstr "" #. Tag: para #, no-c-format msgid "rpmdb" msgstr "" #. Tag: para #, no-c-format msgid "RPM database library" msgstr "" #. Tag: para #, no-c-format msgid "rpmio" msgstr "" #. Tag: para #, no-c-format msgid "RPM input/output" msgstr "" #. Tag: para #, no-c-format msgid "popt" msgstr "" #. Tag: para #, no-c-format msgid "Command-line option parsing library" msgstr "" #. Tag: para #, no-c-format msgid "" "If you are creating RPMs from your C programs, you also need to link in the " "rpmbuild library. To compile and link a simple RPM program, you need a " "command like the following:" msgstr "" #. Tag: para #, no-c-format msgid "gcc -I/usr/include/rpm -o program program.c –lrpmbuild \\" msgstr "" #. Tag: para #, no-c-format msgid "-lrpm -lrpmdb -lrpmio –lpopt" msgstr "" #. Tag: para #, no-c-format msgid "" "On some versions of Linux or on other operating systems, you’ll likely need " "to link a set of helper libraries, as shown following:" msgstr "" #. Tag: para #, no-c-format msgid "-lrpm -lrpmdb -lrpmio –lpopt -lelf -lbz2 -lz" msgstr "" #. Tag: para #, no-c-format msgid "" "If you have installed the rpm libraries in a non-standard directory, you " "need to use the –L option to specify where else to look for libraries. For " "example:" msgstr "" #. Tag: para #, no-c-format msgid "gcc -I/usr/include/rpm -o program program.c –L/opt/lib/rpm \\" msgstr "" #. Tag: para #, no-c-format msgid "-lrpmbuild -lrpm -lrpmdb -lrpmio –lpopt -lelf -lbz2 -lz" msgstr "" #. Tag: para #, no-c-format msgid "" "The -L option tells the cc compiler to look in the /opt/lib/rpm directory as" " well as in the standard locations such as /usr/lib." msgstr "" #. Tag: para #, no-c-format msgid "" "Starting with RPM 4.2, you should just need to link in the rpm library. The " "other libraries will get pulled in automatically if needed." msgstr "" #. Tag: title #, no-c-format msgid "Getting information on your RPM environment" msgstr "" #. Tag: para #, no-c-format msgid "" "A large part of the RPM system lies in system-specific configuration, " "including the platform you are running on, compatible platforms, and " "locations of various files. The RPM rc and macro systems support hundreds of" " options tuned to the specifics of your system, and any customizations you " "have configured." msgstr "" #. Tag: para #, no-c-format msgid " covers customizing RPM." msgstr "" #. Tag: para #, no-c-format msgid "" "Your C programs need to access these RPM system settings to ensure that all " "data values are properly set up for your system architecture and " "installation. So, to start an RPM C program, you need to read in all the " "configuration files. To do this, call rpmReadConfigFiles." msgstr "" #. Tag: para #, no-c-format msgid "int rpmReadConfigFiles(const char *files, const char *target);" msgstr "" #. Tag: para #, no-c-format msgid "" "The files parameter holds a colon-delimited list of files that make up your " "system’s configuration. The target parameter holds the target platform. You " "can pass NULL for both these parameters to use the RPM defaults, which is " "generally what you want." msgstr "" #. Tag: para #, no-c-format msgid "" "The rpmReadConfigFiles function returns a 0 on success, or –1 on errors." msgstr "" #. Tag: para #, no-c-format msgid "" "Once you have read in the configuration files, you can access values in the " "configuration, or print it out." msgstr "" #. Tag: title #, no-c-format msgid "Printing the Configuration" msgstr "" #. Tag: para #, no-c-format msgid "To print out the configuration, call rpmShowRC." msgstr "" #. Tag: para #, no-c-format msgid "int rpmShowRC(FILE* output);" msgstr "" #. Tag: para #, no-c-format msgid "" "Pass in an output file to print the configuration to, such as stdout. For " "example:" msgstr "" #. Tag: para #, no-c-format msgid "rpmShowRC( stdout );" msgstr "" #. Tag: para #, no-c-format msgid "The rpmShowRC function always returns 0." msgstr "" #. Tag: para #, no-c-format msgid "" "To control some of the output from rpmShowRC, and other RPM library " "functions, you can set the logging verbosity level by calling " "rpmSetVerbosity:" msgstr "" #. Tag: para #, no-c-format msgid "void rpmSetVerbosity(int level);" msgstr "" #. Tag: para #, no-c-format msgid "For example:" msgstr "" #. Tag: para #, no-c-format msgid "rpmSetVerbosity(RPMMESS_NORMAL);" msgstr "" #. Tag: para #, no-c-format msgid "" "Table 16-4 lists the verbosity levels from rpmio/rpmmessages.h going from " "least output to more output." msgstr "" #. Tag: para #, no-c-format msgid "Table 16-4 Output verbosity levels" msgstr "" #. Tag: para #, no-c-format msgid "Level" msgstr "" #. Tag: para #, no-c-format msgid "RPMMESS_FATALERROR" msgstr "" #. Tag: para #, no-c-format msgid "Only critical error conditions and above" msgstr "" #. Tag: para #, no-c-format msgid "RPMMESS_ERROR" msgstr "" #. Tag: para #, no-c-format msgid "Only error conditions and above" msgstr "" #. Tag: para #, no-c-format msgid "RPMMESS_WARNING" msgstr "" #. Tag: para #, no-c-format msgid "Only warning conditions and above" msgstr "" #. Tag: para #, no-c-format msgid "RPMMESS_QUIET" msgstr "" #. Tag: para #, no-c-format msgid "Same as RPMMESS_WARNING" msgstr "" #. Tag: para #, no-c-format msgid "RPMMESS_NORMAL" msgstr "" #. Tag: para #, no-c-format msgid "Only significant messages" msgstr "" #. Tag: para #, no-c-format msgid "RPMMESS_VERBOSE" msgstr "" #. Tag: para #, no-c-format msgid "Verbose informational messages" msgstr "" #. Tag: para #, no-c-format msgid "RPMMESS_DEBUG" msgstr "" #. Tag: para #, no-c-format msgid "Debugging messages, and everything above" msgstr "" #. Tag: para #, no-c-format msgid "" "You can put together a simple RPM program such as the one shown in Listing " "16-1." msgstr "" #. Tag: para #, no-c-format msgid "Listing 16-1: rpm1.c" msgstr "" #. Tag: para #, no-c-format msgid "/* Show the rpmrc settings. */" msgstr "" #. Tag: para #, no-c-format msgid "#include <stdio.h>" msgstr "" #. Tag: para #, no-c-format msgid "#include <stdlib.h>" msgstr "" #. Tag: para #, no-c-format msgid "#include <rpmlib.h>" msgstr "" #. Tag: para #, no-c-format msgid "int main(int argc, char * argv[]) {" msgstr "" #. Tag: para #, no-c-format msgid "int status = rpmReadConfigFiles( (const char*) NULL," msgstr "" #. Tag: para #, no-c-format msgid "(const char*) NULL);" msgstr "" #. Tag: para #, no-c-format msgid "if (status != 0) {" msgstr "" #. Tag: para #, no-c-format msgid "printf(\"Error reading RC files.\\n\");" msgstr "" #. Tag: para #, no-c-format msgid "exit(-1);" msgstr "" #. Tag: para #, no-c-format msgid "} else {" msgstr "" #. Tag: para #, no-c-format msgid "printf(\"Read RC OK\\n\");" msgstr "" #. Tag: para #, no-c-format msgid "}" msgstr "" #. Tag: para #, no-c-format msgid "exit(0);" msgstr "" #. Tag: para #, no-c-format msgid "Compile this program with a command like the following:" msgstr "" #. Tag: para #, no-c-format msgid "$ cc -I/usr/include/rpm -o rpm1 rpm1.c -lrpm -lrpmdb -lrpmio –lpopt" msgstr "" #. Tag: para #, no-c-format msgid "" "When you run this program, you should see the contents of your configuration" " printed to the screen." msgstr "" #. Tag: title #, no-c-format msgid "Expanding the Value of Macros" msgstr "" #. Tag: para #, no-c-format msgid "" "With all the rc and macro configuration files, the RPM system has a lot of " "values, usually called macros, that you can use to refer to settings. The " "term macro is used because the values can be more than simple strings. You " "can have one macro refer to the value of other macros, for example. The " "basic macro syntax is:" msgstr "" #. Tag: para #, no-c-format msgid "%name_of_macro" msgstr "" #. Tag: para #, no-c-format msgid "%_target" msgstr "" #. Tag: para #, no-c-format msgid "Most of the internal RPM macros start with an underscore, _." msgstr "" #. Tag: para #, no-c-format msgid "You can expand a macro with the rpm --eval command:" msgstr "" #. Tag: para #, no-c-format msgid "$ rpm --eval %_target" msgstr "" #. Tag: para #, no-c-format msgid "i386-linux" msgstr "" #. Tag: para #, no-c-format msgid "You can also refer to a macro using the following syntax:" msgstr "" #. Tag: para #, no-c-format msgid "%{name_of_macro}" msgstr "" #. Tag: para #, no-c-format msgid "%{_target}" msgstr "" #. Tag: para #, no-c-format msgid "" "This syntax makes it easier to include a macro in combinations with other " "text and other macros, since it clearly delineates the macro name." msgstr "" #. Tag: para #, no-c-format msgid "" " covers macros in depth. In your C " "programs, your code will likely need to expand the value of macros to place " "data in the proper directories, determine the platform architecture, and so " "on." msgstr "" #. Tag: title #, no-c-format msgid "Expanding Macros in Your Code" msgstr "" #. Tag: para #, no-c-format msgid "" "You can use rpmExpand to determine the value of system macros from within " "your C programs." msgstr "" #. Tag: para #, no-c-format msgid "" "The rpmExpand function can expand the values of one or more macros, " "returning the expanded value. You can pass a variable number of parameters " "to rpmExpand, and you must terminate the list with a NULL:" msgstr "" #. Tag: para #, no-c-format msgid "char* rpmExpand (const char *arg,...);" msgstr "" #. Tag: para #, no-c-format msgid "You need to free the data returned by rpmExpand by calling free." msgstr "" #. Tag: para #, no-c-format msgid "" "The program in Listing 16-2 takes the first command-line argument to your " "program (after the program name) and expands that argument as a macro." msgstr "" #. Tag: para #, no-c-format msgid "Listing 16-2: rpmexpand.c" msgstr "" #. Tag: para #, no-c-format msgid "/* Show some macro settings. */" msgstr "" #. Tag: para #, no-c-format msgid "#include <rpmmacro.h>" msgstr "" #. Tag: para #, no-c-format msgid "char* value = rpmExpand(argv[1], (const char*) NULL);" msgstr "" #. Tag: para #, no-c-format msgid "printf(\"Value of macro is [%s]\\n\", value);" msgstr "" #. Tag: para #, no-c-format msgid "Compile and link this program as shown previously." msgstr "" #. Tag: para #, no-c-format msgid "" "When you run this program, pass the name of a macro to expand. For example:" msgstr "" #. Tag: para #, no-c-format msgid "$ ./rpmexpand %_target" msgstr "" #. Tag: para #, no-c-format msgid "Value of macro is [i386-linux]" msgstr "" #. Tag: para #, no-c-format msgid "You can pass multiple macros together, as shown following:" msgstr "" #. Tag: para #, no-c-format msgid "$ ./rpmexpand %_builddir/%_target" msgstr "" #. Tag: para #, no-c-format msgid "Value of macro is [/usr/src/redhat/BUILD/i386-linux]" msgstr "" #. Tag: para #, no-c-format msgid "" "You can verify this program with the rpm --eval command, introduced " "previously:" msgstr "" #. Tag: para #, no-c-format msgid "$ rpm --eval %_builddir/%_target" msgstr "" #. Tag: para #, no-c-format msgid "/usr/src/redhat/BUILD/i386-linux" msgstr "" #. Tag: title #, no-c-format msgid "The Power of popt" msgstr "" #. Tag: para #, no-c-format msgid "" "Popt provides a powerful command-line processing library, allowing the rpm " "command to handle a variety of options in a very flexible way. You can use " "popt alone as a library in its own right, or use it combined with the rpm " "library to handle command-line options like those of the rpm command." msgstr "" #. Tag: para #, no-c-format msgid "" "At its most basic, popt processes the command-line arguments to a C program," " traditionally called argc and argv, into an option table that describes and" " contains all the option values." msgstr "" #. Tag: para #, no-c-format msgid "" "The main advantage popt has over simpler libraries such as getopt lies in " "the ability to handle complex arguments and to define aliases. The rpm " "command supports three different behaviors for the –i option, depending on " "the context (install a package, get information on a package as part of a " "query, and perform the install stage of a source RPM, as part of rpmbuild)." msgstr "" #. Tag: para #, no-c-format msgid "" "The popt library supports both traditional UNIX short options such as –U and" " the longer options common for GNU programs, especially on Linux, such as " "--upgrade. For the popt library, you can define both short and long variants" " for each option. In addition, command-line options may be individual flags," " such as –v for verbose, or options that expect one or more data values as " "arguments, such as –f, which requires a file name." msgstr "" #. Tag: title #, no-c-format msgid "Popt aliases" msgstr "" #. Tag: para #, no-c-format msgid "" "One of the most powerful features of popt is the ability to define aliases. " "A popt alias allows you to define one command-line option as an alias for a " "set of options. As its simplest, the rpm command-line options --upgrade and " "–U refer to the same action. You could define one as an alias for the other." msgstr "" #. Tag: para #, no-c-format msgid "" "With rpm, the file /usr/lib/rpm/rpmpopt-4.1 (for RPM version 4.1) defines " "over 400 lines of popt aliases to configure the rpm command-line options. " "For example:" msgstr "" #. Tag: para #, no-c-format msgid "Rpm alias –requires --qf \\" msgstr "" #. Tag: para #, no-c-format msgid "\"[%{REQUIRENAME} %{REQUIREFLAGS:depflags} %{REQUIREVERSION}\\n]\" \\" msgstr "" #. Tag: para #, no-c-format msgid "--POPTdesc=$\"list capabilities required by package(s)\"" msgstr "" #. Tag: para #, no-c-format msgid "" "This example defines rpm --requires as really a query using the --qf or " "--queryformat options covered in ." msgstr "" #. Tag: para #, no-c-format msgid "" "See for more on defining popt " "aliases." msgstr "" #. Tag: title #, no-c-format msgid "Programming with popt" msgstr "" #. Tag: para #, no-c-format msgid "" "To use popt in your programs, you need to fill in a table of options and " "then call poptGetContext. The poptGetContext function parses the command-" "line options and returns a poptContext, an opaque data type that you need to" " pass as a parameter to a number of popt functions. The poptContext holds " "the state of your command-line processing. This allows you to call the popt " "library with multiple sets of arguments. Each set will have an associate " "poptContext to keep all the data separate." msgstr "" #. Tag: para #, no-c-format msgid "The basic poptGetContext function signature follows:" msgstr "" #. Tag: para #, no-c-format msgid "poptContext poptGetContext (const char * name," msgstr "" #. Tag: para #, no-c-format msgid "int argc," msgstr "" #. Tag: para #, no-c-format msgid "const char ** argv," msgstr "" #. Tag: para #, no-c-format msgid "const struct poptOption * options," msgstr "" #. Tag: para #, no-c-format msgid "int flags );" msgstr "" #. Tag: para #, no-c-format msgid "All the popt functions require the popt.h include file:" msgstr "" #. Tag: para #, no-c-format msgid "#include <popt.h>" msgstr "" #. Tag: para #, no-c-format msgid "" "The flags should be a bitmask of any options you require, including those " "listed in Table 16-5." msgstr "" #. Tag: para #, no-c-format msgid "Table 16-5 Flags for poptGetContext" msgstr "" #. Tag: para #, no-c-format msgid "Flag" msgstr "" #. Tag: para #, no-c-format msgid "Meaning" msgstr "" #. Tag: para #, no-c-format msgid "POPT_CONTEXT_NO_EXEC" msgstr "" #. Tag: para #, no-c-format msgid "Ignore executable expansions" msgstr "" #. Tag: para #, no-c-format msgid "POPT_CONTEXT_KEEP_FIRST" msgstr "" #. Tag: para #, no-c-format msgid "Treat argv[0], the command name, as an option" msgstr "" #. Tag: para #, no-c-format msgid "POPT_CONTEXT_POSIXMEHARDER" msgstr "" #. Tag: para #, no-c-format msgid "Do not allow options to follow arguments" msgstr "" #. Tag: para #, no-c-format msgid "" "When done with a poptContext, you should free it by calling poptFreeContext:" msgstr "" #. Tag: para #, no-c-format msgid "poptContext poptFreeContext(poptContext context);" msgstr "" #. Tag: para #, no-c-format msgid "" "The call to poptFreeContext frees up the memory allocated for the context." msgstr "" #. Tag: para #, no-c-format msgid "" "You can also fill in a poptContext from settings in a file with " "poptReadConfigFile:" msgstr "" #. Tag: para #, no-c-format msgid "int poptReadConfigFile(poptContext context," msgstr "" #. Tag: para #, no-c-format msgid "const char * file_name);" msgstr "" #. Tag: title #, no-c-format msgid "Filling in the Options Table" msgstr "" #. Tag: para #, no-c-format msgid "" "You need to pass in a table that defines all the possible options. This " "table is an array of structures, where each structure defines one option. " "The format for a single option follows:" msgstr "" #. Tag: para #, no-c-format msgid "struct poptOption {" msgstr "" #. Tag: para #, no-c-format msgid "const char * longName;" msgstr "" #. Tag: para #, no-c-format msgid "char shortName;" msgstr "" #. Tag: para #, no-c-format msgid "int argInfo;" msgstr "" #. Tag: para #, no-c-format msgid "void * arg;" msgstr "" #. Tag: para #, no-c-format msgid "int val;" msgstr "" #. Tag: para #, no-c-format msgid "const char * descrip;" msgstr "" #. Tag: para #, no-c-format msgid "const char * argDescrip;" msgstr "" #. Tag: para #, no-c-format msgid "};" msgstr "" #. Tag: para #, no-c-format msgid "" "Going through this structure, the longName defines the long version of the " "option, such as \"upgrade\" for --upgrade. The shortName defines the short, " "one-character option, such as 'U' for an option of -U. You can place a null " "character, '\\0', to specify no short option. With the rpm command, the " "--rebuilddb option has only a long name and not a short name, for example." msgstr "" #. Tag: para #, no-c-format msgid "" "The longName is not preceded by the double minus sign. Similarly, the " "shortName is not preceded by the single minus sign." msgstr "" #. Tag: para #, no-c-format msgid "" "The descrip field holds a short description of the option and the argDescrip" " field holds a description of the types of values it expects, or NULL if " "this option expects no values." msgstr "" #. Tag: para #, no-c-format msgid "" "The argInfo field holds a flag that tells the popt library how to treat the " "option. At the very least, you need to define the type of the option. You " "can also define special processing flags. Table 16-6 lists the argument " "types in the options table." msgstr "" #. Tag: para #, no-c-format msgid "Table 16-6 Popt option table argInfo argument types" msgstr "" #. Tag: para #, no-c-format msgid "Type" msgstr "" #. Tag: para #, no-c-format msgid "Value" msgstr "" #. Tag: para #, no-c-format msgid "POPT_ARG_NONE" msgstr "" #. Tag: para #, no-c-format msgid "0" msgstr "" #. Tag: para #, no-c-format msgid "No argument data, just the option such as -v" msgstr "" #. Tag: para #, no-c-format msgid "POPT_ARG_STRING" msgstr "" #. Tag: para #, no-c-format msgid "1" msgstr "" #. Tag: para #, no-c-format msgid "arg treated as string" msgstr "" #. Tag: para #, no-c-format msgid "POPT_ARG_INT" msgstr "" #. Tag: para #, no-c-format msgid "2" msgstr "" #. Tag: para #, no-c-format msgid "arg treated as int" msgstr "" #. Tag: para #, no-c-format msgid "POPT_ARG_LONG" msgstr "" #. Tag: para #, no-c-format msgid "3" msgstr "" #. Tag: para #, no-c-format msgid "arg treated as long" msgstr "" #. Tag: para #, no-c-format msgid "POPT_ARG_INCLUDE_TABLE" msgstr "" #. Tag: para #, no-c-format msgid "4" msgstr "" #. Tag: para #, no-c-format msgid "arg points to a table" msgstr "" #. Tag: para #, no-c-format msgid "POPT_ARG_CALLBACK" msgstr "" #. Tag: para #, no-c-format msgid "5" msgstr "" #. Tag: para #, no-c-format msgid "arg points to a callback function" msgstr "" #. Tag: para #, no-c-format msgid "POPT_ARG_INTL_DOMAIN" msgstr "" #. Tag: para #, no-c-format msgid "6" msgstr "" #. Tag: para #, no-c-format msgid "sets translation domain" msgstr "" #. Tag: para #, no-c-format msgid "POPT_ARG_VAL" msgstr "" #. Tag: para #, no-c-format msgid "7" msgstr "" #. Tag: para #, no-c-format msgid "use value of val field for arg" msgstr "" #. Tag: para #, no-c-format msgid "POPT_ARG_FLOAT" msgstr "" #. Tag: para #, no-c-format msgid "8" msgstr "" #. Tag: para #, no-c-format msgid "arg treated as float" msgstr "" #. Tag: para #, no-c-format msgid "POPT_ARG_DOUBLE" msgstr "" #. Tag: para #, no-c-format msgid "9" msgstr "" #. Tag: para #, no-c-format msgid "arg treated as double" msgstr "" #. Tag: para #, no-c-format msgid "" "Use these constants, from the include file popt.h, in place of the actual " "numbers." msgstr "" #. Tag: para #, no-c-format msgid "" "Depending on the type you define in the argInfo field, popt will interpret " "the generic pointer field, arg, in different ways. Using a pointer allows " "the popt library to automatically update your program variables based on the" " command-line option settings." msgstr "" #. Tag: para #, no-c-format msgid "" "You can pass NULL for the arg field. In this case, the popt library will not" " set any values for you." msgstr "" #. Tag: para #, no-c-format msgid "" "The POPT_ARG_NONE type indicates that this option has no argument. For " "example, the -v verbose option has no data. On the other hand, the " "POPT_ARG_STRING type indicates that the user should provide a string. For " "example, the -f option to the rpm command is expected to include a string " "argument, the name of the file to look up." msgstr "" #. Tag: para #, no-c-format msgid "" "If the argInfo argument type is POPT_ARG_NONE, the popt library will set arg" " to 1 if the option is present on the command line. You should pass a " "pointer to an int if you want this set for you." msgstr "" #. Tag: title #, no-c-format msgid "Popt Callbacks" msgstr "" #. Tag: para #, no-c-format msgid "" "The POPT_ARG_CALLBACK type indicates that the arg field holds a function " "pointer to a callback function of the following type:" msgstr "" #. Tag: para #, no-c-format msgid "typedef void (*poptCallbackType) (poptContext con," msgstr "" #. Tag: para #, no-c-format msgid "enum poptCallbackReason reason," msgstr "" #. Tag: para #, no-c-format msgid "const struct poptOption * opt," msgstr "" #. Tag: para #, no-c-format msgid "const char * arg," msgstr "" #. Tag: para #, no-c-format msgid "const void * data);" msgstr "" #. Tag: para #, no-c-format msgid "The callback reason will be one of the following enum values:" msgstr "" #. Tag: para #, no-c-format msgid "enum poptCallbackReason {" msgstr "" #. Tag: para #, no-c-format msgid "POPT_CALLBACK_REASON_PRE = 0," msgstr "" #. Tag: para #, no-c-format msgid "POPT_CALLBACK_REASON_POST = 1," msgstr "" #. Tag: para #, no-c-format msgid "POPT_CALLBACK_REASON_OPTION = 2" msgstr "" #. Tag: para #, no-c-format msgid "" "The data field holds the value of the descrip field in the poptOption entry." " You can cheat and stuff a pointer to arbitrary data into this field." msgstr "" #. Tag: para #, no-c-format msgid "" "The callback function is most useful if you are using nested option tables. " "You can place your processing code for the nested options into a callback." msgstr "" #. Tag: title #, no-c-format msgid "Special Option Table Flags" msgstr "" #. Tag: para #, no-c-format msgid "" "In addition to the types in Table 16-6, you can also define special bit " "flags that define extra processing information for each option. Combine " "these bit flags with the type values using a logical OR operation:" msgstr "" #. Tag: para #, no-c-format msgid "" "*The POPT_ARGFLAG_ONEDASH flag allows the longName to be used with one or " "two dashes, such as -upgrade or --upgrade." msgstr "" #. Tag: para #, no-c-format msgid "" "*For bitmask options, the POPT_ARGFLAG_OR, POPT_ARGFLAG_NOR, " "POPT_ARGFLAG_AND, POPT_ARGFLAG_NAND, and POPT_ARGFLAG_XOR type flags tell " "the popt library to apply the given operation, OR, NOR, AND, NAND, or XOR, " "to the value if set. The POPT_ARGFLAG_NOT flag tells the popt library to " "negate the value first." msgstr "" #. Tag: para #, no-c-format msgid "" "*You can also use the macros POPT_BIT_SET to set a bit and POPT_BIT_CLR to " "clear a bit." msgstr "" #. Tag: para #, no-c-format msgid "" "*The POPT_ARGFLAG_OPTIONAL flag indicates that the argument value is " "optional." msgstr "" #. Tag: para #, no-c-format msgid "" "*The POPT_ARGFLAG_DOC_HIDDEN flag tells popt to hide this option when " "displaying the help documentation. In other words, this is an internal " "option." msgstr "" #. Tag: para #, no-c-format msgid "" "*The rarely used POPT_ARGFLAG_STRIP flag tells popt to consume an option and" " ignore it. This option is rarely used." msgstr "" #. Tag: para #, no-c-format msgid "" "*The POPT_ARGFLAG_SHOW_DEFAULT flag tells popt to show the initial value of " "the argument for this option as a default when displaying a help message." msgstr "" #. Tag: title #, no-c-format msgid "Magic Options" msgstr "" #. Tag: para #, no-c-format msgid "" "With RPM programs, developers usually round out the option table with three " "special options: POPT_AUTOALIAS, POPT_AUTOHELP, and POPT_TABLEEND. The " "POPT_AUTOALIAS option sets up a table of aliases:" msgstr "" #. Tag: para #, no-c-format msgid "" "#define POPT_AUTOALIAS { NULL, '\\0', POPT_ARG_INCLUDE_TABLE, " "poptAliasOptions, \\" msgstr "" #. Tag: para #, no-c-format msgid "0, \"Options implemented via popt alias/exec:\", NULL }," msgstr "" #. Tag: para #, no-c-format msgid "" "This option refers to the table, poptAliasOptions. You can use the " "POPT_ARG_INCLUDE_TABLE argInfo type to include another table of options. " "These options get filled in from popt aliases. In addition, within RPM " "programs, another table, rpmcliAllPoptTable, holds a set of options common " "to all RPM programs." msgstr "" #. Tag: para #, no-c-format msgid "" "The POPT_AUTOHELP option supports standard help options. The POPT_AUTOHELP " "macro adds in automatic support for -?, --help, and --usage options." msgstr "" #. Tag: para #, no-c-format msgid "" "#define POPT_AUTOHELP { NULL, '\\0', POPT_ARG_INCLUDE_TABLE, " "poptHelpOptions, \\" msgstr "" #. Tag: para #, no-c-format msgid "0, \"Help options:\", NULL }," msgstr "" #. Tag: para #, no-c-format msgid "" "The POPT_TABLEEND option defines an empty option to mark the end of the " "table. You must include an empty option to end the table, and POPT_TABLEEND " "makes this easy." msgstr "" #. Tag: para #, no-c-format msgid "#define POPT_TABLEEND { NULL, '\\0', 0, 0, 0, NULL, NULL }" msgstr "" #. Tag: para #, no-c-format msgid "" "The code in Listing 16-3, in the \"Running a Popt Example\" section later in" " this chapter, shows a full option table." msgstr "" #. Tag: title #, no-c-format msgid "Parsing the Command-Line Options" msgstr "" #. Tag: para #, no-c-format msgid "" "Once you have set up a poptGetContext, you need to iterate over all the " "command-line parameters. To do this, call poptGetNextOpt:" msgstr "" #. Tag: para #, no-c-format msgid "int poptGetNextOpt(poptContext context);" msgstr "" #. Tag: para #, no-c-format msgid "" "If an error occurs, poptGetNextOpt returns a negative error code. If the " "context is at the end of the options, poptGetNextOpt returns –1. Table 16-7 " "lists the error codes:" msgstr "" #. Tag: para #, no-c-format msgid "Table 16-7 Error codes from poptGetNextOpt" msgstr "" #. Tag: para #, no-c-format msgid "Code" msgstr "" #. Tag: para #, no-c-format msgid "POPT_ERROR_NOARG" msgstr "" #. Tag: para #, no-c-format msgid "Option requires an argument, but it is missing" msgstr "" #. Tag: para #, no-c-format msgid "POPT_ERROR_BADOPT" msgstr "" #. Tag: para #, no-c-format msgid "Argument could not be parsed" msgstr "" #. Tag: para #, no-c-format msgid "POPT_ERROR_OPTSTOODEEP" msgstr "" #. Tag: para #, no-c-format msgid "Aliases are nested too deeply" msgstr "" #. Tag: para #, no-c-format msgid "POPT_ERROR_BADQUOTE" msgstr "" #. Tag: para #, no-c-format msgid "Start and end quotation marks don't match" msgstr "" #. Tag: para #, no-c-format msgid "POPT_ERROR_BADNUMBER" msgstr "" #. Tag: para #, no-c-format msgid "Argument could not be converted to a number" msgstr "" #. Tag: para #, no-c-format msgid "POPT_ERROR_OVERFLOW" msgstr "" #. Tag: para #, no-c-format msgid "Argument number was too big or too small" msgstr "" #. Tag: para #, no-c-format msgid "POPT_ERROR_ERRNO" msgstr "" #. Tag: para #, no-c-format msgid "A system call returned an error in errno" msgstr "" #. Tag: title #, no-c-format msgid "Walking Through the Command-Line Options" msgstr "" #. Tag: para #, no-c-format msgid "" "In normal circumstances, poptGetNextOpt parses all the options and returns " "–1. If your needs are simple, you can use the pointers to the variables " "passed in the options table, described previously. If you need some special " "processing for options not handled by popt, that is, options of type " "POPT_ARG_NONE, then poptGetNextOpt returns the single-character option." msgstr "" #. Tag: para #, no-c-format msgid "" "In this case, you can call poptGetNextOpt in a while loop. For example:" msgstr "" #. Tag: para #, no-c-format msgid "while ((option = poptGetNextOpt(context) ) {" msgstr "" #. Tag: para #, no-c-format msgid "/* Do something... */" msgstr "" #. Tag: para #, no-c-format msgid "" "Inside your while loop, you can call poptGetOptArg to get the value of the " "argument:" msgstr "" #. Tag: para #, no-c-format msgid "char * poptGetOptArg(poptContext context);" msgstr "" #. Tag: para #, no-c-format msgid "" "You can restart the processing of the options by calling poptResetContext:" msgstr "" #. Tag: para #, no-c-format msgid "void poptResetContext(poptContext context);" msgstr "" #. Tag: para #, no-c-format msgid "" "The popt system is just looking for arguments that start with a dash, -. In " "most command-line applications, you may have a number of extra arguments at " "the end, such as a list of file names. The popt library doesn’t process " "these, but can provide them to you." msgstr "" #. Tag: para #, no-c-format msgid "Call poptGetArg to return the next extra argument:" msgstr "" #. Tag: para #, no-c-format msgid "char * poptGetArg(poptContext context);" msgstr "" #. Tag: para #, no-c-format msgid "Keep calling this function until it returns NULL." msgstr "" #. Tag: para #, no-c-format msgid "" "Call poptPeekArg to look at the next argument but not mark it as being " "processed:" msgstr "" #. Tag: para #, no-c-format msgid "char * poptPeekArg(poptContext context);" msgstr "" #. Tag: para #, no-c-format msgid "" "Or, you can get the whole list of extra arguments by calling poptGetArgs:" msgstr "" #. Tag: para #, no-c-format msgid "char ** poptGetArgs(poptContext context);" msgstr "" #. Tag: title #, no-c-format msgid "Handling Errors" msgstr "" #. Tag: para #, no-c-format msgid "" "Inside your while loop processing the command-line arguments, you can call " "poptBadOption to get the option that was bad, and poptStrerror to look up " "the error message associated with the error." msgstr "" #. Tag: para #, no-c-format msgid "" "For poptBadOption, you need to pass in the context, and a bitmask of flags. " "Normally, pass 0 for no flags or POPT_BADOPTION_NOALIAS, which tells popt to" " return the actual option, not a value defined in an alias. This makes " "poptBadOption return the option closest to, if not exactly the same as, what" " the user entered, which makes for better error reporting." msgstr "" #. Tag: para #, no-c-format msgid "The poptBadOption function signature follows:" msgstr "" #. Tag: para #, no-c-format msgid "char * poptBadOption(poptContext context, int flags);" msgstr "" #. Tag: para #, no-c-format msgid "" "Pass the error number returned by poptGetOptArg to poptStrerror to get the " "standard error message for that option:" msgstr "" #. Tag: para #, no-c-format msgid "const char * poptStrerror(const int error_code);" msgstr "" #. Tag: para #, no-c-format msgid "" "You can combine these and print out an error with code like the following:" msgstr "" #. Tag: para #, no-c-format msgid "fprintf( stderr, \"Error with option [%s]\\n %s\"," msgstr "" #. Tag: para #, no-c-format msgid "poptBadOption(context, POPT_BADOPTION_NOALIAS)," msgstr "" #. Tag: para #, no-c-format msgid "poptStrerror(error_code);" msgstr "" #. Tag: para #, no-c-format msgid "To print out a usage message, call poptPrintUsage:" msgstr "" #. Tag: para #, no-c-format msgid "void poptPrintUsage(poptContext context," msgstr "" #. Tag: para #, no-c-format msgid "FILE *output," msgstr "" #. Tag: para #, no-c-format msgid "int flags);" msgstr "" #. Tag: para #, no-c-format msgid "" "This function prints out the usage help information, which is a useful " "function when the user has called a program with incomplete or wrong " "options." msgstr "" #. Tag: title #, no-c-format msgid "Running a popt example" msgstr "" #. Tag: para #, no-c-format msgid "" "Pulling this all together, you can use the popt1.c program, in Listing 16-3," " as an example for using popt to process command-line options." msgstr "" #. Tag: para #, no-c-format msgid "Listing 16-3: popt1.c" msgstr "" #. Tag: para #, no-c-format msgid "/* Processes command-line options. */" msgstr "" #. Tag: para #, no-c-format msgid "/* Data values for the options. */" msgstr "" #. Tag: para #, no-c-format msgid "static int intVal = 55;" msgstr "" #. Tag: para #, no-c-format msgid "static int print = 0;" msgstr "" #. Tag: para #, no-c-format msgid "static char* stringVal;" msgstr "" #. Tag: para #, no-c-format msgid "void callback(poptContext context," msgstr "" #. Tag: para #, no-c-format msgid "const struct poptOption * option," msgstr "" #. Tag: para #, no-c-format msgid "const void * data)" msgstr "" #. Tag: para #, no-c-format msgid "{" msgstr "" #. Tag: para #, no-c-format msgid "switch(reason)" msgstr "" #. Tag: para #, no-c-format msgid "case POPT_CALLBACK_REASON_PRE:" msgstr "" #. Tag: para #, no-c-format msgid "printf(\"\\t Callback in pre setting\\n\"); break;" msgstr "" #. Tag: para #, no-c-format msgid "case POPT_CALLBACK_REASON_POST:" msgstr "" #. Tag: para #, no-c-format msgid "printf(\"\\t Callback in post setting\\n\"); break;" msgstr "" #. Tag: para #, no-c-format msgid "case POPT_CALLBACK_REASON_OPTION:" msgstr "" #. Tag: para #, no-c-format msgid "printf(\"\\t Callback in option setting\\n\"); break;" msgstr "" #. Tag: para #, no-c-format msgid "/* Set up a table of options. */" msgstr "" #. Tag: para #, no-c-format msgid "static struct poptOption optionsTable[] = {" msgstr "" #. Tag: para #, no-c-format msgid "{ (const) \"int\", (char) 'i', POPT_ARG_INT, (void*) &intVal, 0," msgstr "" #. Tag: para #, no-c-format msgid "(const) \"follow with an integer value\", (const) \"2, 4, 8, or 16\" }," msgstr "" #. Tag: para #, no-c-format msgid "{ \"callback\", '\\0', POPT_ARG_CALLBACK|POPT_ARGFLAG_DOC_HIDDEN," msgstr "" #. Tag: para #, no-c-format msgid "&callback, 0, NULL, NULL }," msgstr "" #. Tag: para #, no-c-format msgid "" "{ (const) \"file\", (char) 'f', POPT_ARG_STRING, (void*) &stringVal, 0," msgstr "" #. Tag: para #, no-c-format msgid "(const) \"follow with a file name\", NULL }," msgstr "" #. Tag: para #, no-c-format msgid "{ (const) \"print\", (char) 'p', POPT_ARG_NONE, &print, 0," msgstr "" #. Tag: para #, no-c-format msgid "(const) \"send output to the printer\", NULL }," msgstr "" #. Tag: para #, no-c-format msgid "POPT_AUTOALIAS" msgstr "" #. Tag: para #, no-c-format msgid "POPT_AUTOHELP" msgstr "" #. Tag: para #, no-c-format msgid "POPT_TABLEEND" msgstr "" #. Tag: para #, no-c-format msgid "int main(int argc, char *argv[]) {" msgstr "" #. Tag: para #, no-c-format msgid "poptContext context = poptGetContext(" msgstr "" #. Tag: para #, no-c-format msgid "(const char*) \"popt1\"," msgstr "" #. Tag: para #, no-c-format msgid "argc," msgstr "" #. Tag: para #, no-c-format msgid "argv," msgstr "" #. Tag: para #, no-c-format msgid "(const struct poptOption* ) &optionsTable," msgstr "" #. Tag: para #, no-c-format msgid "0);" msgstr "" #. Tag: para #, no-c-format msgid "int option = poptGetNextOpt(context);" msgstr "" #. Tag: para #, no-c-format msgid "printf(\"option = %d\\n\", option);" msgstr "" #. Tag: para #, no-c-format msgid "/* Print out option values. */" msgstr "" #. Tag: para #, no-c-format msgid "printf(\"After processing, options have values:\\n\");" msgstr "" #. Tag: para #, no-c-format msgid "printf(\"\\t intVal holds %d\\n\", intVal);" msgstr "" #. Tag: para #, no-c-format msgid "printf(\"\\t print flag holds %d\\n\", print);" msgstr "" #. Tag: para #, no-c-format msgid "printf(\"\\t stringVal holds [%s]\\n\", stringVal);" msgstr "" #. Tag: para #, no-c-format msgid "poptFreeContext(context);" msgstr "" #. Tag: para #, no-c-format msgid "" "This example defines a callback but otherwise uses the simplest case for " "processing the command-line options. This program lets the popt library " "simply set the values into the option table. In most cases, you should avoid" " more complex command-line processing." msgstr "" #. Tag: para #, no-c-format msgid "To compile popt programs, you just need the popt library. For example:" msgstr "" #. Tag: para #, no-c-format msgid "gcc -I/usr/include/rpm -o popt1 popt1.c -lpopt" msgstr "" #. Tag: para #, no-c-format msgid "" "When you run this program, try out the different options. For example, when " "you set all the options, you’ll see output like the following:" msgstr "" #. Tag: para #, no-c-format msgid "$ ./popt1 -i 42 --print -f filename1" msgstr "" #. Tag: para #, no-c-format msgid "Callback in option setting" msgstr "" #. Tag: para #, no-c-format msgid "Callback in post setting" msgstr "" #. Tag: para #, no-c-format msgid "option = -1" msgstr "" #. Tag: para #, no-c-format msgid "After processing, options have values:" msgstr "" #. Tag: para #, no-c-format msgid "intVal holds 42" msgstr "" #. Tag: para #, no-c-format msgid "print flag holds 1" msgstr "" #. Tag: para #, no-c-format msgid "stringVal holds [filename1]" msgstr "" #. Tag: para #, no-c-format msgid "" "This command used two short options and one long. You can mix and match " "short and long options, as shown following:" msgstr "" #. Tag: para #, no-c-format msgid "$ ./popt1 --int 42 -p --file filename1" msgstr "" #. Tag: para #, no-c-format msgid "" "This example used a short option for print, -p, and long options for the " "other two options. The popt library also provides handy help and usage " "messages, using the option table macro POPT_AUTOALIAS. To get a help " "message, use --help or -?:" msgstr "" #. Tag: para #, no-c-format msgid "$ ./popt1 --help" msgstr "" #. Tag: para #, no-c-format msgid "Usage: popt1 [OPTION...]" msgstr "" #. Tag: para #, no-c-format msgid "-i, --int=2, 4, 8, or 16 follow with an integer value" msgstr "" #. Tag: para #, no-c-format msgid "-f, --file=STRING follow with a file name" msgstr "" #. Tag: para #, no-c-format msgid "-p, --print send output to the printer" msgstr "" #. Tag: para #, no-c-format msgid "Options implemented via popt alias/exec:" msgstr "" #. Tag: para #, no-c-format msgid "Help options:" msgstr "" #. Tag: para #, no-c-format msgid "-?, --help Show this help message" msgstr "" #. Tag: para #, no-c-format msgid "--usage Display brief usage message" msgstr "" #. Tag: para #, no-c-format msgid "Notice how the help descriptions from the options table are used." msgstr "" #. Tag: para #, no-c-format msgid "" "With some shells, especially the tcsh shell, you need to wrap a -? In single" " quotes. For example:" msgstr "" #. Tag: para #, no-c-format msgid "$ ./popt1 '-?'" msgstr "" #. Tag: para #, no-c-format msgid "The usage message is shorter, and you also get it for free:" msgstr "" #. Tag: para #, no-c-format msgid "$ ./popt1 --usage" msgstr "" #. Tag: para #, no-c-format msgid "Usage: popt1 [-i|--int 2, 4, 8, or 16] [-f|--file STRING] [-p|--print]" msgstr "" #. Tag: para #, no-c-format msgid "[-?|--help] [--usage]" msgstr "" #. Tag: para #, no-c-format msgid "" "All in all, the popt library provides a handy library for processing " "command-line options and aliases, covered in ." msgstr "" #. Tag: title #, no-c-format msgid "Handling rpm command-line options" msgstr "" #. Tag: para #, no-c-format msgid "" "The RPM C library makes extensive use of popt for processing command-line " "arguments. Functions that set up the RPM library, such as rpmcliInit, which " "sets up the RPM command-line environment, require a table of poptOption " "entries that define the command-line options for your program." msgstr "" #. Tag: para #, no-c-format msgid "" "To create a simple program that handles the standard rpm command-line " "options, set up the following options table:" msgstr "" #. Tag: para #, no-c-format msgid "{ NULL, '\\0', POPT_ARG_INCLUDE_TABLE, rpmcliAllPoptTable, 0," msgstr "" #. Tag: para #, no-c-format msgid "\"Common options for all rpm modes and executables:\"," msgstr "" #. Tag: para #, no-c-format msgid "NULL }," msgstr "" #. Tag: para #, no-c-format msgid "Then, initialize your program with a call to rpmcliInit:" msgstr "" #. Tag: para #, no-c-format msgid "poptContext rpmcliInit(int argc, char *const argv[]," msgstr "" #. Tag: para #, no-c-format msgid "struct poptOption * optionsTable);" msgstr "" #. Tag: para #, no-c-format msgid "" "When you call rpmcliInit, it will set up all the variables for the standard " "rpm command-line options." msgstr "" #. Tag: para #, no-c-format msgid "" "For example, to see if the verbose flag is turned on, call rpmIsVerbose:" msgstr "" #. Tag: para #, no-c-format msgid "int rpmIsVerbose();" msgstr "" #. Tag: para #, no-c-format msgid "" "When you are done with a program that called rpmcliInit, call rpmcliFini to " "clean up the global data:" msgstr "" #. Tag: para #, no-c-format msgid "poptContext rpmcliFini(poptContext context);" msgstr "" #. Tag: para #, no-c-format msgid "The call to rpmcliFini returns NULL." msgstr "" #. Tag: title #, no-c-format msgid "Working with RPM Files" msgstr "" #. Tag: para #, no-c-format msgid "" "The RPM C library provides functions to read RPM files as well as query the " "RPM database. Going beyond querying, you can perform all the tasks that the " "rpm and rpmbuild commands do, since both these commands are written in C " "using the RPM library. That said, some tasks are much easier than other " "tasks. If you are writing a complex package installation program, or a " "program that keeps various systems up to date with regards to package " "versions, you may want to look at the Python RPM API instead of the C RPM " "library." msgstr "" #. Tag: para #, no-c-format msgid " covers the Python RPM API." msgstr "" #. Tag: title #, no-c-format msgid "Opening RPM files" msgstr "" #. Tag: para #, no-c-format msgid "" "When working with an RPM file from within a program, the first thing you " "need to do is open the file. Use Fopen:" msgstr "" #. Tag: para #, no-c-format msgid "FD_t Fopen(const char * path," msgstr "" #. Tag: para #, no-c-format msgid "const char * fmode);" msgstr "" #. Tag: para #, no-c-format msgid "Fopen works like the standard C function fopen(3)." msgstr "" #. Tag: para #, no-c-format msgid "" "The reason the RPM library wraps the input/output C library functions is to " "ensure portability to other operating systems. This is a fairly common " "technique." msgstr "" #. Tag: title #, no-c-format msgid "Reading the RPM lead and signature" msgstr "" #. Tag: para #, no-c-format msgid "" "Once you have opened an RPM file, you can start to read header information, " "which is the most interesting information to most RPM programs. (You may " "also want to read the files in the RPM payload, for example.) Before you can" " start reading the header, though, you must read forward in the RPM file " "past the lead and signature." msgstr "" #. Tag: para #, no-c-format msgid " introduces the lead and signature." msgstr "" #. Tag: para #, no-c-format msgid "" "Even if your programs don’t want to examine the lead or signature, you must " "read past to position the file offset properly for reading the header " "information. To read past the lead, call readLead:" msgstr "" #. Tag: para #, no-c-format msgid "int readLead(FD_t fd, struct rpmlead *lead);" msgstr "" #. Tag: para #, no-c-format msgid "" "The readLead function returns 0 on success or 1 on an error. It fills in an " "rpmlead struct:" msgstr "" #. Tag: para #, no-c-format msgid "struct rpmlead {" msgstr "" #. Tag: para #, no-c-format msgid "unsigned char magic[4];" msgstr "" #. Tag: para #, no-c-format msgid "unsigned char major;" msgstr "" #. Tag: para #, no-c-format msgid "unsigned char minor;" msgstr "" #. Tag: para #, no-c-format msgid "short type;" msgstr "" #. Tag: para #, no-c-format msgid "short archnum;" msgstr "" #. Tag: para #, no-c-format msgid "char name[66];" msgstr "" #. Tag: para #, no-c-format msgid "short osnum;" msgstr "" #. Tag: para #, no-c-format msgid "short signature_type;" msgstr "" #. Tag: para #, no-c-format msgid "char reserved[16];" msgstr "" #. Tag: para #, no-c-format msgid "To read past the signature, call rpmReadSignature:" msgstr "" #. Tag: para #, no-c-format msgid "rpmRC rpmReadSignature(FD_t fd," msgstr "" #. Tag: para #, no-c-format msgid "Header * header," msgstr "" #. Tag: para #, no-c-format msgid "sigType sig_type);" msgstr "" #. Tag: para #, no-c-format msgid "The return code is one of the values listed in Table 16-8." msgstr "" #. Tag: para #, no-c-format msgid "Table 16-8 Return codes from rpmReadSignature" msgstr "" #. Tag: para #, no-c-format msgid "RPMRC_OK" msgstr "" #. Tag: para #, no-c-format msgid "RPMRC_BADMAGIC" msgstr "" #. Tag: para #, no-c-format msgid "RPMRC_FAIL" msgstr "" #. Tag: para #, no-c-format msgid "RPMRC_BADSIZE" msgstr "" #. Tag: para #, no-c-format msgid "RPMRC_SHORTREAD" msgstr "" #. Tag: para #, no-c-format msgid "" "You can do more with the signature than merely reading past it, of course. " "Look in the online RPM documentation for more on verifying signatures." msgstr "" #. Tag: para #, no-c-format msgid "" "After reading the signature, you can start to read the general header " "entries." msgstr "" #. Tag: title #, no-c-format msgid "Reading header information" msgstr "" #. Tag: para #, no-c-format msgid "" "The header information includes the package name, version, pre- and post-" "installation scripts, and so on. To read in the RPM header, call headerRead." " If successful, headerRead returns a Header object. You can then read data " "values from the Header." msgstr "" #. Tag: para #, no-c-format msgid "Header headerRead(FD_t fd," msgstr "" #. Tag: para #, no-c-format msgid "enum hMagic magicp);" msgstr "" #. Tag: para #, no-c-format msgid "When working with the RPM database, you will also use Header objects." msgstr "" #. Tag: para #, no-c-format msgid "" "The trickiest thing about calling headerRead is that you must pass a special" " magic number flag. This value must be HEADER_MAGIC_YES if the header has a " "set of magic numbers, and HEADER_MAGIC_NO if not. If you guess incorrectly, " "headerRead will return an error. To get around, this, you can compare the " "major number in the lead. For example:" msgstr "" #. Tag: para #, no-c-format msgid "Header header = headerRead(fd, (lead.major >= 3) ?" msgstr "" #. Tag: para #, no-c-format msgid "HEADER_MAGIC_YES : HEADER_MAGIC_NO);" msgstr "" #. Tag: para #, no-c-format msgid "" "This snippet is one of the gems you'll find when you browse the RPM source " "code. Use the source." msgstr "" #. Tag: para #, no-c-format msgid "" "To read values from the Header, call headerGetEntry. To call headerGetEntry," " you pass in a Header and a tag ID. You get back the type of the tag, a " "pointer to the tag values, and a count of the number of values stored under " "this tag." msgstr "" #. Tag: para #, no-c-format msgid "int headerGetEntry(Header header," msgstr "" #. Tag: para #, no-c-format msgid "int_32 tag," msgstr "" #. Tag: para #, no-c-format msgid "hTYP_t type," msgstr "" #. Tag: para #, no-c-format msgid "void **pointer," msgstr "" #. Tag: para #, no-c-format msgid "hCNT_t data_size);" msgstr "" #. Tag: para #, no-c-format msgid "" "The call to headerGetEntry returns a 1 on success, or a 0 on failure. On " "success, the pointer will point at the retrieved data, with the type " "parameter set to one of the following enum values:" msgstr "" #. Tag: para #, no-c-format msgid "enum rpmTagType_e {" msgstr "" #. Tag: para #, no-c-format msgid "RPM_NULL_TYPE = 0," msgstr "" #. Tag: para #, no-c-format msgid "RPM_CHAR_TYPE = 1," msgstr "" #. Tag: para #, no-c-format msgid "RPM_INT8_TYPE = 2," msgstr "" #. Tag: para #, no-c-format msgid "RPM_INT16_TYPE = 3," msgstr "" #. Tag: para #, no-c-format msgid "RPM_INT32_TYPE = 4," msgstr "" #. Tag: para #, no-c-format msgid "RPM_STRING_TYPE = 6," msgstr "" #. Tag: para #, no-c-format msgid "RPM_BIN_TYPE = 7," msgstr "" #. Tag: para #, no-c-format msgid "RPM_STRING_ARRAY_TYPE = 8," msgstr "" #. Tag: para #, no-c-format msgid "RPM_I18NSTRING_TYPE" msgstr "" #. Tag: para #, no-c-format msgid "" "If the type is RPM_STRING_ARRAY_TYPE or RPM_BIN_TYPE, you must free the " "pointer. Call headerFreeData to free the data:" msgstr "" #. Tag: para #, no-c-format msgid "void* headerFreeData(const void *pointer," msgstr "" #. Tag: para #, no-c-format msgid "rpmTagType type);" msgstr "" #. Tag: para #, no-c-format msgid "" "You need to pass in the data pointer and the type flag. You can safely call " "headerFreeData for all types. The function will do nothing if the type is " "not set up to require freeing." msgstr "" #. Tag: para #, no-c-format msgid "" "When you call headerGetEntry, you must identify the tag you want from the " "header. This tag is an identifier for the --queryformat tags introduced in " " . The file rpmlib.h lists the various " "tags, such as RPMTAG_NAME, RPMTAG_VERSION, and RPMTAG_RELEASE." msgstr "" #. Tag: para #, no-c-format msgid "The following function shows how to read a string entry from a Header:" msgstr "" #. Tag: para #, no-c-format msgid "/* Function to read a string header entry. */" msgstr "" #. Tag: para #, no-c-format msgid "char* readHeaderString(Header header, int_32 tag_id) {" msgstr "" #. Tag: para #, no-c-format msgid "int_32 type;" msgstr "" #. Tag: para #, no-c-format msgid "void* pointer;" msgstr "" #. Tag: para #, no-c-format msgid "int_32 data_size;" msgstr "" #. Tag: para #, no-c-format msgid "int header_status = headerGetEntry(header," msgstr "" #. Tag: para #, no-c-format msgid "tag_id," msgstr "" #. Tag: para #, no-c-format msgid "&type," msgstr "" #. Tag: para #, no-c-format msgid "&pointer," msgstr "" #. Tag: para #, no-c-format msgid "&data_size);" msgstr "" #. Tag: para #, no-c-format msgid "if (header_status) {" msgstr "" #. Tag: para #, no-c-format msgid "if (type == RPM_STRING_TYPE) {" msgstr "" #. Tag: para #, no-c-format msgid "return pointer;" msgstr "" #. Tag: para #, no-c-format msgid "return NULL;" msgstr "" #. Tag: para #, no-c-format msgid "Pass the Header object and the ID of the tag to read. For example:" msgstr "" #. Tag: para #, no-c-format msgid "char* name = readHeaderString(header, RPMTAG_NAME);" msgstr "" #. Tag: para #, no-c-format msgid "char* version = readHeaderString(header, RPMTAG_VERSION);" msgstr "" #. Tag: para #, no-c-format msgid "char* release = readHeaderString(header, RPMTAG_RELEASE);" msgstr "" #. Tag: para #, no-c-format msgid "" "To just get the name, version, and release number, you can call the utility " "function headerNVR, which has the following function signature:" msgstr "" #. Tag: para #, no-c-format msgid "int headerNVR(Header header," msgstr "" #. Tag: para #, no-c-format msgid "const char **nameptr," msgstr "" #. Tag: para #, no-c-format msgid "const char **versionptr," msgstr "" #. Tag: para #, no-c-format msgid "const char **releaseptr);" msgstr "" #. Tag: para #, no-c-format msgid "When you are through with a header, free it by calling headerFree:" msgstr "" #. Tag: para #, no-c-format msgid "Header headerFree(Header header);" msgstr "" #. Tag: para #, no-c-format msgid "" "The call to headerFree returns NULL, so you can use the call to set the " "original pointer to to NULL to prevent accidental reuse. For example:" msgstr "" #. Tag: para #, no-c-format msgid "header = headerFree(header);" msgstr "" #. Tag: title #, no-c-format msgid "A shortcut to header information" msgstr "" #. Tag: para #, no-c-format msgid "" "You can read in a Header using the shortcut utility method " "rpmReadPackageFile:" msgstr "" #. Tag: para #, no-c-format msgid "int rpmReadPackageFile(rpmts ts," msgstr "" #. Tag: para #, no-c-format msgid "FD_t fd," msgstr "" #. Tag: para #, no-c-format msgid "const char *filename," msgstr "" #. Tag: para #, no-c-format msgid "Header *header);" msgstr "" #. Tag: para #, no-c-format msgid "" "You need to pass a transaction set to rpmReadPackageFile and an open file. " "The filename is just used for reporting errors. On success, " "rpmReadPackageFile fills in a Header object from the package file. The " "return value is 0 for success." msgstr "" #. Tag: para #, no-c-format msgid "" "To get the necessary transaction set, you need to create one with " "rpmtsCreate, covered in the \"Programming with the RPM Database\" section, " "following." msgstr "" #. Tag: para #, no-c-format msgid "" "In most cases, you should call rpmReadPackageFile in place of readLead, " "rpmReadSignature, and headerRead, since rpmReadPackageFile also verifies the" " package integrity." msgstr "" #. Tag: title #, no-c-format msgid "Closing RPM files" msgstr "" #. Tag: para #, no-c-format msgid "When you’re done with an RPM file, close it with Fclose:" msgstr "" #. Tag: para #, no-c-format msgid "int Fclose(FD_t fd);" msgstr "" #. Tag: para #, no-c-format msgid "" "Fclose acts much like the standard C function fclose(3). The FD_t is an RPM " "data type that is very similar to a FILE pointer." msgstr "" #. Tag: para #, no-c-format msgid "" "The RPM I/O subsystem, defined with rpmio.h, includes functions that mimic " "(and in most cases wrap) the ANSI C stdio functions. These include: Fopen, " "Fclose, Fread, Fwrite, Ferror, Fflush, Fileno, and Fseek." msgstr "" #. Tag: para #, no-c-format msgid "" "These functions wrap the ANSI C stdio functions to add new features. The " "Fopen function, for example, supports HTTP or FTP URLs in the place of a " "file name, so long as you append \".ufdio\" to the mode." msgstr "" #. Tag: title #, no-c-format msgid "Programming with the RPM Database" msgstr "" #. Tag: para #, no-c-format msgid "" "Many functions in rpmlib require a transaction set. In particular, accessing" " the rpm database is quite easy using a transaction set." msgstr "" #. Tag: para #, no-c-format msgid "Create a transaction set by calling rpmtsCreate:" msgstr "" #. Tag: para #, no-c-format msgid "rpmts rpmtsCreate(void);" msgstr "" #. Tag: para #, no-c-format msgid "" "RPM uses transaction sets to bracket operations on the RPM database. As the " "RPM API evolves, transaction sets will become more and more important. " "Transaction sets also help in that the RPM library will automatically open " "the RPM database as needed." msgstr "" #. Tag: para #, no-c-format msgid "When you are done with a transaction set, call rpmtsFree:" msgstr "" #. Tag: para #, no-c-format msgid "rpmts rpmtsFree(rpmts ts);" msgstr "" #. Tag: para #, no-c-format msgid "The call to rpmtsFree returns NULL." msgstr "" #. Tag: title #, no-c-format msgid "Database iterators" msgstr "" #. Tag: para #, no-c-format msgid "" "Once you have a transaction set, you can iterate over the installed packages" " in the RPM database by creating an iterator. To do this, call " "rpmtsInitIterator:" msgstr "" #. Tag: para #, no-c-format msgid "rpmdbMatchIterator rpmtsInitIterator(const rpmts ts," msgstr "" #. Tag: para #, no-c-format msgid "rpmTag rpmtag," msgstr "" #. Tag: para #, no-c-format msgid "const void *keypointer," msgstr "" #. Tag: para #, no-c-format msgid "size_t keylen);" msgstr "" #. Tag: para #, no-c-format msgid "" "You need to specify which tag to iterate by, which in most cases will be the" " package name, RPMTAG_NAME, introduced previously With the RPMTAG_NAME tag, " "you need to pass the name of a package to look for in the keypointer " "parameter. (The keypointer varies based on the tag you pass.)" msgstr "" #. Tag: para #, no-c-format msgid "" "For string data, you can pass 0 for the keylen parameter. For example, this " "call to rpmtsInitIterator looks for all packages named sendmail." msgstr "" #. Tag: para #, no-c-format msgid "rpmdbMatchIterator iter;" msgstr "" #. Tag: para #, no-c-format msgid "iter = rpmtsInitIterator(ts, RPMTAG_NAME, \"sendmail\", 0);" msgstr "" #. Tag: para #, no-c-format msgid "" "The rpmdbMatchIterator allows you to iterate through a number of packages, " "in this case, all the packages that match a given name. After calling " "rpmtsInitIterator, the next step is to call rpmdbNextIterator:" msgstr "" #. Tag: para #, no-c-format msgid "Header rpmdbNextIterator(rpmdbMatchIterator iter);" msgstr "" #. Tag: para #, no-c-format msgid "" "This function returns the next package Header object in the iterator. The " "Header will be NULL if there are no more packages in the iterator." msgstr "" #. Tag: para #, no-c-format msgid "" "If the Header is not NULL, you can get entries from it, as shown previously." " You can use a while loop to go through all the matching packages. For " "example:" msgstr "" #. Tag: para #, no-c-format msgid "while ( (installed_header = rpmdbNextIterator(iter) ) != NULL) {" msgstr "" #. Tag: para #, no-c-format msgid "" "In future versions of the RPM library, rpmtsNextIterator, will replace " "rpmdbNextIterator." msgstr "" #. Tag: para #, no-c-format msgid "" "You do not need to free the Header returned by rpmdbNextIterator. Also, the " "next call to rpmdbNextIterator will reset the Header." msgstr "" #. Tag: para #, no-c-format msgid "" "You can customize how an iterator works by adding a pattern to the iterator " "with rpmdbSetIteratorRE:" msgstr "" #. Tag: para #, no-c-format msgid "int rpmdbSetIteratorRE(rpmdbMatchIterator iter," msgstr "" #. Tag: para #, no-c-format msgid "rpmTag tag," msgstr "" #. Tag: para #, no-c-format msgid "rpmMireMode mode," msgstr "" #. Tag: para #, no-c-format msgid "const char * pattern);" msgstr "" #. Tag: para #, no-c-format msgid "" "Calling rpmdbSetIteratorRE modifies the passed-in iterator to use the given " "pattern as a further test on the given tag. The mode parameter names the " "type of pattern used, which can be one of those listed in Table 16-9." msgstr "" #. Tag: para #, no-c-format msgid "Table 16-9 Types of patterns for rpmdbSetIteratorRE" msgstr "" #. Tag: para #, no-c-format msgid "RPMMIRE_DEFAULT" msgstr "" #. Tag: para #, no-c-format msgid "Same as regular expressions but with \\., .*, and ^..$ added." msgstr "" #. Tag: para #, no-c-format msgid "RPMMIRE_GLOB" msgstr "" #. Tag: para #, no-c-format msgid "Glob-style patterns using fnmatch." msgstr "" #. Tag: para #, no-c-format msgid "RPMMIRE_REGEX" msgstr "" #. Tag: para #, no-c-format msgid "Regular expressions using regcomp." msgstr "" #. Tag: para #, no-c-format msgid "RPMMIRE_STRCMP" msgstr "" #. Tag: para #, no-c-format msgid "String comparisons using strcmp." msgstr "" #. Tag: para #, no-c-format msgid "" "For more on these patterns, see the online manual pages for fnmatch(3), " "glob(7), regcomp(3), regex(7), and strcmp(3)." msgstr "" #. Tag: para #, no-c-format msgid "Free the iterator when done with rpmdbFreeIterator:" msgstr "" #. Tag: para #, no-c-format msgid "rpmdbMatchIterator rpmdbFreeIterator(rpmdbMatchIterator iter);" msgstr "" #. Tag: para #, no-c-format msgid "The call to rpmdbFreeIterator returns NULL." msgstr "" #. Tag: title #, no-c-format msgid "Dependency Sets" msgstr "" #. Tag: para #, no-c-format msgid "" "To compare package versions, create a dependency set. The rpm command, for " "example, uses dependency sets to compare package versions." msgstr "" #. Tag: para #, no-c-format msgid "" "You could compare the version numbers directly, calling headerGetEntry to " "get the version and release tags, converting these strings to numbers and " "then comparing, but this would cause problems. The custom comparison is not " "as exact as the code in this section, especially since many packages have " "version numbers that are not true numbers, such as 1.12.4, with one too many" " decimal points. This makes the comparisons harder. In addition, there is " "more than just the version number to take into account. You need to deal " "with the Epoch value, as well as the release, too." msgstr "" #. Tag: para #, no-c-format msgid "" "To handle all the complicated logic of comparing versions, you can use the " "code in this section, or call rpmvercmp. Do not try to compare version " "numbers with custom code." msgstr "" #. Tag: para #, no-c-format msgid "" "To create a dependency set for a given package Header, call rpmdsThis. " "Calling rpmdsThis creates a dependency set that holds a triple of the " "package name, the Epoch/Version/Release information, and the flags." msgstr "" #. Tag: para #, no-c-format msgid "rpmds rpmdsThis(Header header," msgstr "" #. Tag: para #, no-c-format msgid "rpmTag tagID," msgstr "" #. Tag: para #, no-c-format msgid "int_32 Flags);" msgstr "" #. Tag: para #, no-c-format msgid "" "For comparing packages, you can pass RPMTAG_REQUIRENAME for the tagID. The " "actual tagID here is ignored for the version check. What you do need, " "though, are flags to check whether another package is less than or equal to " "the Epoch/Version/Release information in this dependency set. For this task," " pass the following bit flags:" msgstr "" #. Tag: para #, no-c-format msgid "(RPMSENSE_EQUAL|RPMSENSE_LESS)" msgstr "" #. Tag: para #, no-c-format msgid "" "Once you have a dependency set, you can use the handy function " "rpmdsNVRMatchesDep to compare the NVR, or Name, Version, Release entries in " "the header of one package against the data in the dependency set." msgstr "" #. Tag: para #, no-c-format msgid "int rpmdsNVRMatchesDep(const Header header," msgstr "" #. Tag: para #, no-c-format msgid "const rpmds dependency_set," msgstr "" #. Tag: para #, no-c-format msgid "int nopromote);" msgstr "" #. Tag: para #, no-c-format msgid "" "After checking the dependencies, rpmdsNVRMatchesDep returns 1 if the " "dependency overlaps, or 0 otherwise. In terms of comparing packages, 1 means" " that the package file is as old or older than the installed package, and 0 " "means that the package already installed is newer. Pass 1 to prevent " "promoting the Epoch value in the packages during the comparison." msgstr "" #. Tag: para #, no-c-format msgid "" "The actual comparison is controlled by the call that creates the dependency " "set, especially the flags. Thus, passing flags of " "(RPMSENSE_EQUAL|RPMSENSE_LESS) to rpmdsThis set up the test as a less than " "or equal test." msgstr "" #. Tag: para #, no-c-format msgid "" "The RPM C API documentation marks rpmdsNVRMatchesDep as deprecated, to be " "replaced in the future." msgstr "" #. Tag: para #, no-c-format msgid "" "You can also call rpmVersionCompare to compare the versions of two packages:" msgstr "" #. Tag: para #, no-c-format msgid "int rpmVersionCompare(Header header1, Header header2);" msgstr "" #. Tag: para #, no-c-format msgid "" "The return value is -1 if the header1 represents an older version than " "header2, 0 if the two headers represent the same version, and 1 if header1 " "represents a newer version than header2." msgstr "" #. Tag: para #, no-c-format msgid "To get the name of the package from a dependency set, call rpmdsN:" msgstr "" #. Tag: para #, no-c-format msgid "const char* rpmdsN(const rpmds dependency_set);" msgstr "" #. Tag: para #, no-c-format msgid "" "You can use rpmdsN to get the name when calling rpmtsInitIterator if you are" " working with dependency sets when searching the RPM database." msgstr "" #. Tag: para #, no-c-format msgid "Free a dependency set when done by calling rpmdsFree:" msgstr "" #. Tag: para #, no-c-format msgid "rpmds rpmdsFree(rpmds dependency_set);" msgstr "" #. Tag: para #, no-c-format msgid "As with other free functions, rpmdsFree returns NULL." msgstr "" #. Tag: title #, no-c-format msgid "Comparing an RPM File to an Installed Package" msgstr "" #. Tag: para #, no-c-format msgid "" "You can pull together the RPM file and database discussions, shown " "previously, to create a number of RPM programs. A useful utility that shows " "the RPM C library compares a package file against installed packages, " "reporting whether the package in the RPM file represents a newer or older " "package than what was already installed." msgstr "" #. Tag: para #, no-c-format msgid "Listing 16-4 shows such a program." msgstr "" #. Tag: para #, no-c-format msgid "Listing 16-4: vercompare.c" msgstr "" #. Tag: para #, no-c-format msgid "/* Compares a package file with an installed package," msgstr "" #. Tag: para #, no-c-format msgid "telling which one is newer." msgstr "" #. Tag: para #, no-c-format msgid "Usage:" msgstr "" #. Tag: para #, no-c-format msgid "vercompare pkg_files+" msgstr "" #. Tag: para #, no-c-format msgid "Compile as" msgstr "" #. Tag: para #, no-c-format msgid "" "cc -I/usr/include/rpm -o vercompare vercompare.c -lrpm -lrpmdb -lrpmio " "-lpopt" msgstr "" #. Tag: para #, no-c-format msgid "*/" msgstr "" #. Tag: para #, no-c-format msgid "#include <rpmcli.h>" msgstr "" #. Tag: para #, no-c-format msgid "#include <rpmdb.h>" msgstr "" #. Tag: para #, no-c-format msgid "#include <rpmds.h>" msgstr "" #. Tag: para #, no-c-format msgid "#include <rpmts.h>" msgstr "" #. Tag: para #, no-c-format msgid "/* Set up a table of options using standard RPM options. */" msgstr "" #. Tag: para #, no-c-format msgid "int main(int argc, char * argv[])" msgstr "" #. Tag: para #, no-c-format msgid "poptContext context;" msgstr "" #. Tag: para #, no-c-format msgid "const char ** fnp;" msgstr "" #. Tag: para #, no-c-format msgid "Header file_header, installed_header;" msgstr "" #. Tag: para #, no-c-format msgid "rpmts ts;" msgstr "" #. Tag: para #, no-c-format msgid "rpmds dependency_set;" msgstr "" #. Tag: para #, no-c-format msgid "FD_t fd;" msgstr "" #. Tag: para #, no-c-format msgid "rpmRC rpmrc;" msgstr "" #. Tag: para #, no-c-format msgid "int rc;" msgstr "" #. Tag: para #, no-c-format msgid "context = rpmcliInit(argc, argv, optionsTable);" msgstr "" #. Tag: para #, no-c-format msgid "if (context == NULL) {" msgstr "" #. Tag: para #, no-c-format msgid "exit(EXIT_FAILURE);" msgstr "" #. Tag: para #, no-c-format msgid "ts = rpmtsCreate();" msgstr "" #. Tag: para #, no-c-format msgid "for (fnp = poptGetArgs(context); fnp && *fnp; fnp++) {" msgstr "" #. Tag: para #, no-c-format msgid "/* Read package header, continuing to next arg on failure. */" msgstr "" #. Tag: para #, no-c-format msgid "fd = Fopen(*fnp, \"r.ufdio\");" msgstr "" #. Tag: para #, no-c-format msgid "if (fd == NULL || Ferror(fd)) {" msgstr "" #. Tag: para #, no-c-format msgid "rpmError(RPMERR_OPEN, \"open of %s failed: %s\\n\", *fnp," msgstr "" #. Tag: para #, no-c-format msgid "Fstrerror(fd));" msgstr "" #. Tag: para #, no-c-format msgid "if (fd) {" msgstr "" #. Tag: para #, no-c-format msgid "Fclose(fd);" msgstr "" #. Tag: para #, no-c-format msgid "continue;" msgstr "" #. Tag: para #, no-c-format msgid "rpmrc = rpmReadPackageFile(ts, fd, *fnp, &file_header);" msgstr "" #. Tag: para #, no-c-format msgid "if (rpmrc != RPMRC_OK) {" msgstr "" #. Tag: para #, no-c-format msgid "rpmError(RPMERR_OPEN, \"%s cannot be read\\n\", *fnp);" msgstr "" #. Tag: para #, no-c-format msgid "/* Generate \"name <= epoch:version-release\" depset for package */" msgstr "" #. Tag: para #, no-c-format msgid "dependency_set = rpmdsThis(file_header, RPMTAG_REQUIRENAME," msgstr "" #. Tag: para #, no-c-format msgid "(RPMSENSE_EQUAL|RPMSENSE_LESS));" msgstr "" #. Tag: para #, no-c-format msgid "rc = -1; /* assume no package is installed. */" msgstr "" #. Tag: para #, no-c-format msgid "/* Search all installed packages with same name. */" msgstr "" #. Tag: para #, no-c-format msgid "iter = rpmtsInitIterator(ts, RPMTAG_NAME, rpmdsN(dependency_set), 0);" msgstr "" #. Tag: para #, no-c-format msgid "while ((installed_header = rpmdbNextIterator(iter)) != NULL) {" msgstr "" #. Tag: para #, no-c-format msgid "/* Is the installed package newer than the file? */" msgstr "" #. Tag: para #, no-c-format msgid "rc = rpmdsNVRMatchesDep(installed_header, dependency_set, 1);" msgstr "" #. Tag: para #, no-c-format msgid "switch (rc) {" msgstr "" #. Tag: para #, no-c-format msgid "case 1:" msgstr "" #. Tag: para #, no-c-format msgid "if ( rpmIsVerbose() )" msgstr "" #. Tag: para #, no-c-format msgid "fprintf(stderr, \"installed package is older (or same) as %s\\n\"," msgstr "" #. Tag: para #, no-c-format msgid "*fnp);" msgstr "" #. Tag: para #, no-c-format msgid "break;" msgstr "" #. Tag: para #, no-c-format msgid "case 0:" msgstr "" #. Tag: para #, no-c-format msgid "fprintf(stderr, \"installed package is newer than %s\\n\"," msgstr "" #. Tag: para #, no-c-format msgid "/* Clean up. */" msgstr "" #. Tag: para #, no-c-format msgid "iter = rpmdbFreeIterator(iter);" msgstr "" #. Tag: para #, no-c-format msgid "dependency_set = rpmdsFree(dependency_set);" msgstr "" #. Tag: para #, no-c-format msgid "if (rc < 0 && rpmIsVerbose() )" msgstr "" #. Tag: para #, no-c-format msgid "fprintf(stderr, \"no package is installed %s\\n\", *fnp);" msgstr "" #. Tag: para #, no-c-format msgid "ts = rpmtsFree(ts);" msgstr "" #. Tag: para #, no-c-format msgid "context = rpmcliFini(context);" msgstr "" #. Tag: para #, no-c-format msgid "return rc;" msgstr "" #. Tag: para #, no-c-format msgid "" "The vercompare.c program shows reading in RPM package files as well as " "querying the RPM database. It introduces transaction sets, used extensively " "in the RPM API, and also dependency sets. You can use this program as a " "guide for making your own RPM programs." msgstr "" #. Tag: para #, no-c-format msgid "" "When you run the vercompare.c program, pass the names of one or more RPM " "files. The vercompare.c program will extract the package name from the " "files, and then query the RPM database for matching packages. For each " "matching package, vercompare.c checks whether the installed package is newer" " than the RPM file, or at the same version or older. For example, if you " "have installed version 1.17-1 of the jikes package (a Java compiler), you " "can compare the installed version against RPM files. If you have a package " "that has a newer version, you should see output like the following:" msgstr "" #. Tag: para #, no-c-format msgid "$ ./vercompare -v jikes-1.18-1.i386.rpm" msgstr "" #. Tag: para #, no-c-format msgid "installed package is older (or same) as jikes-1.18-1.i386.rpm" msgstr "" #. Tag: para #, no-c-format msgid "Note that the output is relative to the installed package." msgstr "" #. Tag: para #, no-c-format msgid "" "If you compare against a file that has an older version of the package, you " "will see results like the following:" msgstr "" #. Tag: para #, no-c-format msgid "$ ./vercompare -v jikes-1.14-1-glibc-2.2.i386.rpm" msgstr "" #. Tag: para #, no-c-format msgid "installed package is newer than jikes-1.14-1-glibc-2.2.i386.rpm" msgstr "" #. Tag: para #, no-c-format msgid "" "And, if you compare to an RPM file that holds the same package, you will see" " output as follows:" msgstr "" #. Tag: para #, no-c-format msgid "$ ./vercompare -v jikes-1.17-glibc2.2-1.i386.rpm" msgstr "" #. Tag: para #, no-c-format msgid "installed package is older (or same) as jikes-1.17-glibc2.2-1.i386.rpm" msgstr "" #. Tag: para #, no-c-format msgid "" "You can change this aspect of the test by changing the flags passed to " "rpmdsThis." msgstr "" #. Tag: para #, no-c-format msgid "" "The vercompare.c program prints out nothing unless there is an error. " "Instead, it sets the program exit status based on the package version " "comparison. You can use this with automated tools, such as make, that check " "the exit status." msgstr "" #. Tag: para #, no-c-format msgid "" "If you want output from the program, pass the –v, verbose, option to the " "command, as shown in the previous examples." msgstr "" #. Tag: para #, no-c-format msgid "" "The RPM cli or command-line interface functions, such as rpmcliInit, are " "based on the command-line options expected by the rpm and rpmbuild commands." " You can use these functions to provide a high level of abstraction onto the" " RPM system. For example, to run the query options just like the rpm " "command, call rpmcliQuery." msgstr "" #. Tag: para #, no-c-format msgid "int rpmcliQuery(rpmts transaction_set," msgstr "" #. Tag: para #, no-c-format msgid "QVA_t qva," msgstr "" #. Tag: para #, no-c-format msgid "const char **argv);" msgstr "" #. Tag: para #, no-c-format msgid "" "Set the QVA_t variable to point at the global variable rpmQVKArgs, which is " "set up from the global option table for the query mode, rpmQueryPoptTable. " "Pass rpmcliQuery a set of file names or package names. You can get these " "names in the given format by calling poptGetArgs, introduced previously." msgstr "" #. Tag: para #, no-c-format msgid "" "To support the query options, you need the rpm query entries in your " "poptOption table. To get these options, add the following entry:" msgstr "" #. Tag: para #, no-c-format msgid "{ NULL, '\\0', POPT_ARG_INCLUDE_TABLE, rpmQueryPoptTable, 0," msgstr "" #. Tag: para #, no-c-format msgid "\"Query options (with -q or --query):\"," msgstr "" #. Tag: para #, no-c-format msgid "" "With the rpmQueryPoptTable options, you can make a program that works like " "the rpm --query command using just the following code:" msgstr "" #. Tag: para #, no-c-format msgid "QVA_t qva = &rpmQVKArgs;" msgstr "" #. Tag: para #, no-c-format msgid "int ec;" msgstr "" #. Tag: para #, no-c-format msgid "/* Display error and exit... */" msgstr "" #. Tag: para #, no-c-format msgid "if (qva->qva_mode == 'q') {" msgstr "" #. Tag: para #, no-c-format msgid "/* Make sure there's something to do. */" msgstr "" #. Tag: para #, no-c-format msgid "" "if (qva->qva_source != RPMQV_ALL && !poptPeekArg(context)) {" msgstr "" #. Tag: para #, no-c-format msgid "fprintf(stderr, \"no arguments given for --query\");" msgstr "" #. Tag: para #, no-c-format msgid "ec = rpmcliQuery(ts, qva, (const char **) poptGetArgs(context));" msgstr "" #. Tag: para #, no-c-format msgid "" "This code supports all the query options just like the rpm command. That's " "both good and bad. If you wanted everything exactly like the rpm command, " "chances are you could use the rpm command as is. But if you need to add RPM " "query support into your programs, this is probably the easiest way to do it." msgstr "" #. Tag: para #, no-c-format msgid "" "With a small additional set of code, you can add support for all the " "--verify options to your program. You need to include the --verify command-" "line option definitions, which come from the global rpmVerifyPoptTable " "table:" msgstr "" #. Tag: para #, no-c-format msgid "/* Add in --verify options. */" msgstr "" #. Tag: para #, no-c-format msgid "{ NULL, '\\0', POPT_ARG_INCLUDE_TABLE, rpmVerifyPoptTable, 0," msgstr "" #. Tag: para #, no-c-format msgid "\"Verify options (with -V or --verify):\"," msgstr "" #. Tag: para #, no-c-format msgid "" "You can then check for the verify mode, and support the options, with code " "like the following:" msgstr "" #. Tag: para #, no-c-format msgid "if (qva->qva_mode == 'V') {" msgstr "" #. Tag: para #, no-c-format msgid "rpmVerifyFlags verifyFlags = VERIFY_ALL;" msgstr "" #. Tag: para #, no-c-format msgid "/* Verify flags are negated from query flags. */" msgstr "" #. Tag: para #, no-c-format msgid "verifyFlags &= ~qva->qva_flags;" msgstr "" #. Tag: para #, no-c-format msgid "qva->qva_flags = (rpmQueryFlags) verifyFlags;" msgstr "" #. Tag: para #, no-c-format msgid "fprintf(stderr, \"no arguments given for --verify\");" msgstr "" #. Tag: para #, no-c-format msgid "ec = rpmcliVerify(ts, qva, (const char **)" msgstr "" #. Tag: para #, no-c-format msgid "poptGetArgs(context));" msgstr "" #. Tag: para #, no-c-format msgid "" "The workhorse function in this code is rpmcliVerify, a high-level function " "that performs all the --verify work done by the rpm command." msgstr "" #. Tag: para #, no-c-format msgid "int rpmcliVerify(rpmts transaction_set," msgstr "" #. Tag: para #, no-c-format msgid "" "Again, set the QVA_t variable to point at the global variable rpmQVKArgs, " "which is set up from the global option table for the query mode, " "rpmQueryPoptTable." msgstr "" #. Tag: para #, no-c-format msgid "" "Putting this all together, Listing 16-5 shows a program that performs the " "same as the rpm command for the --query and --verify options." msgstr "" #. Tag: para #, no-c-format msgid "Listing 16-5: rpmq.c" msgstr "" #. Tag: para #, no-c-format msgid "/*" msgstr "" #. Tag: para #, no-c-format msgid "rpm --query and --verify modes in standalone program." msgstr "" #. Tag: para #, no-c-format msgid "cc -I/usr/include/rpm -o rpmq rpmq.c -lrpm -lrpmdb -lrpmio -lpopt" msgstr "" #. Tag: para #, no-c-format msgid "See option usage by invoking" msgstr "" #. Tag: para #, no-c-format msgid "./rpmq --help" msgstr "" #. Tag: para #, no-c-format msgid "poptPrintUsage(context, stderr, 0);" msgstr "" #. Tag: para #, no-c-format msgid "/* Check for query mode. */" msgstr "" #. Tag: para #, no-c-format msgid "/* Check for verify mode. */" msgstr "" #. Tag: para #, no-c-format msgid "else if (qva->qva_mode == 'V') {" msgstr "" #. Tag: para #, no-c-format msgid "ec = rpmcliVerify(ts, qva, (const char **) poptGetArgs(context));" msgstr "" #. Tag: para #, no-c-format msgid "else {" msgstr "" #. Tag: para #, no-c-format msgid "return ec;" msgstr "" #. Tag: para #, no-c-format msgid "" "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." msgstr "" #. Tag: para #, no-c-format msgid "" "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." msgstr "" #. Tag: para #, no-c-format msgid "For example, rpmq supports query formats:" msgstr "" #. Tag: para #, no-c-format msgid "$ ./rpmq -q --qf \"%{NAME} %{INSTALLTID:date}\\n\" jikes" msgstr "" #. Tag: para #, no-c-format msgid "jikes Fri 25 Oct 2002 06:49:38 PM CDT" msgstr "" #. Tag: title #, no-c-format msgid "Where to Go from Here" msgstr "" #. Tag: para #, no-c-format msgid "" "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." msgstr "" #. Tag: para #, no-c-format msgid "" "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." msgstr "" #. Tag: para #, no-c-format msgid "" "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." msgstr "" #. Tag: para #, no-c-format msgid "" "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." msgstr "" #. Tag: title #, no-c-format msgid "Summary" msgstr "" #. Tag: para #, no-c-format msgid "" "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." msgstr "" #. Tag: para #, no-c-format msgid "" "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." msgstr "" #. Tag: para #, no-c-format msgid "" "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." msgstr "" #. Tag: para #, no-c-format msgid "" "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." msgstr "" #. Tag: para #, no-c-format msgid "" "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." msgstr ""