From 0bc8c1c7e19af5446edbf6175718975699fda85f Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 17 Sep 2001 08:25:36 +0000 Subject: [PATCH] Added more doc entries and prepared for 0.2.3 --- ChangeLog | 11 +- Makefile.am | 2 +- NEWS | 9 + TODO | 2 - configure.in | 20 +- doc/Makefile.am | 27 ++ doc/gdoc | 681 +++++++++++++++++++++++++++++++++++++++++++++ gpgme/ChangeLog | 4 + gpgme/data.c | 57 +++- gpgme/delete.c | 11 + gpgme/genkey.c | 57 ++-- gpgme/gpgme.c | 34 ++- gpgme/gpgme.h | 2 +- gpgme/import.c | 9 + gpgme/key.c | 68 +++++ gpgme/keylist.c | 17 +- gpgme/posix-sema.c | 2 +- gpgme/posix-util.c | 5 +- gpgme/recipient.c | 81 ++++++ gpgme/wait.c | 3 +- 20 files changed, 1041 insertions(+), 61 deletions(-) create mode 100644 doc/Makefile.am create mode 100755 doc/gdoc diff --git a/ChangeLog b/ChangeLog index 414dbb01..ed275973 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,15 @@ +2001-09-17 Werner Koch + + Released 0.2.3. + + * configure.in (NEED_GPG_VERSION): Set to 1.0.6. Incremented LT + current and age. + + * Makefile.am (SUBDIRS): Add doc + 2001-06-12 Werner Koch - Releases 0.2.2. + Released 0.2.2. 2001-04-05 Werner Koch diff --git a/Makefile.am b/Makefile.am index d48510b9..df846864 100644 --- a/Makefile.am +++ b/Makefile.am @@ -33,6 +33,6 @@ complus = endif -SUBDIRS = jnlib gpgme tests ${bonobo} ${complus} +SUBDIRS = jnlib gpgme tests doc ${bonobo} ${complus} diff --git a/NEWS b/NEWS index 6d21d0e7..110e5ab7 100644 --- a/NEWS +++ b/NEWS @@ -1,7 +1,16 @@ +Noteworthy changes in version 0.2.3 (2001-09-17) +------------------------------------------------ * New function gpgme_get_op_info which can be used to get the micalg parameter needed for MOSS. + * New functions gpgme_get_armor and gpgme_get_textmode. + + * The usual bug fixes and some minor functionality improvements. + + * Added a simple encryption component for MS-Windows; however the + build procedure might have some problems. +o Noteworthy changes in version 0.2.2 (2001-06-12) ------------------------------------------------ diff --git a/TODO b/TODO index c24446fd..0446059c 100644 --- a/TODO +++ b/TODO @@ -10,5 +10,3 @@ * Should --delete silently delete secret keys or is there a need for another flag or a callback? -* There is no status response if we have no usable recipients - must - add one to gpg so that gpgme_encrypt does return with an error. \ No newline at end of file diff --git a/configure.in b/configure.in index e2714f0d..34ea2698 100644 --- a/configure.in +++ b/configure.in @@ -31,12 +31,12 @@ AM_MAINTAINER_MODE # AGE, set REVISION to 0. # 3. Interfaces removed (BAD, breaks upward compatibility): Increment # CURRENT, set AGE and REVISION to 0. -AM_INIT_AUTOMAKE(gpgme,0.2.2a) -# --> New functions introduced <---- -LIBGPGME_LT_CURRENT=3 -LIBGPGME_LT_AGE=3 -LIBGPGME_LT_REVISION=1 -NEED_GPG_VERSION=1.0.4h +AM_INIT_AUTOMAKE(gpgme,0.2.3) +# +LIBGPGME_LT_CURRENT=4 +LIBGPGME_LT_AGE=4 +LIBGPGME_LT_REVISION=0 +NEED_GPG_VERSION=1.0.6 ############################################## AC_SUBST(LIBGPGME_LT_CURRENT) @@ -170,6 +170,7 @@ jnlib/Makefile gpgme/Makefile gpgme/gpgme-config tests/Makefile +doc/Makefile bonobo/Makefile complus/Makefile ]) @@ -180,10 +181,3 @@ echo " GPG version: min. $NEED_GPG_VERSION GPG path: $GPG " - - - - - - - diff --git a/doc/Makefile.am b/doc/Makefile.am new file mode 100644 index 00000000..97697608 --- /dev/null +++ b/doc/Makefile.am @@ -0,0 +1,27 @@ +# doc - Automake template +# Copyright (C) 2001 g10 Code GmbH +# +# This file is part of GPGME. +# +# GPGME is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# GPGME is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + +## Process this file with automake to produce Makefile.in + +EXTRA_DIST = gdoc + + + + + diff --git a/doc/gdoc b/doc/gdoc new file mode 100755 index 00000000..a1c314d8 --- /dev/null +++ b/doc/gdoc @@ -0,0 +1,681 @@ +#!/usr/bin/perl + +## Copyright (c) 1998 Michael Zucchi, All Rights Reserved ## +## hacked to allow -tex option --nmav ## +## ## +## This software falls under the GNU Public License. Please read ## +## the COPYING file for more information ## + +# +# This will read a 'c' file and scan for embedded comments in the +# style of gnome comments (+minor extensions - see below). +# + +# Note: This only supports 'c'. + +# usage: +# gdoc [ -docbook | -html | -text | -man ] +# [ -function funcname [ -function funcname ...] ] c file(s)s > outputfile +# +# Set output format using one of -docbook -html -text or -man. Default is man. +# +# -function funcname +# If set, then only generate documentation for the given function(s). All +# other functions are ignored. +# +# c files - list of 'c' files to process +# +# All output goes to stdout, with errors to stderr. + +# +# format of comments. +# In the following table, (...)? signifies optional structure. +# (...)* signifies 0 or more structure elements +# /** +# * function_name(:)? (- short description)? +# (* @parameterx: (description of parameter x)?)* +# (* a blank line)? +# * (Description:)? (Description of function)? +# * (section header: (section description)? )* +# (*)?*/ +# +# So .. the trivial example would be: +# +# /** +# * my_function +# **/ +# +# If the Description: header tag is ommitted, then there must be a blank line +# after the last parameter specification. +# e.g. +# /** +# * my_function - does my stuff +# * @my_arg: its mine damnit +# * +# * Does my stuff explained. +# */ +# +# or, could also use: +# /** +# * my_function - does my stuff +# * @my_arg: its mine damnit +# * Description: Does my stuff explained. +# */ +# etc. +# +# All descriptions can be multiline, apart from the short function description. +# +# All descriptive text is further processed, scanning for the following special +# patterns, which are highlighted appropriately. +# +# 'funcname()' - function +# '$ENVVAR' - environmental variable +# '&struct_name' - name of a structure +# '@parameter' - name of a parameter +# '%CONST' - name of a constant. + +# match expressions used to find embedded type information +$type_constant = "\\\%(\\w+)"; +#$type_func = "(\\w+\\(\\))"; +$type_func = "(\\(w||\\\\)+\\(\\))"; +$type_param = "\\\@(\\w+)"; +$type_struct = "\\\&(\\w+)"; +$type_env = "(\\\$\\w+)"; + + +# Output conversion substitutions. +# One for each output format + +# these work fairly well +%highlights_html = ( $type_constant, "\$1", + $type_func, "\$1", + $type_struct, "\$1", + $type_param, "\$1" ); +$blankline_html = "

"; + +%highlights_tex = ( $type_constant, "{\\\\it \$1}", + $type_func, "{\\\\bf \$1}", + $type_struct, "{\\\\it \$1}", + $type_param, "{\\\\bf \$1}" ); +$blankline_tex = "\\par"; + +# sgml, docbook format +%highlights_sgml = ( $type_constant, "\$1", + $type_func, "\$1", + $type_struct, "\$1", + $type_env, "\$1", + $type_param, "\$1" ); +$blankline_sgml = "\n"; + +# these are pretty rough +%highlights_man = ( $type_constant, "\\n.I \\\"\$1\\\"\\n", + $type_func, "\\n.B \\\"\$1\\\"\\n", + $type_struct, "\\n.I \\\"\$1\\\"\\n", + $type_param."([\.\, ]*)\n?", "\\n.I \\\"\$1\$2\\\"\\n" ); +$blankline_man = ""; + +# text-mode +%highlights_text = ( $type_constant, "\$1", + $type_func, "\$1", + $type_struct, "\$1", + $type_param, "\$1" ); +$blankline_text = ""; + + +sub usage { + print "Usage: $0 [ -v ] [ -docbook | -html | -text | -man | -tex ]\n"; + print " [ -function funcname [ -function funcname ...] ]\n"; + print " c source file(s) > outputfile\n"; + exit 1; +} + +# read arguments +if ($#ARGV==-1) { + usage(); +} + +$verbose = 0; +$output_mode = "man"; +%highlights = %highlights_man; +$blankline = $blankline_man; +$modulename = "API Documentation"; +$function_only = 0; +while ($ARGV[0] =~ m/^-(.*)/) { + $cmd = shift @ARGV; + if ($cmd eq "-html") { + $output_mode = "html"; + %highlights = %highlights_html; + $blankline = $blankline_html; + } elsif ($cmd eq "-man") { + $output_mode = "man"; + %highlights = %highlights_man; + $blankline = $blankline_man; + } elsif ($cmd eq "-tex") { + $output_mode = "tex"; + %highlights = %highlights_tex; + $blankline = $blankline_tex; + } elsif ($cmd eq "-text") { + $output_mode = "text"; + %highlights = %highlights_text; + $blankline = $blankline_text; + } elsif ($cmd eq "-docbook") { + $output_mode = "sgml"; + %highlights = %highlights_sgml; + $blankline = $blankline_sgml; + } elsif ($cmd eq "-module") { # not needed for sgml, inherits from calling document + $modulename = shift @ARGV; + } elsif ($cmd eq "-function") { # to only output specific functions + $function_only = 1; + $function = shift @ARGV; + $function_table{$function} = 1; + } elsif ($cmd eq "-v") { + $verbose = 1; + } elsif (($cmd eq "-h") || ($cmd eq "--help")) { + usage(); + } +} + + +# generate a sequence of code that will splice in highlighting information +# using the s// operator. +$dohighlight = ""; +foreach $pattern (keys %highlights) { +# print "scanning pattern $pattern ($highlights{$pattern})\n"; + $dohighlight .= "\$contents =~ s:$pattern:$highlights{$pattern}:gs;\n"; +} + +## +# dumps section contents to arrays/hashes intended for that purpose. +# +sub dump_section { + my $name = shift @_; + my $contents = join "\n", @_; + + if ($name =~ m/$type_constant/) { + $name = $1; +# print STDERR "constant section '$1' = '$contents'\n"; + $constants{$name} = $contents; + } elsif ($name =~ m/$type_param/) { +# print STDERR "parameter def '$1' = '$contents'\n"; + $name = $1; + $parameters{$name} = $contents; + } else { +# print STDERR "other section '$name' = '$contents'\n"; + $sections{$name} = $contents; + push @sectionlist, $name; + } +} + +## +# output function +# +# parameters, a hash. +# function => "function name" +# parameterlist => @list of parameters +# parameters => %parameter descriptions +# sectionlist => @list of sections +# sections => %descriont descriptions +# + +sub output_highlight { + my $contents = join "\n", @_; + my $line; + + eval $dohighlight; + foreach $line (split "\n", $contents) { + if ($line eq ""){ + print $lineprefix, $blankline; + } else { + print $lineprefix, $line; + } + print "\n"; + } +} + + +# output in html +sub output_html { + my %args = %{$_[0]}; + my ($parameter, $section); + my $count; + print "\n\n 

Function

\n"; + + print "".$args{'functiontype'}."\n"; + print "".$args{'function'}."\n"; + print "("; + $count = 0; + foreach $parameter (@{$args{'parameterlist'}}) { + print "".$args{'parametertypes'}{$parameter}." ".$parameter."\n"; + if ($count != $#{$args{'parameterlist'}}) { + $count++; + print ", "; + } + } + print ")\n"; + + print "

Arguments

\n"; + print "
\n"; + foreach $parameter (@{$args{'parameterlist'}}) { + print "
".$args{'parametertypes'}{$parameter}." ".$parameter."\n"; + print "
"; + output_highlight($args{'parameters'}{$parameter}); + } + print "
\n"; + foreach $section (@{$args{'sectionlist'}}) { + print "

$section

\n"; + print "
    \n"; + output_highlight($args{'sections'}{$section}); + print "
\n"; + } + print "
\n"; +} + +# output in tex +sub output_tex { + my %args = %{$_[0]}; + my ($parameter, $section); + my $count; + my $func = $args{'function'}; + my $param; + my $param2; + my $sec; + my $check; + my $type; + + $func =~ s/_/\\_/g; + + print "\n\n\\subsection{". $func . "}\n\\label{" . $args{'function'} . "}\n"; + + $type = $args{'functiontype'}; + $type =~ s/_/\\_/g; + + print "{\\it ".$type."}\n"; + print "{\\bf ".$func."}\n"; + print "(\n"; + $count = 0; + foreach $parameter (@{$args{'parameterlist'}}) { + $param = $args{'parametertypes'}{$parameter}; + $param2 = $parameter; + $param =~ s/_/\\_/g; + $param2 =~ s/_/\\_/g; + + print "{\\it ".$param."} {\\bf ".$param2."}\n"; + if ($count != $#{$args{'parameterlist'}}) { + $count++; + print ", "; + } + } + print ")\n"; + + print "\n{\\large{Arguments}}\n"; + + print "\\begin{itemize}\n"; + $check=0; + foreach $parameter (@{$args{'parameterlist'}}) { + $param = $args{'parametertypes'}{$parameter}; + $param =~ s/_/\\_/g; + $param2 = $parameter; + $param2 =~ s/_/\\_/g; + + $check = 1; + print "\\item {\\it ".$param."} {\\bf ".$param2."}\n"; + print "\n"; + + output_highlight($param{$parameter}); + } + if ($check==0) { + print "\\item void\n"; + } + print "\\end{itemize}\n"; + + foreach $section (@{$args{'sectionlist'}}) { + print "\n\\par{\\large{$section}}\\par\n"; + print "\\begin{rmfamily}\n"; + + $sec = $args{'sections'}{$section}; + $sec =~ s/_/\\_/g; + $sec =~ s/&/\\&/g; + output_highlight($sec); + print "\\end{rmfamily}\n"; + } + print "\n"; +} + + +# output in sgml DocBook +sub output_sgml { + my %args = %{$_[0]}; + my ($parameter, $section); + my $count; + my $id; + + $id = $args{'module'}."-".$args{'function'}; + $id =~ s/[^A-Za-z0-9]/-/g; + + print "\n"; + print "\n"; + print "".$args{'function'}."\n"; + print "\n"; + print "\n"; + print " ".$args{'function'}."\n"; + print " \n"; + print " ".$args{'purpose'}."\n"; + print " \n"; + print "\n"; + + print "\n"; + print " Synopsis\n"; + print " \n"; + print " ".$args{'functiontype'}." "; + print "".$args{'function'}." "; + print "\n"; + +# print "\n"; +# print " Synopsis\n"; +# print " \n"; +# print " ".$args{'functiontype'}." "; +# print "".$args{'function'}." "; +# print "\n"; + + $count = 0; + if ($#{$args{'parameterlist'}} >= 0) { + foreach $parameter (@{$args{'parameterlist'}}) { + print " ".$args{'parametertypes'}{$parameter}; + print " $parameter\n"; + } + } else { + print " \n"; + } + print " \n"; + print "\n"; +# print "\n"; + + # print parameters + print "\n Arguments\n"; +# print "\nArguments\n"; + if ($#{$args{'parameterlist'}} >= 0) { + print " \n"; + foreach $parameter (@{$args{'parameterlist'}}) { + print " \n $parameter\n"; + print " \n \n"; + $lineprefix=" "; + output_highlight($args{'parameters'}{$parameter}); + print " \n \n \n"; + } + print " \n"; + } else { + print " \n None\n \n"; + } + print "\n"; + + # print out each section + $lineprefix=" "; + foreach $section (@{$args{'sectionlist'}}) { + print "\n $section\n \n"; +# print "\n$section\n"; + if ($section =~ m/EXAMPLE/i) { + print "\n"; + } + output_highlight($args{'sections'}{$section}); +# print ""; + if ($section =~ m/EXAMPLE/i) { + print "\n"; + } + print " \n\n"; + } + + print "\n\n"; +} + +## +# output in man +sub output_man { + my %args = %{$_[0]}; + my ($parameter, $section); + my $count; + + print ".TH \"$args{'module'}\" \"$args{'function'}\" \"25 May 1998\" \"API Manual\" GNOME\n"; + + print ".SH Function\n"; + + print ".I \"".$args{'functiontype'}."\"\n"; + print ".B \"".$args{'function'}."\"\n"; + print "(\n"; + $count = 0; + foreach $parameter (@{$args{'parameterlist'}}) { + print ".I \"".$args{'parametertypes'}{$parameter}."\"\n.B \"".$parameter."\"\n"; + if ($count != $#{$args{'parameterlist'}}) { + $count++; + print ",\n"; + } + } + print ")\n"; + + print ".SH Arguments\n"; + foreach $parameter (@{$args{'parameterlist'}}) { + print ".IP \"".$args{'parametertypes'}{$parameter}." ".$parameter."\" 12\n"; + output_highlight($args{'parameters'}{$parameter}); + } + foreach $section (@{$args{'sectionlist'}}) { + print ".SH \"$section\"\n"; + output_highlight($args{'sections'}{$section}); + } +} + +## +# output in text +sub output_text { + my %args = %{$_[0]}; + my ($parameter, $section); + + print "Function = ".$args{'function'}."\n"; + print " return type: ".$args{'functiontype'}."\n\n"; + foreach $parameter (@{$args{'parameterlist'}}) { + print " ".$args{'parametertypes'}{$parameter}." ".$parameter."\n"; + print " -> ".$args{'parameters'}{$parameter}."\n"; + } + foreach $section (@{$args{'sectionlist'}}) { + print " $section:\n"; + print " -> "; + output_highlight($args{'sections'}{$section}); + } +} + +## +# generic output function - calls the right one based +# on current output mode. +sub output_function { +# output_html(@_); + eval "output_".$output_mode."(\@_);"; +} + + +## +# takes a function prototype and spits out all the details +# stored in the global arrays/hsahes. +sub dump_function { + my $prototype = shift @_; + + if ($prototype =~ m/^()([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/ || + $prototype =~ m/^(\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/ || + $prototype =~ m/^(\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/ || + $prototype =~ m/^(\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/ || + $prototype =~ m/^(\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/) { + $return_type = $1; + $function_name = $2; + $args = $3; + +# print STDERR "ARGS = '$args'\n"; + + foreach $arg (split ',', $args) { + # strip leading/trailing spaces + $arg =~ s/^\s*//; + $arg =~ s/\s*$//; +# print STDERR "SCAN ARG: '$arg'\n"; + @args = split('\s', $arg); + +# print STDERR " -> @args\n"; + $param = pop @args; +# print STDERR " -> @args\n"; + if ($param =~ m/^(\*+)(.*)/) { + $param = $2; + push @args, $1; + } + $type = join " ", @args; + + if ($parameters{$param} eq "") { + $parameters{$param} = "-- undescribed --"; + print STDERR "Warning($lineno): Function parameter '$param' not described in '$function_name'\n"; + } + + push @parameterlist, $param; + $parametertypes{$param} = $type; + +# print STDERR "param = '$param', type = '$type'\n"; + } + } else { + print STDERR "Error($lineno): cannot understand prototype: '$prototype'\n"; + return; + } + + if ($function_only==0 || defined($function_table{$function_name})) { + output_function({'function' => $function_name, + 'module' => $modulename, + 'functiontype' => $return_type, + 'parameterlist' => \@parameterlist, + 'parameters' => \%parameters, + 'parametertypes' => \%parametertypes, + 'sectionlist' => \@sectionlist, + 'sections' => \%sections, + 'purpose' => $function_purpose + }); + } +} + +###################################################################### +# main +# states +# 0 - normal code +# 1 - looking for function name +# 2 - scanning field start. +# 3 - scanning prototype. +$state = 0; +$section = ""; + +$doc_special = "\@\%\$\&"; + +$doc_start = "^/\\*\\*\$"; +$doc_end = "\\*/"; +$doc_com = "\\s*\\*\\s*"; +$doc_func = $doc_com."(\\w+):?"; +$doc_sect = $doc_com."([".$doc_special."]?[\\w ]+):(.*)"; +$doc_content = $doc_com."(.*)"; + +%constants = (); +%parameters = (); +@parameterlist = (); +%sections = (); +@sectionlist = (); + +$contents = ""; +$section_default = "Description"; # default section +$section = $section_default; + +$lineno = 0; +foreach $file (@ARGV) { + if (!open(IN,"<$file")) { + print STDERR "Error: Cannot open file $file\n"; + next; + } + while () { + $lineno++; + + if ($state == 0) { + if (/$doc_start/o) { + $state = 1; # next line is always the function name + } + } elsif ($state == 1) { # this line is the function name (always) + if (/$doc_func/o) { + $function = $1; + $state = 2; + if (/-(.*)/) { + $function_purpose = $1; + } else { + $function_purpose = ""; + } + if ($verbose) { + print STDERR "Info($lineno): Scanning doc for $function\n"; + } + } else { + print STDERR "WARN($lineno): Cannot understand $_ on line $lineno", + " - I thought it was a doc line\n"; + $state = 0; + } + } elsif ($state == 2) { # look for head: lines, and include content + if (/$doc_sect/o) { + $newsection = $1; + $newcontents = $2; + + if ($contents ne "") { + dump_section($section, $contents); + $section = $section_default; + } + + $contents = $newcontents; + if ($contents ne "") { + $contents .= "\n"; + } + $section = $newsection; + } elsif (/$doc_end/) { + + if ($contents ne "") { + dump_section($section, $contents); + $section = $section_default; + $contents = ""; + } + +# print STDERR "end of doc comment, looking for prototype\n"; + $prototype = ""; + $state = 3; + } elsif (/$doc_content/) { + # miguel-style comment kludge, look for blank lines after + # @parameter line to signify start of description + if ($1 eq "" && $section =~ m/^@/) { + dump_section($section, $contents); + $section = $section_default; + $contents = ""; + } else { + $contents .= $1."\n"; + } + } else { + # i dont know - bad line? ignore. + print STDERR "WARNING($lineno): bad line: $_"; + } + } elsif ($state == 3) { # scanning for function { (end of prototype) + if (m#\s*/\*\s+MACDOC\s*#io) { + # do nothing + } + elsif (/([^\{]*)/) { + $prototype .= $1; + } + if (/\{/) { + $prototype =~ s@/\*.*?\*/@@gos; # strip comments. + $prototype =~ s@[\r\n]+@ @gos; # strip newlines/cr's. + $prototype =~ s@^ +@@gos; # strip leading spaces + dump_function($prototype); + + $function = ""; + %constants = (); + %parameters = (); + %parametertypes = (); + @parameterlist = (); + %sections = (); + @sectionlist = (); + $prototype = ""; + + $state = 0; + } + } + } +} + diff --git a/gpgme/ChangeLog b/gpgme/ChangeLog index e4794d9a..ff788bfc 100644 --- a/gpgme/ChangeLog +++ b/gpgme/ChangeLog @@ -1,3 +1,7 @@ +2001-09-12 Werner Koch + + * data.c (gpgme_data_rewind): Allow rewind for callbacks. + 2001-09-07 Werner Koch * rungpg.h: Add NO_RECP. diff --git a/gpgme/data.c b/gpgme/data.c index b4cde8e5..a0c37693 100644 --- a/gpgme/data.c +++ b/gpgme/data.c @@ -77,7 +77,7 @@ gpgme_data_new ( GpgmeData *r_dh ) * caller has to make sure that this buffer is valid until gpgme_release_data() * is called. * - * Return value: + * Return value: An error value or 0 for success. **/ GpgmeError gpgme_data_new_from_mem ( GpgmeData *r_dh, @@ -114,6 +114,31 @@ gpgme_data_new_from_mem ( GpgmeData *r_dh, } +/** + * gpgme_data_new_with_read_cb: + * @r_dh: returns the new data object + * @read_cb: callback function + * @read_cb_value: value passed to the callback function + * + * Create a new data object which is a wrapper around the callback function. + * The callback function is defined as: + * + * typedef int (*read_cb) (void *cb_value, + * char *buffer, + * size_t count, + * size_t *nread); + * + * + * The callback should return a maximium of @count bytes in @buffer + * and the number actually read in @nread. It may return 0 in @nread + * if there are no bytes currently available. To indicate EOF the + * function should return with an error code of %-1 and set @nread to + * 0. The callback may support passing %NULL for @buffer and @nread + * and %0 for count as an indication to reset its internal read + * pointer. + * + * Return value: An error value or 0 for success. + **/ GpgmeError gpgme_data_new_with_read_cb ( GpgmeData *r_dh, int (*read_cb)(void*,char *,size_t,size_t*), @@ -218,6 +243,22 @@ gpgme_data_new_from_file ( GpgmeData *r_dh, const char *fname, int copy ) } +/** + * gpgme_data_new_from_filepart: + * @r_dh: returns the new data object + * @fname: filename + * @fp: filepointer + * @offset: Start reading at this offset + * @length: Read this many bytes + * + * Create a new data object and initialize it with @length bytes + * starting at @offset of @file or @fp. Either a filename or an open + * filepointer may be given. + * + + * Return value: An error code or 0 on success. If the error code is + * %GPGME_File_Error, the OS error code is held in %errno. + **/ GpgmeError gpgme_data_new_from_filepart ( GpgmeData *r_dh, const char *fname, FILE *fp, off_t offset, off_t length ) @@ -306,6 +347,14 @@ gpgme_data_release ( GpgmeData dh ) } } +/* + * Release the data object @dh. @dh may be NULL in which case nothing + * happens. + * + * Return value: An allocated memory object with the content of the + * data object. The function makes sure that the returned string can + * safely be accessed using the string fucntions. + **/ char * _gpgme_data_release_and_return_string ( GpgmeData dh ) { @@ -419,8 +468,8 @@ gpgme_data_rewind ( GpgmeData dh ) else if (dh->type == GPGME_DATA_TYPE_CB) { dh->len = dh->readpos = 0; dh->read_cb_eof = 0; - /* FIXME: do a special call to the read function to trigger a rewind - there */ + if ( dh->read_cb (dh->read_cb_value, NULL, 0, NULL) ) + return mk_error (Not_Implemented); } else return mk_error (General_Error); @@ -442,7 +491,7 @@ gpgme_data_rewind ( GpgmeData dh ) * * With a @buffer of NULL, the function does only return the number of * bytes available and does not move the read pointer. This does only - * work for certain data types, all other will respnd with an + * work for certain data types, all other will respond with an * %GPGME_Invalid_Type. * * Return value: An errorcode or 0 on success, EOF is indcated by the diff --git a/gpgme/delete.c b/gpgme/delete.c index 8744efc7..84f2f687 100644 --- a/gpgme/delete.c +++ b/gpgme/delete.c @@ -99,6 +99,17 @@ gpgme_op_delete_start ( GpgmeCtx c, const GpgmeKey key, int allow_secret ) } +/** + * gpgme_op_delete: + * @c: Context + * @key: A Key Object + * @allow_secret: Allow secret key delete + * + * Delete the give @key from the key database. To delete a secret + * along with the public key, @allow_secret must be true. + * + * Return value: 0 on success or an error code. + **/ GpgmeError gpgme_op_delete ( GpgmeCtx c, const GpgmeKey key, int allow_secret ) { diff --git a/gpgme/genkey.c b/gpgme/genkey.c index c765286c..bb0351cc 100644 --- a/gpgme/genkey.c +++ b/gpgme/genkey.c @@ -65,24 +65,45 @@ genkey_status_handler ( GpgmeCtx ctx, GpgStatusCode code, char *args ) } - -/* - * Here is how the parms should be formatted: - -Key-Type: DSA -Key-Length: 1024 -Subkey-Type: ELG-E -Subkey-Length: 1024 -Name-Real: Joe Tester -Name-Comment: with stupid passphrase -Name-Email: joe@foo.bar -Expire-Date: 0 -Passphrase: abc - - * Strings should be given in UTF-8 encoding. The format we support for now - * "internal". The content of the container is passed - * verbatim to GnuPG. Control statements (e.g. %pubring) are not allowed. - */ +/** + * gpgme_op_genkey: + * @c: the context + * @parms: XML string with the key parameters + * @pubkey: Returns the public key + * @seckey: Returns the secret key + * + * Generate a new key and store the key in the default keyrings if + * both @pubkey and @seckey are NULL. If @pubkey and @seckey are + * given, the newly created key will be returned in these data + * objects. This function just starts the gheneration and does not + * wait for completion. + * + * Here is an example on how @parms should be formatted; for deatils + * see the file doc/DETAILS from the GnuPG distribution. + * + * + * + * Key-Type: DSA + * Key-Length: 1024 + * Subkey-Type: ELG-E + * Subkey-Length: 1024 + * Name-Real: Joe Tester + * Name-Comment: with stupid passphrase + * Name-Email: joe@foo.bar + * Expire-Date: 0 + * Passphrase: abc + * + * ]]> + * + * + * Strings should be given in UTF-8 encoding. The format we support + * for now is only "internal". The content of the + * <GnupgKeyParms> container is passed verbatim to GnuPG. + * Control statements are not allowed. + * + * Return value: 0 for success or an error code + **/ GpgmeError gpgme_op_genkey_start ( GpgmeCtx c, const char *parms, diff --git a/gpgme/gpgme.c b/gpgme/gpgme.c index b34fbde6..c36a9448 100644 --- a/gpgme/gpgme.c +++ b/gpgme/gpgme.c @@ -127,9 +127,10 @@ gpgme_cancel (GpgmeCtx c) * gpgme_get_notation: * @c: the context * - * If there is notation data available from the last signature check, this - * function may be used to return this notation data as a string. The string - * is an XML represantaton of that data embedded in a % container. + * If there is notation data available from the last signature check, + * this function may be used to return this notation data as a string. + * The string is an XML represantaton of that data embedded in a + * %<notation> container. * * Return value: An XML string or NULL if no notation data is available. **/ @@ -152,18 +153,21 @@ gpgme_get_notation ( GpgmeCtx c ) * operation available or the operation has not yet finished. * * Here is a sample information we return: - - - - 17 - 2 - pgp-sha1 - 01 - 9222222 - 121212121212121212 - - - * + * + * + * + * + * 17 + * 2 + * pgp-sha1 + * 01 + * 9222222 + * 121212121212121212 + * + * + * ]]> + * * Return value: NULL for no info available or an XML string **/ char * diff --git a/gpgme/gpgme.h b/gpgme/gpgme.h index 7d5fde9e..b806d64f 100644 --- a/gpgme/gpgme.h +++ b/gpgme/gpgme.h @@ -44,7 +44,7 @@ extern "C" { * let autoconf (using the AM_PATH_GPGME macro) check that this * header matches the installed library. * Warning: Do not edit the next line. configure will do that for you! */ -#define GPGME_VERSION "0.2.2a" +#define GPGME_VERSION "0.2.3" diff --git a/gpgme/import.c b/gpgme/import.c index 37bd45ef..357fa887 100644 --- a/gpgme/import.c +++ b/gpgme/import.c @@ -82,6 +82,15 @@ gpgme_op_import_start ( GpgmeCtx c, GpgmeData keydata ) } +/** + * gpgme_op_import: + * @c: Context + * @keydata: Data object + * + * Import all key material from @keydata into the key database. + * + * Return value: o on success or an error code. + **/ GpgmeError gpgme_op_import ( GpgmeCtx c, GpgmeData keydata ) { diff --git a/gpgme/key.c b/gpgme/key.c index a4649df3..4db6ec15 100644 --- a/gpgme/key.c +++ b/gpgme/key.c @@ -268,6 +268,14 @@ _gpgme_key_new_secret ( GpgmeKey *r_key ) return key_new ( r_key, 1 ); } + +/** + * gpgme_key_ref: + * @key: Key object + * + * To safe memory the Key objects implement reference counting. + * Use this function to bump the reference counter. + **/ void gpgme_key_ref ( GpgmeKey key ) { @@ -309,6 +317,17 @@ _gpgme_key_add_secret_subkey (GpgmeKey key) return add_subkey (key, 1); } + + +/** + * gpgme_key_release: + * @key: Key Object or NULL + * + * Release the key object. Note, that this function may not do an + * actual release if there are other shallow copies of the objects. + * You have to call this function for every newly created key object + * as well as for every gpgme_key_ref() done on the key object. + **/ void gpgme_key_release ( GpgmeKey key ) { @@ -335,6 +354,12 @@ gpgme_key_release ( GpgmeKey key ) xfree (key); } +/** + * gpgme_key_unref: + * @key: Key Object + * + * This is an alias for gpgme_key_release(). + **/ void gpgme_key_unref (GpgmeKey key) { @@ -575,6 +600,16 @@ one_uid_as_xml (GpgmeData d, struct user_id_s *u) } +/** + * gpgme_key_get_as_xml: + * @key: Key object + * + * Return the key object as an XML string. The classer has to free + * that string. + * + * Return value: An XML string or NULL in case of a memory problem or + * a NULL passed as @key + **/ char * gpgme_key_get_as_xml ( GpgmeKey key ) { @@ -665,6 +700,23 @@ capabilities_to_string (struct subkey_s *k) | (!!k->flags.can_certify ) ]; } + + +/** + * gpgme_key_get_string_attr: + * @key: Key Object + * @what: Attribute specifier + * @reserved: Must be 0 + * @idx: Index counter + * + * Return a attribute as specified by @what and @idx. Note that not + * all attributes can be returned as a string, in which case NULL is + * returned. @idx is used to iterate through attributes which do have + * more than one instance (e.g. user IDs or sub keys). + * + * Return value: NULL or an const string which is only valid as long + * as the key object itself is valid. + **/ const char * gpgme_key_get_string_attr ( GpgmeKey key, GpgmeAttr what, const void *reserved, int idx ) @@ -767,6 +819,22 @@ gpgme_key_get_string_attr ( GpgmeKey key, GpgmeAttr what, } +/** + * gpgme_key_get_ulong_attr: + * @key: + * @what: + * @reserved: + * @idx: + * + * Return a attribute as specified by @what and @idx. Note that not + * all attributes can be returned as an integer, in which case 0 is + * returned. @idx is used to iterate through attributes which do have + * more than one instance (e.g. user IDs or sub keys). + * + * See gpgme.h for a list of attributes. + * + * Return value: 0 or the requested value. + **/ unsigned long gpgme_key_get_ulong_attr ( GpgmeKey key, GpgmeAttr what, const void *reserved, int idx ) diff --git a/gpgme/keylist.c b/gpgme/keylist.c index 11bbf5d9..44f1489e 100644 --- a/gpgme/keylist.c +++ b/gpgme/keylist.c @@ -376,10 +376,12 @@ finish_key ( GpgmeCtx ctx ) /** * gpgme_op_keylist_start: * @c: context - * @pattern: a GnuPg user ID or NULL for all + * @pattern: a GnuPG user ID or NULL for all * @secret_only: List only keys where the secret part is available * - * Note that this function also cancels a pending key listing operaton.. + * Note that this function also cancels a pending key listing + * operaton. To actually retrieve the key, use + * gpgme_op_keylist_next(). * * Return value: 0 on success or an errorcode. **/ @@ -443,6 +445,17 @@ gpgme_op_keylist_start ( GpgmeCtx c, const char *pattern, int secret_only ) } +/** + * gpgme_op_keylist_next: + * @c: Context + * @r_key: Returned key object + * + * Return the next key from the key listing started with + * gpgme_op_keylist_start(). The caller must free the key using + * gpgme_key_release(). + * + * Return value: 0 on success, %GPGME_EOF or anoter error code. + **/ GpgmeError gpgme_op_keylist_next ( GpgmeCtx c, GpgmeKey *r_key ) { diff --git a/gpgme/posix-sema.c b/gpgme/posix-sema.c index 5d56cc44..3d895200 100644 --- a/gpgme/posix-sema.c +++ b/gpgme/posix-sema.c @@ -42,7 +42,7 @@ void _gpgme_sema_subsystem_init () { -#warning Posix semaphore support has not yet been implemented + /* FIXME: Posix semaphore support has not yet been implemented */ } diff --git a/gpgme/posix-util.c b/gpgme/posix-util.c index 2478063e..a0c755e0 100644 --- a/gpgme/posix-util.c +++ b/gpgme/posix-util.c @@ -34,8 +34,9 @@ const char * _gpgme_get_gpg_path (void) { - #warning Forced to take GPG development version - return "/home/wk/work/gnupg-stable/g10/gpg"; + /* #warning Forced to take GPG development version + * return "/home/wk/work/gnupg-stable/g10/gpg"; + */ return GPG_PATH; } diff --git a/gpgme/recipient.c b/gpgme/recipient.c index 522f6794..5e3297f8 100644 --- a/gpgme/recipient.c +++ b/gpgme/recipient.c @@ -28,6 +28,14 @@ #include "context.h" #include "rungpg.h" +/** + * gpgme_recipients_new: + * @r_rset: Returns the new object. + * + * Create a new uninitialized Reciepient set Object. + * + * Return value: 0 on success or an error code. + **/ GpgmeError gpgme_recipients_new (GpgmeRecipients *r_rset) { @@ -40,6 +48,12 @@ gpgme_recipients_new (GpgmeRecipients *r_rset) return 0; } +/** + * gpgme_recipients_release: + * @rset: Recipient Set object + * + * Free the given object. + **/ void gpgme_recipients_release ( GpgmeRecipients rset ) { @@ -55,6 +69,15 @@ gpgme_recipients_release ( GpgmeRecipients rset ) } +/** + * gpgme_recipients_add_name: + * @rset: Recipient Set object + * @name: user name or keyID + * + * Add a name to the recipient Set. + * + * Return value: 0 on success or an error code + **/ GpgmeError gpgme_recipients_add_name (GpgmeRecipients rset, const char *name ) { @@ -63,6 +86,22 @@ gpgme_recipients_add_name (GpgmeRecipients rset, const char *name ) ); } +/** + * gpgme_recipients_add_name_with_validity: + * @rset: Recipient Set object + * @name: user name or keyID + * @val: Validity value + * + * Same as gpgme_recipients_add_name() but with explictly given key + * validity. Use one of the constants + * %GPGME_VALIDITY_UNKNOWN, %GPGME_VALIDITY_UNDEFINED, + * %GPGME_VALIDITY_NEVER, %GPGME_VALIDITY_MARGINAL, + * %GPGME_VALIDITY_FULL, %GPGME_VALIDITY_ULTIMATE5 + * for the validity. %GPGME_VALIDITY_UNKNOWN is implicitly used by + * gpgme_recipients_add_name(). + * + * Return value: o on success or an error value. + **/ GpgmeError gpgme_recipients_add_name_with_validity (GpgmeRecipients rset, const char *name, @@ -87,6 +126,12 @@ gpgme_recipients_add_name_with_validity (GpgmeRecipients rset, +/** + * gpgme_recipients_count: + * @rset: Recipient Set object + * + * Return value: The number of recipients in the set. + **/ unsigned int gpgme_recipients_count ( const GpgmeRecipients rset ) { @@ -102,6 +147,18 @@ gpgme_recipients_count ( const GpgmeRecipients rset ) +/** + * gpgme_recipients_enum_open: + * @rset: Recipient Set object + * @ctx: Enumerator + * + * Start an enumeration on the Recipient Set object. The caller must pass + * the address of a void pointer which is used as the enumerator object. + * + * Return value: 0 on success or an error code. + * + * See also: gpgme_recipients_enum_read(), gpgme_recipients_enum_close(). + **/ GpgmeError gpgme_recipients_enum_open ( const GpgmeRecipients rset, void **ctx ) { @@ -112,6 +169,19 @@ gpgme_recipients_enum_open ( const GpgmeRecipients rset, void **ctx ) return 0; } +/** + * gpgme_recipients_enum_read: + * @rset: Recipient Set object + * @ctx: Enumerator + * + * Return the name of the next user name from the given recipient + * set. This name is valid as along as the @rset is valid and until + * the next call to this function. + * + * Return value: name or NULL for no more names. + * + * See also: gpgme_recipients_enum_read(), gpgme_recipients_enum_close(). + **/ const char * gpgme_recipients_enum_read ( const GpgmeRecipients rset, void **ctx ) { @@ -131,6 +201,17 @@ gpgme_recipients_enum_read ( const GpgmeRecipients rset, void **ctx ) return NULL; } +/** + * gpgme_recipients_enum_close: + * @rset: Recipient Set object + * @ctx: Enumerator + * + * Release the enumerator @rset for this object. + * + * Return value: 0 on success or %GPGME_Invalid_Value; + * + * See also: gpgme_recipients_enum_read(), gpgme_recipients_enum_close(). + **/ GpgmeError gpgme_recipients_enum_close ( const GpgmeRecipients rset, void **ctx ) { diff --git a/gpgme/wait.c b/gpgme/wait.c index 47b2261a..26b86d08 100644 --- a/gpgme/wait.c +++ b/gpgme/wait.c @@ -157,10 +157,11 @@ _gpgme_wait_on_condition ( GpgmeCtx c, int hang, volatile int *cond ) { DEBUG3 ("waiting... ctx=%p hang=%d cond=%p", c, hang, cond ); do { - int did_work = do_select(); int any = 0; struct proc_s *proc; + do_select(); + if ( cond && *cond ) hang = 0; else {