From cvs at cvs.gnupg.org Tue Feb 2 15:06:21 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 02 Feb 2010 15:06:21 +0100 Subject: [svn] GnuPG - r5254 - in trunk: doc g10 jnlib sm tools Message-ID: Author: wk Date: 2010-02-02 15:06:19 +0100 (Tue, 02 Feb 2010) New Revision: 5254 Modified: trunk/doc/gpg.texi trunk/g10/ChangeLog trunk/g10/card-util.c trunk/g10/free-packet.c trunk/g10/getkey.c trunk/g10/gpg.h trunk/g10/keydb.c trunk/g10/keydb.h trunk/g10/keyedit.c trunk/g10/keylist.c trunk/g10/main.h trunk/g10/mainproc.c trunk/g10/misc.c trunk/g10/packet.h trunk/g10/photoid.c trunk/g10/revoke.c trunk/g10/server.c trunk/g10/sign.c trunk/g10/skclist.c trunk/jnlib/w32-gettext.c trunk/sm/keylist.c trunk/tools/ChangeLog trunk/tools/symcryptrun.c Log: Various changes to eventually support openpgp keys in pgp-agent. Comment fixes. Minor chnages in preparation of a W32CE port. [The diff below has been truncated] Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2010-01-29 10:37:12 UTC (rev 5253) +++ trunk/g10/ChangeLog 2010-02-02 14:06:19 UTC (rev 5254) @@ -1,3 +1,53 @@ +2010-02-02 Werner Koch + + * keyedit.c (keyedit_menu): Change prompt to "gpg". + * card-util.c (card_edit): Change prompt to "gpg/card". + +2010-01-11 Werner Koch + + * sign.c (only_old_style, write_onepass_sig_packets, hash_for) + (write_signature_packets, print_status_sig_created) + (clearsign_file, make_keysig_packet, mk_notation_policy_etc) + (complete_sig, do_sign, update_keysig_packet): Replace all + secret key access by the matching public key. + * keylist.c (print_seckey_info): Ditto. + * revoke.c (gen_desig_revoke): Ditto. + * skclist.c (release_sk_list): Ditto. + * keyedit.c (sign_uids): Ditto. + * misc.c (get_signature_count): Ditto. + * main.h (struct expand_args): s/sk/pksk/. Change all users. + + * keyedit.c (keyedit_passwd): Finish implementation. + +2010-01-10 Werner Koch + + * skclist.c (GCRYCTL_FAKED_RANDOM_P): Remove because we require + libgcrypt 1.4. + (is_insecure, key_present_in_sk_list): Work with public keys. + (build_sk_list): Change to work on public keys. + * keydb.h (struct sk_list): Replace field SK by a PK field. + + * keylist.c (list_keyblock_print): Always look for the public key + and ignore all secret key packets. + (list_keyblock_colon): Ditto. + (print_capabilities): Remove arg SK and all secret key stuff. + Adjust all callers. + (dump_attribs): Ditto. + + * getkey.c (getkey_bynames, getkey_next, get_pubkey_end): New. + (getkey_byname): New. + (getkey_ctx_s): Add WANT_SECRET. + (key_byname): Set it. + (merge_keys_and_selfsig): Remove all the secret key merging. + (lookup): Simplify by removing secret key code. + + * keylist.c (list_all): Scan public keys and use have_secret_key + to filter secret keys. + (list_one): Use the new get_key functions. + + * gpg.h (kbnode_t): Add as alias for KBNODE. + * keydb.h (getkey_ctx_t): Add as alias for GETKEY_CTX. + 2010-01-09 Werner Koch * getkey.c, keylist.c: Re-indent. Modified: trunk/tools/ChangeLog =================================================================== --- trunk/tools/ChangeLog 2010-01-29 10:37:12 UTC (rev 5253) +++ trunk/tools/ChangeLog 2010-02-02 14:06:19 UTC (rev 5254) @@ -1,3 +1,7 @@ +2010-01-10 Werner Koch + + * symcryptrun.c (utmp.h): Remove header; it is not used. + 2009-12-18 Werner Koch * applygnupgdefaults (errorfile): Use mktemp. Fixes bug#1146. Modified: trunk/doc/gpg.texi =================================================================== --- trunk/doc/gpg.texi 2010-01-29 10:37:12 UTC (rev 5253) +++ trunk/doc/gpg.texi 2010-02-02 14:06:19 UTC (rev 5254) @@ -888,6 +888,13 @@ non-exportable. This is a shortcut version of the subcommand "lsign" from @option{--edit-key}. + at ifclear gpgone + at item --passwd @var{user_id} + at opindex passwd +Change the passphrase of the secret key belonging to the certificate +specified as @var{user_id}. This is a shortcut for the sub-command + at code{passwd} of the edit key menu. + at end ifclear @end table Modified: trunk/g10/card-util.c =================================================================== --- trunk/g10/card-util.c 2010-01-29 10:37:12 UTC (rev 5253) +++ trunk/g10/card-util.c 2010-02-02 14:06:19 UTC (rev 5254) @@ -1817,7 +1817,7 @@ if (!have_commands) { tty_enable_completion (card_edit_completion); - answer = cpr_get_no_help("cardedit.prompt", _("Command> ")); + answer = cpr_get_no_help("cardedit.prompt", _("gpg/card> ")); cpr_kill_prompt(); tty_disable_completion (); } Modified: trunk/g10/free-packet.c =================================================================== --- trunk/g10/free-packet.c 2010-01-29 10:37:12 UTC (rev 5253) +++ trunk/g10/free-packet.c 2010-02-02 14:06:19 UTC (rev 5254) @@ -471,6 +471,7 @@ { int n, i; + log_debug ("FIXME: %s Should not be used\n", __func__); if( a->timestamp != b->timestamp ) return -1; if( a->version < 4 && a->expiredate != b->expiredate ) Modified: trunk/g10/getkey.c =================================================================== --- trunk/g10/getkey.c 2010-01-29 10:37:12 UTC (rev 5253) +++ trunk/g10/getkey.c 2010-02-02 14:06:19 UTC (rev 5254) @@ -46,6 +46,7 @@ struct getkey_ctx_s { int exact; + int want_secret; /* The caller requested only secret keys. */ KBNODE keyblock; KBPOS kbpos; KBNODE found_key; /* Pointer into some keyblock. */ @@ -101,8 +102,8 @@ static user_id_db_t user_id_db; static int uid_cache_entries; /* Number of entries in uid cache. */ -static void merge_selfsigs (KBNODE keyblock); -static int lookup (GETKEY_CTX ctx, KBNODE * ret_keyblock, int secmode); +static void merge_selfsigs (kbnode_t keyblock); +static int lookup (getkey_ctx_t ctx, kbnode_t *ret_keyblock, int want_secret); #if 0 static void @@ -599,7 +600,7 @@ /* Try to get the pubkey by the userid. This function looks for the - * first pubkey certificate which has the given name in a user_id. if + * first pubkey certificate which has the given name in a user_id. If * pk/sk has the pubkey algo set, the function will only return a * pubkey with that algo. If namelist is NULL, the first key is * returned. The caller should provide storage for either the pk or @@ -608,7 +609,7 @@ static int key_byname (GETKEY_CTX * retctx, strlist_t namelist, PKT_public_key * pk, PKT_secret_key * sk, - int secmode, int include_unusable, + int want_secret, int include_unusable, KBNODE * ret_kb, KEYDB_HANDLE * ret_kdbhd) { int rc = 0; @@ -617,6 +618,8 @@ GETKEY_CTX ctx; KBNODE help_kb = NULL; + /* FIXME: Eventually remove the SK argument. */ + if (retctx) { /* Reset the returned context in case of error. */ @@ -667,36 +670,26 @@ } } - ctx->kr_handle = keydb_new (secmode); + ctx->want_secret = want_secret; + ctx->kr_handle = keydb_new (0); if (!ret_kb) ret_kb = &help_kb; - if (secmode) + if (pk) { - if (sk) - { - ctx->req_algo = sk->req_algo; - ctx->req_usage = sk->req_usage; - } - rc = lookup (ctx, ret_kb, 1); - if (!rc && sk) - { - sk_from_block (ctx, sk, *ret_kb); - } + ctx->req_algo = pk->req_algo; + ctx->req_usage = pk->req_usage; } - else + else if (sk) /* FIXME: We should remove this. */ { - if (pk) - { - ctx->req_algo = pk->req_algo; - ctx->req_usage = pk->req_usage; - } - rc = lookup (ctx, ret_kb, 0); - if (!rc && pk) - { - pk_from_block (ctx, pk, *ret_kb); - } + ctx->req_algo = sk->req_algo; + ctx->req_usage = sk->req_usage; } + rc = lookup (ctx, ret_kb, want_secret); + if (!rc && pk) + { + pk_from_block (ctx, pk, *ret_kb); + } release_kbnode (help_kb); @@ -1219,115 +1212,102 @@ return rc; } + -/************************************************ - ************* Merging stuff ******************** - ************************************************/ +/* The new function to return a key. + FIXME: Document it. */ +gpg_error_t +getkey_bynames (getkey_ctx_t *retctx, PKT_public_key *pk, + strlist_t names, int want_secret, kbnode_t *ret_keyblock) +{ + return key_byname (retctx, names, pk, NULL, want_secret, 1, + ret_keyblock, NULL); +} -/* Merge all self-signatures with the keys. - * FIXME: replace this at least for the public key parts - * by merge_selfsigs. - * It is still used in keyedit.c and - * at 2 or 3 other places - check whether it is really needed. - * It might be needed by the key edit and import stuff because - * the keylock is changed. */ -void -merge_keys_and_selfsig (KBNODE keyblock) +/* Get a key by name and store it into PK. If RETCTX is not NULL + * return the search context which needs to be released by the caller + * using getkey_end. If NAME is NULL use the default key (see below). + * On success and if RET_KEYBLOCK is not NULL the found keyblock is + * stored at this address. WANT_SECRET passed as true requires that a + * secret key is available for the selected key. + * + * If WANT_SECRET is true and NAME is NULL and a default key has been + * defined that defined key is used. In all other cases the first + * available key is used. + * + * FIXME: Explain what is up with unusable keys. + * + * FIXME: We also have the get_pubkey_byname fucntion which has a + * different semantic. Should be merged with this one. + */ +gpg_error_t +getkey_byname (getkey_ctx_t *retctx, PKT_public_key *pk, + const char *name, int want_secret, kbnode_t *ret_keyblock) { - PKT_public_key *pk = NULL; - PKT_secret_key *sk = NULL; - PKT_signature *sig; - KBNODE k; - u32 kid[2] = { 0, 0 }; - u32 sigdate = 0; + gpg_error_t err; + strlist_t namelist = NULL; + int with_unusable = 1; - if (keyblock && keyblock->pkt->pkttype == PKT_PUBLIC_KEY) - { - /* Divert to our new function. */ - merge_selfsigs (keyblock); - return; - } + if (want_secret && !name && opt.def_secret_key && *opt.def_secret_key) + add_to_strlist (&namelist, opt.def_secret_key); + else if (name) + add_to_strlist (&namelist, name); + else + with_unusable = 0; - /* Still need the old one because the new one can't handle secret keys. */ + err = key_byname (retctx, namelist, pk, NULL, want_secret, with_unusable, + ret_keyblock, NULL); + + /* FIXME: Check that we really return GPG_ERR_NO_SECKEY if + WANT_SECRET has been used. */ - for (k = keyblock; k; k = k->next) - { - if (k->pkt->pkttype == PKT_PUBLIC_KEY - || k->pkt->pkttype == PKT_PUBLIC_SUBKEY) - { - pk = k->pkt->pkt.public_key; - sk = NULL; - if (pk->version < 4) - pk = NULL; /* Not needed for old keys. */ - else if (k->pkt->pkttype == PKT_PUBLIC_KEY) - keyid_from_pk (pk, kid); - else if (!pk->expiredate) - { - /* and subkey */ - /* insert the expiration date here */ - /*FIXME!!! pk->expiredate = subkeys_expiretime( k, kid ); */ - } - sigdate = 0; - } - else if (k->pkt->pkttype == PKT_SECRET_KEY - || k->pkt->pkttype == PKT_SECRET_SUBKEY) - { - pk = NULL; - sk = k->pkt->pkt.secret_key; - if (sk->version < 4) - sk = NULL; - else if (k->pkt->pkttype == PKT_SECRET_KEY) - keyid_from_sk (sk, kid); - sigdate = 0; - } - else if ((pk || sk) && k->pkt->pkttype == PKT_SIGNATURE - && (sig = k->pkt->pkt.signature)->sig_class >= 0x10 - && sig->sig_class <= 0x30 && sig->version > 3 - && !(sig->sig_class == 0x18 || sig->sig_class == 0x28) - && sig->keyid[0] == kid[0] && sig->keyid[1] == kid[1]) - { - /* okay this is a self-signature which can be used. - * This is not used for subkey binding signature, becuase this - * is done above. - * FIXME: We should only use this if the signature is valid - * but this is time consuming - we must provide another - * way to handle this - */ - const byte *p; - u32 ed; + free_strlist (namelist); - p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL); - if (pk) - { - ed = p ? pk->timestamp + buffer_to_u32 (p) : 0; - if (sig->timestamp > sigdate) - { - pk->expiredate = ed; - sigdate = sig->timestamp; - } - } - else - { - ed = p ? sk->timestamp + buffer_to_u32 (p) : 0; - if (sig->timestamp > sigdate) - { - sk->expiredate = ed; - sigdate = sig->timestamp; - } - } - } + return err; +} - if (pk && (pk->expiredate == 0 || - (pk->max_expiredate && pk->expiredate > pk->max_expiredate))) - pk->expiredate = pk->max_expiredate; - if (sk && (sk->expiredate == 0 || - (sk->max_expiredate && sk->expiredate > sk->max_expiredate))) - sk->expiredate = sk->max_expiredate; - } +/* The new function to return the next key. */ +gpg_error_t +getkey_next (getkey_ctx_t ctx, PKT_public_key *pk, kbnode_t *ret_keyblock) +{ + int rc; /* Fixme: Make sure this is proper gpg_error */ + + rc = lookup (ctx, ret_keyblock, ctx->want_secret); + if (!rc && pk && ret_keyblock) + pk_from_block (ctx, pk, *ret_keyblock); + + return rc; } + +/* The new function to finish a key listing. */ +void +getkey_end (getkey_ctx_t ctx) +{ + get_pubkey_end (ctx); +} + + + +/************************************************ + ************* Merging stuff ******************** + ************************************************/ + +/* Merge all self-signatures with the keys. */ +void +merge_keys_and_selfsig (KBNODE keyblock) +{ + if (!keyblock) + ; + else if (keyblock->pkt->pkttype == PKT_PUBLIC_KEY) + merge_selfsigs (keyblock); + else + log_debug ("FIXME: merging secret key blocks is not anymore available\n"); +} + + static int parse_key_usage (PKT_signature * sig) { @@ -2309,146 +2289,10 @@ } -/* - * Merge the secret keys from secblock into the pubblock thereby - * replacing the public (sub)keys with their secret counterparts Hmmm: - * It might be better to get away from the concept of entire secret - * keys at all and have a way to store just the real secret parts - * from the key. - */ -static void -merge_public_with_secret (KBNODE pubblock, KBNODE secblock) -{ - KBNODE pub; - - assert (pubblock->pkt->pkttype == PKT_PUBLIC_KEY); - assert (secblock->pkt->pkttype == PKT_SECRET_KEY); - - for (pub = pubblock; pub; pub = pub->next) - { - if (pub->pkt->pkttype == PKT_PUBLIC_KEY) - { - PKT_public_key *pk = pub->pkt->pkt.public_key; - PKT_secret_key *sk = secblock->pkt->pkt.secret_key; - assert (pub == pubblock); /* Only in the first node. */ - /* There is nothing to compare in this case, so just replace - * some information. */ - copy_public_parts_to_secret_key (pk, sk); - free_public_key (pk); - pub->pkt->pkttype = PKT_SECRET_KEY; - pub->pkt->pkt.secret_key = copy_secret_key (NULL, sk); - } - else if (pub->pkt->pkttype == PKT_PUBLIC_SUBKEY) - { - KBNODE sec; - PKT_public_key *pk = pub->pkt->pkt.public_key; - - /* This is more complicated: It may happen that the sequence - * of the subkeys dosn't match, so we have to find the - * appropriate secret key. */ - for (sec = secblock->next; sec; sec = sec->next) - { - if (sec->pkt->pkttype == PKT_SECRET_SUBKEY) - { - PKT_secret_key *sk = sec->pkt->pkt.secret_key; - if (!cmp_public_secret_key (pk, sk)) - { - copy_public_parts_to_secret_key (pk, sk); - free_public_key (pk); - pub->pkt->pkttype = PKT_SECRET_SUBKEY; - pub->pkt->pkt.secret_key = copy_secret_key (NULL, sk); - break; - } - } - } - if (!sec) - BUG (); /* Already checked in premerge. */ - } - } -} - - -/* This function checks that for every public subkey a corresponding - * secret subkey is available and deletes the public subkey otherwise. - * We need this function because we can't delete it later when we - * actually merge the secret parts into the pubring. - * The function also plays some games with the node flags. */ -static void -premerge_public_with_secret (KBNODE pubblock, KBNODE secblock) -{ - KBNODE last, pub; - - assert (pubblock->pkt->pkttype == PKT_PUBLIC_KEY); - assert (secblock->pkt->pkttype == PKT_SECRET_KEY); - - for (pub = pubblock, last = NULL; pub; last = pub, pub = pub->next) - { - pub->flag &= ~3; /* Reset bits 0 and 1. */ - if (pub->pkt->pkttype == PKT_PUBLIC_SUBKEY) - { - KBNODE sec; - PKT_public_key *pk = pub->pkt->pkt.public_key; - - for (sec = secblock->next; sec; sec = sec->next) - { - if (sec->pkt->pkttype == PKT_SECRET_SUBKEY) - { - PKT_secret_key *sk = sec->pkt->pkt.secret_key; - if (!cmp_public_secret_key (pk, sk)) - { - if (sk->protect.s2k.mode == 1001) - { - /* The secret parts are not available so - we can't use that key for signing etc. - Fix the pubkey usage */ - pk->pubkey_usage &= ~(PUBKEY_USAGE_SIG - | PUBKEY_USAGE_AUTH); - } - /* Transfer flag bits 0 and 1 to the pubblock. */ - pub->flag |= (sec->flag & 3); - break; - } - } - } - if (!sec) - { - KBNODE next, ll; - - if (opt.verbose) - log_info (_("no secret subkey" - " for public subkey %s - ignoring\n"), - keystr_from_pk (pk)); - /* We have to remove the subkey in this case. */ - assert (last); - /* Find the next subkey. */ - for (next = pub->next, ll = pub; - next && next->pkt->pkttype != PKT_PUBLIC_SUBKEY; - ll = next, next = next->next) - ; - /* Make new link. */ - last->next = next; - /* Release this public subkey with all sigs. */ - ll->next = NULL; - release_kbnode (pub); - /* Let the loop continue. */ - pub = last; - } - } - } - /* We need to copy the found bits (0 and 1) from the secret key to - the public key. This has already been done for the subkeys but - got lost on the primary key - fix it here. */ - pubblock->flag |= (secblock->flag & 3); -} - - -/* See see whether the key fits our requirements and in case we do not - * request the primary key, we should select a suitable subkey. +/* See whether the key fits our requirements and in case we do not + * request the primary key, select a suitable subkey. * - * FIXME: Check against PGP 7 whether we still need a kludge - * to favor type 16 keys over type 20 keys when type 20 - * has not been explitely requested. * Returns: True when a suitable key has been found. * * We have to distinguish four cases: FIXME! @@ -2533,7 +2377,7 @@ if ((!foundk || foundk->pkt->pkttype == PKT_PUBLIC_SUBKEY) && !req_prim) { KBNODE nextk; - /* ceither start a loop or check just this one subkey. */ + /* Either start a loop or check just this one subkey. */ for (k = foundk ? foundk : keyblock; k; k = nextk) { PKT_public_key *pk; @@ -2635,7 +2479,7 @@ { if (DBG_CACHE) log_debug ("\tno suitable key found - giving up\n"); - return 0; + return 0; /* Not found. */ } found: @@ -2668,11 +2512,13 @@ } +/* The main function to lookup a key. On success the found keyblock + is stored at RET_KEYBLOCK and also in CTX. If WANT_SECRET is true + a corresponding secret key is required. */ static int -lookup (GETKEY_CTX ctx, KBNODE * ret_keyblock, int secmode) +lookup (getkey_ctx_t ctx, kbnode_t *ret_keyblock, int want_secret) { int rc; - KBNODE secblock = NULL; /* Helper. */ int no_suitable_key = 0; rc = 0; @@ -2692,31 +2538,9 @@ goto skip; } - if (secmode) - { - /* Find the correspondig public key and use this - * this one for the selection process. */ - u32 aki[2]; - KBNODE k = ctx->keyblock; + if (want_secret && have_secret_key (ctx->keyblock)) + goto skip; /* No secret key available. */ - if (k->pkt->pkttype != PKT_SECRET_KEY) - BUG (); - - keyid_from_sk (k->pkt->pkt.secret_key, aki); - k = get_pubkeyblock (aki); - if (!k) - { - if (!opt.quiet) - log_info (_("key %s: secret key without public key" - " - skipped\n"), keystr (aki)); - goto skip; - } - secblock = ctx->keyblock; - ctx->keyblock = k; - - premerge_public_with_secret (ctx->keyblock, secblock); - } - /* Warning: node flag bits 0 and 1 should be preserved by * merge_selfsigs. For secret keys, premerge did tranfer the * keys to the keyblock. */ @@ -2724,12 +2548,6 @@ if (finish_lookup (ctx)) { no_suitable_key = 0; - if (secmode) - { - merge_public_with_secret (ctx->keyblock, secblock); - release_kbnode (secblock); - secblock = NULL; - } goto found; } else @@ -2737,15 +2555,10 @@ skip: /* Release resources and continue search. */ - if (secmode) - { - release_kbnode (secblock); - secblock = NULL; - } release_kbnode (ctx->keyblock); ctx->keyblock = NULL; } - + found: if (rc && rc != -1) log_error ("keydb_search failed: %s\n", g10_errstr (rc)); @@ -2756,15 +2569,10 @@ ctx->keyblock = NULL; } else if (rc == -1 && no_suitable_key) - rc = secmode ? G10ERR_UNU_SECKEY : G10ERR_UNU_PUBKEY; + rc = want_secret? G10ERR_UNU_SECKEY : G10ERR_UNU_PUBKEY; else if (rc == -1) - rc = secmode ? G10ERR_NO_SECKEY : G10ERR_NO_PUBKEY; + rc = want_secret? G10ERR_NO_SECKEY : G10ERR_NO_PUBKEY; - if (secmode) - { - release_kbnode (secblock); - secblock = NULL; - } release_kbnode (ctx->keyblock); ctx->keyblock = NULL; @@ -3083,3 +2891,180 @@ return 1; } + + +/* Return 0 if a secret key is available for the key described by + KEYBLOCK. FIXME: How do we handel subkeys? */ +gpg_error_t +have_secret_key (kbnode_t keyblock) +{ + gpg_error_t err; + unsigned char fpr[MAX_FINGERPRINT_LEN]; + size_t fprlen; + KEYDB_HANDLE kdh; + + if (!keyblock || keyblock->pkt->pkttype != PKT_PUBLIC_KEY) + return gpg_error (GPG_ERR_NO_PUBKEY); /* Should not happen. */ + + fingerprint_from_pk (keyblock->pkt->pkt.public_key, fpr, &fprlen); + while (fprlen < MAX_FINGERPRINT_LEN) + fpr[fprlen++] = 0; + + /* FIXME: Always allocating a new handle is too slow. However this + entire implementation is anyway a temporary solution until we can + ask gpg-agent for the secret key. */ + kdh = keydb_new (1); + if (!kdh) + return gpg_error (GPG_ERR_GENERAL); + + err = keydb_search_fpr (kdh, fpr); + if (err == -1 || gpg_err_code (err) == GPG_ERR_EOF) + err = gpg_error (GPG_ERR_NO_SECKEY); + + keydb_release (kdh); + + return err; +} + + + +#if 0 +/* + * Merge the secret keys from secblock into the pubblock thereby + * replacing the public (sub)keys with their secret counterparts Hmmm: + * It might be better to get away from the concept of entire secret + * keys at all and have a way to store just the real secret parts + * from the key. + * + * FIXME: this is not anymore needed but we keep it as example code for the + * new code we need to write for the import/export feature. + */ +static void +merge_public_with_secret (KBNODE pubblock, KBNODE secblock) +{ + KBNODE pub; + + assert (pubblock->pkt->pkttype == PKT_PUBLIC_KEY); + assert (secblock->pkt->pkttype == PKT_SECRET_KEY); + + for (pub = pubblock; pub; pub = pub->next) + { + if (pub->pkt->pkttype == PKT_PUBLIC_KEY) + { + PKT_public_key *pk = pub->pkt->pkt.public_key; + PKT_secret_key *sk = secblock->pkt->pkt.secret_key; + assert (pub == pubblock); /* Only in the first node. */ + /* There is nothing to compare in this case, so just replace + * some information. */ + copy_public_parts_to_secret_key (pk, sk); + free_public_key (pk); + pub->pkt->pkttype = PKT_SECRET_KEY; + pub->pkt->pkt.secret_key = copy_secret_key (NULL, sk); + } + else if (pub->pkt->pkttype == PKT_PUBLIC_SUBKEY) + { + KBNODE sec; + PKT_public_key *pk = pub->pkt->pkt.public_key; + + /* This is more complicated: It may happen that the sequence + * of the subkeys dosn't match, so we have to find the + * appropriate secret key. */ + for (sec = secblock->next; sec; sec = sec->next) + { + if (sec->pkt->pkttype == PKT_SECRET_SUBKEY) + { + PKT_secret_key *sk = sec->pkt->pkt.secret_key; + if (!cmp_public_secret_key (pk, sk)) + { + copy_public_parts_to_secret_key (pk, sk); + free_public_key (pk); + pub->pkt->pkttype = PKT_SECRET_SUBKEY; + pub->pkt->pkt.secret_key = copy_secret_key (NULL, sk); + break; + } + } + } + if (!sec) + BUG (); /* Already checked in premerge. */ + } + } +} + + +/* This function checks that for every public subkey a corresponding + * secret subkey is available and deletes the public subkey otherwise. + * We need this function because we can't delete it later when we + * actually merge the secret parts into the pubring. + * The function also plays some games with the node flags. + * + * FIXME: this is not anymore needed but we keep it as example code for the + * new code we need to write for the import/export feature. + */ +static void +premerge_public_with_secret (KBNODE pubblock, KBNODE secblock) +{ + KBNODE last, pub; + + assert (pubblock->pkt->pkttype == PKT_PUBLIC_KEY); + assert (secblock->pkt->pkttype == PKT_SECRET_KEY); + + for (pub = pubblock, last = NULL; pub; last = pub, pub = pub->next) + { + pub->flag &= ~3; /* Reset bits 0 and 1. */ + if (pub->pkt->pkttype == PKT_PUBLIC_SUBKEY) + { + KBNODE sec; + PKT_public_key *pk = pub->pkt->pkt.public_key; + + for (sec = secblock->next; sec; sec = sec->next) + { + if (sec->pkt->pkttype == PKT_SECRET_SUBKEY) + { + PKT_secret_key *sk = sec->pkt->pkt.secret_key; + if (!cmp_public_secret_key (pk, sk)) + { + if (sk->protect.s2k.mode == 1001) + { + /* The secret parts are not available so + we can't use that key for signing etc. + Fix the pubkey usage */ + pk->pubkey_usage &= ~(PUBKEY_USAGE_SIG + | PUBKEY_USAGE_AUTH); + } + /* Transfer flag bits 0 and 1 to the pubblock. */ + pub->flag |= (sec->flag & 3); + break; + } + } + } + if (!sec) + { + KBNODE next, ll; + + if (opt.verbose) + log_info (_("no secret subkey" + " for public subkey %s - ignoring\n"), + keystr_from_pk (pk)); + /* We have to remove the subkey in this case. */ + assert (last); + /* Find the next subkey. */ + for (next = pub->next, ll = pub; + next && next->pkt->pkttype != PKT_PUBLIC_SUBKEY; + ll = next, next = next->next) + ; + /* Make new link. */ + last->next = next; + /* Release this public subkey with all sigs. */ + ll->next = NULL; + release_kbnode (pub); + /* Let the loop continue. */ + pub = last; + } + } + } + /* We need to copy the found bits (0 and 1) from the secret key to + the public key. This has already been done for the subkeys but + got lost on the primary key - fix it here. */ + pubblock->flag |= (secblock->flag & 3); +} +#endif /*0*/ Modified: trunk/g10/gpg.h =================================================================== --- trunk/g10/gpg.h 2010-01-29 10:37:12 UTC (rev 5253) +++ trunk/g10/gpg.h 2010-02-02 14:06:19 UTC (rev 5254) @@ -1,5 +1,5 @@ /* gpg.h - top level include file for gpg etc. - * Copyright (C) 2003, 2006 Free Software Foundation, Inc. + * Copyright (C) 2003, 2006, 2010 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -50,6 +50,7 @@ /* Object used to describe a keyblok node. */ typedef struct kbnode_struct *KBNODE; +typedef struct kbnode_struct *kbnode_t; /* Session control object. This object is passed to most functions to Modified: trunk/g10/keydb.c =================================================================== --- trunk/g10/keydb.c 2010-01-29 10:37:12 UTC (rev 5253) +++ trunk/g10/keydb.c 2010-02-02 14:06:19 UTC (rev 5254) @@ -353,8 +353,6 @@ KEYDB_HANDLE hd; int i, j; - if (secret) - log_debug ("FIXME: keydb_new called for secret keys\n"); hd = xmalloc_clear (sizeof *hd); hd->found = -1; Modified: trunk/g10/keydb.h =================================================================== --- trunk/g10/keydb.h 2010-01-29 10:37:12 UTC (rev 5253) +++ trunk/g10/keydb.h 2010-02-02 14:06:19 UTC (rev 5254) @@ -1,6 +1,6 @@ /* keydb.h - Key database * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, - * 2006 Free Software Foundation, Inc. + * 2006, 2010 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -40,6 +40,7 @@ struct getkey_ctx_s; typedef struct getkey_ctx_s *GETKEY_CTX; +typedef struct getkey_ctx_s *getkey_ctx_t; /**************** * A Keyblock is all packets which form an entire certificate; @@ -93,12 +94,13 @@ int flags; /* flag bit 1==throw_keyid */ }; -/* structure to hold a couple of secret key certificates */ +/* Structure to hold a list of secret key certificates. */ typedef struct sk_list *SK_LIST; -struct sk_list { - SK_LIST next; - PKT_secret_key *sk; - int mark; /* not used */ +struct sk_list +{ + SK_LIST next; + PKT_public_key *pk; + int mark; /* not used */ }; /* structure to collect all information which can be used to @@ -169,8 +171,8 @@ /*-- skclist.c --*/ int random_is_faked (void); void release_sk_list( SK_LIST sk_list ); -int build_sk_list( strlist_t locusr, SK_LIST *ret_sk_list, - int unlock, unsigned use ); +gpg_error_t build_sk_list (strlist_t locusr, SK_LIST *ret_sk_list, + int unlock, unsigned use); /*-- passphrase.h --*/ unsigned char encode_s2k_iterations (int iterations); @@ -226,7 +228,19 @@ int get_seckeyblock_byfprint (KBNODE *ret_keyblock, const byte *fprint, size_t fprint_len ); +gpg_error_t getkey_bynames (getkey_ctx_t *retctx, PKT_public_key *pk, + strlist_t names, int want_secret, + kbnode_t *ret_keyblock); +gpg_error_t getkey_byname (getkey_ctx_t *retctx, PKT_public_key *pk, + const char *name, int want_secret, + kbnode_t *ret_keyblock); +gpg_error_t getkey_next (getkey_ctx_t ctx, PKT_public_key *pk, + kbnode_t *ret_keyblock); +void getkey_end (getkey_ctx_t ctx); +gpg_error_t have_secret_key (kbnode_t keyblock); + + int enum_secret_keys( void **context, PKT_secret_key *sk, int with_subkeys, int with_spm ); void merge_keys_and_selfsig( KBNODE keyblock ); Modified: trunk/g10/keyedit.c =================================================================== --- trunk/g10/keyedit.c 2010-01-29 10:37:12 UTC (rev 5253) +++ trunk/g10/keyedit.c 2010-02-02 14:06:19 UTC (rev 5254) @@ -511,7 +511,7 @@ int rc = 0; SK_LIST sk_list = NULL; SK_LIST sk_rover = NULL; - PKT_secret_key *sk = NULL; + PKT_public_key *pk = NULL; KBNODE node, uidnode; PKT_public_key *primary_pk=NULL; int select_all = !count_selected_uids(keyblock) || interactive; @@ -550,14 +550,16 @@ opt.cert_policy_url || opt.cert_notations) force_v4=1; - /* we have to use a copy of the sk, because make_keysig_packet + /* We have to use a copy of the pk, because make_keysig_packet * may remove the protection from sk and if we did other * changes to the secret key, we would save the unprotected - * version */ - if( sk ) - free_secret_key(sk); - sk = copy_secret_key( NULL, sk_rover->sk ); - keyid_from_sk( sk, sk_keyid ); + * version. FIXME: This can be removed because all protection + * is now done by gpg-agent. */ + if (pk) + free_public_key (pk); + pk = copy_public_key (NULL, sk_rover->pk); + keyid_from_pk (pk, sk_keyid); + /* set mark A for all selected user ids */ for( node=keyblock; node; node = node->next ) { if( select_all || (node->flag & NODFLG_SELUID) ) @@ -777,10 +779,10 @@ if (!node->pkt->pkt.signature->flags.exportable && local) tty_printf(_( "\"%s\" was already locally signed by key %s\n"), - user,keystr_from_sk(sk)); + user,keystr_from_pk (pk)); else tty_printf(_("\"%s\" was already signed by key %s\n"), - user,keystr_from_sk(sk)); + user,keystr_from_pk (pk)); if(opt.expert && cpr_get_answer_is_yes("sign_uid.dupe_okay", @@ -793,8 +795,8 @@ continue; } - sprintf (buf, "%08lX%08lX", - (ulong)sk->keyid[0], (ulong)sk->keyid[1] ); + snprintf (buf, sizeof buf, "%08lX%08lX", + (ulong)pk->keyid[0], (ulong)pk->keyid[1]); write_status_text (STATUS_ALREADY_SIGNED, buf); uidnode->flag &= ~NODFLG_MARK_A; /* remove mark */ @@ -806,7 +808,7 @@ /* check whether any uids are left for signing */ if( !count_uids_with_flag(keyblock, NODFLG_MARK_A) ) { - tty_printf(_("Nothing to sign with key %s\n"),keystr_from_sk(sk)); + tty_printf (_("Nothing to sign with key %s\n"), keystr_from_pk (pk)); continue; } @@ -883,7 +885,7 @@ currently v3 and we're about to sign it with a v4 sig? If so, danger! */ if(PGP2 && all_v3 && - (sk->version>3 || force_v4) && primary_pk->version<=3) + (pk->version > 3 || force_v4) && primary_pk->version <= 3) { tty_printf(_("You may not make an OpenPGP signature on a " "PGP 2.x key while in --pgp2 mode.\n")); @@ -953,8 +955,8 @@ } p=get_user_id_native(sk_keyid); - tty_printf(_("Are you sure that you want to sign this key with your\n" - "key \"%s\" (%s)\n"),p,keystr_from_sk(sk)); + tty_printf (_("Are you sure that you want to sign this key with your\n" + "key \"%s\" (%s)\n"), p, keystr_from_pk (pk)); xfree(p); if(selfsig) @@ -1051,14 +1053,14 @@ rc = make_keysig_packet( &sig, primary_pk, node->pkt->pkt.user_id, NULL, - sk, + pk, 0x13, 0, force_v4?4:0, 0, 0, keygen_add_std_prefs, primary_pk); else rc = make_keysig_packet( &sig, primary_pk, node->pkt->pkt.user_id, NULL, - sk, + pk, class, 0, force_v4?4:0, timestamp, duration, sign_mk_attrib, &attrib ); @@ -1086,8 +1088,8 @@ leave: release_sk_list( sk_list ); - if( sk ) - free_secret_key(sk); + if (pk) + free_public_key (pk); return rc; } @@ -1653,7 +1655,7 @@ #ifdef HAVE_LIBREADLINE tty_enable_completion(keyedit_completion); #endif - answer = cpr_get_no_help("keyedit.prompt", _("Command> ")); + answer = cpr_get_no_help ("keyedit.prompt", "gpg> "); cpr_kill_prompt(); tty_disable_completion(); } @@ -2331,11 +2333,66 @@ void keyedit_passwd (const char *username) { - gpg_error_t err = gpg_error (GPG_ERR_BUG); /* Not yet implemented. */ + gpg_error_t err; + PKT_public_key *pk; + unsigned char fpr[MAX_FINGERPRINT_LEN]; + size_t fprlen; + KEYDB_HANDLE kdh = NULL; + kbnode_t keyblock = NULL; - log_info ("error changing the passphrase for `%s': %s\n", - username, gpg_strerror (err)); - write_status_error ("keyedit.passwd", err); + pk = xtrycalloc (1, sizeof *pk); + if (!pk) + { + err = gpg_error_from_syserror (); + goto leave; + } + err = getkey_byname (NULL, pk, username, 1, NULL); + if (err) + goto leave; + fingerprint_from_pk (pk, fpr, &fprlen); + while (fprlen < MAX_FINGERPRINT_LEN) + fpr[fprlen++] = 0; + + /* FIXME: Call an agent function instead. */ + + kdh = keydb_new (1); + if (!kdh) + { + err = gpg_error (GPG_ERR_GENERAL); + goto leave; + } + + err = keydb_search_fpr (kdh, fpr); + if (err == -1 || gpg_err_code (err) == GPG_ERR_EOF) + err = gpg_error (GPG_ERR_NO_SECKEY); + if (err) + goto leave; + + err = keydb_get_keyblock (kdh, &keyblock); + if (err) + goto leave; + + if (!change_passphrase (keyblock)) + { + err = gpg_error (GPG_ERR_GENERAL); + goto leave; + } + + err = keydb_update_keyblock (kdh, keyblock); + if (err) + log_error( _("update secret failed: %s\n"), gpg_strerror (err)); + + leave: + release_kbnode (keyblock); + if (pk) + free_public_key (pk); + keydb_release (kdh); + if (err) + { + log_info ("error changing the passphrase for `%s': %s\n", + username, gpg_strerror (err)); + write_status_error ("keyedit.passwd", err); + } } Modified: trunk/g10/keylist.c =================================================================== --- trunk/g10/keylist.c 2010-01-29 10:37:12 UTC (rev 5253) +++ trunk/g10/keylist.c 2010-02-02 14:06:19 UTC (rev 5254) @@ -127,18 +127,18 @@ } void -print_seckey_info (PKT_secret_key * sk) +print_seckey_info (PKT_public_key *pk) { u32 keyid[2]; char *p; - keyid_from_sk (sk, keyid); + keyid_from_pk (pk, keyid); p = get_user_id_native (keyid); tty_printf ("\nsec %4u%c/%s %s %s\n", - nbits_from_sk (sk), - pubkey_letter (sk->pubkey_algo), - keystr (keyid), datestr_from_sk (sk), p); + nbits_from_pk (pk), + pubkey_letter (pk->pubkey_algo), + keystr (keyid), datestr_from_pk (pk), p); xfree (p); } @@ -423,7 +423,7 @@ memset (&stats, 0, sizeof (stats)); - hd = keydb_new (secret); + hd = keydb_new (0); if (!hd) rc = G10ERR_GENERAL; else @@ -444,23 +444,28 @@ log_error ("keydb_get_keyblock failed: %s\n", g10_errstr (rc)); goto leave; } - if (!opt.with_colons) - { - resname = keydb_get_resource_name (hd); - if (lastresname != resname) - { - int i; - - printf ("%s\n", resname); - for (i = strlen (resname); i; i--) - putchar ('-'); - putchar ('\n'); - lastresname = resname; - } - } - merge_keys_and_selfsig (keyblock); - list_keyblock (keyblock, secret, opt.fingerprint, - opt.check_sigs ? &stats : NULL); + if (secret && have_secret_key (keyblock)) + ; /* Secret key listing requested but this isn't one. */ + else + { + if (!opt.with_colons) + { + resname = keydb_get_resource_name (hd); + if (lastresname != resname) + { + int i; + + printf ("%s\n", resname); + for (i = strlen (resname); i; i--) + putchar ('-'); + putchar ('\n'); + lastresname = resname; + } + } + merge_keys_and_selfsig (keyblock); + list_keyblock (keyblock, secret, opt.fingerprint, + opt.check_sigs ? &stats : NULL); + } release_kbnode (keyblock); keyblock = NULL; } @@ -499,58 +504,31 @@ * functions) or to have the search function return indicators for * found names. Yet another way is to use the keydb search * facilities directly. */ - if (secret) + rc = getkey_bynames (&ctx, NULL, names, secret, &keyblock); + if (rc) { - rc = get_seckey_bynames (&ctx, NULL, names, &keyblock); - if (rc) - { - log_error ("error reading key: %s\n", g10_errstr (rc)); - get_seckey_end (ctx); - return; - } - do - { - if ((opt.list_options & LIST_SHOW_KEYRING) && !opt.with_colons) - { - resname = keydb_get_resource_name (get_ctx_handle (ctx)); - printf ("%s: %s\n", keyring_str, resname); - for (i = strlen (resname) + strlen (keyring_str) + 2; i; i--) - putchar ('-'); - putchar ('\n'); - } - list_keyblock (keyblock, 1, opt.fingerprint, NULL); - release_kbnode (keyblock); - } - while (!get_seckey_next (ctx, NULL, &keyblock)); - get_seckey_end (ctx); - } - else - { - rc = get_pubkey_bynames (&ctx, NULL, names, &keyblock); - if (rc) - { - log_error ("error reading key: %s\n", g10_errstr (rc)); - get_pubkey_end (ctx); - return; - } - do - { - if ((opt.list_options & LIST_SHOW_KEYRING) && !opt.with_colons) - { - resname = keydb_get_resource_name (get_ctx_handle (ctx)); - printf ("%s: %s\n", keyring_str, resname); - for (i = strlen (resname) + strlen (keyring_str) + 2; i; i--) - putchar ('-'); - putchar ('\n'); - } - list_keyblock (keyblock, 0, opt.fingerprint, - opt.check_sigs ? &stats : NULL); - release_kbnode (keyblock); - } - while (!get_pubkey_next (ctx, NULL, &keyblock)); + log_error ("error reading key: %s\n", g10_errstr (rc)); get_pubkey_end (ctx); + return; } + do + { + if ((opt.list_options & LIST_SHOW_KEYRING) && !opt.with_colons) + { + resname = keydb_get_resource_name (get_ctx_handle (ctx)); + printf ("%s: %s\n", keyring_str, resname); + for (i = strlen (resname) + strlen (keyring_str) + 2; i; i--) + putchar ('-'); + putchar ('\n'); + } + list_keyblock (keyblock, secret, opt.fingerprint, + (!secret && opt.check_sigs)? &stats : NULL); + release_kbnode (keyblock); + } + while (!getkey_next (ctx, NULL, &keyblock)); + getkey_end (ctx); + if (opt.check_sigs && !opt.with_colons) print_signature_stats (&stats); } @@ -610,39 +588,37 @@ } static void -print_capabilities (PKT_public_key * pk, PKT_secret_key * sk, KBNODE keyblock) +print_capabilities (PKT_public_key *pk, KBNODE keyblock) { - if (pk || (sk && sk->protect.s2k.mode != 1001)) + unsigned int use = pk->pubkey_usage; + int c_printed = 0; + + if (use & PUBKEY_USAGE_ENC) + putchar ('e'); + + if (use & PUBKEY_USAGE_SIG) { - unsigned int use = pk ? pk->pubkey_usage : sk->pubkey_usage; - int c_printed = 0; + putchar ('s'); + if (pk->is_primary) + { + putchar ('c'); + /* The PUBKEY_USAGE_CERT flag was introduced later and we + used to always print 'c' for a primary key. To avoid any + regression here we better track whether we printed 'c' + already. */ + c_printed = 1; + } + } - if (use & PUBKEY_USAGE_ENC) - putchar ('e'); + if ((use & PUBKEY_USAGE_CERT) && !c_printed) + putchar ('c'); - if (use & PUBKEY_USAGE_SIG) - { - putchar ('s'); - if (pk ? pk->is_primary : sk->is_primary) - { - putchar ('c'); - /* The PUBKEY_USAGE_CERT flag was introduced later and - we used to always print 'c' for a primary key. To - avoid any regression here we better track whether we - printed 'c' already. */ - c_printed = 1; - } - } + if ((use & PUBKEY_USAGE_AUTH)) + putchar ('a'); - if ((use & PUBKEY_USAGE_CERT) && !c_printed) - putchar ('c'); - - if ((use & PUBKEY_USAGE_AUTH)) - putchar ('a'); - } - if (keyblock) - { /* figure out the usable capabilities */ + { + /* Figure out the usable capabilities. */ KBNODE k; int enc = 0, sign = 0, cert = 0, auth = 0, disabled = 0; @@ -672,27 +648,6 @@ auth = 1; } } - else if (k->pkt->pkttype == PKT_SECRET_KEY - || k->pkt->pkttype == PKT_SECRET_SUBKEY) - { - sk = k->pkt->pkt.secret_key; - if (sk->is_valid && !sk->is_revoked && !sk->has_expired - && sk->protect.s2k.mode != 1001) - { - if (sk->pubkey_usage & PUBKEY_USAGE_ENC) - enc = 1; - if (sk->pubkey_usage & PUBKEY_USAGE_SIG) - { - sign = 1; - if (sk->is_primary) - cert = 1; - } - if ((sk->pubkey_usage & PUBKEY_USAGE_CERT)) - cert = 1; - if ((sk->pubkey_usage & PUBKEY_USAGE_AUTH)) - auth = 1; - } - } } if (enc) putchar ('E'); @@ -705,10 +660,11 @@ if (disabled) putchar ('D'); } - + putchar (':'); } + /* FLAGS: 0x01 hashed 0x02 critical */ static void @@ -731,6 +687,7 @@ printf ("\n"); } + void print_subpackets_colon (PKT_signature * sig) { @@ -756,9 +713,9 @@ } } + void -dump_attribs (const PKT_user_id * uid, PKT_public_key * pk, - PKT_secret_key * sk) +dump_attribs (const PKT_user_id *uid, PKT_public_key *pk) { int i; @@ -773,12 +730,9 @@ char buf[(MAX_FINGERPRINT_LEN * 2) + 90]; size_t j, n; - if (pk) - fingerprint_from_pk (pk, array, &n); - else if (sk) - fingerprint_from_sk (sk, array, &n); - else - BUG (); + if (!pk) + BUG (); + fingerprint_from_pk (pk, array, &n); p = array; for (j = 0; j < n; j++, p++) @@ -799,6 +753,7 @@ } } + static void list_keyblock_print (KBNODE keyblock, int secret, int fpr, void *opaque) { @@ -806,12 +761,12 @@ KBNODE kbctx; KBNODE node; PKT_public_key *pk; - PKT_secret_key *sk; struct sig_stats *stats = opaque; int skip_sigs = 0; + int s2k_char; - /* get the keyid from the keyblock */ - node = find_kbnode (keyblock, secret ? PKT_SECRET_KEY : PKT_PUBLIC_KEY); + /* Get the keyid from the keyblock. */ + node = find_kbnode (keyblock, PKT_PUBLIC_KEY); if (!node) { log_error ("Oops; key lost!\n"); @@ -819,81 +774,57 @@ return; } - if (secret) - { - pk = NULL; - sk = node->pkt->pkt.secret_key; + pk = node->pkt->pkt.public_key; + + /* Fixme: Get s2k mode from the agent. */ + s2k_char = (/*(sk->protect.s2k.mode == 1001)? '#' : + (sk->protect.s2k.mode == 1002)? '>' : */' '); + + check_trustdb_stale (); - printf ("sec%c %4u%c/%s %s", (sk->protect.s2k.mode == 1001) ? '#' : - (sk->protect.s2k.mode == 1002) ? '>' : ' ', - nbits_from_sk (sk), pubkey_letter (sk->pubkey_algo), - keystr_from_sk (sk), datestr_from_sk (sk)); + printf ("%s%c %4u%c/%s %s", + secret? "sec":"pub", + s2k_char, + nbits_from_pk (pk), pubkey_letter (pk->pubkey_algo), + keystr_from_pk (pk), datestr_from_pk (pk)); - if (sk->has_expired) - { - printf (" ["); - printf (_("expired: %s"), expirestr_from_sk (sk)); - printf ("]"); - } - else if (sk->expiredate) - { - printf (" ["); - printf (_("expires: %s"), expirestr_from_sk (sk)); - printf ("]"); - } - - printf ("\n"); + if (pk->is_revoked) + { + printf (" ["); + printf (_("revoked: %s"), revokestr_from_pk (pk)); + printf ("]"); } - else + else if (pk->has_expired) { - pk = node->pkt->pkt.public_key; - sk = NULL; + printf (" ["); + printf (_("expired: %s"), expirestr_from_pk (pk)); + printf ("]"); + } + else if (pk->expiredate) + { + printf (" ["); + printf (_("expires: %s"), expirestr_from_pk (pk)); + printf ("]"); + } - check_trustdb_stale (); - - printf ("pub %4u%c/%s %s", - nbits_from_pk (pk), pubkey_letter (pk->pubkey_algo), - keystr_from_pk (pk), datestr_from_pk (pk)); - - /* We didn't include this before in the key listing, but there - is room in the new format, so why not? */ - - if (pk->is_revoked) - { - printf (" ["); - printf (_("revoked: %s"), revokestr_from_pk (pk)); From cvs at cvs.gnupg.org Tue Feb 2 15:08:50 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 02 Feb 2010 15:08:50 +0100 Subject: [svn] GnuPG - r5255 - branches/STABLE-BRANCH-1-4/g10 Message-ID: Author: wk Date: 2010-02-02 15:08:50 +0100 (Tue, 02 Feb 2010) New Revision: 5255 Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog branches/STABLE-BRANCH-1-4/g10/card-util.c branches/STABLE-BRANCH-1-4/g10/keyedit.c Log: Change menu prompts. Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/g10/ChangeLog 2010-02-02 14:06:19 UTC (rev 5254) +++ branches/STABLE-BRANCH-1-4/g10/ChangeLog 2010-02-02 14:08:50 UTC (rev 5255) @@ -1,3 +1,8 @@ +2010-02-02 Werner Koch + + * card-util.c (card_edit): Change prompt to "gpg/card". + * keyedit.c (keyedit_menu): Change prompt to "gpg". + 2009-12-17 Werner Koch * sig-check.c (do_check_messages): Evaluate the HAS_EXPIRED flag. Modified: branches/STABLE-BRANCH-1-4/g10/card-util.c =================================================================== --- branches/STABLE-BRANCH-1-4/g10/card-util.c 2010-02-02 14:06:19 UTC (rev 5254) +++ branches/STABLE-BRANCH-1-4/g10/card-util.c 2010-02-02 14:08:50 UTC (rev 5255) @@ -1817,7 +1817,7 @@ if (!have_commands) { tty_enable_completion (card_edit_completion); - answer = cpr_get_no_help("cardedit.prompt", _("Command> ")); + answer = cpr_get_no_help("cardedit.prompt", _("gpg/card> ")); cpr_kill_prompt(); tty_disable_completion (); } Modified: branches/STABLE-BRANCH-1-4/g10/keyedit.c =================================================================== --- branches/STABLE-BRANCH-1-4/g10/keyedit.c 2010-02-02 14:06:19 UTC (rev 5254) +++ branches/STABLE-BRANCH-1-4/g10/keyedit.c 2010-02-02 14:08:50 UTC (rev 5255) @@ -1616,7 +1616,7 @@ if( !have_commands ) { tty_enable_completion(keyedit_completion); - answer = cpr_get_no_help("keyedit.prompt", _("Command> ")); + answer = cpr_get_no_help("keyedit.prompt", "gpg> "); cpr_kill_prompt(); tty_disable_completion(); } From cvs at cvs.gnupg.org Tue Feb 2 15:10:33 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 02 Feb 2010 15:10:33 +0100 Subject: [svn] GnuPG - r5256 - branches/STABLE-BRANCH-2-0/g10 Message-ID: Author: wk Date: 2010-02-02 15:10:32 +0100 (Tue, 02 Feb 2010) New Revision: 5256 Modified: branches/STABLE-BRANCH-2-0/g10/ChangeLog branches/STABLE-BRANCH-2-0/g10/card-util.c branches/STABLE-BRANCH-2-0/g10/keyedit.c Log: Chnage key edit prompts. Modified: branches/STABLE-BRANCH-2-0/g10/ChangeLog =================================================================== --- branches/STABLE-BRANCH-2-0/g10/ChangeLog 2010-02-02 14:08:50 UTC (rev 5255) +++ branches/STABLE-BRANCH-2-0/g10/ChangeLog 2010-02-02 14:10:32 UTC (rev 5256) @@ -1,3 +1,8 @@ +2010-02-02 Werner Koch + + * card-util.c (card_edit): Change prompt to "gpg/card". + * keyedit.c (keyedit_menu): Change prompt to "gpg". + 2010-01-11 Werner Koch * gpg.c: Add option --passwd. Modified: branches/STABLE-BRANCH-2-0/g10/card-util.c =================================================================== --- branches/STABLE-BRANCH-2-0/g10/card-util.c 2010-02-02 14:08:50 UTC (rev 5255) +++ branches/STABLE-BRANCH-2-0/g10/card-util.c 2010-02-02 14:10:32 UTC (rev 5256) @@ -1817,7 +1817,7 @@ if (!have_commands) { tty_enable_completion (card_edit_completion); - answer = cpr_get_no_help("cardedit.prompt", _("Command> ")); + answer = cpr_get_no_help("cardedit.prompt", _("gpg/card> ")); cpr_kill_prompt(); tty_disable_completion (); } Modified: branches/STABLE-BRANCH-2-0/g10/keyedit.c =================================================================== --- branches/STABLE-BRANCH-2-0/g10/keyedit.c 2010-02-02 14:08:50 UTC (rev 5255) +++ branches/STABLE-BRANCH-2-0/g10/keyedit.c 2010-02-02 14:10:32 UTC (rev 5256) @@ -1651,7 +1651,7 @@ #ifdef HAVE_LIBREADLINE tty_enable_completion(keyedit_completion); #endif - answer = cpr_get_no_help("keyedit.prompt", _("Command> ")); + answer = cpr_get_no_help("keyedit.prompt", "gpg> "); cpr_kill_prompt(); tty_disable_completion(); } From cvs at cvs.gnupg.org Tue Feb 16 19:58:19 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 16 Feb 2010 19:58:19 +0100 Subject: [svn] pinentry - r214 - in trunk: . qt4 Message-ID: Author: wk Date: 2010-02-16 19:58:19 +0100 (Tue, 16 Feb 2010) New Revision: 214 Added: trunk/qt4/document-encrypt.png trunk/qt4/gtk-cancel.png trunk/qt4/gtk-ok.png Modified: trunk/ChangeLog trunk/qt4/main.cpp trunk/qt4/pinentrydialog.cpp trunk/qt4/pinentrydialog.h trunk/qt4/pinentrydialog.moc Log: Applied patches to the qt4 versions. Note: It does not build. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-12-16 17:21:59 UTC (rev 213) +++ trunk/ChangeLog 2010-02-16 18:58:19 UTC (rev 214) @@ -1,3 +1,77 @@ +2010-02-16 Werner Koch + + * qt4/document-encrypt.png, qt4/gtk-cancel.png, qt4/gtk-ok.png: New. + * qt4/Makefile.am (EXTRA_DIST): Add them. + +2010-02-15 Christoph Schleifenbaum (wk) + + Also attributed to Marc Mutz . + + * qt4/main.cpp, qt/pinentrydialog.cpp: If the style says so, + set (GTK) icons on OK and Cancel buttons. + +2010-02-15 Christoph Schleifenbaum (wk) + + * qt4/main.cpp: Use an explicit QMessageBox instead of the + 'information' convenience method. We do this for two reasons: + 1. So we can set our own icon (icon()). 2. So we can call our + raiseWindow() function on it. + +2010-02-15 Christoph Schleifenbaum + + * qt4/main.cpp: Use title. Use Qt translation of "OK" and "Cancel" + + * qt4/pinentrydialog.cpp: Don't show the question-mark icon in the + window title. + +2010-02-15 Christoph Schleifenbaum (wk) + + * qt4/pinentrydialog.h, qt4/pinentrydialog.cpp: Use the + document-encrypt icon instead of the + QMessageBox::{Information,Critical} ones. + +2010-02-15 Christoph Schleifenbaum (wk) + + Also attributed to Marc Mutz . + + * qt4/pinentrydialog.cpp: Properly show/hide optional widgets. + +2010-02-15 Christoph Schleifenbaum + + * qt4/pinentrydialog.cpp: Set text color or error label to red. + +2010-02-15 Christoph Schleifenbaum (wk) + + Also attributed to Marc Mutz . + + * qt4/pinentrydialog.cpp: Gather scattered layouting code, use a + single gridlayout for all, and use QDialogButtonBox. + +2010-02-15 Christoph Schleifenbaum (wk) + + * qt4/pinentrydialog.cpp: Call SetForegroundWindow on showEvent() + and set a fixed size on the dialog. + + * qt4/main.cpp: Set document-encrypt as the window icon. + +2010-02-15 Marc Mutz (wk) + + * qt4/main.cpp: Load the correct Qt translation file based on + either lc_messages or the current locale. + + * qt4/main.cpp: Use pinentry_t->parent_wid also for message-box + case. + + * qt4/main.cpp: Properly delete the QApplication. + +2010-02-15 Christoph Schleifenbaum (wk) + + * qt4/main.cpp: Remove guard clause with impossible condition. + + * qt4/main.cpp: Respect pinentry_t->title. + + * qt4/main.cpp: Include config.h. + 2009-12-16 Marcus Brinkmann * gtk+-2/gtksecentry.c: Don't translate properties. Added: trunk/qt4/document-encrypt.png =================================================================== (Binary files differ) Property changes on: trunk/qt4/document-encrypt.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/qt4/gtk-cancel.png =================================================================== (Binary files differ) Property changes on: trunk/qt4/gtk-cancel.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/qt4/gtk-ok.png =================================================================== (Binary files differ) Property changes on: trunk/qt4/gtk-ok.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Modified: trunk/qt4/main.cpp =================================================================== --- trunk/qt4/main.cpp 2009-12-16 17:21:59 UTC (rev 213) +++ trunk/qt4/main.cpp 2010-02-16 18:58:19 UTC (rev 214) @@ -24,19 +24,29 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #include "pinentrydialog.h" #include "pinentry.h" #include +#include #include #include #include +#include +#include +#include +#include #include #include #include +#include + #ifdef FALLBACK_CURSES #include #endif @@ -62,19 +72,27 @@ { QWidget *parent = 0; + QTranslator trans; + const QString lang = pe->lc_messages ? QString::fromLatin1 (pe->lc_messages) : QLocale ().name () ; + if( trans.load (QString::fromLatin1(":/qt_%1").arg(lang)) ) + qApp->installTranslator (&trans); + + /* FIXME: Add parent window ID to pinentry and GTK. */ + if (pe->parent_wid) + parent = new ForeignWidget ((WId) pe->parent_wid); + int want_pass = !!pe->pin; if (want_pass) { - /* FIXME: Add parent window ID to pinentry and GTK. */ - if (pe->parent_wid) - parent = new ForeignWidget ((WId) pe->parent_wid); - PinEntryDialog pinentry (parent, 0, true, !!pe->quality_bar); pinentry.setPinentryInfo (pe); pinentry.setPrompt (QString::fromUtf8 (pe->prompt)); pinentry.setDescription (QString::fromUtf8 (pe->description)); + if ( pe->title ) + pinentry.setWindowTitle( QString::fromUtf8( pe->title ) ); + /* If we reuse the same dialog window. */ pinentry.setPin (secqstring()); @@ -95,8 +113,6 @@ const secstring pinUtf8 = toUtf8( pinentry.pin() ); const char *pin = pinUtf8.data(); - if (!pin) - return -1; int len = strlen (pin); if (len >= 0) @@ -112,14 +128,48 @@ } else { - QString desc = QString::fromUtf8 (pe->description? pe->description :""); - QString ok = QString::fromUtf8 (pe->ok ? pe->ok : "OK"); - QString can = QString::fromUtf8 (pe->cancel ? pe->cancel : "Cancel"); - bool ret; + const QString title = pe->title ? QString::fromUtf8 ( pe->title ) : QString(); + const QString desc = pe->description ? QString::fromUtf8 ( pe->description ) : QString(); + const QString ok = pe->ok ? QString::fromUtf8 ( pe->ok ) : QDialogButtonBox::tr( "&OK" ); + const QString can = pe->cancel ? QString::fromUtf8 ( pe->cancel ) : QDialogButtonBox::tr( "Cancel" ); - ret = QMessageBox::information (parent, "", desc, ok, can ); + QMessageBox box( parent ); - return !ret; + if ( !title.isEmpty() ) + box.setWindowTitle( title ); + + if ( !ok.isEmpty() ) + if ( !can.isEmpty() ) + box.setStandardButtons( QMessageBox::Ok|QMessageBox::Cancel ); + else + box.setStandardButtons( QMessageBox::Ok ); + else + if ( !can.isEmpty() ) + box.setStandardButtons( QMessageBox::Cancel ); + else + box.setStandardButtons( QMessageBox::NoButton ); + + if ( !ok.isEmpty() ) + { + box.button( QMessageBox::Ok )->setText( ok ); + if ( box.style()->styleHint( QStyle::SH_DialogButtonBox_ButtonsHaveIcons ) ) + box.button( QMessageBox::Ok )->setIcon( QIcon( QLatin1String( ":/gtk-ok.png" ) ) ); + } + + if ( !can.isEmpty() ) + { + box.button( QMessageBox::Cancel )->setText( can ); + if ( box.style()->styleHint( QStyle::SH_DialogButtonBox_ButtonsHaveIcons ) ) + box.button( QMessageBox::Cancel )->setIcon( QIcon( QLatin1String( ":/gtk-cancel.png" ) ) ); + } + + box.setText( desc ); + box.setIconPixmap( icon() ); + + box.show(); + raiseWindow( &box ); + + return box.exec() == QMessageBox::Ok ; } } @@ -130,6 +180,8 @@ { pinentry_init ("pinentry-qt4"); + std::auto_ptr app; + #ifdef FALLBACK_CURSES if (!pinentry_have_display (argc, argv)) pinentry_cmd_handler = curses_cmd_handler; @@ -171,7 +223,9 @@ /* We use a modal dialog window, so we don't need the application window anymore. */ i = argc; - new QApplication (i, new_argv); + app.reset (new QApplication (i, new_argv)); + const QIcon icon( QLatin1String( ":/document-encrypt.png" ) ); + app->setWindowIcon( icon ); } @@ -179,11 +233,11 @@ if (pinentry_parse_opts (argc, argv)) { printf ("pinentry-qt4 (pinentry) " /* VERSION */ "\n"); - exit (EXIT_SUCCESS); + return EXIT_SUCCESS; } + else + { + return pinentry_loop () ? EXIT_FAILURE : EXIT_SUCCESS ; + } - if (pinentry_loop ()) - return 1; - - return 0; } Modified: trunk/qt4/pinentrydialog.cpp =================================================================== --- trunk/qt4/pinentrydialog.cpp 2009-12-16 17:21:59 UTC (rev 213) +++ trunk/qt4/pinentrydialog.cpp 2010-02-16 18:58:19 UTC (rev 214) @@ -26,75 +26,118 @@ #include "qsecurelineedit.h" +#include +#include +#include #include #include #include +#include #include #include #include +#include +#include +#ifdef Q_WS_WIN +#include +#endif + +#ifdef Q_WS_WIN +void SetForegroundWindowEx( HWND hWnd ) +{ + //Attach foreground window thread to our thread + const DWORD ForeGroundID = GetWindowThreadProcessId(::GetForegroundWindow(),NULL); + const DWORD CurrentID = GetCurrentThreadId(); + + AttachThreadInput ( ForeGroundID, CurrentID, TRUE ); + //Do our stuff here + HWND hLastActivePopupWnd = GetLastActivePopup( hWnd ); + SetForegroundWindow( hLastActivePopupWnd ); + + //Detach the attached thread + AttachThreadInput ( ForeGroundID, CurrentID, FALSE ); +}// End SetForegroundWindowEx +#endif + +void raiseWindow( QWidget* w ) +{ +#ifdef Q_WS_WIN + SetForegroundWindowEx( w->winId() ); +#endif + w->raise(); + w->activateWindow(); +} + +QPixmap icon( QStyle::StandardPixmap which ) +{ + QPixmap pm = qApp->windowIcon().pixmap( 48, 48 ); + + if ( which != QStyle::SP_CustomBase ) { + const QIcon ic = qApp->style()->standardIcon( which ); + QPainter painter( &pm ); + const int emblemSize = 22; + painter.drawPixmap( pm.width()-emblemSize, 0, + ic.pixmap( emblemSize, emblemSize ) ); + } + + return pm; +} + PinEntryDialog::PinEntryDialog( QWidget* parent, const char* name, bool modal, bool enable_quality_bar ) : QDialog( parent ), _grabbed( false ) { + setWindowFlags( windowFlags() & ~Qt::WindowContextHelpButtonHint ); + if ( modal ) { setWindowModality( Qt::ApplicationModal ); } - QBoxLayout* top = new QVBoxLayout( this ); - top->setMargin( 6 ); - QBoxLayout* upperLayout = new QHBoxLayout(); - top->addLayout( upperLayout, 1 ); - _icon = new QLabel( this ); - _icon->setPixmap( QMessageBox::standardIcon( QMessageBox::Information ) ); - upperLayout->addWidget( _icon ); + _icon->setPixmap( icon() ); - QBoxLayout* labelLayout = new QVBoxLayout(); - upperLayout->addLayout( labelLayout, 5 ); - _error = new QLabel( this ); _error->setWordWrap(true); - labelLayout->addWidget( _error, 1 ); + QPalette pal; + pal.setColor( QPalette::WindowText, Qt::red ); + _error->setPalette( pal ); + _error->hide(); _desc = new QLabel( this ); _desc->setWordWrap(true); - labelLayout->addWidget( _desc, 5 ); + _desc->hide(); - QGridLayout* grid = new QGridLayout; - top->addLayout( grid ); + _prompt = new QLabel( this ); + _prompt->hide(); - _prompt = new QLabel( this ); - grid->addWidget( _prompt, 0, 0 ); _edit = new QSecureLineEdit( this ); _edit->setMaxLength( 256 ); - grid->addWidget( _edit, 0, 1 ); if (enable_quality_bar) { _quality_bar_label = new QLabel( this ); _quality_bar_label->setAlignment( Qt::AlignRight | Qt::AlignVCenter ); - grid->addWidget ( _quality_bar_label, 1, 0 ); _quality_bar = new QProgressBar( this ); _quality_bar->setAlignment( Qt::AlignCenter ); - grid->addWidget( _quality_bar, 1, 1 ); _have_quality_bar = true; } else _have_quality_bar = false; - QBoxLayout* l = new QHBoxLayout(); - top->addLayout( l ); + QDialogButtonBox* const buttons = new QDialogButtonBox( this ); + buttons->setStandardButtons( QDialogButtonBox::Ok | QDialogButtonBox::Cancel ); + _ok = buttons->button( QDialogButtonBox::Ok ); + _cancel = buttons->button( QDialogButtonBox::Cancel ); - _ok = new QPushButton( tr("OK"), this ); - _cancel = new QPushButton( tr("Cancel"), this ); - - l->addWidget( _ok ); - l->addStretch(); - l->addWidget( _cancel ); - _ok->setDefault(true); + if ( style()->styleHint( QStyle::SH_DialogButtonBox_ButtonsHaveIcons ) ) + { + _ok->setIcon( QIcon( QLatin1String( ":/gtk-ok.png" ) ) ); + _cancel->setIcon( QIcon( QLatin1String( ":/gtk-cancel.png" ) ) ); + } + connect( _ok, SIGNAL( clicked() ), this, SIGNAL( accepted() ) ); connect( _cancel, SIGNAL( clicked() ), @@ -107,6 +150,25 @@ this, SLOT (reject ())); _edit->setFocus(); + + QBoxLayout* const labels = new QVBoxLayout; + labels->addWidget( _error ); + labels->addWidget( _desc ); + labels->addItem( new QSpacerItem( 0, 1, QSizePolicy::Minimum, QSizePolicy::Expanding ) ); + + QGridLayout* const grid = new QGridLayout( this ); + grid->addWidget( _icon, 0, 0, 4, 1, Qt::AlignTop|Qt::AlignLeft ); + grid->addLayout( labels, 0, 1, 1, 2 ); + grid->addItem( new QSpacerItem( 0, _edit->height() / 10, QSizePolicy::Minimum, QSizePolicy::Fixed ), 1, 1 ); + grid->addWidget( _prompt, 2, 1 ); + grid->addWidget( _edit, 2, 2 ); + if( enable_quality_bar ) + { + grid->addWidget( _quality_bar_label, 3, 1 ); + grid->addWidget( _quality_bar, 3, 2 ); + } + grid->addWidget( buttons, 4, 0, 1, 3 ); + setMinimumWidth( 450 ); resize( minimumSizeHint() ); } @@ -119,6 +181,27 @@ QDialog::hideEvent( ev ); } +void PinEntryDialog::showEvent( QShowEvent* event ) +{ + QDialog::showEvent( event ); + QMetaObject::invokeMethod( this, "setFixedSize", Qt::QueuedConnection ); +} + +void PinEntryDialog::setFixedSize() +{ + QTextDocument doc; + doc.setDefaultFont( _desc->font() ); + doc.setHtml( _desc->text() ); + doc.setTextWidth( _desc->width() ); + _desc->setFixedSize( doc.size().toSize() ); + + layout()->activate(); + setFixedHeight( minimumSizeHint().height() + 5 ); + QDialog::setFixedSize( size() ); + + raiseWindow( this ); +} + void PinEntryDialog::keyPressEvent( QKeyEvent* e ) { if ( e->modifiers() == Qt::NoModifier && e->key() == Qt::Key_Escape ) { @@ -130,8 +213,9 @@ void PinEntryDialog::setDescription( const QString& txt ) { + _desc->setVisible( !txt.isEmpty() ); _desc->setText( txt ); - _icon->setPixmap( QMessageBox::standardIcon( QMessageBox::Information ) ); + _icon->setPixmap( icon() ); setError( QString::null ); } @@ -142,8 +226,9 @@ void PinEntryDialog::setError( const QString& txt ) { - if( !txt.isNull() )_icon->setPixmap( QMessageBox::standardIcon( QMessageBox::Critical ) ); + if( !txt.isNull() )_icon->setPixmap( icon( QStyle::SP_MessageBoxCritical ) ); _error->setText( txt ); + _error->setVisible( !txt.isEmpty() ); } QString PinEntryDialog::error() const @@ -164,6 +249,7 @@ void PinEntryDialog::setPrompt( const QString& txt ) { _prompt->setText( txt ); + _prompt->setVisible( !txt.isEmpty() ); } QString PinEntryDialog::prompt() const @@ -174,11 +260,13 @@ void PinEntryDialog::setOkText( const QString& txt ) { _ok->setText( txt ); + _ok->setVisible( !txt.isEmpty() ); } void PinEntryDialog::setCancelText( const QString& txt ) { _cancel->setText( txt ); + _cancel->setVisible( !txt.isEmpty() ); } void PinEntryDialog::setQualityBar( const QString& txt ) Modified: trunk/qt4/pinentrydialog.h =================================================================== --- trunk/qt4/pinentrydialog.h 2009-12-16 17:21:59 UTC (rev 213) +++ trunk/qt4/pinentrydialog.h 2010-02-16 18:58:19 UTC (rev 214) @@ -26,6 +26,7 @@ #include #include +#include #include "secstring.h" #include "pinentry.h" @@ -35,7 +36,9 @@ class QSecureLineEdit; class QString; +QPixmap icon( QStyle::StandardPixmap which = QStyle::SP_CustomBase ); +void raiseWindow( QWidget* w ); class PinEntryDialog : public QDialog { Q_OBJECT @@ -76,10 +79,14 @@ void rejected(); protected: + /* reimp */ void showEvent( QShowEvent* event ); /* reimp */ void keyPressEvent( QKeyEvent *e ); /* reimp */ void hideEvent( QHideEvent* ); /* reimp */ void paintEvent( QPaintEvent* event ); +private Q_SLOTS: + void setFixedSize(); + private: QLabel* _icon; QLabel* _desc; Modified: trunk/qt4/pinentrydialog.moc =================================================================== --- trunk/qt4/pinentrydialog.moc 2009-12-16 17:21:59 UTC (rev 213) +++ trunk/qt4/pinentrydialog.moc 2010-02-16 18:58:19 UTC (rev 214) @@ -23,8 +23,8 @@ 1, // revision 0, // classname 0, 0, // classinfo - 3, 10, // methods - 4, 25, // properties + 4, 10, // methods + 4, 30, // properties 0, 0, // enums/sets // signals: signature, parameters, type, tag, flags @@ -33,21 +33,22 @@ // slots: signature, parameters, type, tag, flags 38, 15, 15, 15, 0x0a, + 64, 15, 15, 15, 0x08, // properties: name, type, flags - 72, 64, 0x0a095103, - 84, 64, 0x0a095103, - 101, 90, 0x0009510b, - 105, 64, 0x0a095103, + 87, 79, 0x0a095103, + 99, 79, 0x0a095103, + 116, 105, 0x0009510b, + 120, 79, 0x0a095103, 0 // eod }; static const char qt_meta_stringdata_PinEntryDialog[] = { "PinEntryDialog\0\0accepted()\0rejected()\0" - "updateQuality(secqstring)\0QString\0" - "description\0error\0secqstring\0pin\0" - "prompt\0" + "updateQuality(secqstring)\0setFixedSize()\0" + "QString\0description\0error\0secqstring\0" + "pin\0prompt\0" }; const QMetaObject PinEntryDialog::staticMetaObject = { @@ -78,8 +79,9 @@ case 0: accepted(); break; case 1: rejected(); break; case 2: updateQuality((*reinterpret_cast< const secqstring(*)>(_a[1]))); break; + case 3: setFixedSize(); break; } - _id -= 3; + _id -= 4; } #ifndef QT_NO_PROPERTIES else if (_c == QMetaObject::ReadProperty) { From cvs at cvs.gnupg.org Tue Feb 16 20:05:59 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 16 Feb 2010 20:05:59 +0100 Subject: [svn] pinentry - r215 - trunk/qt4 Message-ID: Author: wk Date: 2010-02-16 20:05:59 +0100 (Tue, 16 Feb 2010) New Revision: 215 Modified: trunk/qt4/Makefile.am Log: Ooops forgot these changes. Modified: trunk/qt4/Makefile.am =================================================================== --- trunk/qt4/Makefile.am 2010-02-16 18:58:19 UTC (rev 214) +++ trunk/qt4/Makefile.am 2010-02-16 19:05:59 UTC (rev 215) @@ -22,6 +22,9 @@ bin_PROGRAMS = pinentry-qt4 +EXTRA_DIST = document-encrypt.png gtk-cancel.png gtk-ok.png + + if FALLBACK_CURSES ncurses_include = $(NCURSES_INCLUDE) libcurses = ../pinentry/libpinentry-curses.a $(LIBCURSES) $(LIBICONV) From cvs at cvs.gnupg.org Tue Feb 16 20:37:52 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 16 Feb 2010 20:37:52 +0100 Subject: [svn] gpgme - r1452 - trunk/src Message-ID: Author: wk Date: 2010-02-16 20:37:51 +0100 (Tue, 16 Feb 2010) New Revision: 1452 Modified: trunk/src/gpgme-tool.c Log: Convert C++ comments to C90 comments. Modified: trunk/src/gpgme-tool.c =================================================================== --- trunk/src/gpgme-tool.c 2010-01-25 16:04:27 UTC (rev 1451) +++ trunk/src/gpgme-tool.c 2010-02-16 19:37:51 UTC (rev 1452) @@ -948,11 +948,11 @@ { result_xml_tag_start (&state, "signature", NULL); - // FIXME: Could be done better. + /* FIXME: Could be done better. */ result_add_value (&state, "summary", sig->summary); result_add_fpr (&state, "fpr", sig->fpr); result_add_error (&state, "status", sig->status); - // FIXME: notations + /* FIXME: notations */ result_add_timestamp (&state, "timestamp", sig->timestamp); result_add_timestamp (&state, "exp-timestamp", sig->exp_timestamp); result_add_value (&state, "wrong-key-usage", sig->wrong_key_usage); @@ -1017,7 +1017,7 @@ result_add_fpr (&state, "fpr", stat->fpr); result_add_error (&state, "result", stat->result); - // FIXME: Could be done better. + /* FIXME: Could be done better. */ result_add_value (&state, "status", stat->status); result_xml_tag_end (&state); @@ -2667,9 +2667,9 @@ assuan_handler_t handler; const char * const help; } table[] = { - // RESET, BYE are implicit. + /* RESET, BYE are implicit. */ { "VERSION", cmd_version, hlp_version }, - // TODO: Set engine info. + /* TODO: Set engine info. */ { "ENGINE", cmd_engine }, { "PROTOCOL", cmd_protocol, hlp_protocol }, { "SUB_PROTOCOL", cmd_sub_protocol }, @@ -2683,10 +2683,10 @@ { "RECIPIENT", cmd_recipient }, { "SIGNER", cmd_signer }, { "SIGNERS_CLEAR", cmd_signers_clear }, - // TODO: SIGNOTATION missing. - // TODO: Could add wait interface if we allow more than one context - // and add _START variants. - // TODO: Could add data interfaces if we allow multiple data objects. + /* TODO: SIGNOTATION missing. */ + /* TODO: Could add wait interface if we allow more than one context */ + /* and add _START variants. */ + /* TODO: Could add data interfaces if we allow multiple data objects. */ { "DECRYPT", cmd_decrypt }, { "DECRYPT_VERIFY", cmd_decrypt_verify }, { "ENCRYPT", cmd_encrypt }, @@ -2698,17 +2698,17 @@ { "EXPORT", cmd_export }, { "GENKEY", cmd_genkey }, { "DELETE", cmd_delete }, - // TODO: EDIT, CARD_EDIT (with INQUIRE) + /* TODO: EDIT, CARD_EDIT (with INQUIRE) */ { "KEYLIST", cmd_keylist }, { "LISTKEYS", cmd_keylist }, - // TODO: TRUSTLIST, TRUSTLIST_EXT + /* TODO: TRUSTLIST, TRUSTLIST_EXT */ { "GETAUDITLOG", cmd_getauditlog, hlp_getauditlog }, - // TODO: ASSUAN + /* TODO: ASSUAN */ { "VFS_MOUNT", cmd_vfs_mount }, { "MOUNT", cmd_vfs_mount }, { "VFS_CREATE", cmd_vfs_create }, { "CREATE", cmd_vfs_create }, - // TODO: GPGCONF + /* TODO: GPGCONF */ { "RESULT", cmd_result }, { "STRERROR", cmd_strerror }, { "PUBKEY_ALGO_NAME", cmd_pubkey_algo_name }, From cvs at cvs.gnupg.org Tue Feb 16 21:07:03 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 16 Feb 2010 21:07:03 +0100 Subject: [svn] gpgme - r1453 - in trunk: . doc src Message-ID: Author: wk Date: 2010-02-16 21:07:03 +0100 (Tue, 16 Feb 2010) New Revision: 1453 Modified: trunk/NEWS trunk/doc/gpgme.texi trunk/src/ChangeLog trunk/src/engine-gpg.c trunk/src/export.c trunk/src/gpgme-tool.c trunk/src/gpgme.h.in Log: Add option GPGME_EXPORT_MODE_MINIMAL Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2010-02-16 19:37:51 UTC (rev 1452) +++ trunk/src/ChangeLog 2010-02-16 20:07:03 UTC (rev 1453) @@ -1,3 +1,12 @@ +2010-02-16 Werner Koch + + * gpgme-tool.c (spacep, has_option, skip_options): New. + (cmd_export): Implement option --minimal. + + * gpgme.h.in (GPGME_EXPORT_MODE_MINIMAL): New. + * export.c (export_start, export_ext_start): Implement it. + * engine-gpg.c (export_common): Ditto. + 2010-01-25 Werner Koch * w32-io.c (_gpgme_io_connect): Fix return code check to make it work. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2010-02-16 19:37:51 UTC (rev 1452) +++ trunk/NEWS 2010-02-16 20:07:03 UTC (rev 1453) @@ -3,7 +3,12 @@ * Under development. + * Interface changes relative to the 1.3.0 release: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + GPGME_EXPORT_MODE_MINIMAL NEW. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Noteworthy changes in version 1.3.0 (2010-01-11) ------------------------------------------------ Modified: trunk/doc/gpgme.texi =================================================================== --- trunk/doc/gpgme.texi 2010-02-16 19:37:51 UTC (rev 1452) +++ trunk/doc/gpgme.texi 2010-02-16 20:07:03 UTC (rev 1453) @@ -3402,6 +3402,12 @@ time. Using this flag requires that the @var{keydata} argument of the export function is set to @code{NULL}. + at item GPGME_EXPORT_MODE_MINIMAL +If this bit is set, the smallest possible key is exported. For OpenPGP +keys it removes all signatures except for the latest self-signatures. +For X.509 keys it has no effect. + + @end table Modified: trunk/src/engine-gpg.c =================================================================== --- trunk/src/engine-gpg.c 2010-02-16 19:37:51 UTC (rev 1452) +++ trunk/src/engine-gpg.c 2010-02-16 20:07:03 UTC (rev 1453) @@ -1727,12 +1727,18 @@ export_common (engine_gpg_t gpg, gpgme_export_mode_t mode, gpgme_data_t keydata, int use_armor) { - gpgme_error_t err; + gpgme_error_t err = 0; - if ((mode & ~GPGME_EXPORT_MODE_EXTERN)) + if ((mode & ~(GPGME_EXPORT_MODE_EXTERN + |GPGME_EXPORT_MODE_MINIMAL))) return gpg_error (GPG_ERR_NOT_SUPPORTED); - if ((mode & GPGME_EXPORT_MODE_EXTERN)) + if ((mode & GPGME_EXPORT_MODE_MINIMAL)) + err = add_arg (gpg, "--export-options=export-minimal"); + + if (err) + ; + else if ((mode & GPGME_EXPORT_MODE_EXTERN)) { err = add_arg (gpg, "--send-keys"); } Modified: trunk/src/export.c =================================================================== --- trunk/src/export.c 2010-02-16 19:37:51 UTC (rev 1452) +++ trunk/src/export.c 2010-02-16 20:07:03 UTC (rev 1453) @@ -1,6 +1,6 @@ /* export.c - Export a key. Copyright (C) 2000 Werner Koch (dd9jn) - Copyright (C) 2001, 2002, 2003, 2004 g10 Code GmbH + Copyright (C) 2001, 2002, 2003, 2004, 2010 g10 Code GmbH This file is part of GPGME. @@ -15,9 +15,8 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser 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. */ + License along with this program; if not, see . + */ #if HAVE_CONFIG_H #include @@ -44,7 +43,8 @@ { gpgme_error_t err; - if ((mode & ~(GPGME_EXPORT_MODE_EXTERN))) + if ((mode & ~(GPGME_EXPORT_MODE_EXTERN + |GPGME_EXPORT_MODE_MINIMAL))) return gpg_error (GPG_ERR_INV_VALUE); /* Invalid flags in MODE. */ @@ -107,7 +107,8 @@ { gpgme_error_t err; - if ((mode & ~(GPGME_EXPORT_MODE_EXTERN))) + if ((mode & ~(GPGME_EXPORT_MODE_EXTERN + |GPGME_EXPORT_MODE_MINIMAL))) return gpg_error (GPG_ERR_INV_VALUE); /* Invalid flags in MODE. */ if ((mode & GPGME_EXPORT_MODE_EXTERN)) Modified: trunk/src/gpgme-tool.c =================================================================== --- trunk/src/gpgme-tool.c 2010-02-16 19:37:51 UTC (rev 1452) +++ trunk/src/gpgme-tool.c 2010-02-16 20:07:03 UTC (rev 1453) @@ -468,6 +468,9 @@ FILE *log_stream; char *program_name = "gpgme-tool"; +#define spacep(p) (*(p) == ' ' || *(p) == '\t') + + void log_error (int status, gpg_error_t errnum, const char *fmt, ...) GT_GCC_A_PRINTF(3,4); @@ -497,6 +500,35 @@ } +/* Check whether the option NAME appears in LINE. */ +static int +has_option (const char *line, const char *name) +{ + const char *s; + int n = strlen (name); + + s = strstr (line, name); + return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n))); +} + +/* Skip over options. It is assumed that leading spaces have been + removed (this is the case for lines passed to a handler from + assuan). Blanks after the options are also removed. */ +static char * +skip_options (char *line) +{ + while ( *line == '-' && line[1] == '-' ) + { + while (*line && !spacep (line)) + line++; + while (spacep (line)) + line++; + } + return line; +} + + + typedef gpg_error_t (*result_xml_write_cb_t) (void *hook, const void *buf, size_t len); @@ -2334,6 +2366,11 @@ } +static const char hlp_export[] = + "EXPORT [--extern] [--minimal] []\n" + "\n" + "Export the keys described by PATTERN. Write the\n" + "the output to the object set by the last OUTPUT command."; static gpg_error_t cmd_export (assuan_context_t ctx, char *line) { @@ -2343,7 +2380,6 @@ gpgme_data_t out_data; gpgme_export_mode_t mode = 0; const char *pattern[2]; - const char optstr[] = "--extern "; out_fd = assuan_get_output_fd (ctx); if (out_fd == ASSUAN_INVALID_FD) @@ -2352,11 +2388,13 @@ if (err) return err; - if (strncasecmp (line, optstr, strlen (optstr))) - { - mode |= GPGME_EXPORT_MODE_EXTERN; - line += strlen (optstr); - } + if (has_option (line, "--extern")) + mode |= GPGME_EXPORT_MODE_EXTERN; + if (has_option (line, "--minimal")) + mode |= GPGME_EXPORT_MODE_MINIMAL; + + line = skip_options (line); + pattern[0] = line; pattern[1] = NULL; @@ -2695,7 +2733,7 @@ { "SIGN", cmd_sign }, { "VERIFY", cmd_verify }, { "IMPORT", cmd_import }, - { "EXPORT", cmd_export }, + { "EXPORT", cmd_export, hlp_export }, { "GENKEY", cmd_genkey }, { "DELETE", cmd_delete }, /* TODO: EDIT, CARD_EDIT (with INQUIRE) */ Modified: trunk/src/gpgme.h.in =================================================================== --- trunk/src/gpgme.h.in 2010-02-16 19:37:51 UTC (rev 1452) +++ trunk/src/gpgme.h.in 2010-02-16 20:07:03 UTC (rev 1453) @@ -348,6 +348,7 @@ /* The available export mode flags. */ #define GPGME_EXPORT_MODE_EXTERN 2 +#define GPGME_EXPORT_MODE_MINIMAL 4 typedef unsigned int gpgme_export_mode_t; From cvs at cvs.gnupg.org Wed Feb 17 10:58:39 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 17 Feb 2010 10:58:39 +0100 Subject: [svn] gpg-error - r231 - in trunk: . po src Message-ID: Author: wk Date: 2010-02-17 10:58:38 +0100 (Wed, 17 Feb 2010) New Revision: 231 Modified: trunk/ChangeLog trunk/po/cs.po trunk/po/de.po trunk/po/fr.po trunk/po/it.po trunk/po/libgpg-error.pot trunk/po/pl.po trunk/po/ro.po trunk/po/sv.po trunk/po/vi.po trunk/po/zh_CN.po trunk/src/Makefile.am Log: Made make distcheck work again. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2010-02-16 13:08:41 UTC (rev 230) +++ trunk/ChangeLog 2010-02-17 09:58:38 UTC (rev 231) @@ -1,3 +1,7 @@ +2010-02-17 Werner Koch + + * src/Makefile.am (extra_headers): Remove. + 2010-01-21 Werner Koch * configure.ac (have_w32ce_system): Initialize to no. Modified: trunk/po/cs.po [not shown] Modified: trunk/po/de.po [not shown] Modified: trunk/po/fr.po [not shown] Modified: trunk/po/it.po [not shown] Modified: trunk/po/libgpg-error.pot =================================================================== --- trunk/po/libgpg-error.pot 2010-02-16 13:08:41 UTC (rev 230) +++ trunk/po/libgpg-error.pot 2010-02-17 09:58:38 UTC (rev 231) @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: translations at gnupg.org\n" -"POT-Creation-Date: 2009-08-20 08:57+0200\n" +"POT-Creation-Date: 2010-01-21 12:09+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -73,26 +73,30 @@ msgstr "" #: src/err-sources.h:42 +msgid "G13" +msgstr "" + +#: src/err-sources.h:43 msgid "Any source" msgstr "" -#: src/err-sources.h:43 +#: src/err-sources.h:44 msgid "User defined source 1" msgstr "" -#: src/err-sources.h:44 +#: src/err-sources.h:45 msgid "User defined source 2" msgstr "" -#: src/err-sources.h:45 +#: src/err-sources.h:46 msgid "User defined source 3" msgstr "" -#: src/err-sources.h:46 +#: src/err-sources.h:47 msgid "User defined source 4" msgstr "" -#: src/err-sources.h:47 +#: src/err-sources.h:48 msgid "Unknown source" msgstr "" @@ -817,247 +821,251 @@ msgstr "" #: src/err-codes.h:208 +msgid "No crypto engine" +msgstr "" + +#: src/err-codes.h:209 msgid "Operation not yet finished" msgstr "" -#: src/err-codes.h:209 +#: src/err-codes.h:210 msgid "Buffer too short" msgstr "" -#: src/err-codes.h:210 +#: src/err-codes.h:211 msgid "Invalid length specifier in S-expression" msgstr "" -#: src/err-codes.h:211 +#: src/err-codes.h:212 msgid "String too long in S-expression" msgstr "" -#: src/err-codes.h:212 +#: src/err-codes.h:213 msgid "Unmatched parentheses in S-expression" msgstr "" -#: src/err-codes.h:213 +#: src/err-codes.h:214 msgid "S-expression not canonical" msgstr "" -#: src/err-codes.h:214 +#: src/err-codes.h:215 msgid "Bad character in S-expression" msgstr "" -#: src/err-codes.h:215 +#: src/err-codes.h:216 msgid "Bad quotation in S-expression" msgstr "" -#: src/err-codes.h:216 +#: src/err-codes.h:217 msgid "Zero prefix in S-expression" msgstr "" -#: src/err-codes.h:217 +#: src/err-codes.h:218 msgid "Nested display hints in S-expression" msgstr "" -#: src/err-codes.h:218 +#: src/err-codes.h:219 msgid "Unmatched display hints" msgstr "" -#: src/err-codes.h:219 +#: src/err-codes.h:220 msgid "Unexpected reserved punctuation in S-expression" msgstr "" -#: src/err-codes.h:220 +#: src/err-codes.h:221 msgid "Bad hexadecimal character in S-expression" msgstr "" -#: src/err-codes.h:221 +#: src/err-codes.h:222 msgid "Odd hexadecimal numbers in S-expression" msgstr "" -#: src/err-codes.h:222 +#: src/err-codes.h:223 msgid "Bad octal character in S-expression" msgstr "" -#: src/err-codes.h:223 +#: src/err-codes.h:224 msgid "General IPC error" msgstr "" -#: src/err-codes.h:224 +#: src/err-codes.h:225 msgid "IPC accept call failed" msgstr "" -#: src/err-codes.h:225 +#: src/err-codes.h:226 msgid "IPC connect call failed" msgstr "" -#: src/err-codes.h:226 +#: src/err-codes.h:227 msgid "Invalid IPC response" msgstr "" -#: src/err-codes.h:227 +#: src/err-codes.h:228 msgid "Invalid value passed to IPC" msgstr "" -#: src/err-codes.h:228 +#: src/err-codes.h:229 msgid "Incomplete line passed to IPC" msgstr "" -#: src/err-codes.h:229 +#: src/err-codes.h:230 msgid "Line passed to IPC too long" msgstr "" -#: src/err-codes.h:230 +#: src/err-codes.h:231 msgid "Nested IPC commands" msgstr "" -#: src/err-codes.h:231 +#: src/err-codes.h:232 msgid "No data callback in IPC" msgstr "" -#: src/err-codes.h:232 +#: src/err-codes.h:233 msgid "No inquire callback in IPC" msgstr "" -#: src/err-codes.h:233 +#: src/err-codes.h:234 msgid "Not an IPC server" msgstr "" -#: src/err-codes.h:234 +#: src/err-codes.h:235 msgid "Not an IPC client" msgstr "" -#: src/err-codes.h:235 +#: src/err-codes.h:236 msgid "Problem starting IPC server" msgstr "" -#: src/err-codes.h:236 +#: src/err-codes.h:237 msgid "IPC read error" msgstr "" -#: src/err-codes.h:237 +#: src/err-codes.h:238 msgid "IPC write error" msgstr "" -#: src/err-codes.h:238 +#: src/err-codes.h:239 msgid "Too much data for IPC layer" msgstr "" -#: src/err-codes.h:239 +#: src/err-codes.h:240 msgid "Unexpected IPC command" msgstr "" -#: src/err-codes.h:240 +#: src/err-codes.h:241 msgid "Unknown IPC command" msgstr "" -#: src/err-codes.h:241 +#: src/err-codes.h:242 msgid "IPC syntax error" msgstr "" -#: src/err-codes.h:242 +#: src/err-codes.h:243 msgid "IPC call has been cancelled" msgstr "" -#: src/err-codes.h:243 +#: src/err-codes.h:244 msgid "No input source for IPC" msgstr "" -#: src/err-codes.h:244 +#: src/err-codes.h:245 msgid "No output source for IPC" msgstr "" -#: src/err-codes.h:245 +#: src/err-codes.h:246 msgid "IPC parameter error" msgstr "" -#: src/err-codes.h:246 +#: src/err-codes.h:247 msgid "Unknown IPC inquire" msgstr "" -#: src/err-codes.h:247 +#: src/err-codes.h:248 msgid "User defined error code 1" msgstr "" -#: src/err-codes.h:248 +#: src/err-codes.h:249 msgid "User defined error code 2" msgstr "" -#: src/err-codes.h:249 +#: src/err-codes.h:250 msgid "User defined error code 3" msgstr "" -#: src/err-codes.h:250 +#: src/err-codes.h:251 msgid "User defined error code 4" msgstr "" -#: src/err-codes.h:251 +#: src/err-codes.h:252 msgid "User defined error code 5" msgstr "" -#: src/err-codes.h:252 +#: src/err-codes.h:253 msgid "User defined error code 6" msgstr "" -#: src/err-codes.h:253 +#: src/err-codes.h:254 msgid "User defined error code 7" msgstr "" -#: src/err-codes.h:254 +#: src/err-codes.h:255 msgid "User defined error code 8" msgstr "" -#: src/err-codes.h:255 +#: src/err-codes.h:256 msgid "User defined error code 9" msgstr "" -#: src/err-codes.h:256 +#: src/err-codes.h:257 msgid "User defined error code 10" msgstr "" -#: src/err-codes.h:257 +#: src/err-codes.h:258 msgid "User defined error code 11" msgstr "" -#: src/err-codes.h:258 +#: src/err-codes.h:259 msgid "User defined error code 12" msgstr "" -#: src/err-codes.h:259 +#: src/err-codes.h:260 msgid "User defined error code 13" msgstr "" -#: src/err-codes.h:260 +#: src/err-codes.h:261 msgid "User defined error code 14" msgstr "" -#: src/err-codes.h:261 +#: src/err-codes.h:262 msgid "User defined error code 15" msgstr "" -#: src/err-codes.h:262 +#: src/err-codes.h:263 msgid "User defined error code 16" msgstr "" -#: src/err-codes.h:263 +#: src/err-codes.h:264 msgid "System error w/o errno" msgstr "" -#: src/err-codes.h:264 +#: src/err-codes.h:265 msgid "Unknown system error" msgstr "" -#: src/err-codes.h:265 +#: src/err-codes.h:266 msgid "End of file" msgstr "" -#: src/err-codes.h:266 +#: src/err-codes.h:267 msgid "Unknown error code" msgstr "" -#: src/gpg-error.c:469 +#: src/gpg-error.c:386 #, c-format msgid "Usage: %s GPG-ERROR [...]\n" msgstr "" -#: src/gpg-error.c:497 +#: src/gpg-error.c:442 #, c-format msgid "%s: warning: could not recognize %s\n" msgstr "" Modified: trunk/po/pl.po [not shown] Modified: trunk/po/ro.po [not shown] Modified: trunk/po/sv.po [not shown] Modified: trunk/po/vi.po [not shown] Modified: trunk/po/zh_CN.po [not shown] Modified: trunk/src/Makefile.am =================================================================== --- trunk/src/Makefile.am 2010-02-16 13:08:41 UTC (rev 230) +++ trunk/src/Makefile.am 2010-02-17 09:58:38 UTC (rev 231) @@ -23,10 +23,8 @@ if HAVE_W32CE_SYSTEM -extra_headers = gpg-extra/errno.h extra_cppflags = -idirafter gpg-extra else -extra_headers = extra_cppflags = endif From cvs at cvs.gnupg.org Wed Feb 17 11:23:43 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 17 Feb 2010 11:23:43 +0100 Subject: [svn] GnuPG - r5261 - trunk/g10 Message-ID: Author: wk Date: 2010-02-17 11:23:42 +0100 (Wed, 17 Feb 2010) New Revision: 5261 Modified: trunk/g10/ChangeLog trunk/g10/keygen.c Log: Fix bug#1186. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2010-02-12 15:15:34 UTC (rev 5260) +++ trunk/g10/ChangeLog 2010-02-17 10:23:42 UTC (rev 5261) @@ -1,3 +1,8 @@ +2010-02-17 Werner Koch + + * keygen.c (ask_user_id): Avoid infinite loop in case of invalid + data. Fixes bug#1186. + 2010-02-02 Werner Koch * keyedit.c (keyedit_menu): Change prompt to "gpg". Modified: trunk/g10/keygen.c =================================================================== --- trunk/g10/keygen.c 2010-02-12 15:15:34 UTC (rev 5260) +++ trunk/g10/keygen.c 2010-02-17 10:23:42 UTC (rev 5261) @@ -2203,7 +2203,7 @@ if( strlen(ansstr) != 10 ) BUG(); if( cpr_enabled() ) { - answer = xstrdup(ansstr+6); + answer = xstrdup (ansstr + (fail?8:6)); answer[1] = 0; } else { From cvs at cvs.gnupg.org Wed Feb 17 11:26:33 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 17 Feb 2010 11:26:33 +0100 Subject: [svn] GnuPG - r5262 - branches/STABLE-BRANCH-2-0/g10 Message-ID: Author: wk Date: 2010-02-17 11:26:32 +0100 (Wed, 17 Feb 2010) New Revision: 5262 Modified: branches/STABLE-BRANCH-2-0/g10/keygen.c Log: Fix bug#1186 Modified: branches/STABLE-BRANCH-2-0/g10/keygen.c =================================================================== --- branches/STABLE-BRANCH-2-0/g10/keygen.c 2010-02-17 10:23:42 UTC (rev 5261) +++ branches/STABLE-BRANCH-2-0/g10/keygen.c 2010-02-17 10:26:32 UTC (rev 5262) @@ -2203,7 +2203,7 @@ if( strlen(ansstr) != 10 ) BUG(); if( cpr_enabled() ) { - answer = xstrdup(ansstr+6); + answer = xstrdup (ansstr + (fail?8:6)); answer[1] = 0; } else { From cvs at cvs.gnupg.org Wed Feb 17 11:26:55 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 17 Feb 2010 11:26:55 +0100 Subject: [svn] GnuPG - r5263 - branches/STABLE-BRANCH-2-0/g10 Message-ID: Author: wk Date: 2010-02-17 11:26:54 +0100 (Wed, 17 Feb 2010) New Revision: 5263 Modified: branches/STABLE-BRANCH-2-0/g10/ChangeLog Log: ChangeLog for last change. Modified: branches/STABLE-BRANCH-2-0/g10/ChangeLog =================================================================== --- branches/STABLE-BRANCH-2-0/g10/ChangeLog 2010-02-17 10:26:32 UTC (rev 5262) +++ branches/STABLE-BRANCH-2-0/g10/ChangeLog 2010-02-17 10:26:54 UTC (rev 5263) @@ -1,3 +1,8 @@ +2010-02-17 Werner Koch + + * keygen.c (ask_user_id): Avoid infinite loop in case of invalid + data. Fixes bug#1186. + 2010-02-11 Marcus Brinkmann From trunk 2009-09-23, 2009-11-02, 2009-11-25: From cvs at cvs.gnupg.org Wed Feb 17 11:28:28 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 17 Feb 2010 11:28:28 +0100 Subject: [svn] GnuPG - r5264 - branches/STABLE-BRANCH-1-4/g10 Message-ID: Author: wk Date: 2010-02-17 11:28:27 +0100 (Wed, 17 Feb 2010) New Revision: 5264 Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog branches/STABLE-BRANCH-1-4/g10/keygen.c Log: Fix bug 1186 Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/g10/ChangeLog 2010-02-17 10:26:54 UTC (rev 5263) +++ branches/STABLE-BRANCH-1-4/g10/ChangeLog 2010-02-17 10:28:27 UTC (rev 5264) @@ -1,3 +1,8 @@ +2010-02-17 Werner Koch + + * keygen.c (ask_user_id): Avoid infinite loop in case of invalid + data. Fixes bug#1186. + 2010-02-02 Werner Koch * card-util.c (card_edit): Change prompt to "gpg/card". Modified: branches/STABLE-BRANCH-1-4/g10/keygen.c =================================================================== --- branches/STABLE-BRANCH-1-4/g10/keygen.c 2010-02-17 10:26:54 UTC (rev 5263) +++ branches/STABLE-BRANCH-1-4/g10/keygen.c 2010-02-17 10:28:27 UTC (rev 5264) @@ -1927,7 +1927,7 @@ if( strlen(ansstr) != 10 ) BUG(); if( cpr_enabled() ) { - answer = xstrdup(ansstr+6); + answer = xstrdup (ansstr + (fail?8:6)); answer[1] = 0; } else { From cvs at cvs.gnupg.org Wed Feb 17 13:34:03 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 17 Feb 2010 13:34:03 +0100 Subject: [svn] GnuPG - r5265 - branches/STABLE-BRANCH-2-0/po Message-ID: Author: wk Date: 2010-02-17 13:34:03 +0100 (Wed, 17 Feb 2010) New Revision: 5265 Modified: branches/STABLE-BRANCH-2-0/po/ChangeLog branches/STABLE-BRANCH-2-0/po/de.po Log: Replace Unterschrift by Signatur. Modified: branches/STABLE-BRANCH-2-0/po/ChangeLog =================================================================== --- branches/STABLE-BRANCH-2-0/po/ChangeLog 2010-02-17 10:28:27 UTC (rev 5264) +++ branches/STABLE-BRANCH-2-0/po/ChangeLog 2010-02-17 12:34:03 UTC (rev 5265) @@ -1,3 +1,8 @@ +2010-02-17 Werner Koch + + * de.po: Replace "Unterschrift" by "Signatur". + (keygen.c): Use Abbrechen instead of Quit. + 2009-12-21 Jedi Lin (wk) * zh_TW.po: Update (dated 2009-09-05). Modified: branches/STABLE-BRANCH-2-0/po/de.po [not shown] From cvs at cvs.gnupg.org Wed Feb 17 16:21:28 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 17 Feb 2010 16:21:28 +0100 Subject: [svn] gpg-error - r232 - in trunk: . src Message-ID: Author: wk Date: 2010-02-17 16:21:28 +0100 (Wed, 17 Feb 2010) New Revision: 232 Modified: trunk/ChangeLog trunk/src/Makefile.am Log: Reworked the installation of gpg-extra/errno.h. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2010-02-17 09:58:38 UTC (rev 231) +++ trunk/ChangeLog 2010-02-17 15:21:28 UTC (rev 232) @@ -1,5 +1,14 @@ 2010-02-17 Werner Koch + * src/Makefile.am: Revert last change. + (gpg_extra_headers): New. + (nobase_include_HEADERS): Rename to include_HEADERS and remove + extra_headers. + (mkerrcodes.h): Depend on gpg_extra_headers. + (install-data-local): New. + +2010-02-17 Werner Koch + * src/Makefile.am (extra_headers): Remove. 2010-01-21 Werner Koch Modified: trunk/src/Makefile.am =================================================================== --- trunk/src/Makefile.am 2010-02-17 09:58:38 UTC (rev 231) +++ trunk/src/Makefile.am 2010-02-17 15:21:28 UTC (rev 232) @@ -23,15 +23,17 @@ if HAVE_W32CE_SYSTEM +gpg_extra_headers = gpg-extra/errno.h extra_cppflags = -idirafter gpg-extra else +gpg_extra_headers = extra_cppflags = endif localedir = $(datadir)/locale bin_PROGRAMS = gpg-error lib_LTLIBRARIES = libgpg-error.la -nobase_include_HEADERS = gpg-error.h $(extra_headers) +include_HEADERS = gpg-error.h bin_SCRIPTS = gpg-error-config m4datadir = $(datadir)/aclocal m4data_DATA = gpg-error.m4 @@ -45,7 +47,7 @@ BUILT_SOURCES = err-sources.h err-codes.h code-to-errno.h code-from-errno.h \ err-sources-sym.h err-codes-sym.h errnos-sym.h gpg-error.h \ - gpg-error.def extra-h.in $(extra_headers) + gpg-error.def extra-h.in tmp_files = _mkerrcodes.h _gpg-error.def.h mkw32errmap.tab.h @@ -129,7 +131,7 @@ $(AWK) -f $(srcdir)/mkerrnos.awk $(srcdir)/errnos.in >$@ # It is correct to use $(CPP). We want the host's idea of the error codes. -mkerrcodes.h: Makefile mkerrcodes.awk $(extra_headers) +mkerrcodes.h: Makefile mkerrcodes.awk $(gpg_extra_headers) $(AWK) -f $(srcdir)/mkerrcodes1.awk $(srcdir)/errnos.in >_$@ $(CPP) $(extra_cppflags) _$@ | grep GPG_ERR_ | \ $(AWK) -f $(srcdir)/mkerrcodes.awk >$@ @@ -190,3 +192,14 @@ $(srcdir)/errnos.in \ extra-h.in \ $(srcdir)/gpg-error.h.in > $@ + + +install-data-local: +if HAVE_W32CE_SYSTEM + test -z "$(includedir)/gpg-extra" \ + || $(MKDIR_P) "$(DESTDIR)$(includedir)/gpg-extra" + $(INSTALL_DATA) gpg-extra/errno.h \ + "$(DESTDIR)$(includedir)/gpg-extra/errno.h" +else + : +endif From cvs at cvs.gnupg.org Wed Feb 17 18:08:04 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 17 Feb 2010 18:08:04 +0100 Subject: [svn] gpg-error - r233 - in trunk: . src Message-ID: Author: wk Date: 2010-02-17 18:08:04 +0100 (Wed, 17 Feb 2010) New Revision: 233 Removed: trunk/src/gpg-extra/ Modified: trunk/ChangeLog trunk/src/Makefile.am Log: Yet another try to make it work: We need to create the gpg-extra directory. With that we don't need to keep that directory in the repo. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2010-02-17 15:21:28 UTC (rev 232) +++ trunk/ChangeLog 2010-02-17 17:08:04 UTC (rev 233) @@ -6,6 +6,7 @@ extra_headers. (mkerrcodes.h): Depend on gpg_extra_headers. (install-data-local): New. + (gpg-extra/errno.h): Create gpg-extra dir if needed. 2010-02-17 Werner Koch Modified: trunk/src/Makefile.am =================================================================== --- trunk/src/Makefile.am 2010-02-17 15:21:28 UTC (rev 232) +++ trunk/src/Makefile.am 2010-02-17 17:08:04 UTC (rev 233) @@ -143,6 +143,7 @@ $(CPP) -DRESOLVE_MACROS $(srcdir)/mkw32errmap.c | \ grep '{&mkw32errmap_marker' >$@ gpg-extra/errno.h: mkw32errmap + -$(MKDIR_P) gpg-extra ./mkw32errmap > $@ endif @@ -196,8 +197,7 @@ install-data-local: if HAVE_W32CE_SYSTEM - test -z "$(includedir)/gpg-extra" \ - || $(MKDIR_P) "$(DESTDIR)$(includedir)/gpg-extra" + -$(MKDIR_P) "$(DESTDIR)$(includedir)/gpg-extra" $(INSTALL_DATA) gpg-extra/errno.h \ "$(DESTDIR)$(includedir)/gpg-extra/errno.h" else From cvs at cvs.gnupg.org Wed Feb 17 19:58:39 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 17 Feb 2010 19:58:39 +0100 Subject: [svn] pinentry - r216 - in trunk: . pinentry Message-ID: Author: wk Date: 2010-02-17 19:58:39 +0100 (Wed, 17 Feb 2010) New Revision: 216 Modified: trunk/ChangeLog trunk/pinentry/pinentry-curses.c trunk/pinentry/pinentry.c trunk/pinentry/pinentry.h Log: Provide default strings for ok and cancel in case a GUI wants it. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2010-02-16 19:05:59 UTC (rev 215) +++ trunk/ChangeLog 2010-02-17 18:58:39 UTC (rev 216) @@ -1,3 +1,11 @@ +2010-02-17 Werner Koch + + * pinentry/pinentry.h (struct pinentry): Add default_ok and + default_cancel. + * pinentry/pinentry.c (noprefix_strdup): New. + (option_handler): Support "default-ok" and "default-cancel". + (strcpy_escaped): Change second arg from unsigend char to char. + 2010-02-16 Werner Koch * qt4/document-encrypt.png, qt4/gtk-cancel.png, qt4/gtk-ok.png: New. Modified: trunk/pinentry/pinentry-curses.c =================================================================== --- trunk/pinentry/pinentry-curses.c 2010-02-16 19:05:59 UTC (rev 215) +++ trunk/pinentry/pinentry-curses.c 2010-02-17 18:58:39 UTC (rev 216) @@ -44,6 +44,9 @@ #include "pinentry.h" +/* FIXME: We should allow configuration of these button labels and in + any case use the default_ok, default_cancel values if available. + However, I have no clue about curses and localization. */ #define STRING_OK "" #define STRING_NOTOK "" #define STRING_CANCEL "" Modified: trunk/pinentry/pinentry.c =================================================================== --- trunk/pinentry/pinentry.c 2010-02-16 19:05:59 UTC (rev 215) +++ trunk/pinentry/pinentry.c 2010-02-17 18:58:39 UTC (rev 216) @@ -1,5 +1,5 @@ /* pinentry.c - The PIN entry support library - Copyright (C) 2002, 2003, 2007, 2008 g10 Code GmbH + Copyright (C) 2002, 2003, 2007, 2008, 2010 g10 Code GmbH This file is part of PINENTRY. @@ -80,7 +80,9 @@ PINENTRY_COLOR_DEFAULT, PINENTRY_COLOR_DEFAULT, 0, - NULL /* Assuan context. */ + NULL, /* default_ok */ + NULL, /* default_cancel */ + NULL /* Assuan context. */ }; @@ -578,6 +580,20 @@ } +static char * +noprefix_strdup (const char *string) +{ + const char *s; + + if (*string == '|' && (s = strchr (string+1, '|'))) + s++; + else + s = string; + + return strdup (s); +} + + static int option_handler (ASSUAN_CONTEXT ctx, const char *key, const char *value) { @@ -645,6 +661,18 @@ if (!pinentry.touch_file) return ASSUAN_Out_Of_Core; } + else if (!strcmp (key, "default-ok")) + { + pinentry.default_ok = noprefix_strdup (value); + if (!pinentry.default_ok) + return ASSUAN_Out_Of_Core; + } + else if (!strcmp (key, "default-cancel")) + { + pinentry.default_cancel = noprefix_strdup (value); + if (!pinentry.default_cancel) + return ASSUAN_Out_Of_Core; + } else return ASSUAN_Invalid_Option; return 0; @@ -654,7 +682,7 @@ /* Note, that it is sufficient to allocate the target string D as long as the source string S, i.e.: strlen(s)+1; */ static void -strcpy_escaped (char *d, const unsigned char *s) +strcpy_escaped (char *d, const char *s) { while (*s) { Modified: trunk/pinentry/pinentry.h =================================================================== --- trunk/pinentry/pinentry.h 2010-02-16 19:05:59 UTC (rev 215) +++ trunk/pinentry/pinentry.h 2010-02-17 18:58:39 UTC (rev 216) @@ -1,5 +1,5 @@ /* pinentry.h - The interface for the PIN entry support library. - Copyright (C) 2002, 2003 g10 Code GmbH + Copyright (C) 2002, 2003, 2010 g10 Code GmbH This file is part of PINENTRY. @@ -14,9 +14,8 @@ 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 */ + along with this program; if not, see . + */ #ifndef PINENTRY_H #define PINENTRY_H @@ -120,9 +119,16 @@ pinentry_color_t color_so; int color_so_bright; - /* Fo the quality indicator we need to do an inquiry. Thus we need + /* Malloced and i18ned default strings or NULL. These strings may + include an underscore character to indicate an accelerator + key. */ + char *default_ok; + char *default_cancel; + + /* For the quality indicator we need to do an inquiry. Thus we need to save the assuan ctx. */ void *ctx_assuan; + }; typedef struct pinentry *pinentry_t; From cvs at cvs.gnupg.org Wed Feb 17 20:00:04 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 17 Feb 2010 20:00:04 +0100 Subject: [svn] GnuPG - r5266 - in branches/STABLE-BRANCH-2-0: agent po Message-ID: Author: wk Date: 2010-02-17 20:00:04 +0100 (Wed, 17 Feb 2010) New Revision: 5266 Modified: branches/STABLE-BRANCH-2-0/agent/ChangeLog branches/STABLE-BRANCH-2-0/agent/call-pinentry.c branches/STABLE-BRANCH-2-0/po/POTFILES.in branches/STABLE-BRANCH-2-0/po/de.po Log: Provide default strings for pinentry. Modified: branches/STABLE-BRANCH-2-0/agent/ChangeLog =================================================================== --- branches/STABLE-BRANCH-2-0/agent/ChangeLog 2010-02-17 12:34:03 UTC (rev 5265) +++ branches/STABLE-BRANCH-2-0/agent/ChangeLog 2010-02-17 19:00:04 UTC (rev 5266) @@ -1,5 +1,10 @@ +2010-02-17 Werner Koch + + * call-pinentry.c (start_pinentry): Always free OPTSTR. Send + default-xxx strings. + 2010-02-11 Marcus Brinkmann - + From trunk 2009-09-23, 2009-11-02, 2009-11-04, 2009-11-05, 2009-11-25, 2009-12-08: Modified: branches/STABLE-BRANCH-2-0/agent/call-pinentry.c =================================================================== --- branches/STABLE-BRANCH-2-0/agent/call-pinentry.c 2010-02-17 12:34:03 UTC (rev 5265) +++ branches/STABLE-BRANCH-2-0/agent/call-pinentry.c 2010-02-17 19:00:04 UTC (rev 5266) @@ -1,5 +1,6 @@ -/* call-pinentry.c - fork of the pinentry to query stuff from the user - * Copyright (C) 2001, 2002, 2004, 2007, 2008 Free Software Foundation, Inc. +/* call-pinentry.c - Spawn the pinentry to query stuff from the user + * Copyright (C) 2001, 2002, 2004, 2007, 2008, + * 2010 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -361,6 +362,7 @@ return unlock_pinentry (out_of_core ()); rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL, NULL); + xfree (optstr); if (rc) return unlock_pinentry (rc); } @@ -371,6 +373,7 @@ return unlock_pinentry (out_of_core ()); rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL, NULL); + xfree (optstr); if (rc) return unlock_pinentry (rc); } @@ -381,10 +384,37 @@ return unlock_pinentry (out_of_core ()); rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL, NULL); + xfree (optstr); if (rc) return unlock_pinentry (rc); } + { + /* Provide a few default strings for use by the pinentries. This + may help a pinentry to avoid implementing localization code. */ + static struct { const char *key, *value; } tbl[] = { + /* TRANSLATORS: These are labels for buttons etc used in + Pinentries. A underscore indicates that the next letter + should be used as an accelerator. The actual to be + translated text starts after the second vertical bar. */ + { "ok", N_("|pinentry-label|_OK") }, + { "cancel", N_("|pinentry-label|_Cancel") }, + { NULL, NULL} + }; + char *optstr; + int idx; + + for (idx=0; tbl[idx].key; idx++) + { + if (asprintf (&optstr, "OPTION default-ok=%s", + tbl[idx].key, _(tbl[idx].value)) < 0 ) + return unlock_pinentry (out_of_core ()); + assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL, + NULL); + xfree (optstr); + } + } + /* Tell the pinentry the name of a file it shall touch after having messed with the tty. This is optional and only supported by @@ -923,7 +953,7 @@ if (notok) { /* Try to use the newer NOTOK feature if a cancel button is - requested. If no cacnel button is requested we keep on using + requested. If no cancel button is requested we keep on using the standard cancel. */ if (with_cancel) { Modified: branches/STABLE-BRANCH-2-0/po/POTFILES.in =================================================================== --- branches/STABLE-BRANCH-2-0/po/POTFILES.in 2010-02-17 12:34:03 UTC (rev 5265) +++ branches/STABLE-BRANCH-2-0/po/POTFILES.in 2010-02-17 19:00:04 UTC (rev 5266) @@ -9,6 +9,7 @@ agent/protect-tool.c agent/trustlist.c agent/findkey.c +agent/call-pinentry.c common/exechelp.c common/http.c Modified: branches/STABLE-BRANCH-2-0/po/de.po [not shown] From cvs at cvs.gnupg.org Wed Feb 17 20:03:38 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 17 Feb 2010 20:03:38 +0100 Subject: [svn] GnuPG - r5267 - trunk/agent Message-ID: Author: wk Date: 2010-02-17 20:03:37 +0100 (Wed, 17 Feb 2010) New Revision: 5267 Modified: trunk/agent/ChangeLog trunk/agent/call-pinentry.c Log: Provide default strings for the pinentry. Modified: trunk/agent/ChangeLog =================================================================== --- trunk/agent/ChangeLog 2010-02-17 19:00:04 UTC (rev 5266) +++ trunk/agent/ChangeLog 2010-02-17 19:03:37 UTC (rev 5267) @@ -1,3 +1,8 @@ +2010-02-17 Werner Koch + + * call-pinentry.c (start_pinentry): Always free OPTSTR. Send + default-xxx strings. + 2010-01-26 Werner Koch * protect.c (do_encryption): Encode the s2kcount and no not use a Modified: trunk/agent/call-pinentry.c =================================================================== --- trunk/agent/call-pinentry.c 2010-02-17 19:00:04 UTC (rev 5266) +++ trunk/agent/call-pinentry.c 2010-02-17 19:03:37 UTC (rev 5267) @@ -1,5 +1,6 @@ -/* call-pinentry.c - fork of the pinentry to query stuff from the user - * Copyright (C) 2001, 2002, 2004, 2007, 2008 Free Software Foundation, Inc. +/* call-pinentry.c - Spawn the pinentry to query stuff from the user + * Copyright (C) 2001, 2002, 2004, 2007, 2008, + * 2010 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -361,6 +362,7 @@ return unlock_pinentry (out_of_core ()); rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL, NULL); + xfree (optstr); if (rc) return unlock_pinentry (rc); } @@ -371,6 +373,7 @@ return unlock_pinentry (out_of_core ()); rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL, NULL); + xfree (optstr); if (rc) return unlock_pinentry (rc); } @@ -381,10 +384,37 @@ return unlock_pinentry (out_of_core ()); rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL, NULL); + xfree (optstr); if (rc) return unlock_pinentry (rc); } + { + /* Provide a few default strings for use by the pinentries. This + may help a pinentry to avoid implementing localization code. */ + static struct { const char *key, *value; } tbl[] = { + /* TRANSLATORS: These are labels for buttons etc used in + Pinentries. A underscore indicates that the next letter + should be used as an accelerator. The actual to be + translated text starts after the second vertical bar. */ + { "ok", N_("|pinentry-label|_OK") }, + { "cancel", N_("|pinentry-label|_Cancel") }, + { NULL, NULL} + }; + char *optstr; + int idx; + + for (idx=0; tbl[idx].key; idx++) + { + if (asprintf (&optstr, "OPTION default-ok=%s", + tbl[idx].key, _(tbl[idx].value)) < 0 ) + return unlock_pinentry (out_of_core ()); + assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL, + NULL); + xfree (optstr); + } + } + /* Tell the pinentry the name of a file it shall touch after having messed with the tty. This is optional and only supported by @@ -923,7 +953,7 @@ if (notok) { /* Try to use the newer NOTOK feature if a cancel button is - requested. If no cacnel button is requested we keep on using + requested. If no cancel button is requested we keep on using the standard cancel. */ if (with_cancel) { From cvs at cvs.gnupg.org Wed Feb 17 22:40:02 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 17 Feb 2010 22:40:02 +0100 Subject: [svn] gpgme - r1454 - trunk/src Message-ID: Author: wk Date: 2010-02-17 22:40:02 +0100 (Wed, 17 Feb 2010) New Revision: 1454 Modified: trunk/src/ChangeLog trunk/src/posix-io.c Log: Changed the close notify implementaion to allow for more than 256 fds. We should write a test case for it, though. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2010-02-16 20:07:03 UTC (rev 1453) +++ trunk/src/ChangeLog 2010-02-17 21:40:02 UTC (rev 1454) @@ -1,3 +1,10 @@ +2010-02-17 Werner Koch + + * posix-io.c (notify_table): Change implementation. + (notify_table_item_t, notify_table_size, notify_table_lock): New. + (_gpgme_io_close, _gpgme_io_set_close_notify): Adjust for new + implementation. + 2010-02-16 Werner Koch * gpgme-tool.c (spacep, has_option, skip_options): New. Modified: trunk/src/posix-io.c =================================================================== --- trunk/src/posix-io.c 2010-02-16 20:07:03 UTC (rev 1453) +++ trunk/src/posix-io.c 2010-02-17 21:40:02 UTC (rev 1454) @@ -1,6 +1,6 @@ /* posix-io.c - Posix I/O functions Copyright (C) 2000 Werner Koch (dd9jn) - Copyright (C) 2001, 2002, 2004, 2005, 2007 g10 Code GmbH + Copyright (C) 2001, 2002, 2004, 2005, 2007, 2010 g10 Code GmbH This file is part of GPGME. @@ -15,9 +15,8 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser 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. */ + License along with this program; if not, see . + */ #ifdef HAVE_CONFIG_H #include @@ -73,13 +72,22 @@ } -static struct +/* The table to hold notification handlers. We use a linear search + and extend the table as needed. */ +struct notify_table_item_s { + int fd; /* -1 indicates an unused entry. */ _gpgme_close_notify_handler_t handler; void *value; -} notify_table[256]; +}; +typedef struct notify_table_item_s *notify_table_item_t; +static notify_table_item_t notify_table; +static size_t notify_table_size; +DEFINE_STATIC_LOCK (notify_table_lock); + + int _gpgme_io_read (int fd, void *buffer, size_t count) { @@ -149,6 +157,9 @@ _gpgme_io_close (int fd) { int res; + _gpgme_close_notify_handler_t handler = NULL; + void *handler_value; + int idx; TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_close", fd); @@ -159,17 +170,26 @@ } /* First call the notify handler. */ - if (fd >= 0 && fd < (int) DIM (notify_table)) + LOCK (notify_table_lock); + for (idx=0; idx < notify_table_size; idx++) { - if (notify_table[fd].handler) - { - TRACE_LOG2 ("invoking close handler %p/%p", - notify_table[fd].handler, notify_table[fd].value); - notify_table[fd].handler (fd, notify_table[fd].value); - notify_table[fd].handler = NULL; - notify_table[fd].value = NULL; + if (notify_table[idx].fd == fd) + { + handler = notify_table[idx].handler; + handler_value = notify_table[idx].value; + notify_table[idx].handler = NULL; + notify_table[idx].value = NULL; + notify_table[idx].fd = -1; /* Mark slot as free. */ + break; } } + UNLOCK (notify_table_lock); + if (handler) + { + TRACE_LOG2 ("invoking close handler %p/%p", handler, handler_value); + handler (fd, handler_value); + } + /* Then do the close. */ res = close (fd); return TRACE_SYSRES (res); @@ -180,19 +200,52 @@ _gpgme_io_set_close_notify (int fd, _gpgme_close_notify_handler_t handler, void *value) { + int res = 0; + int idx; + TRACE_BEG2 (DEBUG_SYSIO, "_gpgme_io_set_close_notify", fd, "close_handler=%p/%p", handler, value); assert (fd != -1); + + LOCK (notify_table_lock); + for (idx=0; idx < notify_table_size; idx++) + if (notify_table[idx].fd == -1) + break; + if (idx == notify_table_size) + { + /* We need to increase the size of the table. The approach we + take is straightforward to minimize the risk of bugs. */ + notify_table_item_t newtbl; + size_t newsize = notify_table_size + 64; - if (fd < 0 || fd >= (int) DIM (notify_table)) - { - errno = EINVAL; - return TRACE_SYSRES (-1); + newtbl = calloc (newsize, sizeof *newtbl); + if (!newtbl) + { + res = -1; + goto leave; + } + for (idx=0; idx < notify_table_size; idx++) + newtbl[idx] = notify_table[idx]; + for (; idx < newsize; idx++) + { + newtbl[idx].fd = -1; + newtbl[idx].handler = NULL; + newtbl[idx].value = NULL; + } + free (notify_table); + notify_table = newtbl; + idx = notify_table_size; + notify_table_size = newsize; } - notify_table[fd].handler = handler; - notify_table[fd].value = value; - return TRACE_SYSRES (0); + notify_table[idx].fd = fd; + notify_table[idx].handler = handler; + notify_table[idx].value = value; + + leave: + UNLOCK (notify_table_lock); + + return TRACE_SYSRES (res); } From cvs at cvs.gnupg.org Thu Feb 18 10:52:33 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 18 Feb 2010 10:52:33 +0100 Subject: [svn] GnuPG - r5268 - in branches/STABLE-BRANCH-2-0: . po Message-ID: Author: wk Date: 2010-02-18 10:52:28 +0100 (Thu, 18 Feb 2010) New Revision: 5268 Modified: branches/STABLE-BRANCH-2-0/ChangeLog branches/STABLE-BRANCH-2-0/NEWS branches/STABLE-BRANCH-2-0/README branches/STABLE-BRANCH-2-0/configure.ac branches/STABLE-BRANCH-2-0/po/be.po branches/STABLE-BRANCH-2-0/po/ca.po branches/STABLE-BRANCH-2-0/po/cs.po branches/STABLE-BRANCH-2-0/po/da.po branches/STABLE-BRANCH-2-0/po/de.po branches/STABLE-BRANCH-2-0/po/el.po branches/STABLE-BRANCH-2-0/po/eo.po branches/STABLE-BRANCH-2-0/po/es.po branches/STABLE-BRANCH-2-0/po/et.po branches/STABLE-BRANCH-2-0/po/fi.po branches/STABLE-BRANCH-2-0/po/fr.po branches/STABLE-BRANCH-2-0/po/gl.po branches/STABLE-BRANCH-2-0/po/hu.po branches/STABLE-BRANCH-2-0/po/id.po branches/STABLE-BRANCH-2-0/po/it.po branches/STABLE-BRANCH-2-0/po/ja.po branches/STABLE-BRANCH-2-0/po/nb.po branches/STABLE-BRANCH-2-0/po/pl.po branches/STABLE-BRANCH-2-0/po/pt.po branches/STABLE-BRANCH-2-0/po/pt_BR.po branches/STABLE-BRANCH-2-0/po/ro.po branches/STABLE-BRANCH-2-0/po/ru.po branches/STABLE-BRANCH-2-0/po/sk.po branches/STABLE-BRANCH-2-0/po/sv.po branches/STABLE-BRANCH-2-0/po/tr.po branches/STABLE-BRANCH-2-0/po/zh_CN.po branches/STABLE-BRANCH-2-0/po/zh_TW.po Log: preparing a release candidate Modified: branches/STABLE-BRANCH-2-0/ChangeLog =================================================================== --- branches/STABLE-BRANCH-2-0/ChangeLog 2010-02-17 19:03:37 UTC (rev 5267) +++ branches/STABLE-BRANCH-2-0/ChangeLog 2010-02-18 09:52:28 UTC (rev 5268) @@ -1,3 +1,9 @@ +2010-02-18 Werner Koch + + Release 2.0.15rc1. + + * configure.ac: Remove double check for libassuan. + 2010-02-11 Marcus Brinkmann From trunk 2009-10-16: Modified: branches/STABLE-BRANCH-2-0/NEWS =================================================================== --- branches/STABLE-BRANCH-2-0/NEWS 2010-02-17 19:03:37 UTC (rev 5267) +++ branches/STABLE-BRANCH-2-0/NEWS 2010-02-18 09:52:28 UTC (rev 5268) @@ -6,7 +6,9 @@ * Fixes a regression in 2.0.14 which prevented unprotection of new or changed gpg-agent passphrases. + * Make use of libassuan 2.0 which is available as a DSO. + Noteworthy changes in version 2.0.14 (2009-12-21) ------------------------------------------------- Modified: branches/STABLE-BRANCH-2-0/README =================================================================== --- branches/STABLE-BRANCH-2-0/README 2010-02-17 19:03:37 UTC (rev 5267) +++ branches/STABLE-BRANCH-2-0/README 2010-02-18 09:52:28 UTC (rev 5268) @@ -2,8 +2,8 @@ ========================= Version 2.0 - Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, - 2006, 2007, 2008, 2009 Free Software Foundation, Inc. + Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, + 2007, 2008, 2009, 2010 Free Software Foundation, Inc. INTRODUCTION @@ -31,10 +31,10 @@ GnuPG 2.0 depends on the following packages: - libgpg-error (ftp://ftp.gnupg.org/gcrypt/libgpg-error/) - libgcrypt (ftp://ftp.gnupg.org/gcrypt/libgcrypt/) - libksba (ftp://ftp.gnupg.org/gcrypt/libksba/) - libassuan < 2.0 (ftp://ftp.gnupg.org/gcrypt/libassuan/) + libgpg-error (ftp://ftp.gnupg.org/gcrypt/libgpg-error/) + libgcrypt (ftp://ftp.gnupg.org/gcrypt/libgcrypt/) + libksba (ftp://ftp.gnupg.org/gcrypt/libksba/) + libassuan >= 2.0 (ftp://ftp.gnupg.org/gcrypt/libassuan/) You also need the Pinentry package for most function of GnuPG; however it is not a build requirement. Pinentry is available at Modified: branches/STABLE-BRANCH-2-0/configure.ac =================================================================== --- branches/STABLE-BRANCH-2-0/configure.ac 2010-02-17 19:03:37 UTC (rev 5267) +++ branches/STABLE-BRANCH-2-0/configure.ac 2010-02-18 09:52:28 UTC (rev 5268) @@ -1,6 +1,6 @@ # configure.ac - for GnuPG 2.0 # Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, -# 2006, 2007, 2008 Free Software Foundation, Inc. +# 2006, 2007, 2008, 2010 Free Software Foundation, Inc. # # This file is part of GnuPG. # @@ -24,8 +24,8 @@ # Remember to change the version number immediately *after* a release. # Set my_issvn to "yes" for non-released code. Remember to run an # "svn up" and "autogen.sh" right before creating a distribution. -m4_define([my_version], [2.0.15]) -m4_define([my_issvn], [yes]) +m4_define([my_version], [2.0.15rc1]) +m4_define([my_issvn], [no]) m4_define([svn_revision], m4_esyscmd([printf "%d" $(svn info 2>/dev/null \ | sed -n '/^Revision:/ s/[^0-9]//gp'|head -1)])) @@ -43,7 +43,7 @@ NEED_LIBGCRYPT_VERSION=1.4.0 NEED_LIBASSUAN_API=2 -NEED_LIBASSUAN_VERSION=1.1.0 +NEED_LIBASSUAN_VERSION=2.0.0 NEED_KSBA_API=1 NEED_KSBA_VERSION=1.0.2 @@ -613,9 +613,6 @@ AM_PATH_LIBASSUAN("$NEED_LIBASSUAN_API:$NEED_LIBASSUAN_VERSION", have_libassuan=yes,have_libassuan=no) if test "$have_libassuan" = "yes"; then - have_libassuan=no - AM_PATH_LIBASSUAN("$NEED_LIBASSUAN_API:$NEED_LIBASSUAN_VERSION", - have_libassuan=yes,have_libassuan=no) AC_DEFINE_UNQUOTED(GNUPG_LIBASSUAN_VERSION, "$libassuan_version", [version of the libbassuan library]) fi Modified: branches/STABLE-BRANCH-2-0/po/be.po [not shown] Modified: branches/STABLE-BRANCH-2-0/po/ca.po [not shown] Modified: branches/STABLE-BRANCH-2-0/po/cs.po [not shown] Modified: branches/STABLE-BRANCH-2-0/po/da.po [not shown] Modified: branches/STABLE-BRANCH-2-0/po/de.po [not shown] Modified: branches/STABLE-BRANCH-2-0/po/el.po [not shown] Modified: branches/STABLE-BRANCH-2-0/po/eo.po [not shown] Modified: branches/STABLE-BRANCH-2-0/po/es.po [not shown] Modified: branches/STABLE-BRANCH-2-0/po/et.po [not shown] Modified: branches/STABLE-BRANCH-2-0/po/fi.po [not shown] Modified: branches/STABLE-BRANCH-2-0/po/fr.po [not shown] Modified: branches/STABLE-BRANCH-2-0/po/gl.po [not shown] Modified: branches/STABLE-BRANCH-2-0/po/hu.po [not shown] Modified: branches/STABLE-BRANCH-2-0/po/id.po [not shown] Modified: branches/STABLE-BRANCH-2-0/po/it.po [not shown] Modified: branches/STABLE-BRANCH-2-0/po/ja.po [not shown] Modified: branches/STABLE-BRANCH-2-0/po/nb.po [not shown] Modified: branches/STABLE-BRANCH-2-0/po/pl.po [not shown] Modified: branches/STABLE-BRANCH-2-0/po/pt.po [not shown] Modified: branches/STABLE-BRANCH-2-0/po/pt_BR.po [not shown] Modified: branches/STABLE-BRANCH-2-0/po/ro.po [not shown] Modified: branches/STABLE-BRANCH-2-0/po/ru.po [not shown] Modified: branches/STABLE-BRANCH-2-0/po/sk.po [not shown] Modified: branches/STABLE-BRANCH-2-0/po/sv.po [not shown] Modified: branches/STABLE-BRANCH-2-0/po/tr.po [not shown] Modified: branches/STABLE-BRANCH-2-0/po/zh_CN.po [not shown] Modified: branches/STABLE-BRANCH-2-0/po/zh_TW.po [not shown] From cvs at cvs.gnupg.org Thu Feb 18 11:45:01 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 18 Feb 2010 11:45:01 +0100 Subject: [svn] GnuPG - r5269 - branches/STABLE-BRANCH-2-0/agent Message-ID: Author: wk Date: 2010-02-18 11:45:01 +0100 (Thu, 18 Feb 2010) New Revision: 5269 Modified: branches/STABLE-BRANCH-2-0/agent/ChangeLog branches/STABLE-BRANCH-2-0/agent/call-pinentry.c branches/STABLE-BRANCH-2-0/agent/command.c branches/STABLE-BRANCH-2-0/agent/protect.c Log: Fixed backport of libassuan-2 changes. Modified: branches/STABLE-BRANCH-2-0/agent/ChangeLog =================================================================== --- branches/STABLE-BRANCH-2-0/agent/ChangeLog 2010-02-18 09:52:28 UTC (rev 5268) +++ branches/STABLE-BRANCH-2-0/agent/ChangeLog 2010-02-18 10:45:01 UTC (rev 5269) @@ -1,3 +1,11 @@ +2010-02-18 Werner Koch + + * protect.c (agent_unprotect): Initialize CLEARTEXT. + + * command.c (register_commands): Unconditionally use + assuan_register_post_cmd_notify. + (start_command_handler): Undocumented use assuan_set_io_monitor. + 2010-02-17 Werner Koch * call-pinentry.c (start_pinentry): Always free OPTSTR. Send Modified: branches/STABLE-BRANCH-2-0/agent/call-pinentry.c =================================================================== --- branches/STABLE-BRANCH-2-0/agent/call-pinentry.c 2010-02-18 09:52:28 UTC (rev 5268) +++ branches/STABLE-BRANCH-2-0/agent/call-pinentry.c 2010-02-18 10:45:01 UTC (rev 5269) @@ -406,7 +406,7 @@ for (idx=0; tbl[idx].key; idx++) { - if (asprintf (&optstr, "OPTION default-ok=%s", + if (asprintf (&optstr, "OPTION default-%s=%s", tbl[idx].key, _(tbl[idx].value)) < 0 ) return unlock_pinentry (out_of_core ()); assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL, Modified: branches/STABLE-BRANCH-2-0/agent/command.c =================================================================== --- branches/STABLE-BRANCH-2-0/agent/command.c 2010-02-18 09:52:28 UTC (rev 5268) +++ branches/STABLE-BRANCH-2-0/agent/command.c 2010-02-18 10:45:01 UTC (rev 5269) @@ -1897,9 +1897,7 @@ if (rc) return rc; } -#ifdef HAVE_ASSUAN_SET_IO_MONITOR assuan_register_post_cmd_notify (ctx, post_cmd_notify); -#endif assuan_register_reset_notify (ctx, reset_notify); assuan_register_option_handler (ctx, option_handler); return 0; @@ -1962,9 +1960,7 @@ ctrl->server_local->use_cache_for_signing = 1; ctrl->digest.raw_value = 0; -#ifdef HAVE_ASSUAN_SET_IO_MONITOR assuan_set_io_monitor (ctx, io_monitor, NULL); -#endif for (;;) { Modified: branches/STABLE-BRANCH-2-0/agent/protect.c =================================================================== --- branches/STABLE-BRANCH-2-0/agent/protect.c 2010-02-18 09:52:28 UTC (rev 5268) +++ branches/STABLE-BRANCH-2-0/agent/protect.c 2010-02-18 10:45:01 UTC (rev 5269) @@ -778,7 +778,7 @@ unsigned long s2kcount; const unsigned char *iv; const unsigned char *prot_begin; - unsigned char *cleartext; + unsigned char *cleartext = NULL; /* Just to avoid gcc warning. */ unsigned char *final; size_t finallen; size_t cutoff, cutlen; From cvs at cvs.gnupg.org Thu Feb 18 11:56:12 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 18 Feb 2010 11:56:12 +0100 Subject: [svn] GnuPG - r5270 - tags Message-ID: Author: wk Date: 2010-02-18 11:56:12 +0100 (Thu, 18 Feb 2010) New Revision: 5270 Added: tags/gnupg-2.0.15rc1/ Log: Release tag From cvs at cvs.gnupg.org Fri Feb 19 13:14:24 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 19 Feb 2010 13:14:24 +0100 Subject: [svn] pinentry - r217 - in trunk: . doc gtk+-2 pinentry Message-ID: Author: wk Date: 2010-02-19 13:14:23 +0100 (Fri, 19 Feb 2010) New Revision: 217 Modified: trunk/ChangeLog trunk/doc/pinentry.texi trunk/gtk+-2/pinentry-gtk-2.c trunk/pinentry/pinentry.c trunk/pinentry/pinentry.h Log: Implement a default-prompt option. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2010-02-17 18:58:39 UTC (rev 216) +++ trunk/ChangeLog 2010-02-19 12:14:23 UTC (rev 217) @@ -1,3 +1,12 @@ +2010-02-19 Werner Koch + + * gtk+-2/pinentry-gtk-2.c (create_window): Allow mnemonics in + button labels. + + * pinentry/pinentry.h (struct pinentry): Add default_prompt. + * pinentry/pinentry.c (option_handler): Support "default-prompt". + (cmd_getpin): Use it. + 2010-02-17 Werner Koch * pinentry/pinentry.h (struct pinentry): Add default_ok and Modified: trunk/doc/pinentry.texi =================================================================== --- trunk/doc/pinentry.texi 2010-02-17 18:58:39 UTC (rev 216) +++ trunk/doc/pinentry.texi 2010-02-19 12:14:23 UTC (rev 217) @@ -203,7 +203,6 @@ by some background process which does not have any information on the locale and terminal to use. Assuan protocol options are an alternative way to pass these information. - @end table @c @@ -251,6 +250,12 @@ S: OK @end example +You should use an underscore in the text only if you known that a modern +version of pinentry is used. Modern versions underline the next +character after the underscore and use the first such underlined +character as a keyboard accelerator. Use a double underscore to escape +an underscore. + @item Set the window title This command may be used to change the default window title. When using this feature you should take care that the window is still @@ -261,21 +266,36 @@ @end example @item Set the button texts -There are two text with can be set to override the English defaults: +There are three texts which should be used to override the English +defaults: To set the text for the button signaling confirmation (in UTF-8). +See SETPROMPT on how to use an keyboard accelerator. @example C: SETOK Yes S: OK @end example + To set the text for the button signaling cancellation or disagreement -(in UTF-8). +(in UTF-8). See SETPROMPT on how to use an keyboard accelerator. @example C: SETCANCEL No S: OK @end example + +In case tree buttons are required, use the follwing command to set the +text (UTF-8) for the non-affirmative response button. The affirmative button +text is still set using SETOK and the CANCEL button text with SETCANCEL. +See SETPROMPT on how to use an keyboard accelerator. + at example + C: SETNOTOK Do not do this + S: OK + at end example + + + @item Set the Error text This is used by the client to display an error message. In contrast to the other commands this error message is automatically reset with @@ -368,6 +388,22 @@ appropriate for this tty and @code{lc-ctype} to the locale which defines the character set to use for this terminal. + at item Set the default strings +To avoid having transaltions in Pinentry proper, the caller may set +certain translated strings which are used by Pinentry as default +strings. + + at example + C: OPTION default-ok=_Korrekt + S: OK + C: OPTION default-cancel=Abbruch + S: OK + C: OPTION default-prompt=PIN eingeben: + S: OK + at end example +The strings are subject to accelerator marking, see SETPROMPT for +details. + @end table @c --------------------------------------------------------------------- Modified: trunk/gtk+-2/pinentry-gtk-2.c =================================================================== --- trunk/gtk+-2/pinentry-gtk-2.c 2010-02-17 18:58:39 UTC (rev 216) +++ trunk/gtk+-2/pinentry-gtk-2.c 2010-02-19 12:14:23 UTC (rev 217) @@ -58,8 +58,10 @@ static GtkWidget *entry; static GtkWidget *qualitybar; +#ifdef ENABLE_ENHANCED static GtkWidget *insure; static GtkWidget *time_out; +#endif static GtkTooltips *tooltips; /* Gnome hig small and large space in pixels. */ @@ -67,10 +69,10 @@ #define HIG_LARGE 12 /* The text shown in the quality bar when no text is shown. This is not - * the empty string, becase because with an empty string the height of + * the empty string, because with an empty string the height of * the quality bar is less than with a non-empty string. This results * in ugly layout changes when the text changes from non-empty to empty - * and vice versa */ + * and vice versa. */ #define QUALITYBAR_EMPTY_TEXT " " @@ -360,7 +362,7 @@ if (pinentry->prompt) { msg = pinentry_utf8_validate (pinentry->prompt); - w = gtk_label_new (msg); + w = gtk_label_new_with_mnemonic (msg); g_free (msg); gtk_misc_set_alignment (GTK_MISC (w), 1.0, 0.5); gtk_table_attach (GTK_TABLE (table), w, 0, 1, 0, 1, @@ -438,7 +440,7 @@ if (pinentry->cancel) { msg = pinentry_utf8_validate (pinentry->cancel); - w = gtk_button_new_with_label (msg); + w = gtk_button_new_with_mnemonic (msg); g_free (msg); } else @@ -454,7 +456,7 @@ if (confirm_mode && !pinentry->one_button && pinentry->notok) { msg = pinentry_utf8_validate (pinentry->notok); - w = gtk_button_new_with_label (msg); + w = gtk_button_new_with_mnemonic (msg); g_free (msg); gtk_container_add (GTK_CONTAINER (bbox), w); @@ -467,7 +469,7 @@ if (pinentry->ok) { msg = pinentry_utf8_validate (pinentry->ok); - w = gtk_button_new_with_label (msg); + w = gtk_button_new_with_mnemonic (msg); g_free (msg); } else Modified: trunk/pinentry/pinentry.c =================================================================== --- trunk/pinentry/pinentry.c 2010-02-17 18:58:39 UTC (rev 216) +++ trunk/pinentry/pinentry.c 2010-02-19 12:14:23 UTC (rev 217) @@ -82,6 +82,7 @@ 0, NULL, /* default_ok */ NULL, /* default_cancel */ + NULL, /* default_prompt */ NULL /* Assuan context. */ }; @@ -673,6 +674,12 @@ if (!pinentry.default_cancel) return ASSUAN_Out_Of_Core; } + else if (!strcmp (key, "default-prompt")) + { + pinentry.default_prompt = noprefix_strdup (value); + if (!pinentry.default_prompt) + return ASSUAN_Out_Of_Core; + } else return ASSUAN_Invalid_Option; return 0; @@ -870,7 +877,7 @@ return ASSUAN_Out_Of_Core; if (!pinentry.prompt) { - pinentry.prompt = "PIN:"; + pinentry.prompt = pinentry.default_prompt?pinentry.default_prompt:"PIN:"; set_prompt = 1; } pinentry.locale_err = 0; Modified: trunk/pinentry/pinentry.h =================================================================== --- trunk/pinentry/pinentry.h 2010-02-17 18:58:39 UTC (rev 216) +++ trunk/pinentry/pinentry.h 2010-02-19 12:14:23 UTC (rev 217) @@ -120,10 +120,11 @@ int color_so_bright; /* Malloced and i18ned default strings or NULL. These strings may - include an underscore character to indicate an accelerator - key. */ + include an underscore character to indicate an accelerator key. + A double underscore represents a plain one. */ char *default_ok; char *default_cancel; + char *default_prompt; /* For the quality indicator we need to do an inquiry. Thus we need to save the assuan ctx. */ From cvs at cvs.gnupg.org Fri Feb 19 13:18:30 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 19 Feb 2010 13:18:30 +0100 Subject: [svn] pinentry - r218 - in trunk: . pinentry Message-ID: Author: wk Date: 2010-02-19 13:18:30 +0100 (Fri, 19 Feb 2010) New Revision: 218 Modified: trunk/ChangeLog trunk/pinentry/pinentry.c Log: Do not remove a gettext marker prefix. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2010-02-19 12:14:23 UTC (rev 217) +++ trunk/ChangeLog 2010-02-19 12:18:30 UTC (rev 218) @@ -6,6 +6,7 @@ * pinentry/pinentry.h (struct pinentry): Add default_prompt. * pinentry/pinentry.c (option_handler): Support "default-prompt". (cmd_getpin): Use it. + (noprefix_strdup): Remove; should be done by caller. 2010-02-17 Werner Koch Modified: trunk/pinentry/pinentry.c =================================================================== --- trunk/pinentry/pinentry.c 2010-02-19 12:14:23 UTC (rev 217) +++ trunk/pinentry/pinentry.c 2010-02-19 12:18:30 UTC (rev 218) @@ -581,20 +581,6 @@ } -static char * -noprefix_strdup (const char *string) -{ - const char *s; - - if (*string == '|' && (s = strchr (string+1, '|'))) - s++; - else - s = string; - - return strdup (s); -} - - static int option_handler (ASSUAN_CONTEXT ctx, const char *key, const char *value) { @@ -664,19 +650,19 @@ } else if (!strcmp (key, "default-ok")) { - pinentry.default_ok = noprefix_strdup (value); + pinentry.default_ok = strdup (value); if (!pinentry.default_ok) return ASSUAN_Out_Of_Core; } else if (!strcmp (key, "default-cancel")) { - pinentry.default_cancel = noprefix_strdup (value); + pinentry.default_cancel = strdup (value); if (!pinentry.default_cancel) return ASSUAN_Out_Of_Core; } else if (!strcmp (key, "default-prompt")) { - pinentry.default_prompt = noprefix_strdup (value); + pinentry.default_prompt = strdup (value); if (!pinentry.default_prompt) return ASSUAN_Out_Of_Core; } From cvs at cvs.gnupg.org Fri Feb 19 13:25:14 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 19 Feb 2010 13:25:14 +0100 Subject: [svn] GnuPG - r5271 - branches/STABLE-BRANCH-2-0/agent Message-ID: Author: wk Date: 2010-02-19 13:25:13 +0100 (Fri, 19 Feb 2010) New Revision: 5271 Modified: branches/STABLE-BRANCH-2-0/agent/ChangeLog branches/STABLE-BRANCH-2-0/agent/call-pinentry.c Log: Remove ranslation prefixes and add default-prompt. Modified: branches/STABLE-BRANCH-2-0/agent/ChangeLog =================================================================== --- branches/STABLE-BRANCH-2-0/agent/ChangeLog 2010-02-18 10:56:12 UTC (rev 5270) +++ branches/STABLE-BRANCH-2-0/agent/ChangeLog 2010-02-19 12:25:13 UTC (rev 5271) @@ -1,3 +1,7 @@ +2010-02-19 Werner Koch + + * call-pinentry.c (start_pinentry): Remove a translation prefix. + 2010-02-18 Werner Koch * protect.c (agent_unprotect): Initialize CLEARTEXT. Modified: branches/STABLE-BRANCH-2-0/agent/call-pinentry.c =================================================================== --- branches/STABLE-BRANCH-2-0/agent/call-pinentry.c 2010-02-18 10:56:12 UTC (rev 5270) +++ branches/STABLE-BRANCH-2-0/agent/call-pinentry.c 2010-02-19 12:25:13 UTC (rev 5271) @@ -394,20 +394,25 @@ may help a pinentry to avoid implementing localization code. */ static struct { const char *key, *value; } tbl[] = { /* TRANSLATORS: These are labels for buttons etc used in - Pinentries. A underscore indicates that the next letter - should be used as an accelerator. The actual to be - translated text starts after the second vertical bar. */ + Pinentries. An underscore indicates that the next letter + should be used as an accelerator. Double the underscore for + a literal one. The actual to be translated text starts after + the second vertical bar. */ { "ok", N_("|pinentry-label|_OK") }, { "cancel", N_("|pinentry-label|_Cancel") }, + { "prompt", N_("|pinentry-label|PIN:") }, { NULL, NULL} }; char *optstr; int idx; + const char *s, *s2; for (idx=0; tbl[idx].key; idx++) { - if (asprintf (&optstr, "OPTION default-%s=%s", - tbl[idx].key, _(tbl[idx].value)) < 0 ) + s = _(tbl[idx].value); + if (*s == '|' && (s2=strchr (s+1,'|'))) + s = s2+1; + if (asprintf (&optstr, "OPTION default-%s=%s", tbl[idx].key, s) < 0 ) return unlock_pinentry (out_of_core ()); assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL, NULL); From cvs at cvs.gnupg.org Fri Feb 19 16:07:24 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 19 Feb 2010 16:07:24 +0100 Subject: [svn] pinentry - r219 - in trunk: . qt4 Message-ID: Author: wk Date: 2010-02-19 16:07:24 +0100 (Fri, 19 Feb 2010) New Revision: 219 Added: trunk/qt4/pinentry.qrc trunk/qt4/qrc_pinentry.cpp Removed: trunk/qt4/gtk-cancel.png trunk/qt4/gtk-ok.png Modified: trunk/ChangeLog trunk/qt4/Makefile.am trunk/qt4/main.cpp trunk/qt4/pinentrydialog.cpp trunk/qt4/pinentrydialog.h trunk/qt4/pinentrydialog.moc trunk/qt4/qsecurelineedit.moc Log: Applied MArc's payches. The QT2 Version does ow uild on GNU. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2010-02-19 12:18:30 UTC (rev 218) +++ trunk/ChangeLog 2010-02-19 15:07:24 UTC (rev 219) @@ -1,3 +1,52 @@ +2010-02-19 Marc Mutz (wk) + + * qt4/main.cpp (qt_cmd_handler), qt4/pinentrydialog.cpp + (PinentryDialog::PinEntryDialog): Use the button icons that come + with Qt. + + * qt4/pinentry_qrc, qt4/qrc_pinentry.cpp: New. + * qt4/gtk-cancel.png, qt4/gtk-ok.png: Removed. + * qt4/Makefile.am (EXTRA_DIST): Remove the GTK icons, add + pinentry.qrc. + (pinentry_qt4_SOURCES): add qrc_pinentry.cpp. + + * qt4/main.cpp (qt_cmd_handler): Remove i18n support again. + + * qt4/pinentrydialog.cpp (PinentryDialog::PinentryDialog): + set PIN entry field as buddy of its prompt + + * qt4/main.cpp (escape_accel): New. + (qt_cmd_handler): use it on default_cancel, default_ok, prompt. + + * qt4/pinentrydialog.h, qt4/pinentrydialog.cpp + (PinEntryDialog::PinEntryDialog): don't use a nested vbox layout. + + * qt4/pinentrydialog.h: replace include file with forward decl. + * qt4/pinentrydialog.cpp: add include file here. + + * qt4/pinentrydialog.h, qt4/pinentrydialog.cpp + (PinentryDialog::keyPressEvent()): Removed. + + * qt/4pinentrydialog.cpp (PinEntryDialog::PinEntryDialog): use + QLayout::SetFixedSize instead of rolling our own solution. + * qt4/pinentrydialog.h: (PinentryDialog::setFixedSize): Removed. + * qt4/pinentrydialog.moc: Re-created. + + * qt4/main.cpp: (qt_cmd_handler) make Cancel the default button + for CONFIRM + + * qt4/main.cpp: (qt_cmd_handler) implement the confirm/message + logic correctly + + * qt4/pinentrydialog.h (accepted, rejected): Removed; already + provided by base class. + * qt4/pinentrydialog.cpp (PinEntryDialog::PinEntryDialog): Use + QDialog::{accepted,rejected}. + * qt4/pinentrydialog.moc: Re-created. + + * qt4/pinentrydialog.moc, qt4/qsecurelineedit.moc: Make compatible + with newer Qt version. + 2010-02-19 Werner Koch * gtk+-2/pinentry-gtk-2.c (create_window): Allow mnemonics in Modified: trunk/qt4/Makefile.am =================================================================== --- trunk/qt4/Makefile.am 2010-02-19 12:18:30 UTC (rev 218) +++ trunk/qt4/Makefile.am 2010-02-19 15:07:24 UTC (rev 219) @@ -22,7 +22,7 @@ bin_PROGRAMS = pinentry-qt4 -EXTRA_DIST = document-encrypt.png gtk-cancel.png gtk-ok.png +EXTRA_DIST = document-encrypt.png pinentry.qrc if FALLBACK_CURSES @@ -44,4 +44,5 @@ pinentry_qt4_SOURCES = pinentrydialog.h pinentrydialog.cpp \ main.cpp secstring.h secstring.cpp qsecurelineedit.h \ qsecurelineedit.cpp pinentrydialog.moc qsecurelineedit.moc \ + qrc_pinentry.cpp \ qsecurelineedit_p.h Deleted: trunk/qt4/gtk-cancel.png Deleted: trunk/qt4/gtk-ok.png Modified: trunk/qt4/main.cpp =================================================================== --- trunk/qt4/main.cpp 2010-02-19 12:18:30 UTC (rev 218) +++ trunk/qt4/main.cpp 2010-02-19 15:07:24 UTC (rev 219) @@ -36,9 +36,6 @@ #include #include #include -#include -#include -#include #include #include @@ -51,6 +48,44 @@ #include #endif +static QString escape_accel( const QString & s ) { + + QString result; + result.reserve( s.size() ); + + bool afterUnderscore = false; + + for ( unsigned int i = 0, end = s.size() ; i != end ; ++i ) { + const QChar ch = s[i]; + if ( ch == QLatin1Char( '_' ) ) + { + if ( afterUnderscore ) // escaped _ + { + result += QLatin1Char( '_' ); + afterUnderscore = false; + } + else // accel + { + afterUnderscore = true; + } + } + else + { + if ( afterUnderscore || // accel + ch == QLatin1Char( '&' ) ) // escape & from being interpreted by Qt + result += QLatin1Char( '&' ); + result += ch; + afterUnderscore = false; + } + } + + if ( afterUnderscore ) + // trailing single underscore: shouldn't happen, but deal with it robustly: + result += QLatin1Char( '_' ); + + return result; +} + /* Hack for creating a QWidget with a "foreign" window ID */ class ForeignWidget : public QWidget { @@ -72,23 +107,31 @@ { QWidget *parent = 0; - QTranslator trans; - const QString lang = pe->lc_messages ? QString::fromLatin1 (pe->lc_messages) : QLocale ().name () ; - if( trans.load (QString::fromLatin1(":/qt_%1").arg(lang)) ) - qApp->installTranslator (&trans); - /* FIXME: Add parent window ID to pinentry and GTK. */ if (pe->parent_wid) parent = new ForeignWidget ((WId) pe->parent_wid); int want_pass = !!pe->pin; + const QString ok = + pe->ok ? QString::fromUtf8( pe->ok ) : + pe->default_ok ? escape_accel( QString::fromUtf8( pe->default_ok ) ) : + /* else */ QLatin1String( "&OK" ) ; + const QString cancel = + pe->cancel ? QString::fromUtf8( pe->cancel ) : + pe->default_cancel ? escape_accel( QString::fromUtf8( pe->default_cancel ) ) : + /* else */ QLatin1String( "&Cancel" ) ; + const QString title = + pe->title ? QString::fromUtf8( pe->title ) : + /* else */ QLatin1String( "pinentry-qt4" ) ; + + if (want_pass) { PinEntryDialog pinentry (parent, 0, true, !!pe->quality_bar); pinentry.setPinentryInfo (pe); - pinentry.setPrompt (QString::fromUtf8 (pe->prompt)); + pinentry.setPrompt (escape_accel (QString::fromUtf8 (pe->prompt)) ); pinentry.setDescription (QString::fromUtf8 (pe->description)); if ( pe->title ) pinentry.setWindowTitle( QString::fromUtf8( pe->title ) ); @@ -96,10 +139,8 @@ /* If we reuse the same dialog window. */ pinentry.setPin (secqstring()); - if (pe->ok) - pinentry.setOkText (QString::fromUtf8 (pe->ok)); - if (pe->cancel) - pinentry.setCancelText (QString::fromUtf8 (pe->cancel)); + pinentry.setOkText (ok); + pinentry.setCancelText (cancel); if (pe->error) pinentry.setError (QString::fromUtf8 (pe->error)); if (pe->quality_bar) @@ -128,48 +169,45 @@ } else { - const QString title = pe->title ? QString::fromUtf8 ( pe->title ) : QString(); const QString desc = pe->description ? QString::fromUtf8 ( pe->description ) : QString(); - const QString ok = pe->ok ? QString::fromUtf8 ( pe->ok ) : QDialogButtonBox::tr( "&OK" ); - const QString can = pe->cancel ? QString::fromUtf8 ( pe->cancel ) : QDialogButtonBox::tr( "Cancel" ); + const QString notok = pe->notok ? QString::fromUtf8 ( pe->notok ) : QString(); - QMessageBox box( parent ); + const QMessageBox::StandardButtons buttons = + pe->one_button ? QMessageBox::Ok : + pe->notok ? QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel : + /* else */ QMessageBox::Ok|QMessageBox::Cancel ; - if ( !title.isEmpty() ) - box.setWindowTitle( title ); + QMessageBox box( QMessageBox::Information, title, desc, buttons, parent ); - if ( !ok.isEmpty() ) - if ( !can.isEmpty() ) - box.setStandardButtons( QMessageBox::Ok|QMessageBox::Cancel ); - else - box.setStandardButtons( QMessageBox::Ok ); - else - if ( !can.isEmpty() ) - box.setStandardButtons( QMessageBox::Cancel ); - else - box.setStandardButtons( QMessageBox::NoButton ); + const struct { + QMessageBox::StandardButton button; + QString label; + } buttonLabels[] = { + { QMessageBox::Ok, ok }, + { QMessageBox::Yes, ok }, + { QMessageBox::No, notok }, + { QMessageBox::Cancel, cancel }, + }; - if ( !ok.isEmpty() ) - { - box.button( QMessageBox::Ok )->setText( ok ); - if ( box.style()->styleHint( QStyle::SH_DialogButtonBox_ButtonsHaveIcons ) ) - box.button( QMessageBox::Ok )->setIcon( QIcon( QLatin1String( ":/gtk-ok.png" ) ) ); - } + for ( size_t i = 0 ; i < sizeof buttonLabels / sizeof *buttonLabels ; ++i ) + if ( (buttons & buttonLabels[i].button) && !buttonLabels[i].label.isEmpty() ) + box.button( buttonLabels[i].button )->setText( buttonLabels[i].label ); - if ( !can.isEmpty() ) - { - box.button( QMessageBox::Cancel )->setText( can ); - if ( box.style()->styleHint( QStyle::SH_DialogButtonBox_ButtonsHaveIcons ) ) - box.button( QMessageBox::Cancel )->setIcon( QIcon( QLatin1String( ":/gtk-cancel.png" ) ) ); - } - - box.setText( desc ); box.setIconPixmap( icon() ); + if ( !pe->one_button ) + box.setDefaultButton( QMessageBox::Cancel ); + box.show(); raiseWindow( &box ); - return box.exec() == QMessageBox::Ok ; + const int rc = box.exec(); + + if ( rc == QMessageBox::Cancel ) + pe->canceled = true; + + return rc == QMessageBox::Ok || rc == QMessageBox::Yes ; + } } Added: trunk/qt4/pinentry.qrc =================================================================== --- trunk/qt4/pinentry.qrc (rev 0) +++ trunk/qt4/pinentry.qrc 2010-02-19 15:07:24 UTC (rev 219) @@ -0,0 +1,6 @@ + + + + document-encrypt.png + + Modified: trunk/qt4/pinentrydialog.cpp =================================================================== --- trunk/qt4/pinentrydialog.cpp 2010-02-19 12:18:30 UTC (rev 218) +++ trunk/qt4/pinentrydialog.cpp 2010-02-19 15:07:24 UTC (rev 219) @@ -26,17 +26,14 @@ #include "qsecurelineedit.h" +#include #include #include #include -#include -#include #include #include #include #include -#include -#include #include #ifdef Q_WS_WIN @@ -114,6 +111,8 @@ _edit = new QSecureLineEdit( this ); _edit->setMaxLength( 256 ); + _prompt->setBuddy( _edit ); + if (enable_quality_bar) { _quality_bar_label = new QLabel( this ); @@ -134,43 +133,32 @@ if ( style()->styleHint( QStyle::SH_DialogButtonBox_ButtonsHaveIcons ) ) { - _ok->setIcon( QIcon( QLatin1String( ":/gtk-ok.png" ) ) ); - _cancel->setIcon( QIcon( QLatin1String( ":/gtk-cancel.png" ) ) ); + _ok->setIcon( style()->standardIcon( QStyle::SP_DialogOkButton ) ); + _cancel->setIcon( style()->standardIcon( QStyle::SP_DialogCancelButton ) ); } - connect( _ok, SIGNAL( clicked() ), - this, SIGNAL( accepted() ) ); - connect( _cancel, SIGNAL( clicked() ), - this, SIGNAL( rejected() ) ); + connect( buttons, SIGNAL(accepted()), this, SLOT(accept()) ); + connect( buttons, SIGNAL(rejected()), this, SLOT(reject()) ); connect( _edit, SIGNAL( textChanged(secqstring) ), this, SLOT( updateQuality(secqstring) ) ); - connect (this, SIGNAL (accepted ()), - this, SLOT (accept ())); - connect (this, SIGNAL (rejected ()), - this, SLOT (reject ())); _edit->setFocus(); - QBoxLayout* const labels = new QVBoxLayout; - labels->addWidget( _error ); - labels->addWidget( _desc ); - labels->addItem( new QSpacerItem( 0, 1, QSizePolicy::Minimum, QSizePolicy::Expanding ) ); - QGridLayout* const grid = new QGridLayout( this ); - grid->addWidget( _icon, 0, 0, 4, 1, Qt::AlignTop|Qt::AlignLeft ); - grid->addLayout( labels, 0, 1, 1, 2 ); - grid->addItem( new QSpacerItem( 0, _edit->height() / 10, QSizePolicy::Minimum, QSizePolicy::Fixed ), 1, 1 ); - grid->addWidget( _prompt, 2, 1 ); - grid->addWidget( _edit, 2, 2 ); + grid->addWidget( _icon, 0, 0, 5, 1, Qt::AlignTop|Qt::AlignLeft ); + grid->addWidget( _error, 1, 1, 1, 2 ); + grid->addWidget( _desc, 2, 1, 1, 2 ); + //grid->addItem( new QSpacerItem( 0, _edit->height() / 10, QSizePolicy::Minimum, QSizePolicy::Fixed ), 1, 1 ); + grid->addWidget( _prompt, 3, 1 ); + grid->addWidget( _edit, 3, 2 ); if( enable_quality_bar ) { - grid->addWidget( _quality_bar_label, 3, 1 ); - grid->addWidget( _quality_bar, 3, 2 ); + grid->addWidget( _quality_bar_label, 4, 1 ); + grid->addWidget( _quality_bar, 4, 2 ); } - grid->addWidget( buttons, 4, 0, 1, 3 ); + grid->addWidget( buttons, 5, 0, 1, 3 ); - setMinimumWidth( 450 ); - resize( minimumSizeHint() ); + grid->setSizeConstraint( QLayout::SetFixedSize ); } void PinEntryDialog::hideEvent( QHideEvent* ev ) @@ -184,33 +172,9 @@ void PinEntryDialog::showEvent( QShowEvent* event ) { QDialog::showEvent( event ); - QMetaObject::invokeMethod( this, "setFixedSize", Qt::QueuedConnection ); -} - -void PinEntryDialog::setFixedSize() -{ - QTextDocument doc; - doc.setDefaultFont( _desc->font() ); - doc.setHtml( _desc->text() ); - doc.setTextWidth( _desc->width() ); - _desc->setFixedSize( doc.size().toSize() ); - - layout()->activate(); - setFixedHeight( minimumSizeHint().height() + 5 ); - QDialog::setFixedSize( size() ); - raiseWindow( this ); } -void PinEntryDialog::keyPressEvent( QKeyEvent* e ) -{ - if ( e->modifiers() == Qt::NoModifier && e->key() == Qt::Key_Escape ) { - emit rejected(); - return; - } - QDialog::keyPressEvent( e ); -} - void PinEntryDialog::setDescription( const QString& txt ) { _desc->setVisible( !txt.isEmpty() ); Modified: trunk/qt4/pinentrydialog.h =================================================================== --- trunk/qt4/pinentrydialog.h 2010-02-19 12:18:30 UTC (rev 218) +++ trunk/qt4/pinentrydialog.h 2010-02-19 15:07:24 UTC (rev 219) @@ -24,7 +24,6 @@ #ifndef __PINENTRYDIALOG_H__ #define __PINENTRYDIALOG_H__ -#include #include #include @@ -35,6 +34,7 @@ class QPushButton; class QSecureLineEdit; class QString; +class QProgressBar; QPixmap icon( QStyle::StandardPixmap which = QStyle::SP_CustomBase ); @@ -74,19 +74,11 @@ public slots: void updateQuality(const secqstring&); -signals: - void accepted(); - void rejected(); - protected: /* reimp */ void showEvent( QShowEvent* event ); - /* reimp */ void keyPressEvent( QKeyEvent *e ); /* reimp */ void hideEvent( QHideEvent* ); /* reimp */ void paintEvent( QPaintEvent* event ); -private Q_SLOTS: - void setFixedSize(); - private: QLabel* _icon; QLabel* _desc; Modified: trunk/qt4/pinentrydialog.moc =================================================================== --- trunk/qt4/pinentrydialog.moc 2010-02-19 12:18:30 UTC (rev 218) +++ trunk/qt4/pinentrydialog.moc 2010-02-19 15:07:24 UTC (rev 219) @@ -10,7 +10,7 @@ #include "pinentrydialog.h" #if !defined(Q_MOC_OUTPUT_REVISION) #error "The header file 'pinentrydialog.h' doesn't include ." -#elif Q_MOC_OUTPUT_REVISION != 59 +#elif Q_MOC_OUTPUT_REVISION < 59 #error "This file was generated using the moc from 4.4.1. It" #error "cannot be used with the include files from this version of Qt." #error "(The moc has changed too much.)" @@ -23,30 +23,24 @@ 1, // revision 0, // classname 0, 0, // classinfo - 4, 10, // methods - 4, 30, // properties + 1, 10, // methods + 4, 15, // properties 0, 0, // enums/sets - // signals: signature, parameters, type, tag, flags - 16, 15, 15, 15, 0x05, - 27, 15, 15, 15, 0x05, - // slots: signature, parameters, type, tag, flags - 38, 15, 15, 15, 0x0a, - 64, 15, 15, 15, 0x08, + 16, 15, 15, 15, 0x0a, // properties: name, type, flags - 87, 79, 0x0a095103, - 99, 79, 0x0a095103, - 116, 105, 0x0009510b, - 120, 79, 0x0a095103, + 50, 42, 0x0a095103, + 62, 42, 0x0a095103, + 79, 68, 0x0009510b, + 83, 42, 0x0a095103, 0 // eod }; static const char qt_meta_stringdata_PinEntryDialog[] = { - "PinEntryDialog\0\0accepted()\0rejected()\0" - "updateQuality(secqstring)\0setFixedSize()\0" + "PinEntryDialog\0\0updateQuality(secqstring)\0" "QString\0description\0error\0secqstring\0" "pin\0prompt\0" }; @@ -76,12 +70,9 @@ return _id; if (_c == QMetaObject::InvokeMetaMethod) { switch (_id) { - case 0: accepted(); break; - case 1: rejected(); break; - case 2: updateQuality((*reinterpret_cast< const secqstring(*)>(_a[1]))); break; - case 3: setFixedSize(); break; + case 0: updateQuality((*reinterpret_cast< const secqstring(*)>(_a[1]))); break; } - _id -= 4; + _id -= 1; } #ifndef QT_NO_PROPERTIES else if (_c == QMetaObject::ReadProperty) { @@ -118,16 +109,4 @@ #endif // QT_NO_PROPERTIES return _id; } - -// SIGNAL 0 -void PinEntryDialog::accepted() -{ - QMetaObject::activate(this, &staticMetaObject, 0, 0); -} - -// SIGNAL 1 -void PinEntryDialog::rejected() -{ - QMetaObject::activate(this, &staticMetaObject, 1, 0); -} QT_END_MOC_NAMESPACE Added: trunk/qt4/qrc_pinentry.cpp =================================================================== --- trunk/qt4/qrc_pinentry.cpp (rev 0) +++ trunk/qt4/qrc_pinentry.cpp 2010-02-19 15:07:24 UTC (rev 219) @@ -0,0 +1,180 @@ +/**************************************************************************** +** Resource object code +** +** Created: Wed Feb 17 23:35:02 2010 +** by: The Resource Compiler for Qt version 4.4.3 +** +** WARNING! All changes made in this file will be lost! +*****************************************************************************/ + +#include + +static const unsigned char qt_resource_data[] = { + // /home/marc/KDE/src/gnupg-backend/pinentry/qt4/document-encrypt.png + 0x0,0x0,0x7,0x2b, + 0x89, + 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, + 0x0,0x0,0x30,0x0,0x0,0x0,0x30,0x8,0x6,0x0,0x0,0x0,0x57,0x2,0xf9,0x87, + 0x0,0x0,0x0,0x4,0x73,0x42,0x49,0x54,0x8,0x8,0x8,0x8,0x7c,0x8,0x64,0x88, + 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0x5,0x31,0x0,0x0,0x5,0x31, + 0x1,0xb7,0xed,0x28,0x52,0x0,0x0,0x0,0x19,0x74,0x45,0x58,0x74,0x53,0x6f,0x66, + 0x74,0x77,0x61,0x72,0x65,0x0,0x77,0x77,0x77,0x2e,0x69,0x6e,0x6b,0x73,0x63,0x61, + 0x70,0x65,0x2e,0x6f,0x72,0x67,0x9b,0xee,0x3c,0x1a,0x0,0x0,0x6,0xa8,0x49,0x44, + 0x41,0x54,0x78,0xda,0xd5,0x59,0x4b,0x6c,0x55,0x45,0x18,0xfe,0x67,0xce,0x7d,0xf5, + 0xfd,0xc0,0x82,0xb1,0xd,0xb,0xdd,0x11,0x34,0x46,0xd1,0xd,0x1b,0x42,0x4c,0x48, + 0x31,0xb4,0x68,0x52,0x16,0xb8,0x31,0xae,0x4c,0xec,0x92,0x85,0xa9,0x8b,0x6e,0x8c, + 0xb2,0x60,0xa9,0x21,0xee,0x5c,0xdb,0xf8,0x58,0xb9,0xa1,0x6d,0x60,0x61,0x42,0xb4, + 0xe0,0x2,0x41,0xd,0x8,0xd1,0xb6,0x94,0x36,0x5c,0xfb,0xa6,0xbd,0xf7,0x9e,0x73, + 0xc6,0xef,0xfb,0x73,0x99,0x73,0xe3,0xc5,0x40,0xd3,0x9e,0x5b,0x99,0xe4,0xe3,0x9f, + 0x33,0x33,0x67,0xce,0xff,0xfd,0xaf,0x99,0x72,0x8d,0x73,0x4e,0x9e,0xe6,0x96,0x91, + 0x14,0xda,0x8d,0x1b,0x37,0x72,0xd7,0xaf,0x5f,0x7f,0xb1,0x54,0x2a,0xbd,0xba,0xb9, + 0xb9,0xc9,0xa1,0x2b,0xb3,0xb3,0xb3,0xd7,0x46,0x47,0x47,0xcb,0xb2,0xc3,0x6d,0xc7, + 0x3c,0x30,0x3e,0x3e,0xbe,0xbf,0x52,0xa9,0x7c,0x8,0xa5,0x5f,0xc9,0x66,0xb3,0x2f, + 0x37,0x37,0x37,0xe7,0x3b,0x3a,0x3a,0xc4,0x5a,0x2b,0x2b,0x2b,0x2b,0xb2,0xbc,0xbc, + 0x5c,0xba,0x7f,0xff,0xfe,0x35,0xcc,0xff,0xb4,0x67,0xcf,0x9e,0xb3,0x43,0x43,0x43, + 0x7f,0xfd,0x6f,0x8,0x4c,0x4c,0x4c,0x7c,0x10,0x86,0xe1,0x68,0x6b,0x6b,0x6b,0x4f, + 0x77,0x77,0xb7,0xe4,0x72,0x39,0xe1,0xbe,0x4b,0x4b,0x4b,0x2a,0xf7,0xee,0xdd,0x2b, + 0x50,0x5a,0xc7,0x17,0x16,0x16,0xe4,0xd2,0xa5,0x4b,0x45,0x90,0x1c,0x3d,0x75,0xea, + 0xd4,0xe7,0xbb,0x4a,0x60,0x72,0x72,0xb2,0x17,0x8a,0x7f,0x89,0xee,0x1b,0x5d,0x5d, + 0x5d,0x2,0xf,0xc8,0xad,0x5b,0xb7,0x64,0x71,0x71,0x51,0x15,0x6f,0x6b,0x6b,0x13, + 0x63,0xc,0x3d,0xa0,0x63,0x50,0x5a,0xe,0x1e,0x3c,0x28,0xc7,0x8e,0x1d,0x93,0xa9, + 0xa9,0x29,0x29,0x16,0x8b,0xe3,0xed,0xed,0xed,0xef,0x1e,0x3d,0x7a,0x74,0xb6,0xe1, + 0x4,0xc6,0xc6,0xc6,0x72,0xb0,0xf6,0x1f,0xe8,0xf6,0xc1,0xf2,0x72,0xf7,0xee,0x5d, + 0x86,0x89,0x74,0x76,0x76,0x4a,0x14,0x45,0x12,0xc7,0xb1,0x80,0x9c,0xca,0x20,0x8, + 0x24,0x93,0xc9,0x28,0x90,0xb,0x32,0x3d,0x3d,0x2d,0xc3,0xc3,0xc3,0x3a,0x7f,0xf3, + 0xe6,0xcd,0x99,0xde,0xde,0xde,0x17,0xe,0x1c,0x38,0x50,0x6e,0x24,0x1,0x86,0xcd, + 0x37,0x78,0xf7,0xad,0x7c,0x3e,0x2f,0xb7,0x6f,0xdf,0x16,0xc4,0x3c,0xad,0x4e,0x8b, + 0xff,0xd,0xa5,0x3f,0x3,0xa6,0x40,0x64,0xea,0xc1,0x83,0x7,0x24,0x70,0xa8,0x5c, + 0x2e,0x1f,0x82,0x1c,0x46,0x5e,0x74,0x93,0xe0,0xd5,0xab,0x57,0x65,0x70,0x70,0x50, + 0xf0,0x3e,0x3d,0xf7,0xed,0xe1,0xc3,0x87,0xdf,0x6e,0x18,0x81,0xb,0x17,0x2e,0x1c, + 0x47,0x72,0x7e,0x7,0x8b,0x66,0x69,0x51,0x48,0x2a,0x41,0x12,0x5f,0x6d,0x6c,0x6c, + 0xbc,0x7f,0xfa,0xf4,0xe9,0x45,0x79,0x44,0x3b,0x7f,0xfe,0x7c,0x17,0xac,0xfe,0x5, + 0x3c,0x36,0x54,0x28,0x14,0xe4,0xf2,0xe5,0xcb,0x32,0x32,0x32,0x42,0x2f,0x84,0x20, + 0x3e,0x8,0x12,0xdf,0xa7,0x4e,0xe0,0xe2,0xc5,0x8b,0x19,0x28,0x39,0x3,0xcb,0xed, + 0xa3,0xd2,0xf3,0xf3,0xf3,0x6a,0x79,0xe4,0xc0,0xc8,0xc0,0xc0,0xc0,0xa7,0xf2,0x4, + 0xed,0xdc,0xb9,0x73,0x1f,0xf5,0xf4,0xf4,0x7c,0xbc,0xbe,0xbe,0xae,0x89,0xdd,0xdf, + 0xdf,0x2f,0x73,0x73,0x73,0xf3,0x6b,0x6b,0x6b,0x7d,0x47,0x8e,0x1c,0x9,0x65,0xb, + 0xcd,0x6e,0x91,0x30,0xe3,0xfc,0x24,0x3e,0xba,0x8f,0xc9,0x39,0x33,0x33,0xa3,0xf1, + 0xe,0x32,0xbf,0x42,0xf9,0xb3,0xf2,0x84,0xed,0xcc,0x99,0x33,0x9f,0x20,0xb1,0x7f, + 0x69,0x6a,0x6a,0xd2,0xdc,0x41,0x69,0xa5,0x7,0xf7,0x61,0xea,0x24,0x20,0x69,0x12, + 0x60,0xe2,0xf5,0xb3,0x9a,0xd0,0xea,0x54,0x9e,0x7,0x55,0x4b,0x4b,0xcb,0x9b,0x98, + 0xda,0x8a,0x2b,0x1d,0x94,0x1e,0x0,0x1c,0x3c,0xc7,0x83,0x8f,0x15,0x8a,0xf9,0xd3, + 0x9f,0x36,0x1,0x5a,0x8a,0xc9,0x28,0x48,0x4a,0x92,0xe1,0x47,0x57,0x4f,0x9c,0x38, + 0x71,0x47,0xb6,0xd6,0xe8,0x85,0x3b,0x78,0x7f,0x81,0x7b,0xdd,0xbb,0x77,0x4f,0xe8, + 0xd,0xe4,0xd5,0xa1,0xb4,0x9,0xb0,0x2c,0xf6,0x2,0xac,0xed,0x24,0xc1,0x4,0xfe, + 0xdd,0x4f,0x6e,0x7d,0xaf,0x6b,0xf4,0x22,0xf,0x37,0x96,0x62,0xb4,0xde,0xb4,0x9, + 0xd0,0x4a,0x9d,0xc,0x9f,0xd5,0xd5,0x55,0x12,0xe0,0x61,0x35,0xe9,0x27,0xb7,0xbe, + 0xd7,0xf,0xc,0x41,0x1a,0xa4,0xda,0x3a,0xd3,0x26,0xc0,0x90,0x9,0xf0,0x61,0x86, + 0xf,0xad,0xcf,0xa1,0x95,0x6d,0x10,0x58,0xe6,0x1e,0x2c,0x8,0xa8,0x40,0x1c,0xa, + 0xd2,0x23,0x50,0xff,0x71,0x3d,0x84,0xd8,0x76,0x62,0xf,0x5f,0xce,0x1b,0x45,0x0, + 0xc9,0xc7,0xc4,0xdb,0x2e,0x81,0x6d,0xef,0x91,0xd9,0xe,0x1,0x1e,0x42,0xdb,0x6d, + 0x3c,0x91,0x7d,0x6b,0xb0,0x7,0xfc,0xc7,0x53,0xda,0x23,0x7d,0x2,0x8c,0xdf,0x6d, + 0x36,0xee,0xf1,0xd4,0x12,0x60,0xe,0x30,0xc,0xd3,0xff,0x83,0xe6,0xc7,0xaf,0xdf, + 0x71,0x2f,0xbd,0xe6,0xa4,0x38,0xdd,0x2d,0x8b,0xc5,0x66,0xdc,0x5d,0x22,0x9e,0x1, + 0x1e,0x15,0x95,0x25,0xf6,0xeb,0x20,0xce,0xb1,0xdc,0x12,0xbc,0x2e,0x40,0xe1,0xbc, + 0xe4,0xf2,0x39,0x55,0x3c,0x8b,0x3e,0x25,0xd,0x41,0x14,0x9a,0x72,0xd2,0xdd,0xd7, + 0x25,0xd9,0x67,0x9c,0x5c,0x99,0xf8,0x59,0x8e,0xbf,0x37,0x66,0x76,0x2c,0x89,0x6d, + 0x26,0x94,0x67,0xf7,0xff,0x26,0xdd,0x1d,0x7f,0xca,0xc6,0x52,0x28,0xeb,0xeb,0x4d, + 0xb8,0x7,0x65,0x65,0x63,0xc3,0x0,0x56,0x36,0x36,0x45,0x4a,0x81,0x91,0x4d,0xeb, + 0xa4,0xa4,0x88,0x25,0xb,0x80,0x0,0x94,0x34,0x92,0x27,0xf2,0x84,0x95,0x2,0x1c, + 0x97,0x2f,0x20,0x81,0x5b,0x9c,0x34,0x17,0x80,0xf6,0xb2,0x74,0xf4,0x64,0xa5,0xe9, + 0xb9,0xd7,0xc5,0xb4,0x3d,0x2f,0xc5,0xb9,0x62,0x7a,0x55,0xc8,0x18,0x7,0x65,0x8a, + 0x92,0x33,0xeb,0x52,0xce,0xc4,0xb2,0x89,0x1d,0xd6,0x4c,0x20,0xad,0x90,0x65,0x44, + 0x43,0x58,0xe0,0x15,0x81,0xb0,0x12,0x58,0x86,0x1a,0xde,0x81,0xcc,0x6,0xec,0x43, + 0xe2,0x1d,0x95,0x58,0x97,0x6b,0x1,0x89,0x56,0x10,0x6c,0xc5,0x73,0x4b,0x9f,0x2e, + 0xc4,0x9b,0xc,0xad,0x74,0x8,0x50,0xa9,0x28,0x22,0x2,0x71,0x84,0x33,0x12,0x39, + 0xc6,0x32,0x89,0x19,0x82,0x4a,0x60,0xdc,0xa2,0xaf,0x74,0x1,0x84,0x90,0xce,0x13, + 0xb1,0x44,0x92,0xc1,0x12,0x23,0xb1,0xe5,0xd7,0x1d,0xd6,0xc6,0x80,0xc3,0x1c,0xde, + 0xe1,0x46,0x0,0xae,0x16,0xe9,0x10,0xb0,0x96,0xd6,0x73,0x30,0x25,0x3e,0x8a,0x8f, + 0x84,0xb4,0x96,0xe8,0x4c,0x95,0x0,0x3e,0xc,0x38,0x6b,0x34,0x74,0x38,0x19,0x83, + 0x44,0x88,0xe1,0x80,0xd6,0xd5,0x57,0x23,0x90,0xc7,0x32,0x40,0x42,0xc,0x68,0x1d, + 0xa8,0x0,0xbc,0xd9,0x2,0xd6,0xa6,0xe4,0x1,0xdf,0x9c,0xc4,0x80,0x8b,0x61,0xb5, + 0xc0,0xd1,0x60,0x0,0x65,0xa4,0x16,0x57,0xc3,0x1a,0xc7,0x2e,0x43,0x88,0xc4,0x54, + 0x5a,0x8c,0x5,0xec,0x63,0x5c,0x3,0x5,0x2f,0x3a,0x1a,0xc2,0x71,0x4d,0x6,0x32, + 0x20,0x68,0x98,0xd4,0x3c,0xe0,0xc3,0xa8,0xea,0x7f,0xc8,0x90,0xa,0x78,0x44,0x40, + 0x88,0xb9,0x58,0x17,0x92,0x26,0x63,0x5f,0x9f,0xc4,0xa8,0x53,0xac,0x5f,0x6b,0xa2, + 0x8,0x88,0x51,0x9d,0x1c,0x40,0x19,0x81,0x19,0x90,0xb6,0x7,0x18,0x46,0x21,0xc3, + 0xc4,0x44,0x4c,0x68,0x40,0x3c,0xb2,0x81,0xc6,0x35,0x74,0xd7,0xf0,0xf1,0x49,0x5c, + 0xcd,0x1,0xed,0x5b,0x63,0x28,0x81,0x98,0xde,0x21,0x4f,0xcd,0x29,0xb,0x18,0x1a, + 0x26,0x5d,0xf,0xf8,0xd0,0x96,0xd8,0x51,0x51,0x42,0x95,0xa8,0xc2,0xe8,0x58,0x54, + 0x55,0xc0,0xe9,0xba,0x2c,0x3d,0xa2,0x4a,0x87,0x21,0xc3,0xc9,0xe1,0x3c,0x88,0xa1, + 0xb0,0xd3,0x67,0x74,0x7d,0x75,0x13,0xd1,0x87,0x74,0x3d,0x60,0x4c,0x2d,0x8c,0xa2, + 0x36,0x3f,0xf8,0x64,0xf9,0xaf,0x4a,0x5a,0x3f,0xe4,0x70,0xd5,0x3,0xde,0x2b,0x55, + 0x90,0x8c,0x46,0x8d,0x42,0x14,0xb6,0x31,0xb7,0x51,0x63,0x34,0x79,0x21,0x1d,0xa4, + 0xa9,0x8b,0x71,0x6d,0xec,0x13,0x31,0xd7,0xea,0x9c,0xe,0x26,0x9c,0xd,0xbc,0x80, + 0xb9,0x10,0x79,0x0,0xaf,0xd9,0xf4,0xaf,0xd3,0xac,0xd1,0x55,0xe8,0x79,0x60,0x7c, + 0x8,0x51,0xb9,0x84,0x84,0xe6,0x8a,0xf7,0x54,0xc6,0x5b,0xd9,0x2b,0xf,0x19,0xd5, + 0x78,0x42,0x47,0xf0,0x9e,0x6e,0x90,0x26,0x81,0x58,0x15,0x73,0x80,0x9,0x20,0x81, + 0x87,0xa,0xc4,0x80,0xf,0x5,0xd1,0x40,0xaa,0x3b,0xc1,0xf9,0x2e,0xc7,0x95,0x84, + 0xca,0x8,0x48,0xc8,0x89,0x21,0x4c,0x63,0x42,0x28,0x49,0x5c,0xab,0x32,0xf1,0x2, + 0x51,0x1b,0x2a,0xc6,0xaf,0xe7,0x69,0x9b,0x9,0x9c,0x5f,0x1f,0x86,0x56,0x72,0x2e, + 0xd9,0x47,0x20,0xd1,0x69,0xc,0x1,0x6b,0x1f,0x22,0xae,0xb9,0x4a,0xd4,0x12,0x20, + 0xa1,0xc4,0xb,0xc9,0x5a,0x2d,0xa3,0x94,0x80,0xf8,0xbc,0xa8,0xae,0xda,0xb5,0x9f, + 0x98,0x18,0xbf,0x80,0xd4,0x82,0x25,0x93,0xe3,0xfe,0x0,0xa4,0x7,0x24,0x88,0x94, + 0x48,0x12,0xff,0x9,0x39,0x51,0xd8,0xc6,0x11,0x88,0x63,0x8f,0x5a,0x2b,0x7a,0xa5, + 0xd9,0xa2,0x88,0xb7,0x21,0xab,0xa7,0xad,0x88,0xc1,0xb3,0x55,0xeb,0x4b,0x5,0x28, + 0x63,0x75,0xe,0xa3,0x15,0xbd,0x5e,0x35,0xa2,0xa,0xd1,0xca,0xa,0xad,0x3e,0xf8, + 0x6c,0xd,0x91,0xa0,0x2e,0x17,0xd0,0x83,0xe2,0x3c,0x7d,0x35,0x79,0x6b,0xae,0x14, + 0x9a,0xd0,0x3c,0x3,0x38,0xaf,0x30,0x9c,0x48,0x9f,0x0,0x13,0x53,0xc1,0xaa,0xe1, + 0xe3,0x9f,0xa,0xb8,0x38,0xa2,0xf2,0xe8,0xf8,0x3c,0xd4,0x6b,0x83,0xf5,0x57,0x8a, + 0x8,0x10,0x26,0x31,0x43,0x9,0xf0,0x21,0x87,0x7e,0xc,0xb8,0xdd,0xfc,0x99,0xd5, + 0xd7,0x7f,0xf,0x25,0x61,0xab,0xca,0x9,0x9,0xb0,0x2f,0xc9,0x19,0x91,0x24,0x7d, + 0x42,0x64,0xb7,0x8,0x38,0x47,0xc4,0x2a,0x13,0xab,0xd6,0xa2,0x76,0x6d,0x1d,0x59, + 0xc0,0xed,0x2e,0x1,0x7f,0x18,0x29,0x1e,0x55,0x6a,0x3d,0x89,0xda,0xd2,0x5b,0x87, + 0x54,0xff,0x5b,0x25,0xfd,0xf6,0x14,0x12,0x48,0xe1,0x97,0x7a,0x5f,0xce,0x32,0x40, + 0xf0,0x18,0x58,0x2f,0x13,0x18,0x2f,0x89,0xfa,0xe6,0xaa,0x88,0xbd,0x4c,0x10,0x3d, + 0x94,0x8f,0x41,0x48,0x9d,0x6b,0x9,0x50,0xe9,0xa0,0xaa,0x74,0x96,0x72,0x87,0x61, + 0xab,0x8a,0x85,0x3b,0x88,0xa,0x50,0x66,0xff,0xbf,0x3c,0x60,0xeb,0x91,0x58,0xfd, + 0x31,0xb0,0x89,0xe2,0xa,0xa9,0xb3,0xb4,0x87,0x7f,0xe,0xeb,0x3d,0x50,0xef,0x1d, + 0xc2,0xfd,0x4b,0xe1,0x7f,0x0,0xd8,0x6e,0xc6,0xdd,0x5d,0xd6,0xb,0x18,0x0,0x0, + 0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, + +}; + +static const unsigned char qt_resource_name[] = { + // document-encrypt.png + 0x0,0x14, + 0x8,0xbf,0x25,0x67, + 0x0,0x64, + 0x0,0x6f,0x0,0x63,0x0,0x75,0x0,0x6d,0x0,0x65,0x0,0x6e,0x0,0x74,0x0,0x2d,0x0,0x65,0x0,0x6e,0x0,0x63,0x0,0x72,0x0,0x79,0x0,0x70,0x0,0x74,0x0,0x2e, + 0x0,0x70,0x0,0x6e,0x0,0x67, + +}; + +static const unsigned char qt_resource_struct[] = { + // : + 0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x1, + // :/document-encrypt.png + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0, + +}; + +QT_BEGIN_NAMESPACE + +extern bool qRegisterResourceData + (int, const unsigned char *, const unsigned char *, const unsigned char *); + +extern bool qUnregisterResourceData + (int, const unsigned char *, const unsigned char *, const unsigned char *); + +QT_END_NAMESPACE + + +int QT_MANGLE_NAMESPACE(qInitResources_pinentry)() +{ + QT_PREPEND_NAMESPACE(qRegisterResourceData) + (0x01, qt_resource_struct, qt_resource_name, qt_resource_data); + return 1; +} + +Q_CONSTRUCTOR_FUNCTION(QT_MANGLE_NAMESPACE(qInitResources_pinentry)) + +int QT_MANGLE_NAMESPACE(qCleanupResources_pinentry)() +{ + QT_PREPEND_NAMESPACE(qUnregisterResourceData) + (0x01, qt_resource_struct, qt_resource_name, qt_resource_data); + return 1; +} + +Q_DESTRUCTOR_FUNCTION(QT_MANGLE_NAMESPACE(qCleanupResources_pinentry)) + Modified: trunk/qt4/qsecurelineedit.moc =================================================================== --- trunk/qt4/qsecurelineedit.moc 2010-02-19 12:18:30 UTC (rev 218) +++ trunk/qt4/qsecurelineedit.moc 2010-02-19 15:07:24 UTC (rev 219) @@ -10,7 +10,7 @@ #include "qsecurelineedit.h" #if !defined(Q_MOC_OUTPUT_REVISION) #error "The header file 'qsecurelineedit.h' doesn't include ." -#elif Q_MOC_OUTPUT_REVISION != 59 +#elif Q_MOC_OUTPUT_REVISION < 59 #error "This file was generated using the moc from 4.4.1. It" #error "cannot be used with the include files from this version of Qt." #error "(The moc has changed too much.)" From cvs at cvs.gnupg.org Mon Feb 22 12:35:19 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 22 Feb 2010 12:35:19 +0100 Subject: [svn] gcry - r1421 - branches/LIBGCRYPT-1-4-BRANCH/mpi Message-ID: Author: wk Date: 2010-02-22 12:35:18 +0100 (Mon, 22 Feb 2010) New Revision: 1421 Modified: branches/LIBGCRYPT-1-4-BRANCH/mpi/ChangeLog branches/LIBGCRYPT-1-4-BRANCH/mpi/longlong.h Log: Fix for gcc 4.4 on mips. Modified: branches/LIBGCRYPT-1-4-BRANCH/mpi/ChangeLog =================================================================== --- branches/LIBGCRYPT-1-4-BRANCH/mpi/ChangeLog 2010-01-21 21:36:43 UTC (rev 1420) +++ branches/LIBGCRYPT-1-4-BRANCH/mpi/ChangeLog 2010-02-22 11:35:18 UTC (rev 1421) @@ -1,3 +1,8 @@ +2010-02-22 Aurelien Jarno (wk) + + * longlong.h (umul_ppmm) [__GNUC__ >= 4.4]: Patch according + to recommended gcc 4.4 changes. + 2009-12-09 Werner Koch * config.links: Remove asm modules for all sparc64. This is Modified: branches/LIBGCRYPT-1-4-BRANCH/mpi/longlong.h =================================================================== --- branches/LIBGCRYPT-1-4-BRANCH/mpi/longlong.h 2010-01-21 21:36:43 UTC (rev 1420) +++ branches/LIBGCRYPT-1-4-BRANCH/mpi/longlong.h 2010-02-22 11:35:18 UTC (rev 1421) @@ -714,8 +714,16 @@ ************** MIPS ***************** ***************************************/ #if defined (__mips__) && W_TYPE_SIZE == 32 -#if __GNUC__ > 2 || __GNUC_MINOR__ >= 7 +#if (__GNUC__ >= 5) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) #define umul_ppmm(w1, w0, u, v) \ + do { \ + UDItype _r; \ + _r = (UDItype) u * v; \ + (w1) = _r >> 32; \ + (w0) = (USItype) _r; \ + } while (0) +#elif __GNUC__ > 2 || __GNUC_MINOR__ >= 7 +#define umul_ppmm(w1, w0, u, v) \ __asm__ ("multu %2,%3" \ : "=l" ((USItype)(w0)), \ "=h" ((USItype)(w1)) \ @@ -739,8 +747,17 @@ ************** MIPS/64 ************** ***************************************/ #if (defined (__mips) && __mips >= 3) && W_TYPE_SIZE == 64 -#if __GNUC__ > 2 || __GNUC_MINOR__ >= 7 +#if (__GNUC__ >= 5) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) +typedef unsigned int UTItype __attribute__ ((mode (TI))); #define umul_ppmm(w1, w0, u, v) \ + do { \ + UTItype _r; \ + _r = (UTItype) u * v; \ + (w1) = _r >> 64; \ + (w0) = (UDItype) _r; \ + } while (0) +#elif __GNUC__ > 2 || __GNUC_MINOR__ >= 7 +#define umul_ppmm(w1, w0, u, v) \ __asm__ ("dmultu %2,%3" \ : "=l" ((UDItype)(w0)), \ "=h" ((UDItype)(w1)) \ From cvs at cvs.gnupg.org Mon Feb 22 12:35:39 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 22 Feb 2010 12:35:39 +0100 Subject: [svn] gcry - r1422 - trunk/mpi Message-ID: Author: wk Date: 2010-02-22 12:35:38 +0100 (Mon, 22 Feb 2010) New Revision: 1422 Modified: trunk/mpi/ChangeLog trunk/mpi/longlong.h Log: Fix for gcc 4.4 on mips Modified: trunk/mpi/ChangeLog =================================================================== --- trunk/mpi/ChangeLog 2010-02-22 11:35:18 UTC (rev 1421) +++ trunk/mpi/ChangeLog 2010-02-22 11:35:38 UTC (rev 1422) @@ -1,3 +1,8 @@ +2010-02-22 Aurelien Jarno (wk) + + * longlong.h (umul_ppmm) [__GNUC__ >= 4.4]: Patch according + to recommended gcc 4.4 changes. + 2009-12-09 Werner Koch * config.links: Remove asm modules for all sparc64. This is Modified: trunk/mpi/longlong.h =================================================================== --- trunk/mpi/longlong.h 2010-02-22 11:35:18 UTC (rev 1421) +++ trunk/mpi/longlong.h 2010-02-22 11:35:38 UTC (rev 1422) @@ -714,8 +714,16 @@ ************** MIPS ***************** ***************************************/ #if defined (__mips__) && W_TYPE_SIZE == 32 -#if __GNUC__ > 2 || __GNUC_MINOR__ >= 7 +#if (__GNUC__ >= 5) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) #define umul_ppmm(w1, w0, u, v) \ + do { \ + UDItype _r; \ + _r = (UDItype) u * v; \ + (w1) = _r >> 32; \ + (w0) = (USItype) _r; \ + } while (0) +#elif __GNUC__ > 2 || __GNUC_MINOR__ >= 7 +#define umul_ppmm(w1, w0, u, v) \ __asm__ ("multu %2,%3" \ : "=l" ((USItype)(w0)), \ "=h" ((USItype)(w1)) \ @@ -739,8 +747,17 @@ ************** MIPS/64 ************** ***************************************/ #if (defined (__mips) && __mips >= 3) && W_TYPE_SIZE == 64 -#if __GNUC__ > 2 || __GNUC_MINOR__ >= 7 +#if (__GNUC__ >= 5) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) +typedef unsigned int UTItype __attribute__ ((mode (TI))); #define umul_ppmm(w1, w0, u, v) \ + do { \ + UTItype _r; \ + _r = (UTItype) u * v; \ + (w1) = _r >> 64; \ + (w0) = (UDItype) _r; \ + } while (0) +#elif __GNUC__ > 2 || __GNUC_MINOR__ >= 7 +#define umul_ppmm(w1, w0, u, v) \ __asm__ ("dmultu %2,%3" \ : "=l" ((UDItype)(w0)), \ "=h" ((UDItype)(w1)) \ From cvs at cvs.gnupg.org Wed Feb 24 16:50:55 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 24 Feb 2010 16:50:55 +0100 Subject: [svn] assuan - r357 - in trunk: . doc src tests Message-ID: Author: wk Date: 2010-02-24 16:50:55 +0100 (Wed, 24 Feb 2010) New Revision: 357 Added: trunk/src/gpgcedev.c trunk/src/gpgcedev.def trunk/src/gpgcemgr.c trunk/tests/ce-createpipe.c Modified: trunk/ChangeLog trunk/NEWS trunk/configure.ac trunk/doc/assuan.texi trunk/src/ChangeLog trunk/src/Makefile.am trunk/src/assuan-defs.h trunk/src/assuan-handler.c trunk/src/assuan-inquire.c trunk/src/assuan-pipe-connect.c trunk/src/assuan-socket-connect.c trunk/src/assuan.h trunk/src/libassuan.def trunk/src/libassuan.vers trunk/src/system.c trunk/src/sysutils.c trunk/tests/Makefile.am trunk/tests/ce-server.c trunk/tests/common.h Log: A couple of changes to eventually fully support W32ce. [The diff below has been truncated] Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2010-02-03 17:00:09 UTC (rev 356) +++ trunk/ChangeLog 2010-02-24 15:50:55 UTC (rev 357) @@ -1,3 +1,17 @@ +2010-02-24 Werner Koch + + * tests/ce-server.c: New. + + * tests/ce-createpipe.c [W32CE]: New. + +2010-02-11 Werner Koch + + * configure.ac (inet_pton): Check for it. + +2010-02-04 Werner Koch + + * configure.ac (AC_TYPE_UINT16_T): New. + 2010-01-27 Werner Koch * tests/common.h (SOCKET2HANDLE, HANDLE2SOCKET): New. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2010-02-03 17:00:09 UTC (rev 356) +++ trunk/src/ChangeLog 2010-02-24 15:50:55 UTC (rev 357) @@ -1,3 +1,35 @@ +2010-02-24 Werner Koch + + * gpgcemgr.c: New. + * gpgcedev.c: New. + * sysutils.c (_assuan_w32ce_create_pipe): Rewrote to make use of + the new driver. + +2010-02-16 Werner Koch + + * system.c (assuan_free): New. + * libassuan.vers (assuan_free): Add it. + * libassuan.def (assuan_free): Add it. + +2010-02-11 Werner Koch + + * assuan-inquire.c (assuan_inquire): Allow case insensitive + responses. + (_assuan_inquire_ext_cb): Ditto. + +2010-02-10 Werner Koch + + * assuan-handler.c (std_handler_input, std_handler_output): Make + the parsed FD available to the notification functions. This is + the documented behaviour. + +2010-02-04 Werner Koch + + * assuan-socket-connect.c: Include stdint.h and arpa/inet.h. + (parse_portno): New. + (assuan_socket_connect): Return a correct error code on failure. + Support assuan:// and file:// schemes. + 2010-02-03 Marcus Brinkmann * libassuan.vers, libassuan.def: Add assuan_set_sock_nonce. @@ -2,2 +34,9 @@ +2010-02-01 Werner Koch + + * sysutils.c (_assuan_w32ce_create_pipe): New. + * libassuan.def (_assuan_w32ce_create_pipe): New. + * assuan-defs.h (CreateFile) [W32CE]: New macro + * system.c (__assuan_pipe): Make it work for W32CE. + 2010-01-28 Werner Koch Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2010-02-03 17:00:09 UTC (rev 356) +++ trunk/NEWS 2010-02-24 15:50:55 UTC (rev 357) @@ -5,7 +5,16 @@ * Support for WindowsCE. + * Input and output notification handler can now really access the + parsed fd as stated in the manual. + * Interface changes relative to the 2.0.0 release: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + assuan_free NEW. + _assuan_w32ce_create_pipe NEW. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Noteworthy changes in version 2.0.0 (2010-01-08) ------------------------------------------------ Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2010-02-03 17:00:09 UTC (rev 356) +++ trunk/configure.ac 2010-02-24 15:50:55 UTC (rev 357) @@ -224,6 +224,7 @@ AC_HEADER_STDC AC_CHECK_HEADERS([string.h locale.h sys/uio.h stdint.h inttypes.h]) AC_TYPE_UINTPTR_T +AC_TYPE_UINT16_T # Checks for typedefs, structures, and compiler characteristics. AC_C_CONST @@ -267,7 +268,7 @@ # # Checks for library functions. # -AC_CHECK_FUNCS([flockfile funlockfile]) +AC_CHECK_FUNCS([flockfile funlockfile inet_pton]) # On some systems (e.g. Solaris) nanosleep requires linking to librl. # Given that we use nanosleep only as an optimization over a select Modified: trunk/doc/assuan.texi =================================================================== --- trunk/doc/assuan.texi 2010-02-03 17:00:09 UTC (rev 356) +++ trunk/doc/assuan.texi 2010-02-24 15:50:55 UTC (rev 357) @@ -216,7 +216,7 @@ On a connect request the server responds either with an okay or an error status. For authentication-check the server may send an Inquiry -Response prior to the first Okay, and it may also issue Status +response prior to the first Okay, and it may also issue Status messages. The server must check that the client is allowed to connect, this is done by requesting the credentials for the peer and comparing them to those of the server. This avoids attacks based on @@ -1379,7 +1379,8 @@ argument passed to that function is the entire line. Because that line has already been parsed when the function gets called, a file descriptor set with the @code{INPUT} command may already be used. That file -descriptor is available by calling @code{assuan_get_input_fd}. +descriptor is available by calling @code{assuan_get_input_fd}. If the +notification function returns an error, the input fd does not change. @end deftypefun @deftypefun gpg_error_t assuan_register_output_notify (@w{assuan_context_t @var{ctx}}, @w{assuan_handler_t @var{handler}}) @@ -1390,7 +1391,8 @@ argument passed to that function is the entire line. Because that line has already been parsed when the function gets called, a file descriptor set with the @code{OUTPUT} command may already be used. That file -descriptor is available by calling @code{assuan_get_output_fd}. +descriptor is available by calling @code{assuan_get_output_fd}. If the +notification function returns an error, the output fd does not change. @end deftypefun @deftypefun gpg_error_t assuan_set_hello_line (@w{assuan_context_t @var{ctx}}, @w{const char *@var{line}}) Modified: trunk/src/Makefile.am =================================================================== --- trunk/src/Makefile.am 2010-02-03 17:00:09 UTC (rev 356) +++ trunk/src/Makefile.am 2010-02-24 15:50:55 UTC (rev 357) @@ -25,6 +25,10 @@ m4datadir = $(datadir)/aclocal m4data_DATA = libassuan.m4 lib_LTLIBRARIES = libassuan.la +if HAVE_W32CE_SYSTEM +lib_LTLIBRARIES += libgpgcedev.la +bin_PROGRAMS = gpgcemgr +endif include_HEADERS = assuan.h if HAVE_LD_VERSION_SCRIPT @@ -97,3 +101,12 @@ libassuan_la_DEPENDENCIES = @LTLIBOBJS@ \ $(srcdir)/libassuan.vers $(libassuan_deps) libassuan_la_LIBADD = @LTLIBOBJS@ @NETLIBS@ @GPG_ERROR_LIBS@ + +if HAVE_W32CE_SYSTEM +libgpgcedev_la_SOURCES = gpgcedev.c +libgpgcedev_la_CPPFLAGS = $(AM_CPPFLAGS) +libgpgcedev_la_LDFLAGS = $(no_undefined) -export-symbols $(srcdir)/gpgcedev.def +libgpgcedev_la_DEPENDENCIES = gpgcedev.def +gpgcemgr_SOURCES = gpgcemgr.c +gpgcemgr_CPPFLAGS = $(AM_CPPFLAGS) +endif Modified: trunk/src/assuan-defs.h =================================================================== --- trunk/src/assuan-defs.h 2010-02-03 17:00:09 UTC (rev 356) +++ trunk/src/assuan-defs.h 2010-02-24 15:50:55 UTC (rev 357) @@ -1,5 +1,6 @@ /* assuan-defs.h - Internal definitions to Assuan - Copyright (C) 2001, 2002, 2004, 2005, 2007-2009 Free Software Foundation, Inc. + Copyright (C) 2001, 2002, 2004, 2005, 2007, 2008, + 2009, 2010 Free Software Foundation, Inc. This file is part of Assuan. @@ -339,12 +340,14 @@ const char *_assuan_sysutils_blurb (void); #ifdef HAVE_W32CE_SYSTEM + #define getpid() GetCurrentProcessId () char *_assuan_getenv (const char *name); #define getenv(a) _assuan_getenv ((a)) -#endif +#endif /*HAVE_W32CE_SYSTEM*/ + /* Prototypes for replacement functions. */ #ifndef HAVE_MEMRCHR void *memrchr (const void *block, int c, size_t size); Modified: trunk/src/assuan-handler.c =================================================================== --- trunk/src/assuan-handler.c 2010-02-03 17:00:09 UTC (rev 356) +++ trunk/src/assuan-handler.c 2010-02-24 15:50:55 UTC (rev 357) @@ -234,7 +234,7 @@ return set_error (ctx, GPG_ERR_ASS_SYNTAX, "number required"); #ifdef HAVE_W32_SYSTEM /* Fixme: For a W32/64bit system we will need to change the cast - and the conversion fucntion. */ + and the conversion function. */ *rfd = (void*)strtoul (line, &endp, 10); #else *rfd = strtoul (line, &endp, 10); @@ -259,14 +259,20 @@ std_handler_input (assuan_context_t ctx, char *line) { gpg_error_t rc; - assuan_fd_t fd; + assuan_fd_t fd, oldfd; rc = assuan_command_parse_fd (ctx, line, &fd); if (rc) return PROCESS_DONE (ctx, rc); if (ctx->input_notify_fnc) - rc = ctx->input_notify_fnc (ctx, line); - if (! rc) + { + oldfd = ctx->input_fd; + ctx->input_fd = fd; + rc = ctx->input_notify_fnc (ctx, line); + if (rc) + ctx->input_fd = oldfd; + } + else if (!rc) ctx->input_fd = fd; return PROCESS_DONE (ctx, rc); } @@ -277,14 +283,20 @@ std_handler_output (assuan_context_t ctx, char *line) { gpg_error_t rc; - assuan_fd_t fd; + assuan_fd_t fd, oldfd; rc = assuan_command_parse_fd (ctx, line, &fd); if (rc) return PROCESS_DONE (ctx, rc); if (ctx->output_notify_fnc) - rc = ctx->output_notify_fnc (ctx, line); - if (!rc) + { + oldfd = ctx->output_fd; + ctx->output_fd = fd; + rc = ctx->output_notify_fnc (ctx, line); + if (rc) + ctx->output_fd = oldfd; + } + else if (!rc) ctx->output_fd = fd; return PROCESS_DONE (ctx, rc); } Modified: trunk/src/assuan-inquire.c =================================================================== --- trunk/src/assuan-inquire.c 2010-02-03 17:00:09 UTC (rev 356) +++ trunk/src/assuan-inquire.c 2010-02-24 15:50:55 UTC (rev 357) @@ -183,15 +183,23 @@ linelen = ctx->inbound.linelen; } while (*line == '#' || !linelen); - if (line[0] == 'E' && line[1] == 'N' && line[2] == 'D' + + /* Note: As a convenience for manual testing we allow case + insensitive keywords. */ + if ((line[0] == 'E'||line[0] == 'e') + && (line[1] == 'N' || line[1] == 'n') + && (line[2] == 'D' || line[2] == 'd') && (!line[3] || line[3] == ' ')) break; /* END command received*/ - if (line[0] == 'C' && line[1] == 'A' && line[2] == 'N') + if ((line[0] == 'C' || line[0] == 'c') + && (line[1] == 'A' || line[1] == 'a') + && (line[2] == 'N' || line[2] == 'n')) { rc = _assuan_error (ctx, GPG_ERR_ASS_CANCELED); goto leave; } - if (line[0] != 'D' || line[1] != ' ' || nodataexpected) + if ((line[0] != 'D' && line[0] != 'd') + || line[1] != ' ' || nodataexpected) { rc = _assuan_error (ctx, GPG_ERR_ASS_UNEXPECTED_CMD); goto leave; @@ -268,19 +276,23 @@ linelen = ctx->inbound.linelen; mb = ctx->inquire_membuf; - if (line[0] == 'C' && line[1] == 'A' && line[2] == 'N') + if ((line[0] == 'C' || line[0] == 'c') + && (line[1] == 'A' || line[1] == 'a') + && (line[2] == 'N' || line[2] == 'n')) { rc = _assuan_error (ctx, GPG_ERR_ASS_CANCELED); goto leave; } - if (line[0] == 'E' && line[1] == 'N' && line[2] == 'D' + if ((line[0] == 'E'||line[0] == 'e') + && (line[1] == 'N' || line[1] == 'n') + && (line[2] == 'D' || line[2] == 'd') && (!line[3] || line[3] == ' ')) { rc = 0; goto leave; } - if (line[0] != 'D' || line[1] != ' ' || mb == NULL) + if ((line[0] != 'D' && line[0] != 'd') || line[1] != ' ' || mb == NULL) { rc = _assuan_error (ctx, GPG_ERR_ASS_UNEXPECTED_CMD); goto leave; @@ -344,8 +356,8 @@ * @cb: A callback handler which is invoked after the operation completed. * @cb_data: A user-provided value passed to the callback handler. * - * A Server may use this to Send an inquire. r_buffer, r_length and - * maxlen may all be NULL/0 to indicate that no real data is expected. + * A server may use this to send an inquire. R_BUFFER, R_LENGTH and + * MAXLEN may all be NULL/0 to indicate that no real data is expected. * When this function returns, * * Return value: 0 on success or an ASSUAN error code Modified: trunk/src/assuan-pipe-connect.c =================================================================== --- trunk/src/assuan-pipe-connect.c 2010-02-03 17:00:09 UTC (rev 356) +++ trunk/src/assuan-pipe-connect.c 2010-02-24 15:50:55 UTC (rev 357) @@ -382,7 +382,7 @@ pipes are usually created using the `socketpair' function. It also enables features only available with such servers. - Bit 7: If set and there is a need to start ther server it will be + Bit 7: If set and there is a need to start the server it will be started as a background process. This flag is useful under W32 systems, so that no new console is created and pops up a console window when starting the server Modified: trunk/src/assuan-socket-connect.c =================================================================== --- trunk/src/assuan-socket-connect.c 2010-02-03 17:00:09 UTC (rev 356) +++ trunk/src/assuan-socket-connect.c 2010-02-24 15:50:55 UTC (rev 357) @@ -23,13 +23,18 @@ #include #include #include +#ifdef HAVE_STDINT_H +# include +#endif #include #include -#ifndef HAVE_W32_SYSTEM -#include -#include +#ifdef HAVE_W32_SYSTEM +# include #else -#include +# include +# include +# include +# include #endif #include "assuan-defs.h" @@ -53,19 +58,74 @@ #endif +#undef WITH_IPV6 +#if defined (AF_INET6) && defined(PF_INET) \ + && defined (INET6_ADDRSTRLEN) && defined(HAVE_INET_PTON) +# define WITH_IPV6 1 +#endif + + + +/* Returns true if STR represents a valid port number in decimal + notation and no garbage is following. */ +static int +parse_portno (const char *str, uint16_t *r_port) +{ + unsigned int value; + + for (value=0; *str && (*str >= '0' && *str <= '9'); str++) + { + value = value * 10 + (*str - '0'); + if (value > 65535) + return 0; + } + if (*str || !value) + return 0; + + *r_port = value; + return 1; +} + + + /* Make a connection to the Unix domain socket NAME and return a new Assuan context in CTX. SERVER_PID is currently not used but may - become handy in the future. With flags set to 1 sendmsg and - recvmsg are used. */ + become handy in the future. Defined flag bits are: + + ASSUAN_SOCKET_CONNECT_FDPASSING + sendmsg and recvmsg are used. + + NAME must either start with a slash and optional with a drive + prefix ("c:") or use one of these URL schemata: + + file:// + + This is the same as the defualt just with an explicit schemata. + + assuan://: + assuan://[]: + + Connect using TCP to PORT of the server with the numerical + IPADDR. Not that the '[' and ']' are literal characters. + + */ gpg_error_t assuan_socket_connect (assuan_context_t ctx, const char *name, pid_t server_pid, unsigned int flags) { - gpg_error_t err; + gpg_error_t err = 0; assuan_fd_t fd; - struct sockaddr_un srvr_addr; - size_t len; +#ifdef WITH_IPV6 + struct sockaddr_in6 srvr_addr_in6; +#endif + struct sockaddr_un srvr_addr_un; + struct sockaddr_in srvr_addr_in; + struct sockaddr *srvr_addr = NULL; + uint16_t port = 0; + size_t len = 0; const char *s; + int af = AF_LOCAL; + int pf = PF_LOCAL; TRACE2 (ctx, ASSUAN_LOG_CTX, "assuan_socket_connect", ctx, "name=%s, flags=0x%x", name ? name : "(null)", flags); @@ -73,38 +133,127 @@ if (!ctx || !name) return _assuan_error (ctx, GPG_ERR_ASS_INV_VALUE); - /* We require that the name starts with a slash, so that we - eventually can reuse this function for other socket types. To - make things easier we allow an optional driver prefix. */ - s = name; - if (*s && s[1] == ':') - s += 2; - if (*s != DIRSEP_C && *s != '/') - return _assuan_error (ctx, GPG_ERR_ASS_INV_VALUE); + if (!strncmp (name, "file://", 7) && name[7]) + name += 7; + else if (!strncmp (name, "assuan://", 9) && name[9]) + { + name += 9; + af = AF_INET; + pf = PF_INET; + } + else /* Default. */ + { + /* We require that the name starts with a slash if no URL + schemata is used. To make things easier we allow an optional + driver prefix. */ + s = name; + if (*s && s[1] == ':') + s += 2; + if (*s != DIRSEP_C && *s != '/') + return _assuan_error (ctx, GPG_ERR_ASS_INV_VALUE); + } - if (strlen (name)+1 >= sizeof srvr_addr.sun_path) - return _assuan_error (ctx, GPG_ERR_ASS_INV_VALUE); + if (af == AF_LOCAL) + { + if (strlen (name)+1 >= sizeof srvr_addr_un.sun_path) + return _assuan_error (ctx, GPG_ERR_ASS_INV_VALUE); - fd = _assuan_sock_new (ctx, PF_LOCAL, SOCK_STREAM, 0); + memset (&srvr_addr_un, 0, sizeof srvr_addr_un); + srvr_addr_un.sun_family = AF_LOCAL; + strncpy (srvr_addr_un.sun_path, name, sizeof (srvr_addr_un.sun_path) - 1); + srvr_addr_un.sun_path[sizeof (srvr_addr_un.sun_path) - 1] = 0; + len = SUN_LEN (&srvr_addr_un); + + srvr_addr = (struct sockaddr *)&srvr_addr_un; + } + else + { + char *addrstr, *p; + void *addrbuf = NULL; + + addrstr = _assuan_malloc (ctx, strlen (name) + 1); + if (!addrstr) + return _assuan_error (ctx, gpg_err_code_from_syserror ()); + + if (*addrstr == '[') + { + strcpy (addrstr, name+1); + p = strchr (addrstr, ']'); + if (!p || p[1] != ':' || !parse_portno (p+2, &port)) + err = _assuan_error (ctx, GPG_ERR_BAD_URI); + else + { + *p = 0; +#ifdef WITH_IPV6 + af = AF_INET6; + pf = PF_INET6; + memset (&srvr_addr_in6, 0, sizeof srvr_addr_in6); + srvr_addr_in6.sin6_family = af; + srvr_addr_in6.sin6_port = htons (port); + addrbuf = &srvr_addr_in6.sin6_addr; + srvr_addr = (struct sockaddr *)&srvr_addr_in6; + len = sizeof srvr_addr_in6; +#else + err = _assuan_error (ctx, GPG_ERR_EAFNOSUPPORT); +#endif + } + } + else + { + strcpy (addrstr, name); + p = strchr (addrstr, ':'); + if (!p || !parse_portno (p+1, &port)) + err = _assuan_error (ctx, GPG_ERR_BAD_URI); + else + { + *p = 0; + memset (&srvr_addr_in, 0, sizeof srvr_addr_in); + srvr_addr_in.sin_family = af; + srvr_addr_in.sin_port = htons (port); + addrbuf = &srvr_addr_in.sin_addr; + srvr_addr = (struct sockaddr *)&srvr_addr_in; + len = sizeof srvr_addr_in; + } + } + + if (!err) + { +#ifdef HAVE_INET_PTON + switch (inet_pton (af, addrstr, addrbuf)) + { + case 1: break; + case 0: err = _assuan_error (ctx, GPG_ERR_BAD_URI); break; + default: err = _assuan_error (ctx, gpg_err_code_from_syserror ()); + } +#else /*!HAVE_INET_PTON*/ + /* We need to use the old function. If we are here v6 + support isn't enabled anyway and thus we can do fine + without. Note that Windows as a compatible inet_pton + function named inetPton, but only since Vista. */ + srvr_addr_in.sin_addr.s_addr = inet_addr (addrstr); + if (srvr_addr_in.sin_addr.s_addr == INADDR_NONE) + err = _assuan_error (ctx, GPG_ERR_BAD_URI); +#endif /*!HAVE_INET_PTON*/ + } + + _assuan_free (ctx, addrstr); + if (err) + return err; + } + + fd = _assuan_sock_new (ctx, pf, SOCK_STREAM, 0); if (fd == ASSUAN_INVALID_FD) { - TRACE1 (ctx, ASSUAN_LOG_SYSIO, "assuan_socket_connect_ext", ctx, - "can't create socket: %s", strerror (errno)); - /* FIXME: Cleanup */ - return _assuan_error (ctx, GPG_ERR_ASS_GENERAL); + err = _assuan_error (ctx, gpg_err_code_from_syserror ()); + TRACE1 (ctx, ASSUAN_LOG_SYSIO, "assuan_socket_connect", ctx, + "can't create socket: %s", strerror (errno)); + return err; } - memset (&srvr_addr, 0, sizeof srvr_addr); - srvr_addr.sun_family = AF_LOCAL; - strncpy (srvr_addr.sun_path, name, sizeof (srvr_addr.sun_path) - 1); - srvr_addr.sun_path[sizeof (srvr_addr.sun_path) - 1] = 0; - len = SUN_LEN (&srvr_addr); - - if (_assuan_sock_connect (ctx, fd, (struct sockaddr *) &srvr_addr, len) == -1) + if (_assuan_sock_connect (ctx, fd, srvr_addr, len) == -1) { - TRACE2 (ctx, ASSUAN_LOG_SYSIO, "assuan_socket_connect_ext", ctx, + TRACE2 (ctx, ASSUAN_LOG_SYSIO, "assuan_socket_connect", ctx, "can't connect to `%s': %s\n", name, strerror (errno)); - /* FIXME: Cleanup */ _assuan_close (ctx, fd); return _assuan_error (ctx, GPG_ERR_ASS_CONNECT_FAILED); } @@ -129,14 +278,14 @@ err = _assuan_read_from_server (ctx, &response, &off); if (err) - TRACE1 (ctx, ASSUAN_LOG_SYSIO, "assuan_socket_connect_ext", ctx, + TRACE1 (ctx, ASSUAN_LOG_SYSIO, "assuan_socket_connect", ctx, "can't connect to server: %s\n", gpg_strerror (err)); else if (response != ASSUAN_RESPONSE_OK) { char *sname = _assuan_encode_c_string (ctx, ctx->inbound.line); if (sname) { - TRACE1 (ctx, ASSUAN_LOG_SYSIO, "assuan_socket_connect_ext", ctx, + TRACE1 (ctx, ASSUAN_LOG_SYSIO, "assuan_socket_connect", ctx, "can't connect to server: %s", sname); _assuan_free (ctx, sname); } Modified: trunk/src/assuan.h =================================================================== --- trunk/src/assuan.h 2010-02-03 17:00:09 UTC (rev 356) +++ trunk/src/assuan.h 2010-02-24 15:50:55 UTC (rev 357) @@ -199,6 +199,10 @@ /* Release all resources associated with the given context. */ void assuan_release (assuan_context_t ctx); +/* Release the memory at PTR using the allocation handler of the + context CTX. This is a convenience function. */ +void assuan_free (assuan_context_t ctx, void *ptr); + /* Set user-data in a context. */ void assuan_set_pointer (assuan_context_t ctx, void *pointer); @@ -634,7 +638,14 @@ extern struct assuan_system_hooks _assuan_system_pth; #define ASSUAN_SYSTEM_PTH &_assuan_system_pth +#ifdef __MINGW32CE__ +/* FIXME: Include this code only if build for this platform. */ +DWORD _assuan_w32ce_create_pipe (HANDLE *read_hd, HANDLE *write_hd, + LPSECURITY_ATTRIBUTES sec_attr, DWORD size); +#define CreatePipe(a,b,c,d) _assuan_w32ce_create_pipe ((a),(b),(c),(d)) +#endif /*__MINGW32CE__*/ + #ifdef __cplusplus } #endif Added: trunk/src/gpgcedev.c =================================================================== --- trunk/src/gpgcedev.c (rev 0) +++ trunk/src/gpgcedev.c 2010-02-24 15:50:55 UTC (rev 357) @@ -0,0 +1,720 @@ +/* gpgcedrv.c - WindowsCE device driver to implement a pipe. + Copyright (C) 2010 Free Software Foundation, Inc. + + This file is part of Assuan. + + Assuan is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 3 of + the License, or (at your option) any later version. + + Assuan 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, see . + */ + +#include +#include +#include +#include +#include + +#define ENABLE_DEBUG +#warning Cancel and caller process termination not handled. + + +/* Missing IOCTLs in the current mingw32ce. */ +#ifndef IOCTL_PSL_NOTIFY +# define FILE_DEVICE_PSL 259 +# define IOCTL_PSL_NOTIFY \ + CTL_CODE (259, 255, METHOD_NEITHER, FILE_ANY_ACCESS) +#endif /*IOCTL_PSL_NOTIFY*/ + + +/* The IOCTL used to tell the device about the handle. + + The required inbuf parameter is the address of a variable holding + the handle. */ +#define GPGCEDEV_IOCTL_SET_HANDLE \ + CTL_CODE (FILE_DEVICE_STREAMS, 2048, METHOD_BUFFERED, FILE_ANY_ACCESS) + +/* The IOCTL used to create the pipe. + + The caller sends this IOCTL to the read handle. The required inbuf + parameter is the address of variable holding the write handle. + Note that the SET_HANDLE IOCTLs must have been used prior to this + one. */ +#define GPGCEDEV_IOCTL_MAKE_PIPE \ + CTL_CODE (FILE_DEVICE_STREAMS, 2049, METHOD_BUFFERED, FILE_ANY_ACCESS) + + +/* An object to store information pertaining to an open-context. */ +struct opnctx_s; +typedef struct opnctx_s *opnctx_t; +struct opnctx_s +{ + int inuse; /* True if this object has valid data. */ + opnctx_t assoc; /* This context has been associated with this + other context; i.e. a pipe has been + established. */ + int is_write; /* True if this is the write end of the pipe. */ + HANDLE hd; /* The system's handle object or INVALID_HANDLE_VALUE. */ + DWORD access_code;/* Value from OpenFile. */ + DWORD share_mode; /* Value from OpenFile. */ + CRITICAL_SECTION critsect; /* Lock for all operations. */ + int locked; /* True if we are in a critical section. */ + + /* The malloced buffer and its size. We use a buffer for each + handle which allows us eventually implement a system to + distribute data to several handles. Not sure whether this is + really needed but as a side effect it makes the code easier. */ + char *buffer; + size_t buffer_size; + size_t buffer_len; /* The valid length of the bufer. */ + size_t buffer_pos; /* The actual read or write position. */ + + HANDLE space_available; /* Set if space is available. */ + HANDLE data_available; /* Set if data is available. */ +}; + +/* A malloced table of open-context and the number of allocated slots. */ +static opnctx_t opnctx_table; +static size_t opnctx_table_size; + +/* A criticial section object used to protect the OPNCTX_TABLE. */ +static CRITICAL_SECTION opnctx_table_cs; + +/* We don't need a device context thus we use the adress of the + critical section object for it. */ +#define DEVCTX_VALUE ((DWORD)(&opnctx_table_cs)) + +/* Constants used for our lock functions. */ +#define LOCK_TRY 0 +#define LOCK_WAIT 1 + + + +static void +log_debug (const char *fmt, ...) +{ +#ifndef ENABLE_DEBUG + (void)fmt; +#else + va_list arg_ptr; + FILE *fp; + + fp = fopen ("\\gpgcedev.log", "a+"); + if (!fp) + return; + va_start (arg_ptr, fmt); + vfprintf (fp, fmt, arg_ptr); + va_end (arg_ptr); + fclose (fp); +#endif +} + + + + +/* Return a new opnctx handle and mark it as used. Returns NULL and + sets LastError on memory failure etc. On success the context is + locked. */ +static opnctx_t +get_new_opnctx (void) +{ + opnctx_t opnctx = NULL; + int idx; + + EnterCriticalSection (&opnctx_table_cs); + for (idx=0; idx < opnctx_table_size; idx++) + if (!opnctx_table[idx].inuse) + break; + if (idx == opnctx_table_size) + { + /* We need to increase the size of the table. The approach we + take is straightforward to minimize the risk of bugs. */ + opnctx_t newtbl; + size_t newsize = opnctx_table_size + 64; + + newtbl = calloc (newsize, sizeof *newtbl); + if (!newtbl) + goto leave; + for (idx=0; idx < opnctx_table_size; idx++) + newtbl[idx] = opnctx_table[idx]; + free (opnctx_table); + opnctx_table = newtbl; + idx = opnctx_table_size; + opnctx_table_size = newsize; + } + opnctx = opnctx_table + idx; + opnctx->assoc = NULL; + opnctx->hd = INVALID_HANDLE_VALUE; + opnctx->assoc = 0; + opnctx->buffer_size = 512; + opnctx->buffer = malloc (opnctx->buffer_size); + if (!opnctx->buffer) + { + opnctx = NULL; + goto leave; + } + opnctx->buffer_len = 0; + opnctx->buffer_pos = 0; + opnctx->data_available = INVALID_HANDLE_VALUE; + opnctx->space_available = INVALID_HANDLE_VALUE; + + opnctx->inuse = 1; + InitializeCriticalSection (&opnctx->critsect); + EnterCriticalSection (&opnctx->critsect); + opnctx->locked = 1; + + leave: + LeaveCriticalSection (&opnctx_table_cs); + log_debug ("get_new_opnctx -> %p\n", opnctx); + return opnctx; +} + + +/* Find the OPNCTX for handle HD. */ +static opnctx_t +find_and_lock_opnctx (HANDLE hd) +{ + opnctx_t result = NULL; + int idx; + + EnterCriticalSection (&opnctx_table_cs); + for (idx=0; idx < opnctx_table_size; idx++) + if (opnctx_table[idx].inuse && opnctx_table[idx].hd == hd) + { + result = opnctx_table + idx; + break; + } + LeaveCriticalSection (&opnctx_table_cs); + if (!result) + SetLastError (ERROR_INVALID_HANDLE); + else if (TryEnterCriticalSection (&result->critsect)) + result->locked++; + else + { + SetLastError (ERROR_BUSY); + result = NULL; + } + log_debug ("find_opnctx -> %p\n", result); + return result; +} + + +/* Check that OPNCTX is valid. Returns TRUE if it is valid or FALSE + if it is a bad or closed contect. In the latter case SetLastError + is called. In the former case a lock is taken and unlock_opnctx + needs to be called. If WAIT is false the fucntion only tries to + acquire a lock. */ +static BOOL +validate_and_lock_opnctx (opnctx_t opnctx, int wait) +{ + BOOL result = FALSE; + int idx; + + EnterCriticalSection (&opnctx_table_cs); + for (idx=0; idx < opnctx_table_size; idx++) + if (opnctx_table[idx].inuse && (opnctx_table + idx) == opnctx) + { + result = TRUE; + break; + } + LeaveCriticalSection (&opnctx_table_cs); + + if (!result) + SetLastError (ERROR_INVALID_HANDLE); + else if (wait) + { + EnterCriticalSection (&opnctx->critsect); + opnctx->locked++; + } + else if (TryEnterCriticalSection (&opnctx->critsect)) + opnctx->locked++; + else + { + SetLastError (ERROR_BUSY); + result = FALSE; + } + return result; +} + + +static void +unlock_opnctx (opnctx_t opnctx) +{ + opnctx->locked--; + LeaveCriticalSection (&opnctx->critsect); +} + + + + +static char * +wchar_to_utf8 (const wchar_t *string) +{ + int n; + size_t length = wcslen (string); + char *result; + + n = WideCharToMultiByte (CP_UTF8, 0, string, length, NULL, 0, NULL, NULL); + if (n < 0 || (n+1) <= 0) + abort (); + + result = malloc (n+1); + if (!result) + abort (); + n = WideCharToMultiByte (CP_ACP, 0, string, length, result, n, NULL, NULL); + if (n < 0) + abort (); + + result[n] = 0; + return result; +} + + +/* Initialize the device and return a device specific context. */ +DWORD +GPG_Init (LPCTSTR active_key, DWORD bus_context) +{ + char *tmpbuf; + (void)bus_context; + + tmpbuf = wchar_to_utf8 (active_key); + log_debug ("GPG_Init (%s)\n", tmpbuf); + free (tmpbuf); + + /* We don't need any global data. However, we need to return + something. */ + return DEVCTX_VALUE; +} + + + +/* Deinitialize this device driver. */ +BOOL +GPG_Deinit (DWORD devctx) +{ + log_debug ("GPG_Deinit (%p)\n", (void*)devctx); + if (devctx != DEVCTX_VALUE) + { + SetLastError (ERROR_INVALID_PARAMETER); + return FALSE; /* Error. */ + } + + /* FIXME: Release resources. */ + + return TRUE; /* Success. */ +} + + + +/* Create a new open context. This fucntion is called due to a + CreateFile from the application. */ +DWORD +GPG_Open (DWORD devctx, DWORD access_code, DWORD share_mode) +{ + opnctx_t opnctx; + + log_debug ("GPG_Open(devctx=%p)\n", (void*)devctx); + if (devctx != DEVCTX_VALUE) + { + SetLastError (ERROR_INVALID_PARAMETER); + return 0; /* Error. */ + } + + opnctx = get_new_opnctx (); + if (!opnctx) + return 0; + opnctx->access_code = access_code; + opnctx->share_mode = share_mode; + + unlock_opnctx (opnctx); + return (DWORD)opnctx; +} + + + +BOOL +GPG_Close (DWORD opnctx_arg) +{ + opnctx_t opnctx = (opnctx_t)opnctx_arg; + BOOL result = FALSE; + int idx; + + log_debug ("GPG_Close(%p)\n", (void*)opnctx); + + EnterCriticalSection (&opnctx_table_cs); + for (idx=0; idx < opnctx_table_size; idx++) + if (opnctx_table[idx].inuse && (opnctx_table + idx) == opnctx) + { + if (opnctx->hd != INVALID_HANDLE_VALUE) + { + if (opnctx->assoc) + { + opnctx->assoc->assoc = NULL; + opnctx->assoc = NULL; + } + opnctx->hd = INVALID_HANDLE_VALUE; + } + if (opnctx->locked) + { + /* FIXME: Check earlier or use close only in locked state + or use PReClose. */ + log_debug ("GPG_Close while still locked\n"); + } + DeleteCriticalSection (&opnctx->critsect); + if (opnctx->buffer) + { + free (opnctx->buffer); + opnctx->buffer = NULL; + opnctx->buffer_size = 0; + } + if (opnctx->space_available != INVALID_HANDLE_VALUE) + { + CloseHandle (opnctx->space_available); + opnctx->space_available = INVALID_HANDLE_VALUE; + } + if (opnctx->data_available != INVALID_HANDLE_VALUE) + { + CloseHandle (opnctx->data_available); + opnctx->data_available = INVALID_HANDLE_VALUE; + } + opnctx->inuse = 0; + result = TRUE; + break; + } + LeaveCriticalSection (&opnctx_table_cs); + + if (!result) + SetLastError (ERROR_INVALID_HANDLE); + return result; +} + + + +DWORD +GPG_Read (DWORD opnctx_arg, void *buffer, DWORD count) +{ + opnctx_t rctx = (opnctx_t)opnctx_arg; + opnctx_t wctx; + int result = -1; + const char *src; + char *dst; + + log_debug ("GPG_Read(%p, count=%d)\n", (void*)rctx, count); + + /* We use the write end's buffer, thus there is no need to wait for + our (read end) lock. */ + if (!validate_and_lock_opnctx (rctx, LOCK_TRY)) + return -1; /* Error. */ + + if (rctx->is_write) + { + SetLastError (ERROR_INVALID_ACCESS); + goto leave; + } + if (rctx->hd == INVALID_HANDLE_VALUE || !rctx->assoc) + { + SetLastError (ERROR_BROKEN_PIPE); + goto leave; + } + + /* Read from the corresponding write buffer. */ + retry: + wctx = rctx->assoc; + if (!validate_and_lock_opnctx (wctx, LOCK_WAIT)) + goto leave; + + if (wctx->buffer_pos == wctx->buffer_len) + { + unlock_opnctx (wctx); + log_debug ("%s:%d: WFSO(data_available)\n", __func__, __LINE__); + WaitForSingleObject (wctx->data_available, INFINITE); + log_debug ("%s:%d: WFSO ... woke up\n", __func__, __LINE__); + goto retry; + } + + dst = buffer; + src = wctx->buffer + wctx->buffer_pos; + while (count > 0 && wctx->buffer_pos < wctx->buffer_len) + { + *dst++ = *src++; + count--; + wctx->buffer_pos++; + } + result = (dst - (char*)buffer); + if (wctx->buffer_pos == wctx->buffer_len) + wctx->buffer_pos = wctx->buffer_len = 0; + + /* Now there should be some space available. Signal the write end. + Even if COUNT was passed as NULL and no space is available, + signaling must be done. */ + if (!SetEvent (wctx->space_available)) + { + log_debug ("%s:%d: SetEvent(space_available) failed: rc=%d\n", + __func__, __LINE__, (int)GetLastError ()); + unlock_opnctx (wctx); + goto leave; + } + unlock_opnctx (wctx); + + leave: + unlock_opnctx (rctx); + return result; +} + + + +DWORD +GPG_Write (DWORD opnctx_arg, const void *buffer, DWORD count) +{ + opnctx_t wctx = (opnctx_t)opnctx_arg; + int result = -1; + const char *src; + char *dst; + size_t nwritten = 0; + + log_debug ("GPG_Write(%p, count=%d)\n", (void*)wctx, count); + retry: + if (!validate_and_lock_opnctx (wctx, LOCK_WAIT)) + return -1; /* Error. */ + + if (!wctx->is_write) + { + SetLastError (ERROR_INVALID_ACCESS); + goto leave; + } + if (wctx->hd == INVALID_HANDLE_VALUE || !wctx->assoc) + { + SetLastError (ERROR_BROKEN_PIPE); + goto leave; + } + if (!count) + { + result = 0; + goto leave; + } + + /* Write to our buffer. */ + if (wctx->buffer_len == wctx->buffer_size) + { + /* Buffer is full. */ + unlock_opnctx (wctx); + log_debug ("%s:%d: WFSO(space_available)\n", __func__, __LINE__); + WaitForSingleObject (wctx->space_available, INFINITE); + log_debug ("%s:%d: WFSO ... woke up\n", __func__, __LINE__); + goto retry; + } + + src = buffer; + dst = wctx->buffer + wctx->buffer_len; + while (count > 0 && wctx->buffer_len < wctx->buffer_size) + { + *dst++ = *src++; + count--; + wctx->buffer_len++; + nwritten++; + } + if (!SetEvent (wctx->data_available)) + { + log_debug ("%s:%d: SetEvent(data_available) failed: rc=%d\n", + __func__, __LINE__, (int)GetLastError ()); + goto leave; + } + result = nwritten; + + leave: + unlock_opnctx (wctx); + return result; +} + + + +DWORD +GPG_Seek (DWORD opnctx, long amount, WORD type) +{ + SetLastError (ERROR_SEEK_ON_DEVICE); + return -1; /* Error. */ +} + + + +static BOOL +set_handle (opnctx_t opnctx, HANDLE hd) +{ + log_debug (" set_handle(%p, hd=%p)\n", opnctx, hd); + if (opnctx->hd != INVALID_HANDLE_VALUE) + { + SetLastError (ERROR_ALREADY_ASSIGNED); + return FALSE; + } + opnctx->hd = hd; + return TRUE; +} + +static BOOL +make_pipe (opnctx_t rctx, HANDLE hd) +{ + BOOL result = FALSE; + opnctx_t wctx = NULL; + + log_debug (" make_pipe(%p, hd=%p)\n", rctx, hd); + if (rctx->hd == INVALID_HANDLE_VALUE) + { + SetLastError (ERROR_NOT_READY); + goto leave; + } + if (rctx->assoc) + { + SetLastError (ERROR_ALREADY_ASSIGNED); + goto leave; + } + if (!(rctx->access_code & GENERIC_READ)) + { + SetLastError (ERROR_INVALID_ACCESS); + goto leave; + } + + wctx = find_and_lock_opnctx (hd); + if (!wctx) + { + SetLastError (ERROR_NOT_FOUND); + goto leave; + } + if (wctx == rctx) + { + SetLastError (ERROR_INVALID_TARGET_HANDLE); + goto leave; + } + if (wctx->hd == INVALID_HANDLE_VALUE) + { + SetLastError (ERROR_NOT_READY); + goto leave; + } + if (wctx->assoc) + { + SetLastError (ERROR_ALREADY_ASSIGNED); + goto leave; + } + if (!(wctx->access_code & GENERIC_WRITE)) + { + SetLastError (ERROR_INVALID_ACCESS); + goto leave; + } + wctx->space_available = CreateEvent (NULL, FALSE, FALSE, NULL); + wctx->data_available = CreateEvent (NULL, FALSE, FALSE, NULL); + + rctx->assoc = wctx; + wctx->assoc = rctx; + rctx->is_write = 0; + wctx->is_write = 1; + result = TRUE; + + leave: + if (wctx) + unlock_opnctx (wctx); + return result; +} + + +BOOL +GPG_IOControl (DWORD opnctx_arg, DWORD code, void *inbuf, DWORD inbuflen, + void *outbuf, DWORD outbuflen, DWORD *actualoutlen) +{ + opnctx_t opnctx = (opnctx_t)opnctx_arg; + BOOL result = FALSE; + + log_debug ("GPG_IOControl(%p, %d)\n", (void*)opnctx, code); + if (!validate_and_lock_opnctx (opnctx, LOCK_TRY)) + return FALSE; + + switch (code) + { + case GPGCEDEV_IOCTL_SET_HANDLE: + if (!opnctx || !inbuf || inbuflen < sizeof (HANDLE) + || outbuf || outbuflen || actualoutlen ) + { + SetLastError (ERROR_INVALID_PARAMETER); + goto leave; + } + if (set_handle (opnctx, *(HANDLE*)inbuf)) + result = TRUE; + break; + + case GPGCEDEV_IOCTL_MAKE_PIPE: + if (!opnctx || !inbuf || inbuflen < sizeof (HANDLE) + || outbuf || outbuflen || actualoutlen ) + { + SetLastError (ERROR_INVALID_PARAMETER); + goto leave; + } + if (make_pipe (opnctx, *(HANDLE*)inbuf)) + result = TRUE; + break; + + case IOCTL_PSL_NOTIFY: + /* Unexpected process termination. */ + break; + + default: + SetLastError (ERROR_INVALID_PARAMETER); + break; + } + + leave: + unlock_opnctx (opnctx); + return result; +} + + + +void +GPG_PowerUp (DWORD devctx) +{ +} + + + +void +GPG_PowerDown (DWORD devctx) +{ +} + + + + +/* Entry point called by the DLL loader. */ +int WINAPI +DllMain (HINSTANCE hinst, DWORD reason, LPVOID reserved) +{ + (void)reserved; + + switch (reason) + { + case DLL_PROCESS_ATTACH: + InitializeCriticalSection (&opnctx_table_cs); + break; + + case DLL_THREAD_ATTACH: + break; + + case DLL_THREAD_DETACH: + break; + + case DLL_PROCESS_DETACH: + DeleteCriticalSection (&opnctx_table_cs); + break; + + default: + break; + } + + return TRUE; +} + Added: trunk/src/gpgcedev.def =================================================================== --- trunk/src/gpgcedev.def (rev 0) +++ trunk/src/gpgcedev.def 2010-02-24 15:50:55 UTC (rev 357) @@ -0,0 +1,33 @@ +; gpgcedev.def - List of symbols to export for gpgcedev. +; Copyright (C) 2010 Free Software Foundation, Inc. +; +; This file is part of Assuan. +; +; Assuan is free software; you can redistribute it and/or modify it +; under the terms of the GNU Lesser General Public License as +; published by the Free Software Foundation; either version 3 of +; the License, or (at your option) any later version. +; +; Assuan 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 +; Lesser General Public License for more details. +; +; You should have received a copy of the GNU Lesser General Public +; License along with this program; if not, see . + + +EXPORTS + GPG_Init + GPG_Deinit + GPG_Open + GPG_Close + GPG_Read + GPG_Write + GPG_Seek + GPG_IOControl + GPG_PowerUp + GPG_PowerDown + +; END + Added: trunk/src/gpgcemgr.c =================================================================== --- trunk/src/gpgcemgr.c (rev 0) +++ trunk/src/gpgcemgr.c 2010-02-24 15:50:55 UTC (rev 357) @@ -0,0 +1,72 @@ +/* gpgcempg.c - Manager fopr GPG CE devices + Copyright (C) 2010 Free Software Foundation, Inc. + + This file is part of Assuan. + + Assuan is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 3 of + the License, or (at your option) any later version. + + Assuan 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, see . + */ + +#define _WIN32_WCE 0x0500 + +#include +#include + +#define PGM "gpgcemgr" + +#warning Fixme: Add support to create the device. + +int +main (int argc, char **argv) +{ + int result = 0; + HANDLE shd; + DEVMGR_DEVICE_INFORMATION dinfo; + + memset (&dinfo, 0, sizeof dinfo); + dinfo.dwSize = sizeof dinfo; + shd = FindFirstDevice (DeviceSearchByLegacyName, L"GPG1:", &dinfo); + if (shd == INVALID_HANDLE_VALUE) + { + if (GetLastError () == 18) + fprintf (stderr, PGM": device not found\n"); + else + { + fprintf (stderr, PGM": FindFirstDevice failed: rc=%d\n", + (int)GetLastError ()); + result = 1; + } + } + else + { + fprintf (stderr, PGM": ActivateDevice handle is %p\n", dinfo.hDevice); + if (dinfo.hDevice && dinfo.hDevice != INVALID_HANDLE_VALUE) + { + if (!DeactivateDevice (dinfo.hDevice)) + { + fprintf (stderr, PGM": DeactivateDevice failed: rc=%d\n", + (int)GetLastError ()); + result = 1; + } + else + fprintf (stderr, PGM": DeactivateDevice succeeded\n"); + } + FindClose (shd); + } + fflush (stdout); + fflush (stderr); + Sleep (1000); + return result; +} + + Modified: trunk/src/libassuan.def =================================================================== --- trunk/src/libassuan.def 2010-02-03 17:00:09 UTC (rev 356) +++ trunk/src/libassuan.def 2010-02-24 15:50:55 UTC (rev 357) @@ -97,5 +97,8 @@ assuan_client_read_response @76 assuan_client_parse_response @77 assuan_set_sock_nonce @78 + _assuan_w32ce_create_pipe @79 + assuan_free @80 + ; END Modified: trunk/src/libassuan.vers =================================================================== --- trunk/src/libassuan.vers 2010-02-03 17:00:09 UTC (rev 356) +++ trunk/src/libassuan.vers 2010-02-24 15:50:55 UTC (rev 357) @@ -97,6 +97,7 @@ assuan_transact; assuan_write_line; assuan_write_status; + assuan_free; __assuan_close; __assuan_pipe; Modified: trunk/src/system.c =================================================================== --- trunk/src/system.c 2010-02-03 17:00:09 UTC (rev 356) +++ trunk/src/system.c 2010-02-24 15:50:55 UTC (rev 357) @@ -113,6 +113,16 @@ ctx->malloc_hooks.free (ptr); } + +/* Release the memory at PTR using the allocation handler of the + context CTX. This is a convenience function. */ +void +assuan_free (assuan_context_t ctx, void *ptr) +{ + _assuan_free (ctx, ptr); +} + + /* Copy the system hooks struct, paying attention to version differences. SRC is usually from the user, DST MUST be from the @@ -203,19 +213,13 @@ sec_attr.nLength = sizeof (sec_attr); sec_attr.bInheritHandle = FALSE; -#ifdef HAVE_W32CE_SYSTEM -# warning Implement a CreatePipe Replacement. - gpg_err_set_errno (EIO); - return -1; -#else - if (! CreatePipe (&rh, &wh, &sec_attr, 0)) + if (!CreatePipe (&rh, &wh, &sec_attr, 0)) { TRACE1 (ctx, ASSUAN_LOG_SYSIO, "__assuan_pipe", ctx, "CreatePipe failed: %s", _assuan_w32_strerror (ctx, -1)); gpg_err_set_errno (EIO); return -1; } -#endif From cvs at cvs.gnupg.org Thu Feb 25 14:03:16 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 25 Feb 2010 14:03:16 +0100 Subject: [svn] assuan - r358 - in trunk: . m4 Message-ID: Author: wk Date: 2010-02-25 14:03:16 +0100 (Thu, 25 Feb 2010) New Revision: 358 Modified: trunk/ChangeLog trunk/m4/libtool.m4 Log: Fix DLL creation. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2010-02-24 15:50:55 UTC (rev 357) +++ trunk/ChangeLog 2010-02-25 13:03:16 UTC (rev 358) @@ -1,3 +1,8 @@ +2010-02-25 Werner Koch + + * m4/libtool.m4 (_LT_CHECK_MAGIC_METHOD): Fix for non x86 mingw + targets. + 2010-02-24 Werner Koch * tests/ce-server.c: New. Modified: trunk/m4/libtool.m4 =================================================================== --- trunk/m4/libtool.m4 2010-02-24 15:50:55 UTC (rev 357) +++ trunk/m4/libtool.m4 2010-02-25 13:03:16 UTC (rev 358) @@ -3007,6 +3007,17 @@ lt_cv_file_magic_cmd='func_win32_libid' ;; + +mingw32ce*) + # Windows CE is often used with non-x86 platforms and thus the below + # mingw and cegcc checks don't work. It would be possible to + # support other architectures in these checks. However x86 is pretty + # hard coded and changing this would require quite some tests on all + # the platforms to be sure not to break something. Thus we take the + # easy way out and don't check at all. + lt_cv_deplibs_check_method=pass_all + ;; + mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', From cvs at cvs.gnupg.org Thu Feb 25 20:47:37 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 25 Feb 2010 20:47:37 +0100 Subject: [svn] w32pth - r32 - in trunk: . m4 Message-ID: Author: wk Date: 2010-02-25 20:47:37 +0100 (Thu, 25 Feb 2010) New Revision: 32 Added: trunk/m4/gpg-error.m4 trunk/utils.h Modified: trunk/ChangeLog trunk/Makefile.am trunk/NEWS trunk/autogen.sh trunk/configure.ac trunk/ltmain.sh trunk/m4/libtool.m4 trunk/pth.h trunk/w32-io.c trunk/w32-pth.c Log: Ported to Windows CE Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-12-08 21:23:52 UTC (rev 31) +++ trunk/ChangeLog 2010-02-25 19:47:37 UTC (rev 32) @@ -1,3 +1,35 @@ +2010-02-25 Werner Koch + + * utils.h: New. + (set_errno): New. Always use it to change ERRNO. + * w32-io.c (pth_pipe) [W32CE]: Take care of handles being global. + (create_pipe): New. Taken from libassuan. + (pth_pipe): Use it. + + * w32-pth.c: Include utils.h. + [!HAVE_SIGNAL_H]: Don't include signal.h. + (w32_read_registry, getenv) [W32CE]: New. + (destroy_timer): New. + (do_pth_event_free): Use it instead of a CloseHandle. + (w32ce_timer_thread): New. + (create_timer) [W32CE]: Add CE implementation. + (do_pth_wait) : Move timer setting to ... + (set_timer): New. Add code for W32CE. + (w32_strerror, wsa_strerror) [W32CE]: Do not use FormatMessage. + (create_event) [W32CE]: Don't set to synchronize. + + * Makefile.am (libw32pth_la_LIBADD): Use NETLIBS. + * configure.ac [W32CE]: Require gpg-error. + (NETLIBS): New. + * configure.ac: Test for signal.h. + +2010-02-24 Werner Koch + + * ltmain.sh (wrappers_required): Don't set for mingw32ce. + * ltmain.sh: Updated. + + * autogen.sh: Modernized. + 2009-12-08 Marcus Brinkmann * libw32pth.def: Add pth_cancel. @@ -21,11 +53,11 @@ (w32pth_la_LDFLAGS): Remove w32pth_res_ldflag usage. (w32pth_la_LIBADD): Add w32pth_res. * depcomp, compile, INSTALL, missing: Update from automake 1.10. - + 2008-10-17 Marcus Brinkmann Released 2.0.2. - + * configure.ac (W32PTH_LT_CURRENT, W32PTH_LT_AGE): Bump. (W32PTH_LT_REVISION): Reset. @@ -50,7 +82,7 @@ 2008-05-27 Werner Koch * w32-pth.c (_pth_malloc, _pth_calloc, _pth_free): New. Always - use these wrappers to be prepared to change the allocators. + use these wrappers to be prepared to change the allocators. 2008-05-26 Werner Koch @@ -60,7 +92,7 @@ * w32-pth.c (pth_thread_id): New. * libw32pth.def (pth_thread_id): New. - + 2008-03-25 Marcus Brinkmann * debug.h (DEBUG_INFO, DEBUG_CALLS): New macros. @@ -146,11 +178,11 @@ 2007-07-05 Werner Koch - Released 2.0.0 (first release). + Released 2.0.0 (first release). 2007-07-04 Werner Koch - * w32-pth.c: Major rewrite of the event stuff. + * w32-pth.c: Major rewrite of the event stuff. 2007-07-03 Werner Koch @@ -189,9 +221,9 @@ Package created. * w32-pth.c, w32-pth.h: Taken from GnuPG 2.0.4 - - Copyright 2007 g10 Code GmbH + Copyright 2007, 2010 g10 Code GmbH + This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without modifications, as long as this notice is preserved. Modified: trunk/Makefile.am =================================================================== --- trunk/Makefile.am 2009-12-08 21:23:52 UTC (rev 31) +++ trunk/Makefile.am 2010-02-25 19:47:37 UTC (rev 32) @@ -20,7 +20,7 @@ ## Process this file with automake to produce Makefile.in -ACLOCAL_AMFLAGS = +ACLOCAL_AMFLAGS = -I m4 AUTOMAKE_OPTIONS = no-dist-gzip dist-bzip2 DISTCHECK_CONFIGURE_FLAGS = --host=i586-mingw32msvc @@ -49,12 +49,15 @@ uninstall-def-file: -rm $(DESTDIR)$(libdir)/libw32pth.def +# Note that the GPG_ERROR_CFLAGS are only required for W32CE and not +# defined on plain Windows. +libw32pth_la_CFLAGS = $(GPG_ERROR_CFLAGS) libw32pth_la_LDFLAGS = $(no_undefined) $(export_symbols) \ -version-info \ @W32PTH_LT_CURRENT@:@W32PTH_LT_REVISION@:@W32PTH_LT_AGE@ libw32pth_la_DEPENDENCIES = $(w32pth_res) libw32pth.def -libw32pth_la_LIBADD = $(w32pth_res) @LTLIBOBJS@ -lws2_32 -libw32pth_la_SOURCES = pth.h debug.h w32-pth.c w32-io.h w32-io.c +libw32pth_la_LIBADD = $(w32pth_res) @LTLIBOBJS@ $(NETLIBS) $(GPG_ERROR_LIBS) +libw32pth_la_SOURCES = pth.h debug.h w32-pth.c w32-io.h w32-io.c utils.h install-data-local: install-def-file Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-12-08 21:23:52 UTC (rev 31) +++ trunk/NEWS 2010-02-25 19:47:37 UTC (rev 32) @@ -1,3 +1,9 @@ +Noteworthy changes in version 2.0.3 +------------------------------------------------ + + * Support WindowsCE. + + Noteworthy changes in version 2.0.2 (2008-10-17) ------------------------------------------------ Modified: trunk/autogen.sh =================================================================== --- trunk/autogen.sh 2009-12-08 21:23:52 UTC (rev 31) +++ trunk/autogen.sh 2010-02-25 19:47:37 UTC (rev 32) @@ -35,10 +35,26 @@ shift fi +# Convenience option to use certain configure options for some hosts. +myhost="" +myhostsub="" +case "$1" in + --build-w32) + myhost="w32" + ;; + --build-w32ce) + myhost="w32" + myhostsub="ce" + ;; + *) + ;; +esac + + # ***** W32 build script ******* # Used to cross-compile for Windows. -if test "$1" = "--build-w32"; then +if [ "$myhost" = "w32" ]; then tmp=`dirname $0` tsdir=`cd "$tmp"; pwd` shift @@ -48,11 +64,22 @@ fi build=`$tsdir/config.guess` - [ -z "$w32root" ] && w32root="$HOME/w32root" + case $myhostsub in + ce) + [ -z "$w32root" ] && w32root="$HOME/w32ce_root" + toolprefixes="arm-mingw32ce" + extra_options="--with-gpg-error-prefix=${w32root}" + ;; + *) + [ -z "$w32root" ] && w32root="$HOME/w32root" + toolprefixes="i586-mingw32msvc i386-mingw32msvc" + extra_options="" + ;; + esac echo "Using $w32root as standard install directory" >&2 crossbindir= - for host in i586-mingw32msvc i386-mingw32msvc mingw32; do + for host in $toolprefixes; do if ${host}-gcc --version >/dev/null 2>&1 ; then crossbindir=/usr/${host}/bin conf_CC="CC=${host}-gcc" @@ -61,8 +88,10 @@ done if [ -z "$crossbindir" ]; then echo "Cross compiler kit not installed" >&2 - echo "Under Debian GNU/Linux, you may install it using" >&2 - echo " apt-get install mingw32 mingw32-runtime mingw32-binutils" >&2 + if [ -z "$sub" ]; then + echo "Under Debian GNU/Linux, you may install it using" >&2 + echo " apt-get install mingw32 mingw32-runtime mingw32-binutils" >&2 + fi echo "Stop." >&2 exit 1 fi @@ -76,7 +105,7 @@ fi ./configure --enable-maintainer-mode --prefix=${w32root} \ - --host=${host} --build=${build} "$@" + --host=${host} --build=${build} ${extra_options} "$@" exit $? fi @@ -140,8 +169,8 @@ exit 1 fi -echo "Running aclocal ${ACLOCAL_FLAGS:+$ACLOCAL_FLAGS }..." -$ACLOCAL $ACLOCAL_FLAGS +echo "Running aclocal -I m4 ${ACLOCAL_FLAGS:+$ACLOCAL_FLAGS }..." +$ACLOCAL -I m4 $ACLOCAL_FLAGS echo "Running autoheader..." $AUTOHEADER echo "Running automake --gnu ..." @@ -149,4 +178,6 @@ echo "Running autoconf${FORCE} ..." $AUTOCONF${FORCE} -echo "You may now run \"./autogen.sh --build-w32 && make\"." +echo "You may now run + ./autogen.sh --build-w32 && make +" Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2009-12-08 21:23:52 UTC (rev 31) +++ trunk/configure.ac 2010-02-25 19:47:37 UTC (rev 32) @@ -26,8 +26,8 @@ # Remember to change the version number immediately *after* a release. # Set my_issvn to "yes" for non-released code. Remember to run an # "svn up" and "autogen.sh" right before creating a distribution. -m4_define([my_version], [2.0.2]) -m4_define([my_issvn], [no]) +m4_define([my_version], [2.0.3]) +m4_define([my_issvn], [yes]) m4_define([svn_revision], m4_esyscmd([echo -n $( (svn info 2>/dev/null \ || echo 'Revision: 0')|sed -n '/^Revision:/ s/[^0-9]//gp'|head -1)])) @@ -46,6 +46,8 @@ # If the API is changed in an incompatible way: increment the next counter. W32PTH_CONFIG_API_VERSION=1 +NEED_GPG_ERROR_VERSION=1.8 + BUILD_REVISION=svn_revision PACKAGE=$PACKAGE_NAME VERSION=$PACKAGE_VERSION @@ -71,10 +73,23 @@ AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of this package]) AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version of this package]) +# +# Initialize libtool +# +LT_PREREQ([2.2.6]) +LT_INIT([win32-dll disable-static]) +LT_LANG([Windows Resource]) + + # Setup some stuff depending on host/target. have_w32_system=no +have_w32ce_system=no case "${host}" in + *-mingw32ce*) + have_w32_system=yes + have_w32ce_system=yes + ;; *-*-mingw32*) have_w32_system=yes ;; @@ -84,9 +99,14 @@ esac if test "$have_w32_system" = yes; then AC_DEFINE(HAVE_W32_SYSTEM,1, [Defined if we run on a W32 API based system]) + if test "$have_w32ce_system" = yes; then + AC_DEFINE(HAVE_W32CE_SYSTEM,1,[Defined if we run on WindowsCE]) + fi fi AM_CONDITIONAL(HAVE_W32_SYSTEM, test "$have_w32_system" = yes) +AM_CONDITIONAL(HAVE_W32CE_SYSTEM, test "$have_w32ce_system" = yes) + # Checks for programs. missing_dir=`cd $ac_aux_dir && pwd` AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir) @@ -106,9 +126,6 @@ AC_PROG_MAKE_SET AC_C_INLINE -LT_PREREQ([2.2.6]) -LT_INIT([win32-dll disable-static]) -LT_LANG([Windows Resource]) if test "$GCC" = yes; then CFLAGS="$CFLAGS -Wall -Wcast-align -Wshadow -Wstrict-prototypes" @@ -135,10 +152,32 @@ fi +# +# On W32CE we need gpg-error because this provides our errno.h replacement. +# +if test "$have_w32ce_system" = yes; then + AM_PATH_GPG_ERROR("$NEED_GPG_ERROR_VERSION") + if test "x$GPG_ERROR_LIBS" = "x"; then + AC_MSG_ERROR([libgpg-error is needed for Windows CE. + See ftp://ftp.gnupg.org/gcrypt/libgpg-error/ .]) + fi +fi + +# +# Set NETLIBS +# +if test "$have_w32ce_system" = yes; then + NETLIBS="-lws2 $NETLIBS" +else + NETLIBS="-lws2_32 $NETLIBS" +fi +AC_SUBST(NETLIBS) + + # Checks for header files. AC_HEADER_STDC -AC_CHECK_HEADERS([string.h]) +AC_CHECK_HEADERS([string.h signal.h]) # Checks for typedefs, structures, and compiler characteristics. AC_C_CONST Modified: trunk/ltmain.sh =================================================================== --- trunk/ltmain.sh 2009-12-08 21:23:52 UTC (rev 31) +++ trunk/ltmain.sh 2010-02-25 19:47:37 UTC (rev 32) @@ -65,7 +65,7 @@ # compiler: $LTCC # compiler flags: $LTCFLAGS # linker: $LD (gnu? $with_gnu_ld) -# $progname: (GNU libtool) 2.2.6 Debian-2.2.6a-4 +# $progname: (GNU libtool) 2.2.6 Debian-2.2.6a-1ubuntu1 # automake: $automake_version # autoconf: $autoconf_version # @@ -73,7 +73,7 @@ PROGRAM=ltmain.sh PACKAGE=libtool -VERSION="2.2.6 Debian-2.2.6a-4" +VERSION="2.2.6 Debian-2.2.6a-1ubuntu1" TIMESTAMP="" package_revision=1.3012 @@ -5347,19 +5347,19 @@ # It is a libtool convenience library, so add in its objects. convenience="$convenience $ladir/$objdir/$old_library" old_convenience="$old_convenience $ladir/$objdir/$old_library" - tmp_libs= - for deplib in $dependency_libs; do - deplibs="$deplib $deplibs" - if $opt_duplicate_deps ; then - case "$tmp_libs " in - *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; - esac - fi - tmp_libs="$tmp_libs $deplib" - done elif test "$linkmode" != prog && test "$linkmode" != lib; then func_fatal_error "\`$lib' is not a convenience library" fi + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if $opt_duplicate_deps ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done continue fi # $pass = conv @@ -5896,7 +5896,6 @@ if test "$link_all_deplibs" != no; then # Add the search paths of all dependency libraries for deplib in $dependency_libs; do - path= case $deplib in -L*) path="$deplib" ;; *.la) @@ -7681,15 +7680,15 @@ wrappers_required=yes case $host in + *cegcc | *mingw32ce*) + # Disable wrappers for cegcc/mingw32ce, we are cross compiling anyway. + wrappers_required=no + ;; *cygwin* | *mingw* ) if test "$build_libtool_libs" != yes; then wrappers_required=no fi ;; - *cegcc) - # Disable wrappers for cegcc, we are cross compiling anyway. - wrappers_required=no - ;; *) if test "$need_relink" = no || test "$build_libtool_libs" != yes; then wrappers_required=no Added: trunk/m4/gpg-error.m4 =================================================================== --- trunk/m4/gpg-error.m4 (rev 0) +++ trunk/m4/gpg-error.m4 2010-02-25 19:47:37 UTC (rev 32) @@ -0,0 +1,65 @@ +# gpg-error.m4 - autoconf macro to detect libgpg-error. +# Copyright (C) 2002, 2003, 2004 g10 Code GmbH +# +# This file is free software; as a special exception the author gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# This file is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +dnl AM_PATH_GPG_ERROR([MINIMUM-VERSION, +dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) +dnl Test for libgpg-error and define GPG_ERROR_CFLAGS and GPG_ERROR_LIBS +dnl +AC_DEFUN([AM_PATH_GPG_ERROR], +[ AC_ARG_WITH(gpg-error-prefix, + AC_HELP_STRING([--with-gpg-error-prefix=PFX], + [prefix where GPG Error is installed (optional)]), + gpg_error_config_prefix="$withval", gpg_error_config_prefix="") + if test x$gpg_error_config_prefix != x ; then + if test x${GPG_ERROR_CONFIG+set} != xset ; then + GPG_ERROR_CONFIG=$gpg_error_config_prefix/bin/gpg-error-config + fi + fi + + AC_PATH_PROG(GPG_ERROR_CONFIG, gpg-error-config, no) + min_gpg_error_version=ifelse([$1], ,0.0,$1) + AC_MSG_CHECKING(for GPG Error - version >= $min_gpg_error_version) + ok=no + if test "$GPG_ERROR_CONFIG" != "no" ; then + req_major=`echo $min_gpg_error_version | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)/\1/'` + req_minor=`echo $min_gpg_error_version | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)/\2/'` + gpg_error_config_version=`$GPG_ERROR_CONFIG $gpg_error_config_args --version` + major=`echo $gpg_error_config_version | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'` + minor=`echo $gpg_error_config_version | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'` + if test "$major" -gt "$req_major"; then + ok=yes + else + if test "$major" -eq "$req_major"; then + if test "$minor" -ge "$req_minor"; then + ok=yes + fi + fi + fi + fi + if test $ok = yes; then + GPG_ERROR_CFLAGS=`$GPG_ERROR_CONFIG $gpg_error_config_args --cflags` + GPG_ERROR_LIBS=`$GPG_ERROR_CONFIG $gpg_error_config_args --libs` + AC_MSG_RESULT([yes ($gpg_error_config_version)]) + ifelse([$2], , :, [$2]) + else + GPG_ERROR_CFLAGS="" + GPG_ERROR_LIBS="" + AC_MSG_RESULT(no) + ifelse([$3], , :, [$3]) + fi + AC_SUBST(GPG_ERROR_CFLAGS) + AC_SUBST(GPG_ERROR_LIBS) +]) + Modified: trunk/m4/libtool.m4 =================================================================== --- trunk/m4/libtool.m4 2009-12-08 21:23:52 UTC (rev 31) +++ trunk/m4/libtool.m4 2010-02-25 19:47:37 UTC (rev 32) @@ -3007,6 +3007,17 @@ lt_cv_file_magic_cmd='func_win32_libid' ;; + +mingw32ce*) + # Windows CE is often used with non-x86 platforms and thus the below + # mingw and cegcc checks don't work. It would be possible to + # support other architectures in these checks. However x86 is pretty + # hard coded and changing this would require quite some tests on all + # the platforms to be sure not to break something. Thus we take the + # easy way out and don't check at all. + lt_cv_deplibs_check_method=pass_all + ;; + mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', @@ -4261,9 +4272,6 @@ openbsd*) with_gnu_ld=no ;; - linux* | k*bsd*-gnu) - _LT_TAGVAR(link_all_deplibs, $1)=no - ;; esac _LT_TAGVAR(ld_shlibs, $1)=yes Modified: trunk/pth.h =================================================================== --- trunk/pth.h 2009-12-08 21:23:52 UTC (rev 31) +++ trunk/pth.h 2010-02-25 19:47:37 UTC (rev 32) @@ -1,6 +1,6 @@ /* pth.h - GNU Pth emulation for W32 (MS Windows). * Copyright (c) 1999-2003 Ralf S. Engelschall - * Copyright (C) 2004, 2006, 2007, 2008 g10 Code GmbH + * Copyright (C) 2004, 2006, 2007, 2008, 2010 g10 Code GmbH * * This file is part of W32PTH. * @@ -15,9 +15,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. + * License along with this program; if not, see . * * ------------------------------------------------------------------ * This code is based on Ralf Engelschall's GNU Pth, a non-preemptive @@ -281,7 +279,7 @@ /* Special W32 function to cope with the problem that pth_self returns - just a pseudo handle which is not very usefule for debugging. */ + just a pseudo handle which is not very useful for debugging. */ unsigned long pth_thread_id (void); #define PTH_HAVE_PTH_THREAD_ID 1 Added: trunk/utils.h =================================================================== --- trunk/utils.h (rev 0) +++ trunk/utils.h 2010-02-25 19:47:37 UTC (rev 32) @@ -0,0 +1,48 @@ +/* utils.h - Internal definitions. + * Copyright (C) 2010 g10 Code GmbH + * + * This file is part of W32PTH. + * + * W32PTH is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * W32PTH 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see . + */ + +#ifndef UTILS_H +#define UTILS_H + +#ifdef HAVE_W32CE_SYSTEM +# include /* Required for gpg_err_set_errno(). */ +#endif + + +static inline void +set_errno (int value) +{ +#ifdef HAVE_W32CE_SYSTEM + gpg_err_set_errno (value); +#else + errno = value; +#endif +} + +#define DIM(v) (sizeof(v)/sizeof((v)[0])) +#define DIMof(type,member) DIM(((type *)0)->member) + + +/*-- w32-pth.c --*/ +void *_pth_malloc (size_t n); +void *_pth_calloc (size_t n, size_t m); +void _pth_free (void *p); + + +#endif /*UTILS_H*/ Modified: trunk/w32-io.c =================================================================== --- trunk/w32-io.c 2009-12-08 21:23:52 UTC (rev 31) +++ trunk/w32-io.c 2010-02-25 19:47:37 UTC (rev 32) @@ -29,9 +29,23 @@ #include +#ifdef HAVE_W32CE_SYSTEM +# include +# include +# define GPGCEDEV_IOCTL_SET_HANDLE \ + CTL_CODE (FILE_DEVICE_STREAMS, 2048, METHOD_BUFFERED, FILE_ANY_ACCESS) +# define GPGCEDEV_IOCTL_MAKE_PIPE \ + CTL_CODE (FILE_DEVICE_STREAMS, 2049, METHOD_BUFFERED, FILE_ANY_ACCESS) +#endif /*HAVE_W32CE_SYSTEM*/ + + + +#include "utils.h" #include "debug.h" #include "w32-io.h" + + struct critsect_s { @@ -178,7 +192,7 @@ UNLOCK (debug_lock); fflush (dbgfp); - errno = saved_errno; + set_errno (saved_errno); } @@ -281,7 +295,7 @@ TRACE1 (DEBUG_SYSIO, "pth:set_synchronize", hd, "DuplicateHandle failed: ec=%d", (int) GetLastError ()); /* FIXME: Should translate the error code. */ - errno = EIO; + set_errno (EIO); return INVALID_HANDLE_VALUE; } @@ -544,7 +558,7 @@ ctx = find_reader (fd, 0); if (!ctx) { - errno = EBADF; + set_errno (EBADF); return TRACE_SYSRES (-1); } if (ctx->eof_shortcut) @@ -572,7 +586,7 @@ TRACE_LOG ("EOF but ctx->eof flag not set"); return 0; } - errno = ctx->error_code; + set_errno (ctx->error_code); return TRACE_SYSRES (-1); } @@ -590,7 +604,7 @@ TRACE_LOG1 ("ResetEvent failed: ec=%d", (int) GetLastError ()); UNLOCK (ctx->mutex); /* FIXME: Should translate the error code. */ - errno = EIO; + set_errno (EIO); return TRACE_SYSRES (-1); } } @@ -599,7 +613,7 @@ TRACE_LOG1 ("SetEvent failed: ec=%d", (int) GetLastError ()); UNLOCK (ctx->mutex); /* FIXME: Should translate the error code. */ - errno = EIO; + set_errno (EIO); return TRACE_SYSRES (-1); } UNLOCK (ctx->mutex); @@ -865,7 +879,7 @@ TRACE_LOG1 ("ResetEvent failed: ec=%d", (int) GetLastError ()); UNLOCK (ctx->mutex); /* FIXME: Should translate the error code. */ - errno = EIO; + set_errno (EIO); return TRACE_SYSRES (-1); } UNLOCK (ctx->mutex); @@ -879,9 +893,9 @@ { UNLOCK (ctx->mutex); if (ctx->error_code == ERROR_NO_DATA) - errno = EPIPE; + set_errno (EPIPE); else - errno = EIO; + set_errno (EIO); return TRACE_SYSRES (-1); } @@ -901,7 +915,7 @@ TRACE_LOG1 ("ResetEvent failed: ec=%d", (int) GetLastError ()); UNLOCK (ctx->mutex); /* FIXME: Should translate the error code. */ - errno = EIO; + set_errno (EIO); return TRACE_SYSRES (-1); } if (!SetEvent (ctx->have_data)) @@ -909,7 +923,7 @@ TRACE_LOG1 ("SetEvent failed: ec=%d", (int) GetLastError ()); UNLOCK (ctx->mutex); /* FIXME: Should translate the error code. */ - errno = EIO; + set_errno (EIO); return TRACE_SYSRES (-1); } UNLOCK (ctx->mutex); @@ -918,6 +932,76 @@ } +/* WindowsCE does not provide a pipe feature. However we need + something like a pipe to convey data between processes and in some + cases within a process. This replacement is not only used by + libassuan but exported and thus usable by gnupg and gpgme as well. */ +static DWORD +create_pipe (HANDLE *read_hd, HANDLE *write_hd, + LPSECURITY_ATTRIBUTES sec_attr, DWORD size) +{ +#ifdef HAVE_W32CE_SYSTEM + HANDLE hd[2] = {INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE}; + TRACE_BEG (DEBUG_SYSIO, "pth:create_pipe", read_hd); + + *read_hd = *write_hd = INVALID_HANDLE_VALUE; + + ActivateDevice (L"Drivers\\GnuPG_Device", 0); + + /* Note: Using "\\$device\\GPG1" should be identical to "GPG1:". + However this returns an invalid parameter error without having + called GPG_Init in the driver. The docs mention something about + RegisterAFXEx but that API is not documented. */ + hd[0] = CreateFile (L"GPG1:", GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (hd[0] == INVALID_HANDLE_VALUE) + return 0; + + if (!DeviceIoControl (hd[0], GPGCEDEV_IOCTL_SET_HANDLE, + &hd[0], sizeof hd[0], NULL, 0, NULL, NULL)) + TRACE_LOG1 ("GPGCEDEV_IOCTL_SET_HANDLE(0) failed: %d\n", + (int)GetLastError ()); + + hd[1] = CreateFile (L"GPG1:", GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL,NULL); + if (hd[1] == INVALID_HANDLE_VALUE) + { + DWORD lasterr = GetLastError (); + CloseHandle (hd[0]); + SetLastError (lasterr); + return 0; + } + if (!DeviceIoControl (hd[1], GPGCEDEV_IOCTL_SET_HANDLE, + &hd[1], sizeof hd[1], NULL, 0, NULL, NULL)) + TRACE_LOG1 ("GPGCEDEV_IOCTL_SET_HANDLE(1) failed: %d\n", + (int)GetLastError ()); + + if (!DeviceIoControl (hd[0], GPGCEDEV_IOCTL_MAKE_PIPE, + &hd[1], sizeof hd[1], NULL, 0, NULL, NULL)) + { + TRACE_LOG1 ("GPGCEDEV_IOCTL_MAKE_PIPE failed: %d\n", + (int)GetLastError ()); + if (hd[0] != INVALID_HANDLE_VALUE) + CloseHandle (hd[0]); + if (hd[1] != INVALID_HANDLE_VALUE) + CloseHandle (hd[1]); + TRACE_SUC (); + return 0; + } + else + { + *read_hd = hd[0]; + *write_hd = hd[1]; + TRACE_SUC (); + return 1; + } +#else /*!HAVE_W32CE_SYSTEM*/ + return CreatePipe (read_hd, write_hd, sec_attr, size); +#endif /*!HAVE_W32CE_SYSTEM*/ +} + int pth_pipe (int filedes[2], int inherit_idx) { @@ -932,17 +1016,20 @@ sec_attr.nLength = sizeof (sec_attr); sec_attr.bInheritHandle = FALSE; - if (!CreatePipe (&rh, &wh, &sec_attr, PIPEBUF_SIZE)) + if (!create_pipe (&rh, &wh, &sec_attr, PIPEBUF_SIZE)) { TRACE_LOG1 ("CreatePipe failed: ec=%d", (int) GetLastError ()); /* FIXME: Should translate the error code. */ - errno = EIO; + set_errno (EIO); return TRACE_SYSRES (-1); } /* Make one end inheritable. */ if (inherit_idx == 0) { + /* Under Windows CE < 6 handles are global without a concept of + inheritable handles. */ +#ifndef HAVE_W32CE_SYSTEM HANDLE hd; if (!DuplicateHandle (GetCurrentProcess(), rh, GetCurrentProcess(), &hd, 0, @@ -953,16 +1040,18 @@ CloseHandle (rh); CloseHandle (wh); /* FIXME: Should translate the error code. */ - errno = EIO; + set_errno (EIO); return TRACE_SYSRES (-1); } CloseHandle (rh); rh = hd; +#endif /*!HAVE_W32CE_SYSTEM*/ /* Pre-create the writer thread. */ find_reader (handle_to_fd (wh), 1); } else if (inherit_idx == 1) { +#ifndef HAVE_W32CE_SYSTEM HANDLE hd; if (!DuplicateHandle( GetCurrentProcess(), wh, GetCurrentProcess(), &hd, 0, @@ -973,11 +1062,12 @@ CloseHandle (rh); CloseHandle (wh); /* FIXME: Should translate the error code. */ - errno = EIO; + set_errno (EIO); return TRACE_SYSRES (-1); } CloseHandle (wh); wh = hd; +#endif /*!HAVE_W32CE_SYSTEM*/ /* Pre-create the reader thread. */ find_reader (handle_to_fd (rh), 1); } @@ -995,7 +1085,7 @@ if (fd == -1) { - errno = EBADF; + set_errno (EBADF); return TRACE_SYSRES (-1); } @@ -1006,7 +1096,7 @@ { TRACE_LOG1 ("CloseHandle failed: ec=%d", (int) GetLastError ()); /* FIXME: Should translate the error code. */ - errno = EIO; + set_errno (EIO); return TRACE_SYSRES (-1); } Modified: trunk/w32-pth.c =================================================================== --- trunk/w32-pth.c 2009-12-08 21:23:52 UTC (rev 31) +++ trunk/w32-pth.c 2010-02-25 19:47:37 UTC (rev 32) @@ -1,6 +1,6 @@ /* w32-pth.c - GNU Pth emulation for W32 (MS Windows). * Copyright (c) 1999-2003 Ralf S. Engelschall - * Copyright (C) 2004, 2006, 2007, 2008 g10 Code GmbH + * Copyright (C) 2004, 2006, 2007, 2008, 2010 g10 Code GmbH * * This file is part of W32PTH. * @@ -15,9 +15,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. + * License along with this program; if not, see . * * ------------------------------------------------------------------ * This code is based on Ralf Engelschall's GNU Pth, a non-preemptive @@ -32,9 +30,12 @@ #include #include #include -#include +#ifdef HAVE_SIGNAL_H +# include +#endif #include +#include "utils.h" #include "debug.h" #include "w32-io.h" @@ -86,6 +87,22 @@ }; +#ifdef HAVE_W32CE_SYSTEM +/* W32CE timer implementation. */ +static HANDLE w32ce_timer_ev; /* Event to kick the timer thread. */ +static CRITICAL_SECTION w32ce_timer_cs; /* Protect the objects below. */ +static int w32ce_timer_thread_lauchend; /* True if the timer thread has + been launched. */ +static struct /* The timer array. */ +{ + HANDLE event; /* Event to be signaled for this timer or + NULL for an unused slot. */ + int active; /* Timer is active. */ + unsigned long remaining; /* Remaining time in milliseconds. */ +} w32ce_timer[32]; +#endif /*HAVE_W32CE_SYSTEM*/ + + /* Pth events are store in a double linked event ring. */ struct pth_event_s { @@ -187,23 +204,111 @@ } +/* Return a string from the Win32 Registry or NULL in case of error. + The returned string is allocated using a plain malloc and thus the + caller needs to call the standard free(). The string is looked up + under HKEY_LOCAL_MACHINE. */ +#ifdef HAVE_W32CE_SYSTEM static char * +w32_read_registry (const wchar_t *dir, const wchar_t *name) +{ + HKEY handle; + DWORD n, nbytes; + wchar_t *buffer = NULL; + char *result = NULL; + + if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, dir, 0, KEY_READ, &handle)) + return NULL; /* No need for a RegClose, so return immediately. */ + + nbytes = 1; + if (RegQueryValueEx (handle, name, 0, NULL, NULL, &nbytes)) + goto leave; + buffer = malloc ((n=nbytes+2)); + if (!buffer) + goto leave; + if (RegQueryValueEx (handle, name, 0, NULL, (PBYTE)buffer, &n)) + { + free (buffer); + buffer = NULL; + goto leave; + } + + n = WideCharToMultiByte (CP_UTF8, 0, buffer, nbytes, NULL, 0, NULL, NULL); + if (n < 0 || (n+1) <= 0) + goto leave; + result = malloc (n+1); + if (!result) + goto leave; + n = WideCharToMultiByte (CP_UTF8, 0, buffer, nbytes, result, n, NULL, NULL); + if (n < 0) + { + free (result); + result = NULL; + goto leave; + } + result[n] = 0; + + leave: + free (buffer); + RegCloseKey (handle); + return result; +} +#endif /*HAVE_W32CE_SYSTEM*/ + +#ifdef HAVE_W32CE_SYSTEM +/* Replacement for getenv which takes care of the our use of getenv. + The code is not thread safe but we expect it to work in all cases + because it is called for the first time early enough. */ +static char * +getenv (const char *name) +{ + static int initialized; + static char *val_debug; + + if (!initialized) + { + val_debug = w32_read_registry (L"\\Software\\GNU\\w32pth", + L"debug"); + initialized = 1; + } + + + if (!strcmp (name, "PTH_DEBUG")) + return val_debug; + else + return NULL; +} +#endif /*HAVE_W32CE_SYSTEM*/ + + + +static char * w32_strerror (char *strerr, size_t strerrsize) { +#ifdef HAVE_W32CE_SYSTEM + /* There is only a wchar_t FormatMessage. It does not make much + sense to play the conversion game; we print only the code. */ + snprintf (strerr, strerrsize, "ec=%d", (int)GetLastError ()); +#else if (strerrsize > 1) FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, (int)GetLastError (), MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), strerr, strerrsize, NULL); +#endif return strerr; } static char * wsa_strerror (char *strerr, size_t strerrsize) { +#ifdef HAVE_W32CE_SYSTEM + snprintf (strerr, strerrsize, "ec=%d", (int)WSAGetLastError ()); +#else if (strerrsize > 1) FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, (int)WSAGetLastError (), MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), strerr, strerrsize, NULL); +#endif return strerr; } @@ -331,6 +436,9 @@ w32_strerror (strerr, sizeof strerr)); return NULL; } +#ifdef HAVE_W32CE_SYSTEM + h2 = h; +#else if (!DuplicateHandle (GetCurrentProcess(), h, GetCurrentProcess(), &h2, EVENT_MODIFY_STATE|SYNCHRONIZE, FALSE, 0 ) ) @@ -344,6 +452,7 @@ return NULL; } CloseHandle (h); +#endif if (DBG_INFO) { fprintf (dbgfp, "%s: CreateEvent(%p) succeeded\n", @@ -352,7 +461,8 @@ return h2; } -#if 0 /* Not yet used. */ + +#ifdef TEST static void set_event (HANDLE h) { @@ -393,29 +503,140 @@ } +#ifdef HAVE_W32CE_SYSTEM +/* WindowsCE does not provide CreateWaitableTimer et al. Thus we have + to roll our own. The timer is not fully correct because we use + GetTickCount and don't adjust for the time it takes to call it. */ +static DWORD CALLBACK +w32ce_timer_thread (void *arg) +{ + int idx; + DWORD timeout, elapsed, lasttick; + (void)arg; + + lasttick = GetTickCount (); + for (;;) + { + elapsed = lasttick; /* Get start time. */ + timeout = 0; + EnterCriticalSection (&w32ce_timer_cs); + for (idx=0; idx < DIM (w32ce_timer); idx++) + { + if (w32ce_timer[idx].event && w32ce_timer[idx].active + && w32ce_timer[idx].remaining > timeout) + timeout = w32ce_timer[idx].remaining; + } + LeaveCriticalSection (&w32ce_timer_cs); + if (timeout > 0x7fffffff) + timeout = 0x7fffffff; + switch (WaitForSingleObject (w32ce_timer_ev, (DWORD)timeout)) + { + case WAIT_OBJECT_0: + break; + case WAIT_TIMEOUT: + break; + case WAIT_FAILED: + if (DBG_ERROR) + fprintf (dbgfp, + "%s:w32ce_timer_thread: WFSO failed: rc=%d\n", + log_get_prefix (NULL), (int)GetLastError ()); + /* This is likely to happen if a handle has been closed + while we are waiting for it. */ + break; + } + EnterCriticalSection (&w32ce_timer_cs); + lasttick = GetTickCount (); + elapsed = lasttick - elapsed; + for (idx=0; idx < DIM (w32ce_timer); idx++) + { + if (w32ce_timer[idx].event && w32ce_timer[idx].active) + { + if (w32ce_timer[idx].remaining > elapsed) + w32ce_timer[idx].remaining -= elapsed; + else + { + w32ce_timer[idx].remaining = 0; + w32ce_timer[idx].active = 0; + if (!SetEvent (w32ce_timer[idx].event)) + { + if (DBG_ERROR) + fprintf (dbgfp, "%s:w32ce_timer_thread: SetEvent(%p) " + "failed: rc=%d\n", + log_get_prefix (NULL), (int)GetLastError ()); + } + } + } + } + LeaveCriticalSection (&w32ce_timer_cs); + } + + return 0; /*NOTREACHED*/ +} +#endif /*HAVE_W32CE_SYSTEM*/ + + /* Create a timer event. */ static HANDLE create_timer (void) { - SECURITY_ATTRIBUTES sa; HANDLE h; - char strerr[256]; +#ifdef HAVE_W32CE_SYSTEM + int idx; + + EnterCriticalSection (&w32ce_timer_cs); + if (!w32ce_timer_thread_lauchend) + { + h = CreateThread (NULL, 0, w32ce_timer_thread, NULL, 0, NULL); + if (!h) + { + if (DBG_ERROR) + fprintf (dbgfp, "%s:create_timer: CreateThread failed: rc=%d\n", + log_get_prefix (NULL), (int)GetLastError ()); + goto leave; + } + CloseHandle (h); + w32ce_timer_thread_lauchend = 1; + } + h = NULL; + for (idx = 0; idx < DIM (w32ce_timer); idx++) + if (!w32ce_timer[idx].event) + break; + if (idx == DIM (w32ce_timer)) + { + SetLastError (ERROR_TOO_MANY_OPEN_FILES); + goto leave; + } + /* We create a manual reset event. */ + w32ce_timer[idx].event = CreateEvent (NULL, TRUE, FALSE, NULL); + if (!w32ce_timer[idx].event) + goto leave; + w32ce_timer[idx].active = 0; + h = w32ce_timer[idx].event; + +leave: + LeaveCriticalSection (&w32ce_timer_cs); + +#else /* Plain Windows. */ + + SECURITY_ATTRIBUTES sa; + memset (&sa, 0, sizeof sa); sa.bInheritHandle = TRUE; sa.lpSecurityDescriptor = NULL; sa.nLength = sizeof sa; h = CreateWaitableTimer (&sa, TRUE, NULL); + +#endif /* Plain Windows. */ + if (!h) { if (DBG_ERROR) - fprintf (dbgfp, "%s: CreateWaitableTimer failed: %s\n", - log_get_prefix (NULL), - w32_strerror (strerr, sizeof strerr)); - return NULL; + fprintf (dbgfp, "%s: CreateWaitableTimer failed: rc=%d\n", + log_get_prefix (NULL), (int)GetLastError ()); } - if (DBG_INFO) + else if (DBG_INFO) { fprintf (dbgfp, "%s: CreateWaitableTimer(%p) succeeded\n", log_get_prefix (NULL), h); @@ -423,7 +644,84 @@ return h; } +static int +set_timer (HANDLE hd, DWORD milliseconds) +{ +#ifdef HAVE_W32CE_SYSTEM + int idx; + int result = -1; + EnterCriticalSection (&w32ce_timer_cs); + for (idx = 0; idx < DIM (w32ce_timer); idx++) + if (hd && w32ce_timer[idx].event == hd) + { + w32ce_timer[idx].remaining = milliseconds; + if (!ResetEvent (w32ce_timer[idx].event)) + { + if (DBG_ERROR) + fprintf (dbgfp, "%s:set_timer: ResetEvent(%p) failed: rc=%d\n", + log_get_prefix (NULL), (int)GetLastError ()); + } + else if (!SetEvent (w32ce_timer_ev)) + { + if (DBG_ERROR) + fprintf (dbgfp, "%s:set_timer: SetEvent(%p) failed: rc=%d\n", + log_get_prefix (NULL), (int)GetLastError ()); + } + else + { + w32ce_timer[idx].active = 1; + result = 0; + } + break; + } + if (idx == DIM (w32ce_timer)) + SetLastError (ERROR_INVALID_HANDLE); + LeaveCriticalSection (&w32ce_timer_cs); + return result; +#else /* Plain Windows. */ + LARGE_INTEGER ll; + char strerr[256]; + + ll.QuadPart = - (milliseconds * 10000); + if (!SetWaitableTimer (hd, &ll, 0, NULL, NULL, FALSE)) + { + if (DBG_ERROR) + fprintf (dbgfp,"%s: %s: SetWaitableTimer failed: %s\n", + log_get_prefix (NULL), __func__, + w32_strerror (strerr, sizeof strerr)); + return -1; + } + return 0; +#endif /* Plain Windows. */ +} + +static void +destroy_timer (HANDLE h) +{ +#ifdef HAVE_W32CE_SYSTEM + int idx; + + EnterCriticalSection (&w32ce_timer_cs); + for (idx = 0; idx < DIM (w32ce_timer); idx++) + if (w32ce_timer[idx].event == h) + { + CloseHandle (w32ce_timer[idx].event); + w32ce_timer[idx].event = NULL; + break; + } + LeaveCriticalSection (&w32ce_timer_cs); +#else /* Plain Windows. */ + CloseHandle (h); +#endif /* Plain Windows. */ +} + + + + + + + int pth_init (void) { @@ -473,7 +771,15 @@ pth_signo_ev = create_event (); if (!pth_signo_ev) return FALSE; - + +#ifdef HAVE_W32CE_SYSTEM + InitializeCriticalSection (&w32ce_timer_cs); + w32ce_timer_ev = CreateEvent (NULL, FALSE, FALSE, NULL); + if (!w32ce_timer_ev) + return FALSE; +#endif /*HAVE_W32CE_SYSTEM*/ + + pth_initialized = 1; thread_counter = 1; EnterCriticalSection (&pth_shd); @@ -491,7 +797,12 @@ pth_signo_ev = NULL; } if (pth_initialized) - DeleteCriticalSection (&pth_shd); + { +#ifdef HAVE_W32CE_SYSTEM + DeleteCriticalSection (&w32ce_timer_cs); +#endif /*HAVE_W32CE_SYSTEM*/ + DeleteCriticalSection (&pth_shd); + } WSACleanup (); pth_initialized = 0; return TRUE; @@ -597,13 +908,13 @@ log_get_prefix (NULL), fd, w32_strerror (strerr, sizeof strerr)); n = -1; - errno = map_w32_to_errno (GetLastError ()); + set_errno (map_w32_to_errno (GetLastError ())); } else n = (int) nread; } else if (n == -1) - errno = map_wsa_to_errno (WSAGetLastError ()); + set_errno (map_wsa_to_errno (WSAGetLastError ())); } return n; @@ -643,7 +954,7 @@ #ifdef NO_PTH_MODE_STATIC do_pth_event_free (ev, PTH_FREE_THIS); #endif - errno = EINTR; + set_errno (EINTR); leave_pth (__FUNCTION__); return -1; } @@ -698,7 +1009,7 @@ if (!WriteFile ((HANDLE)fd, buffer, size, &nwrite, NULL)) { n = -1; - errno = map_w32_to_errno (GetLastError ()); + set_errno (map_w32_to_errno (GetLastError ())); if (DBG_ERROR) fprintf (dbgfp, "%s: pth_write(%d) failed in write: %s\n", log_get_prefix (NULL), fd, @@ -708,7 +1019,7 @@ n = (int) nwrite; } else if (n == -1) - errno = map_wsa_to_errno (WSAGetLastError ()); + set_errno (map_wsa_to_errno (WSAGetLastError ())); } return n; @@ -746,9 +1057,9 @@ if (pth_event_status(ev) != PTH_STATUS_OCCURRED) { #ifdef NO_PTH_MODE_STATIC - do_pth_event_free (ev, PTH_FREE_THIS); + do_pth_event_free (ev, PTH_FREE_THIS); #endif - errno = EINTR; + set_errno (EINTR); leave_pth (__FUNCTION__); return -1; } @@ -870,7 +1181,7 @@ if (ev_extra && !selected) { rc = -1; - errno = EINTR; + set_errno (EINTR); } leave: @@ -1744,7 +2055,9 @@ do { pth_event_t next = cur->next; - if (cur->u_type != PTH_EVENT_HANDLE) + if (cur->u_type == PTH_EVENT_TIME) + destroy_timer (cur->hd); + else if (cur->u_type != PTH_EVENT_HANDLE) CloseHandle (cur->hd); cur->hd = NULL; _pth_free (cur); @@ -1756,7 +2069,9 @@ { ev->prev->next = ev->next; ev->next->prev = ev->prev; - if (ev->u_type != PTH_EVENT_HANDLE) + if (ev->u_type == PTH_EVENT_TIME) + destroy_timer (ev->hd); + else if (ev->u_type != PTH_EVENT_HANDLE) CloseHandle (ev->hd); ev->hd = NULL; _pth_free (ev); @@ -1946,22 +2261,11 @@ case PTH_EVENT_TIME: TRACE_LOG ("adding timer event"); - { - LARGE_INTEGER ll; - - ll.QuadPart = - (r->u.tv.tv_sec * 10000000ll - + r->u.tv.tv_usec * 10); - if (!SetWaitableTimer (r->hd, &ll, 0, NULL, NULL, FALSE)) - { - if (DBG_ERROR) - fprintf (dbgfp,"%s: %s: SetWaitableTimer failed: %s\n", - log_get_prefix (NULL), __func__, - w32_strerror (strerr, sizeof strerr)); - return TRACE_SYSRES (-1); - } - evarray[pos] = r; - waitbuf[pos++] = r->hd; - } + if (set_timer (r->hd, (r->u.tv.tv_sec * 1000 + + (r->u.tv.tv_usec+500) / 1000 ))) + return TRACE_SYSRES (-1); + evarray[pos] = r; + waitbuf[pos++] = r->hd; break; case PTH_EVENT_SELECT: @@ -2253,7 +2557,8 @@ #ifdef TEST #include -void * thread (void * c) +void * +thread (void * c) { Sleep (2000); @@ -2264,7 +2569,8 @@ } -int main_1 (int argc, char ** argv) +int +main_1 (int argc, char ** argv) { pth_attr_t t; pth_t hd; @@ -2287,6 +2593,7 @@ } +#ifndef HAVE_W32CE_SYSTEM static pth_event_t setup_signals (struct sigset_s *sigs, int *signo) { @@ -2348,17 +2655,12 @@ pth_kill (); return 0; } +#endif int main (int argc, char ** argv) { - pth_event_t ev; - pth_key_t ev_key; - pth_init (); - /*ev = pth_event (PTH_EVENT_TIME, &ev_key, pth_timeout (5, 0)); - pth_wait (ev); - pth_event_free (ev, PTH_FREE_ALL);*/ pth_sleep (5); pth_kill (); return 0; From cvs at cvs.gnupg.org Fri Feb 26 11:34:34 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 26 Feb 2010 11:34:34 +0100 Subject: [svn] w32pth - r33 - trunk Message-ID: Author: wk Date: 2010-02-26 11:34:34 +0100 (Fri, 26 Feb 2010) New Revision: 33 Modified: trunk/ChangeLog trunk/w32-pth.c Log: Fix for an empty timer list Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2010-02-25 19:47:37 UTC (rev 32) +++ trunk/ChangeLog 2010-02-26 10:34:34 UTC (rev 33) @@ -1,3 +1,8 @@ +2010-02-26 Werner Koch + + * w32-pth.c (w32ce_timer_thread): Take care of an empty timer + list. + 2010-02-25 Werner Koch * utils.h: New. Modified: trunk/w32-pth.c =================================================================== --- trunk/w32-pth.c 2010-02-25 19:47:37 UTC (rev 32) +++ trunk/w32-pth.c 2010-02-26 10:34:34 UTC (rev 33) @@ -510,7 +510,7 @@ static DWORD CALLBACK w32ce_timer_thread (void *arg) { - int idx; + int idx, any; DWORD timeout, elapsed, lasttick; (void)arg; @@ -521,28 +521,31 @@ elapsed = lasttick; /* Get start time. */ timeout = 0; EnterCriticalSection (&w32ce_timer_cs); - for (idx=0; idx < DIM (w32ce_timer); idx++) + for (idx=any=0; idx < DIM (w32ce_timer); idx++) { - if (w32ce_timer[idx].event && w32ce_timer[idx].active - && w32ce_timer[idx].remaining > timeout) - timeout = w32ce_timer[idx].remaining; + if (w32ce_timer[idx].event && w32ce_timer[idx].active) + { + any = 1; + if (w32ce_timer[idx].remaining > timeout) + timeout = w32ce_timer[idx].remaining; + } } LeaveCriticalSection (&w32ce_timer_cs); - if (timeout > 0x7fffffff) + if (!any) + timeout = INFINITE; + else if (timeout > 0x7fffffff) timeout = 0x7fffffff; switch (WaitForSingleObject (w32ce_timer_ev, (DWORD)timeout)) { case WAIT_OBJECT_0: - break; case WAIT_TIMEOUT: break; - case WAIT_FAILED: + default: if (DBG_ERROR) fprintf (dbgfp, "%s:w32ce_timer_thread: WFSO failed: rc=%d\n", log_get_prefix (NULL), (int)GetLastError ()); - /* This is likely to happen if a handle has been closed - while we are waiting for it. */ + Sleep (500); /* Failsafe pause. */ break; } EnterCriticalSection (&w32ce_timer_cs); From cvs at cvs.gnupg.org Fri Feb 26 11:52:05 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 26 Feb 2010 11:52:05 +0100 Subject: [svn] GnuPG - r5272 - in trunk: . agent common g10 tools Message-ID: Author: wk Date: 2010-02-26 11:52:05 +0100 (Fri, 26 Feb 2010) New Revision: 5272 Modified: trunk/ChangeLog trunk/agent/call-pinentry.c trunk/autogen.sh trunk/common/tlv.c trunk/configure.ac trunk/g10/sign.c trunk/tools/ChangeLog trunk/tools/gpg-connect-agent.c Log: Some minor changes and typo fixes. Started to implement a TCP option in gpg-connect-agent. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2010-02-19 12:25:13 UTC (rev 5271) +++ trunk/ChangeLog 2010-02-26 10:52:05 UTC (rev 5272) @@ -1,3 +1,9 @@ +2010-02-26 Werner Koch + + * configure.ac (HAVE_W32CE_SYSTEM): New ac_define and + am_conditional. + * autogen.sh: New option --build-w32ce. + 2009-12-08 Werner Koch * configure.ac (USE_DNS_CERT): Support ADNS. Modified: trunk/tools/ChangeLog =================================================================== --- trunk/tools/ChangeLog 2010-02-19 12:25:13 UTC (rev 5271) +++ trunk/tools/ChangeLog 2010-02-26 10:52:05 UTC (rev 5272) @@ -1,3 +1,7 @@ +2010-02-26 Werner Koch + + * gpg-connect-agent.c (main): New option --tcp-socket. + 2010-01-10 Werner Koch * symcryptrun.c (utmp.h): Remove header; it is not used. Modified: trunk/agent/call-pinentry.c =================================================================== --- trunk/agent/call-pinentry.c 2010-02-19 12:25:13 UTC (rev 5271) +++ trunk/agent/call-pinentry.c 2010-02-26 10:52:05 UTC (rev 5272) @@ -394,20 +394,25 @@ may help a pinentry to avoid implementing localization code. */ static struct { const char *key, *value; } tbl[] = { /* TRANSLATORS: These are labels for buttons etc used in - Pinentries. A underscore indicates that the next letter - should be used as an accelerator. The actual to be - translated text starts after the second vertical bar. */ + Pinentries. An underscore indicates that the next letter + should be used as an accelerator. Double the underscore for + a literal one. The actual to be translated text starts after + the second vertical bar. */ { "ok", N_("|pinentry-label|_OK") }, { "cancel", N_("|pinentry-label|_Cancel") }, + { "prompt", N_("|pinentry-label|PIN:") }, { NULL, NULL} }; char *optstr; int idx; + const char *s, *s2; for (idx=0; tbl[idx].key; idx++) { - if (asprintf (&optstr, "OPTION default-ok=%s", - tbl[idx].key, _(tbl[idx].value)) < 0 ) + s = _(tbl[idx].value); + if (*s == '|' && (s2=strchr (s+1,'|'))) + s = s2+1; + if (asprintf (&optstr, "OPTION default-%s=%s", tbl[idx].key, s) < 0 ) return unlock_pinentry (out_of_core ()); assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL, NULL); Modified: trunk/autogen.sh =================================================================== --- trunk/autogen.sh 2010-02-19 12:25:13 UTC (rev 5271) +++ trunk/autogen.sh 2010-02-26 10:52:05 UTC (rev 5272) @@ -45,9 +45,28 @@ shift fi +# Convenience option to use certain configure options for some hosts. +myhost="" +myhostsub="" +case "$1" in + --build-w32) + myhost="w32" + ;; + --build-w32ce) + myhost="w32" + myhostsub="ce" + ;; + --build-amd64) + myhost="amd64" + ;; + *) + ;; +esac + + # ***** W32 build script ******* # Used to cross-compile for Windows. -if test "$1" = "--build-w32"; then +if [ "$myhost" = "w32" ]; then tmp=`dirname $0` tsdir=`cd "$tmp"; pwd` shift @@ -57,12 +76,21 @@ fi build=`$tsdir/scripts/config.guess` - [ -z "$w32root" ] && w32root="$HOME/w32root" + case $myhostsub in + ce) + [ -z "$w32root" ] && w32root="$HOME/w32ce_root" + toolprefixes="arm-mingw32ce" + ;; + *) + [ -z "$w32root" ] && w32root="$HOME/w32root" + toolprefixes="i586-mingw32msvc i386-mingw32msvc mingw32" + ;; + esac echo "Using $w32root as standard install directory" >&2 # Locate the cross compiler crossbindir= - for host in i586-mingw32msvc i386-mingw32msvc mingw32; do + for host in $toolprefixes; do if ${host}-gcc --version >/dev/null 2>&1 ; then crossbindir=/usr/${host}/bin conf_CC="CC=${host}-gcc" @@ -71,8 +99,10 @@ done if [ -z "$crossbindir" ]; then echo "Cross compiler kit not installed" >&2 - echo "Under Debian GNU/Linux, you may install it using" >&2 - echo " apt-get install mingw32 mingw32-runtime mingw32-binutils" >&2 + if [ -z "$sub" ]; then + echo "Under Debian GNU/Linux, you may install it using" >&2 + echo " apt-get install mingw32 mingw32-runtime mingw32-binutils" >&2 + fi echo "Stop." >&2 exit 1 fi @@ -102,7 +132,7 @@ # ***** AMD64 cross build script ******* # Used to cross-compile for AMD64 (for testing) -if test "$1" = "--build-amd64"; then +if [ "$myhost" = "amd64" ]; then tmp=`dirname $0` tsdir=`cd "$tmp"; pwd` shift Modified: trunk/common/tlv.c =================================================================== --- trunk/common/tlv.c 2010-02-19 12:25:13 UTC (rev 5271) +++ trunk/common/tlv.c 2010-02-26 10:52:05 UTC (rev 5272) @@ -234,7 +234,7 @@ /* FIXME: The following function should not go into this file but for now it is easier to keep it here. */ -/* Return the next token of an canconical encoded S-expression. BUF +/* Return the next token of an canonical encoded S-expression. BUF is the pointer to the S-expression and BUFLEN is a pointer to the length of this S-expression (used to validate the syntax). Both are updated to reflect the new position. The token itself is Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2010-02-19 12:25:13 UTC (rev 5271) +++ trunk/configure.ac 2010-02-26 10:52:05 UTC (rev 5272) @@ -483,6 +483,7 @@ try_gettext=yes have_dosish_system=no have_w32_system=no +have_w32ce_system=no use_simple_gettext=no case "${host}" in *-mingw32*) @@ -499,6 +500,7 @@ disable_keyserver_path=yes have_dosish_system=yes have_w32_system=yes + case "${host}" in *-mingw32ce*) have_w32ce_system=yes ;; esac try_gettext="no" use_simple_gettext=yes ;; @@ -563,8 +565,12 @@ if test "$have_w32_system" = yes; then AC_DEFINE(HAVE_W32_SYSTEM,1, [Defined if we run on a W32 API based system]) + if test "$have_w32ce_system" = yes; then + AC_DEFINE(HAVE_W32CE_SYSTEM,1,[Defined if we run on WindowsCE]) + fi fi AM_CONDITIONAL(HAVE_W32_SYSTEM, test "$have_w32_system" = yes) +AM_CONDITIONAL(HAVE_W32CE_SYSTEM, test "$have_w32ce_system" = yes) if test "$disable_keyserver_path" = yes; then AC_DEFINE(DISABLE_KEYSERVER_PATH,1, Modified: trunk/g10/sign.c =================================================================== --- trunk/g10/sign.c 2010-02-19 12:25:13 UTC (rev 5271) +++ trunk/g10/sign.c 2010-02-26 10:52:05 UTC (rev 5272) @@ -421,13 +421,16 @@ return match_dsa_hash(qbytes); } - else if (/*FIXME: call agent - pk->is_protected && sk->protect.s2k.mode==1002*/ 0) + else if (0 + /* FIXME: call agent sk->is_protected && sk->protect.s2k.mode == 1002 + && sk->protect.ivlen == 16 + && !memcmp (sk->protect.iv, "\xD2\x76\x00\x01\x24\x01\x01", 7)*/) { - /* The secret key lives on a smartcard, and current smartcards only - handle SHA-1 and RIPEMD/160. This is correct now, but may - need revision as the cards add algorithms. */ - + /* The sk lives on a smartcard, and old smartcards only handle + SHA-1 and RIPEMD/160. Newer smartcards (v2.0) don't have + this restriction anymore. Fortunately the serial number + encodes the version of the card and thus we know that this + key is on a v1 card. */ if(opt.personal_digest_prefs) { prefitem_t *prefs; Modified: trunk/tools/gpg-connect-agent.c =================================================================== --- trunk/tools/gpg-connect-agent.c 2010-02-19 12:25:13 UTC (rev 5271) +++ trunk/tools/gpg-connect-agent.c 2010-02-26 10:52:05 UTC (rev 5272) @@ -49,6 +49,7 @@ oQuiet = 'q', oVerbose = 'v', oRawSocket = 'S', + oTcpSocket = 'T', oExec = 'E', oRun = 'r', oSubst = 's', @@ -72,6 +73,8 @@ ARGPARSE_s_n (oDecode,"decode", N_("decode received data lines")), ARGPARSE_s_s (oRawSocket, "raw-socket", N_("|NAME|connect to Assuan socket NAME")), + ARGPARSE_s_s (oTcpSocket, "tcp-socket", + N_("|ADDR|connect to Assuan server at ADDR")), ARGPARSE_s_n (oExec, "exec", N_("run the Assuan server given on the command line")), ARGPARSE_s_n (oNoExtConnect, "no-ext-connect", @@ -96,6 +99,7 @@ int hex; /* Print data lines in hex format. */ int decode; /* Decode received data lines. */ const char *raw_socket; /* Name of socket to connect in raw mode. */ + const char *tcp_socket; /* Name of server to connect in tcp mode. */ int exec; /* Run the pgm given on the command line. */ unsigned int connect_flags; /* Flags used for connecting. */ int enable_varsubst; /* Set if variable substitution is enabled. */ @@ -1177,6 +1181,7 @@ case oHex: opt.hex = 1; break; case oDecode: opt.decode = 1; break; case oRawSocket: opt.raw_socket = pargs.r.ret_str; break; + case oTcpSocket: opt.tcp_socket = pargs.r.ret_str; break; case oExec: opt.exec = 1; break; case oNoExtConnect: opt.connect_flags &= ~(1); break; case oRun: opt_run = pargs.r.ret_str; break; @@ -1207,8 +1212,23 @@ cmdline_commands = argv; if (opt.exec && opt.raw_socket) - log_info (_("option \"%s\" ignored due to \"%s\"\n"), - "--raw-socket", "--exec"); + { + opt.raw_socket = NULL; + log_info (_("option \"%s\" ignored due to \"%s\"\n"), + "--raw-socket", "--exec"); + } + if (opt.exec && opt.tcp_socket) + { + opt.tcp_socket = NULL; + log_info (_("option \"%s\" ignored due to \"%s\"\n"), + "--tcp-socket", "--exec"); + } + if (opt.tcp_socket && opt.raw_socket) + { + opt.tcp_socket = NULL; + log_info (_("option \"%s\" ignored due to \"%s\"\n"), + "--tcp-socket", "--raw-socket"); + } if (opt_run && !(script_fp = fopen (opt_run, "r"))) { @@ -1269,6 +1289,32 @@ if (opt.verbose) log_info ("connection to socket `%s' established\n", opt.raw_socket); } + else if (opt.tcp_socket) + { + char *url; + + url = xstrconcat ("assuan://", opt.tcp_socket, NULL); + + rc = assuan_new (&ctx); + if (rc) + { + log_error ("assuan_new failed: %s\n", gpg_strerror (rc)); + exit (1); + } + + rc = assuan_socket_connect (ctx, opt.tcp_socket, 0, 0); + if (rc) + { + log_error ("can't connect to server `%s': %s\n", + opt.tcp_socket, gpg_strerror (rc)); + exit (1); + } + + if (opt.verbose) + log_info ("connection to socket `%s' established\n", url); + + xfree (url); + } else ctx = start_agent (); From cvs at cvs.gnupg.org Fri Feb 26 19:44:37 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 26 Feb 2010 19:44:37 +0100 Subject: [svn] GnuPG - r5273 - in trunk: . gl jnlib Message-ID: Author: wk Date: 2010-02-26 19:44:36 +0100 (Fri, 26 Feb 2010) New Revision: 5273 Added: trunk/jnlib/t-timestuff.c Removed: trunk/jnlib/w32-gettext.c Modified: trunk/ChangeLog trunk/NEWS trunk/autogen.sh trunk/configure.ac trunk/gl/Makefile.am trunk/gl/mkdtemp.c trunk/gl/setenv.c trunk/gl/unsetenv.c trunk/jnlib/ChangeLog trunk/jnlib/Makefile.am trunk/jnlib/dotlock.c trunk/jnlib/dynload.h trunk/jnlib/libjnlib-config.h trunk/jnlib/mischelp.c trunk/jnlib/mischelp.h trunk/jnlib/stringhelp.c trunk/jnlib/t-stringhelp.c trunk/jnlib/t-support.c trunk/jnlib/t-support.h trunk/jnlib/utf8conv.c trunk/jnlib/utf8conv.h trunk/jnlib/w32-afunix.c trunk/jnlib/w32help.h Log: First batch of changes to support W32CE. Note that jnlib/w32-reg.c is not yet ready. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2010-02-26 10:52:05 UTC (rev 5272) +++ trunk/ChangeLog 2010-02-26 18:44:36 UTC (rev 5273) @@ -1,9 +1,16 @@ 2010-02-26 Werner Koch + * gl/mkdtemp.c (__set_errno) [W32CE]: Use gpg_err_set_errno. + * gl/setenv.c (__set_errno) [W32CE]: Ditto. + * gl/unsetenv.c (__set_errno) [W32CE]: Ditto. + * configure.ac (HAVE_W32CE_SYSTEM): New ac_define and am_conditional. - * autogen.sh: New option --build-w32ce. + (signal.h, getenv): Check for them. + * autogen.sh: New option --build-w32ce. Remove obsolete option + --without-included-gettext. + 2009-12-08 Werner Koch * configure.ac (USE_DNS_CERT): Support ADNS. @@ -412,7 +419,7 @@ 2006-09-18 Werner Koch Released 1.9.23. - + * configure.ac (--enable-agent-only): Donot build tools and doc (--disable-tools,--disable-doc): New. * Makefile.am (SUBDIRS): Allow to conditional build tools and doc. @@ -421,7 +428,7 @@ Replaced all call gpg_error_from_errno(errno) by gpg_error_from_syserror(). - + * configure.ac: Build gpg by default. (GNUPG_SYS_SO_PEERCRED): Removed. @@ -436,7 +443,7 @@ 2006-09-06 Werner Koch * configure.ac: Define _ASSUAN_ONLY_GPG_ERRORS. Require Assuan - 0.9 and libgpg-error 1.4 + 0.9 and libgpg-error 1.4. 2006-08-31 Werner Koch @@ -478,7 +485,7 @@ 2006-07-03 Werner Koch - * configure.ac: Test for ksba_dn_teststr. + * configure.ac: Test for ksba_dn_teststr. 2006-06-30 Werner Koch @@ -486,7 +493,7 @@ * Makefile.am (SUBDIRS): Include keyserver/. * configure.ac: Include keyserver/. (FAKE_CURL, GPGKEYS_CURL): New. - + 2006-06-20 Werner Koch Released 1.9.21. @@ -540,7 +547,7 @@ 2005-08-01 Werner Koch Released 1.9.18. - + * configure.ac: Require libksba 0.9.12 to match new features in gpgsm. 2005-06-20 Werner Koch @@ -577,7 +584,7 @@ 2005-04-21 Werner Koch Released 1.9.16. - + * configure.ac: Do not build gpg by default. 2005-04-20 Werner Koch @@ -592,7 +599,7 @@ 2005-04-15 Marcus Brinkmann * configure.ac: Check for /usr/bin/shred and define SHRED. - + * configure.ac: Add --enable-symcryptrun, disabled by default. Define automake variable BUILD_SYMCRYPTRUN. Check for openpty -lutil, define LIBUTIL_LIBS. @@ -635,8 +642,8 @@ 2004-12-20 Werner Koch * configure.ac: Add PATHSEP_C and PATHSEP_S. For W32 let all - directories default to c:/gnupg. Require libassuan 0.6.9. - + directories default to c:/gnupg. Require libassuan 0.6.9. + 2004-12-18 Werner Koch * configure.ac (AH_BOTTOM): Define EXEEXT_S. @@ -666,7 +673,7 @@ * configure.ac: Replace strsep. Replaced use of "target" by "host". - + 2004-10-22 Werner Koch Released 1.9.12. @@ -689,7 +696,7 @@ * configure.ac: Build Makefile for tests/pkits. New option --with-pkits-tests. - + 2004-08-05 Werner Koch * configure.ac: Changed tests for libusb to also suuport the @@ -754,7 +761,7 @@ 2004-03-06 Werner Koch Released 1.9.6. - + * configure.ac: Check the Libgcrypt API. 2004-02-25 Werner Koch @@ -842,7 +849,7 @@ 2003-11-17 Werner Koch Release 1.9.2. - + * configure.ac: Requires now libassuan 0.6.1. 2003-10-31 Werner Koch @@ -858,12 +865,12 @@ 2003-10-01 Werner Koch - * configure.ac (AH_BOTTOM): Define GNUPG_MAJOR_VERSION. + * configure.ac (AH_BOTTOM): Define GNUPG_MAJOR_VERSION. 2003-09-23 Werner Koch Merged most of David Shaw's changes in 1.3 since 2003-06-03. - + * configure.ac: Drop all TIGER/192 support. (uint64_t): Check for UINT64_C to go along with uint64_t. (getaddrinfo): Check for it. @@ -877,7 +884,7 @@ 2003-09-06 Werner Koch Released 1.9.1. - + * configure.ac: Require newer versions of some libraries. 2003-09-02 Werner Koch @@ -898,9 +905,9 @@ 2003-08-05 Werner Koch Released 1.9.0. - + * configure.ac (GNUPG_DEFAULT_HONMEDIR): Changed back to ~/.gnupg. - + 2003-07-31 Werner Koch * Makefile.am (DISTCLEANFILES): Add g10defs.h @@ -923,7 +930,7 @@ * configure.ac: Build a limited version of scdaemon if libopensc is not available. - + * configure.ac (ALL_LINUGAS): Removed. * Makefile.am (ACLOCAL_AMFLAGS): New. @@ -945,10 +952,10 @@ 2003-01-09 Werner Koch - * configure.ac (GNUPG_PROTECT_TOOL): New option --with-protect-tool. + * configure.ac (GNUPG_PROTECT_TOOL): New option --with-protect-tool. (NEED_KSBA_VERSION): Does now require 0.4.6. - * README: Noted where to find gpg-protect-tool. + * README: Noted where to find gpg-protect-tool. 2002-10-31 Neal H. Walfield @@ -1004,7 +1011,7 @@ 2002-08-10 Werner Koch Released 0.3.10. - + * configure.ac (NEED_LIBKSBA_VERSION): Require 0.4.4. Add support for gettext. @@ -1015,7 +1022,7 @@ 2002-07-01 Werner Koch Released 0.3.9. - + * README: Short note on how to export in pkcs-12 format. 2002-06-29 Werner Koch @@ -1032,7 +1039,7 @@ 2002-06-25 Werner Koch Released 0.3.8. - + * configure.ac (NEED_LIBGCRYPT_VERSION): Set to 1.1.8. 2002-06-12 Werner Koch @@ -1050,7 +1057,7 @@ 2002-05-14 Werner Koch * doc/: New - * configure.ac, Makefile.am: Added doc/ + * configure.ac, Makefile.am: Added doc/. 2002-05-03 Werner Koch @@ -1067,9 +1074,9 @@ 2002-04-15 Werner Koch Released 0.3.5. - + * NEWS: Started to describe release notes. - + * configure.ac (NEED_LIBKSBA_VERSION, NEED_LIBGCRYPT_VERSION): Defined 2002-04-01 Werner Koch @@ -1154,10 +1161,10 @@ * configure.ac (HAVE_JNLIB_LOGGING): always define it. - - Copyright 2001, 2002, 2003, 2004, 2005, 2006, - 2007 Free Software Foundation, Inc. + Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007. + 2010 Free Software Foundation, Inc. + This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without modifications, as long as this notice is preserved. @@ -1165,5 +1172,5 @@ This file is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY, to the extent permitted by law; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - + Modified: trunk/jnlib/ChangeLog =================================================================== --- trunk/jnlib/ChangeLog 2010-02-26 10:52:05 UTC (rev 5272) +++ trunk/jnlib/ChangeLog 2010-02-26 18:44:36 UTC (rev 5273) @@ -1,3 +1,44 @@ +2010-02-26 Werner Koch + + * t-timestuff.c: New. + + * dynload.h (dlopen, dlsym) [W32CE]: Map to wchar_t. + + * mischelp.c (_jnlib_free): New. + (same_file_p) [W32CE]: Map to wchar_t. + + * utf8conv.c (set_native_charset) [W32CE]: Do not use + GetConsoleOutputCP. + (wchar_to_utf8, utf8_to_wchar) [W32]: New. + + * Makefile.am (t_jnlib_ldadd) [W32CE]: Add gpg-error. + + * t-support.h (getenv) [HAVE_GETENV]: Add getenv stub. + [W32CE]: Include gpg-error.h + * t-support.c (gpg_err_code_from_errno) + (gpg_err_code_from_syserror) [GPG_ERROR_H]: Do not build. + + * t-stringhelp.c (gethome) [!HAVE_GETPWUID]: Keep result of getenv. + + * dotlock.c [!HAVE_SIGNAL_H]: Don't include signal.h. + (create_dotlock) [W32CE]: Map filename top wchar_t. + + * libjnlib-config.h [USE_SIMPLE_GETTEXT]: Include gpg-error.h and + remove w32help.h. + (jnlib_set_errno): New. Use it everywhere to set ERRNO. + (getenv) [!HAVE_GETENV]: New. + (getpid) [W32E]: New. + + * stringhelp.c (get_pwdir) [!HAVE_PWD_H]: Mark unused args. + (w32_strerror) [W32CE]: Use a simple implementation. + + * w32help.h [USE_SIMPLE_GETTEXT]: Remove all definitions; we are + now using the gpg-error included implementation. + * w32-gettext.c: Remove. + + * mischelp.c (same_file_p): Fix bug in case the second file can't + be opened. + 2009-10-19 Werner Koch * strlist.c (add_to_strlist_try): New. @@ -696,11 +737,11 @@ *********************************************************** * Please note that JNLIB is maintained as part of GnuPG. * * You may find it source-copied in other packages. * - *********************************************************** - - Copyright 2000, 2001, 2002, 2003, 2004, - 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + *********************************************************** + Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, + 2010 Free Software Foundation, Inc. + This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without modifications, as long as this notice is preserved. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2010-02-26 10:52:05 UTC (rev 5272) +++ trunk/NEWS 2010-02-26 18:44:36 UTC (rev 5273) @@ -21,7 +21,9 @@ * New and changed passphrases are now created with an iteration count requiring about 100ms of CPU work. + * Ported to Windows CE. + Noteworthy changes in version 2.0.13 (2009-09-04) ------------------------------------------------- Modified: trunk/autogen.sh =================================================================== --- trunk/autogen.sh 2010-02-26 10:52:05 UTC (rev 5272) +++ trunk/autogen.sh 2010-02-26 18:44:36 UTC (rev 5273) @@ -123,8 +123,7 @@ --with-zlib=${w32root} \ --with-regex=${w32root} \ --with-pth-prefix=${w32root} \ - --with-adns=${w32root} \ - --without-included-gettext "$@" + --with-adns=${w32root} "$@" rc=$? exit $rc fi Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2010-02-26 10:52:05 UTC (rev 5272) +++ trunk/configure.ac 2010-02-26 18:44:36 UTC (rev 5273) @@ -918,6 +918,9 @@ # Construct a printable name of the OS # case "${host}" in + *-mingw32ce*) + PRINTABLE_OS_NAME="W32CE" + ;; *-mingw32*) PRINTABLE_OS_NAME="MingW32" ;; @@ -1089,9 +1092,11 @@ # # These are needed by libjnlib - fixme: we should use a jnlib.m4 # Note: We already checked pwd.h. -AC_CHECK_FUNCS([memicmp stpcpy strsep strlwr strtoul memmove stricmp strtol]) -AC_CHECK_FUNCS([memrchr isascii timegm getrusage setrlimit stat setlocale]) -AC_CHECK_FUNCS([flockfile funlockfile fopencookie funopen getpwnam getpwuid]) +AC_CHECK_HEADERS([signal.h]) +AC_CHECK_FUNCS([memicmp stpcpy strsep strlwr strtoul memmove stricmp strtol \ + memrchr isascii timegm getrusage setrlimit stat setlocale \ + flockfile funlockfile fopencookie funopen getpwnam getpwuid \ + getenv ]) # # gnulib checks Modified: trunk/gl/Makefile.am =================================================================== --- trunk/gl/Makefile.am 2010-02-26 10:52:05 UTC (rev 5272) +++ trunk/gl/Makefile.am 2010-02-26 18:44:36 UTC (rev 5273) @@ -29,6 +29,10 @@ AM_CPPFLAGS = +if HAVE_W32CE_SYSTEM +AM_CFLAGS = $(GPG_ERROR_CFLAGS) +endif + ## begin gnulib module alloca-opt BUILT_SOURCES += $(ALLOCA_H) Modified: trunk/gl/mkdtemp.c =================================================================== --- trunk/gl/mkdtemp.c 2010-02-26 10:52:05 UTC (rev 5272) +++ trunk/gl/mkdtemp.c 2010-02-26 18:44:36 UTC (rev 5273) @@ -23,7 +23,12 @@ #include #ifndef __set_errno -# define __set_errno(Val) errno = (Val) +# ifdef HAVE_W32CE_SYSTEM +# include +# define __set_errno(Val) gpg_err_set_errno ((Val)) +# else +# define __set_errno(Val) errno = (Val) +# endif #endif #include Modified: trunk/gl/setenv.c =================================================================== --- trunk/gl/setenv.c 2010-02-26 10:52:05 UTC (rev 5272) +++ trunk/gl/setenv.c 2010-02-26 18:44:36 UTC (rev 5273) @@ -21,7 +21,12 @@ #include #ifndef __set_errno -# define __set_errno(ev) ((errno) = (ev)) +# ifdef HAVE_W32CE_SYSTEM +# include +# define __set_errno(ev) gpg_err_set_errno ((ev)) +# else +# define __set_errno(ev) ((errno) = (ev)) +# endif #endif #include Modified: trunk/gl/unsetenv.c =================================================================== --- trunk/gl/unsetenv.c 2010-02-26 10:52:05 UTC (rev 5272) +++ trunk/gl/unsetenv.c 2010-02-26 18:44:36 UTC (rev 5273) @@ -18,7 +18,12 @@ #include #if !_LIBC -# define __set_errno(ev) ((errno) = (ev)) +# ifdef HAVE_W32CE_SYSTEM +# include +# define __set_errno(ev) gpg_err_set_errno ((ev)) +# else +# define __set_errno(ev) ((errno) = (ev)) +# endif #endif #include Modified: trunk/jnlib/Makefile.am =================================================================== --- trunk/jnlib/Makefile.am 2010-02-26 10:52:05 UTC (rev 5272) +++ trunk/jnlib/Makefile.am 2010-02-26 18:44:36 UTC (rev 5273) @@ -1,6 +1,6 @@ # Makefile for the JNLIB part of GnuPG -# Copyright (C) 1999, 2000, 2001, 2004, -# 2006 Feee Software Soundation, Inc. +# Copyright (C) 1999, 2000, 2001, 2004, 2006, +# 2010 Feee Software Soundation, Inc. # # This file is part of JNLIB. # @@ -44,7 +44,7 @@ types.h mischelp.c mischelp.h dynload.h w32help.h if HAVE_W32_SYSTEM -libjnlib_a_SOURCES += w32-reg.c w32-afunix.c w32-afunix.h w32-gettext.c +libjnlib_a_SOURCES += w32-reg.c w32-afunix.c w32-afunix.h endif @@ -60,11 +60,19 @@ # defines replacements for the actual used memory allocation functions # so that there is no dependency on libgcrypt. # -module_tests = t-stringhelp +module_tests = t-stringhelp t-timestuff t_jnlib_src = t-support.c t-support.h t_jnlib_ldadd = libjnlib.a $(LIBINTL) $(LIBICONV) +# For W32 we need libgpg-error because it provides gettext. +if HAVE_W32_SYSTEM +t_jnlib_ldadd += $(GPG_ERROR_LIBS) +endif t_stringhelp_SOURCES = t-stringhelp.c $(t_jnlib_src) t_stringhelp_LDADD = $(t_jnlib_ldadd) +t_timestuff_SOURCES = t-timestuff.c $(t_jnlib_src) +t_timestuff_LDADD = $(t_jnlib_ldadd) + + Modified: trunk/jnlib/dotlock.c =================================================================== --- trunk/jnlib/dotlock.c 2010-02-26 10:52:05 UTC (rev 5272) +++ trunk/jnlib/dotlock.c 2010-02-26 18:44:36 UTC (rev 5273) @@ -35,11 +35,14 @@ #include #include #include -#include +#ifdef HAVE_SIGNAL_H +# include +#endif #include "libjnlib-config.h" #include "stringhelp.h" #include "dotlock.h" +#include "utf8conv.h" #if !defined(DIRSEP_C) && !defined(EXTSEP_C) \ && !defined(DIRSEP_S) && !defined(EXTSEP_S) @@ -222,7 +225,7 @@ do { - errno = 0; + jnlib_set_errno (0); fd = open (h->tname, O_WRONLY|O_CREAT|O_EXCL, S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR ); } @@ -301,10 +304,23 @@ would not stop as expected but spin til until Windows crashes. Our solution is to keep the lock file open; that does not harm. */ - h->lockhd = CreateFile (h->lockname, - GENERIC_READ|GENERIC_WRITE, - FILE_SHARE_READ|FILE_SHARE_WRITE, - NULL, OPEN_ALWAYS, 0, NULL); + { +#ifdef HAVE_W32CE_SYSTEM + wchar_t *wname = utf8_to_wchar (h->lockname); + + h->lockhd = INVALID_HANDLE_VALUE; + if (wname) + h->lockhd = CreateFile (wname, +#else + h->lockhd = CreateFile (h->lockname, +#endif + GENERIC_READ|GENERIC_WRITE, + FILE_SHARE_READ|FILE_SHARE_WRITE, + NULL, OPEN_ALWAYS, 0, NULL); +#ifdef HAVE_W32CE_SYSTEM + jnlib_free (wname); +#endif + } if (h->lockhd == INVALID_HANDLE_VALUE) { log_error (_("can't create `%s': %s\n"), h->lockname, w32_strerror (-1)); @@ -613,7 +629,7 @@ h->lockname, strerror(errno) ); if (buffer != buffer_space) jnlib_free (buffer); - errno = e; /* Need to return ERRNO here. */ + jnlib_set_errno (e); /* Need to return ERRNO here. */ return -1; } @@ -630,7 +646,7 @@ close (fd); if (buffer != buffer_space) jnlib_free (buffer); - errno = 0; /* Do not return an inappropriate ERRNO. */ + jnlib_set_errno (0); /* Do not return an inappropriate ERRNO. */ return -1; } p += res; @@ -644,7 +660,7 @@ log_info ("invalid size of lockfile `%s'", h->lockname ); if (buffer != buffer_space) jnlib_free (buffer); - errno = 0; /* Better don't return an inappropriate ERRNO. */ + jnlib_set_errno (0); /* Better don't return an inappropriate ERRNO. */ return -1; } @@ -660,7 +676,7 @@ log_error ("invalid pid %d in lockfile `%s'", pid, h->lockname ); if (buffer != buffer_space) jnlib_free (buffer); - errno = 0; + jnlib_set_errno (0); return -1; } Modified: trunk/jnlib/dynload.h =================================================================== --- trunk/jnlib/dynload.h 2010-02-26 10:52:05 UTC (rev 5272) +++ trunk/jnlib/dynload.h 2010-02-26 18:44:36 UTC (rev 5273) @@ -1,5 +1,5 @@ /* dynload.h - Wrapper functions for run-time dynamic loading - * Copyright (C) 2003 Free Software Foundation, Inc. + * Copyright (C) 2003, 2010 Free Software Foundation, Inc. * * This file is part of JNLIB. * @@ -24,13 +24,21 @@ # include #else # include - +# include "utf8conv.h" +# include "mischelp.h" # define RTLD_LAZY 0 static inline void * -dlopen (const char * name, int flag) +dlopen (const char *name, int flag) { - void * hd = LoadLibrary (name); + void *hd; +#ifdef HAVE_W32CE_SYSTEM + wchar_t *wname = utf8_to_wchar (name); + hd = wname? LoadLibrary (wname) : NULL; + _jnlib_free (wname); +#else + hd = LoadLibrary (name); +#endif (void)flag; return hd; } @@ -40,7 +48,13 @@ { if (hd && sym) { - void * fnc = GetProcAddress (hd, sym); +#ifdef HAVE_W32CE_SYSTEM + wchar_t *wsym = utf8_to_wchar (sym); + void *fnc = wsym? GetProcAddress (hd, wsym) : NULL; + _jnlib_free (wsym); +#else + void *fnc = GetProcAddress (hd, sym); +#endif if (!fnc) return NULL; return fnc; @@ -53,7 +67,7 @@ dlerror (void) { static char buf[32]; - sprintf (buf, "ec=%lu", GetLastError ()); + snprintf (buf, sizeof buf, "ec=%lu", GetLastError ()); return buf; } Modified: trunk/jnlib/libjnlib-config.h =================================================================== --- trunk/jnlib/libjnlib-config.h 2010-02-26 10:52:05 UTC (rev 5272) +++ trunk/jnlib/libjnlib-config.h 2010-02-26 18:44:36 UTC (rev 5273) @@ -39,7 +39,7 @@ /* Gettext stuff */ #ifdef USE_SIMPLE_GETTEXT -# include "w32help.h" +# include # define _(a) gettext (a) # define N_(a) (a) @@ -80,5 +80,20 @@ #define jnlib_log_fatal log_fatal #define jnlib_log_bug log_bug +/* Wrapper to set ERRNO. */ +#ifdef HAVE_W32CE_SYSTEM +# define jnlib_set_errno(e) gpg_err_set_errno ((e)) +#else +# define jnlib_set_errno(e) do { errno = (e); } while (0) +#endif +/* Dummy replacement for getenv. */ +#ifndef HAVE_GETENV +#define getenv(a) (NULL) +#endif + +#ifdef HAVE_W32CE_SYSTEM +#define getpid() GetCurrentProcessId () +#endif + #endif /*LIBJNUTIL_CONFIG_H*/ Modified: trunk/jnlib/mischelp.c =================================================================== --- trunk/jnlib/mischelp.c 2010-02-26 10:52:05 UTC (rev 5272) +++ trunk/jnlib/mischelp.c 2010-02-26 18:44:36 UTC (rev 5273) @@ -29,12 +29,24 @@ # include # include #endif /*!HAVE_W32_SYSTEM*/ +#include #include "libjnlib-config.h" #include "stringhelp.h" +#include "utf8conv.h" #include "mischelp.h" +/* Because we can't use our jnlib_free macro in inline functions we + provide this wrapper. */ +void +_jnlib_free (void *p) +{ + if (p) + jnlib_free (p); +} + + /* Check whether the files NAME1 and NAME2 are identical. This is for example achieved by comparing the inode numbers of the files. */ int @@ -50,14 +62,36 @@ #ifdef HAVE_W32_SYSTEM HANDLE file1, file2; BY_HANDLE_FILE_INFORMATION info1, info2; - + +#ifdef HAVE_W32CE_SYSTEM + { + wchar_t *wname = utf8_to_wchar (name1); + if (wname) + file1 = CreateFile (wname, 0, 0, NULL, OPEN_EXISTING, 0, NULL); + else + file1 = INVALID_HANDLE_VALUE; + jnlib_free (wname); + } +#else file1 = CreateFile (name1, 0, 0, NULL, OPEN_EXISTING, 0, NULL); +#endif if (file1 == INVALID_HANDLE_VALUE) yes = 0; /* If we can't open the file, it is not the same. */ else { +#ifdef HAVE_W32CE_SYSTEM + { + wchar_t *wname = utf8_to_wchar (name2); + if (wname) + file2 = CreateFile (wname, 0, 0, NULL, OPEN_EXISTING, 0, NULL); + else + file2 = INVALID_HANDLE_VALUE; + jnlib_free (wname); + } +#else file2 = CreateFile (name2, 0, 0, NULL, OPEN_EXISTING, 0, NULL); - if (file1 == INVALID_HANDLE_VALUE) +#endif + if (file2 == INVALID_HANDLE_VALUE) yes = 0; /* If we can't open the file, it is not the same. */ else { @@ -87,7 +121,7 @@ and get back a time_t. It differs from mktime() in that it handles the case where the struct tm is UTC and the local environment isn't. - Note, that this replacement implementaion is not thread-safe! + Note, that this replacement implementation might not be thread-safe! Some BSDs don't handle the putenv("foo") case properly, so we use unsetenv if the platform has it to remove environment variables. @@ -96,6 +130,35 @@ time_t timegm (struct tm *tm) { +#ifdef HAVE_W32_SYSTEM + /* This one is thread safe. */ + SYSTEMTIME st; + FILETIME ft; + unsigned long long cnsecs; + + st.wYear = tm->tm_year + 1900; + st.wMonth = tm->tm_mon + 1; + st.wDay = tm->tm_mday; + st.wHour = tm->tm_hour; + st.wMinute = tm->tm_min; + st.wSecond = tm->tm_sec; + st.wMilliseconds = 0; /* Not available. */ + st.wDayOfWeek = 0; /* Ignored. */ + + /* System time is UTC thus the conversion is pretty easy. */ + if (!SystemTimeToFileTime (&st, &ft)) + { + jnlib_set_errno (EINVAL); + return (time_t)(-1); + } + + cnsecs = (((unsigned long long)ft.dwHighDateTime << 32) + | ft.dwLowDateTime); + cnsecs -= 116444736000000000ULL; /* The filetime epoch is 1601-01-01. */ + return (time_t)(cnsecs / 10000000ULL); + +#else /* (Non thread safe implementation!) */ + time_t answer; char *zone; @@ -128,6 +191,7 @@ tzset(); return answer; +#endif } #endif /*!HAVE_TIMEGM*/ Modified: trunk/jnlib/mischelp.h =================================================================== --- trunk/jnlib/mischelp.h 2010-02-26 10:52:05 UTC (rev 5272) +++ trunk/jnlib/mischelp.h 2010-02-26 18:44:36 UTC (rev 5273) @@ -22,6 +22,10 @@ #define LIBJNLIB_MISCHHELP_H +/* Because we can't use the internal jnlib_free macro in inline + functions we provide a wrapper fucntion as well. */ +void _jnlib_free (void *p); + /* Check whether the files NAME1 and NAME2 are identical. This is for example achieved by comparing the inode numbers of the files. */ int same_file_p (const char *name1, const char *name2); Modified: trunk/jnlib/stringhelp.c =================================================================== --- trunk/jnlib/stringhelp.c 2010-02-26 10:52:05 UTC (rev 5272) +++ trunk/jnlib/stringhelp.c 2010-02-26 18:44:36 UTC (rev 5273) @@ -346,6 +346,10 @@ else result = jnlib_strdup (pwd->pw_dir); } +#else /*!HAVE_PWD_H*/ + /* No support at all. */ + (void)xmode; + (void)name; #endif /*HAVE_PWD_H*/ return result; } @@ -369,7 +373,7 @@ { if (xmode) BUG (); - errno = EINVAL; + jnlib_set_errno (EINVAL); return NULL; } argc++; @@ -738,9 +742,15 @@ if (ec == -1) ec = (int)GetLastError (); +#ifdef HAVE_W32CE_SYSTEM + /* There is only a wchar_t FormatMessage. It does not make much + sense to play the conversion game; we print only the code. */ + snprintf (strerr, sizeof strerr, "ec=%d", (int)GetLastError ()); +#else FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, ec, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), strerr, DIM (strerr)-1, NULL); +#endif return strerr; } #endif /*HAVE_W32_SYSTEM*/ @@ -1076,7 +1086,7 @@ needed += strlen (argv[argc]); if (argc >= DIM (argv)-1) { - errno = EINVAL; + jnlib_set_errno (EINVAL); return NULL; } argc++; Modified: trunk/jnlib/t-stringhelp.c =================================================================== --- trunk/jnlib/t-stringhelp.c 2010-02-26 10:52:05 UTC (rev 5272) +++ trunk/jnlib/t-stringhelp.c 2010-02-26 18:44:36 UTC (rev 5273) @@ -43,9 +43,9 @@ { char *home = getenv("HOME"); -#if defined(HAVE_GETPWUID) && defined(HAVE_PWD_H) if(home) home_buffer = xstrdup (home); +#if defined(HAVE_GETPWUID) && defined(HAVE_PWD_H) else { struct passwd *pwd; Modified: trunk/jnlib/t-support.c =================================================================== --- trunk/jnlib/t-support.c 2010-02-26 10:52:05 UTC (rev 5272) +++ trunk/jnlib/t-support.c 2010-02-26 18:44:36 UTC (rev 5273) @@ -120,6 +120,7 @@ require functions called from these inline fucntions. Although we do not use gpg-error, gpg-error.h may get included via gcrypt.h if it happens to be used used in libjnlib-config.h. */ +#ifndef GPG_ERROR_H /* Don't do this if gpg-error.h has been included. */ int gpg_err_code_from_errno (int err) { @@ -127,17 +128,20 @@ assert (!"stub function"); return -1; } +#endif /*GPG_ERROR_H*/ /* Retrieve the error code directly from the ERRNO variable. This returns GPG_ERR_UNKNOWN_ERRNO if the system error is not mapped (report this) and GPG_ERR_MISSING_ERRNO if ERRNO has the value 0. */ +#ifndef GPG_ERROR_H /* Don't do this if gpg-error.h has been included. */ int gpg_err_code_from_syserror (void) { assert (!"stub function"); return -1; } +#endif /*GPG_ERROR_H*/ Modified: trunk/jnlib/t-support.h =================================================================== --- trunk/jnlib/t-support.h 2010-02-26 10:52:05 UTC (rev 5272) +++ trunk/jnlib/t-support.h 2010-02-26 18:44:36 UTC (rev 5273) @@ -24,7 +24,17 @@ #error The regression tests should not include with gcrypt.h #endif -/* Repalcement prototypes. */ +#ifdef HAVE_W32CE_SYSTEM +#include /* Defines strerror. */ +#endif + + +#ifndef HAVE_GETENV +# define getenv(a) (NULL) +#endif + + +/* Replacement prototypes. */ void *gcry_xmalloc (size_t n); void *gcry_xcalloc (size_t n, size_t m); void *gcry_xrealloc (void *a, size_t n); Added: trunk/jnlib/t-timestuff.c =================================================================== --- trunk/jnlib/t-timestuff.c (rev 0) +++ trunk/jnlib/t-timestuff.c 2010-02-26 18:44:36 UTC (rev 5273) @@ -0,0 +1,145 @@ +/* t-timestuff.c - Regression tests for time functions + * Copyright (C) 2007 Free Software Foundation, Inc. + * + * This file is part of JNLIB. + * + * JNLIB is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * JNLIB 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see . + */ + +#include +#include +#include +#include +#include +#include + +#include "mischelp.h" + +#include "t-support.h" + + +static int +cmp_time_s (struct tm *a, struct tm *b) +{ + if (a->tm_year != b->tm_year + || a->tm_mon != b->tm_mon + || a->tm_mday != b->tm_mday + || a->tm_hour != b->tm_hour + || a->tm_min != b->tm_min + || a->tm_sec != b->tm_sec + || a->tm_wday != b->tm_wday + || a->tm_yday != b->tm_yday + || !a->tm_isdst != !b->tm_isdst) + return -1; + return 0; +} + + + +static void +test_timegm (void) +{ + static struct { + int year, mon, mday, hour, min, sec; + } tvalues[] = { + { -1 }, + { -2, 1 }, + { -2, 2 }, + { -2, 86399 }, + { -2, 86400 }, + { -2, 0x7ffffffe }, + { -2, 0x7fffffff }, + /* Note: Because we use mktime below we can only start with the + day after Epoch. */ + { 1970, 1, 2, 0, 0 , 1}, + { 1970, 1, 2, 0, 0 , 2}, + { 1970, 1, 2, 12, 0 , 0}, + { 1970, 1, 2, 23, 59 , 59}, + { 1999, 12, 31, 23, 59 , 59}, + { 2000, 1, 1, 0, 0, 0}, + { 2000, 1, 1, 0, 0, 1}, + { 2010, 12, 31, 23, 59 , 59}, + { 2010, 1, 1, 0, 0, 0}, + { 2010, 1, 1, 0, 0, 1}, + /* The date below is about the last time mktime works in CET on + Windows XP; this is a somewhat strange because 32 bit Unices + will happily work along for another month until they reach the + end of all ticks on 20380119T031408 (unless Uli takes + compassion on us and changes time_t to a u64). */ + { 2037, 12, 18, 23, 59, 59} + + }; + int tidx; + time_t now, atime, counter; + struct tm tbuf, tbuf2, *tp; + + counter = 0; + for (tidx=0; tidx < DIM (tvalues); tidx++) + { + if (tvalues[tidx].year == -1) + { + now = time (NULL); + } + else if (tvalues[tidx].year == -2) + { + now = tvalues[tidx].mon; + } + else + { + memset (&tbuf, 0, sizeof tbuf); + tbuf.tm_year = tvalues[tidx].year - 1900; + tbuf.tm_mon = tvalues[tidx].mon; + tbuf.tm_mday = tvalues[tidx].mday; + tbuf.tm_hour = tvalues[tidx].hour; + tbuf.tm_min = tvalues[tidx].min; + tbuf.tm_sec = tvalues[tidx].sec; + now = mktime (&tbuf); + } + if (now == (time_t)(-1)) + fail (tidx); + + tp = gmtime (&now); + if (!tp) + fail (tidx); + tbuf = *tp; + tbuf2 = tbuf; + atime = timegm (&tbuf); + if (atime == (time_t)(-1)) + fail (tidx); + if (atime != now) + fail (tidx); + + tp = gmtime (&atime); + if (!tp) + fail (tidx); + if (cmp_time_s (tp, &tbuf)) + fail (tidx); + if (cmp_time_s (tp, &tbuf2)) + fail (tidx); + } +} + + + +int +main (int argc, char **argv) +{ + (void)argc; + (void)argv; + + test_timegm (); + + return 0; +} + Modified: trunk/jnlib/utf8conv.c =================================================================== --- trunk/jnlib/utf8conv.c 2010-02-26 10:52:05 UTC (rev 5272) +++ trunk/jnlib/utf8conv.c 2010-02-26 18:44:36 UTC (rev 5273) @@ -1,6 +1,6 @@ /* utf8conf.c - UTF8 character set conversion - * Copyright (C) 1994, 1998, 1999, 2000, 2001, - * 2003, 2006, 2008 Free Software Foundation, Inc. + * Copyright (C) 1994, 1998, 1999, 2000, 2001, 2003, 2006, + * 2008, 2010 Free Software Foundation, Inc. * * This file is part of JNLIB. * @@ -50,12 +50,12 @@ #ifdef HAVE_W32_SYSTEM typedef void *iconv_t; #ifndef ICONV_CONST -#define ICONV_CONST const +#define ICONV_CONST #endif static iconv_t (* __stdcall iconv_open) (const char *tocode, const char *fromcode); static size_t (* __stdcall iconv) (iconv_t cd, - const char **inbuf, size_t *inbytesleft, + char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft); static int (* __stdcall iconv_close) (iconv_t cd); @@ -166,8 +166,10 @@ different one for console input. Not sure how to cope with that. If the console Code page is not known we fall back to the system code page. */ +#ifndef HAVE_W32CE_SYSTEM cpno = GetConsoleOutputCP (); if (!cpno) +#endif cpno = GetACP (); sprintf (codepage, "CP%u", cpno ); /* Resolve alias. We use a long string string and not the usual @@ -736,3 +738,76 @@ return iconv_close ((iconv_t)cd); } + + +#ifdef HAVE_W32_SYSTEM +/* Return a malloced string encoded in UTF-8 from the wide char input + string STRING. Caller must free this value. Returns NULL and sets + ERRNO on failure. Calling this function with STRING set to NULL is + not defined. */ +char * +wchar_to_utf8 (const wchar_t *string) +{ + int n; + char *result; + + n = WideCharToMultiByte (CP_UTF8, 0, string, -1, NULL, 0, NULL, NULL); + if (n < 0) + { + jnlib_set_errno (EINVAL); + return NULL; + } + + result = jnlib_malloc (n+1); + if (!result) + return NULL; + + n = WideCharToMultiByte (CP_UTF8, 0, string, -1, result, n, NULL, NULL); + if (n < 0) + { + jnlib_free (result); + jnlib_set_errno (EINVAL); + result = NULL; + } + return result; +} + + +/* Return a malloced wide char string from an UTF-8 encoded input + string STRING. Caller must free this value. Returns NULL and sets + ERRNO on failure. Calling this function with STRING set to NULL is + not defined. */ +wchar_t * +utf8_to_wchar (const char *string) +{ + int n; + size_t nbytes; + wchar_t *result; + + n = MultiByteToWideChar (CP_UTF8, 0, string, -1, NULL, 0); + if (n < 0) + { + jnlib_set_errno (EINVAL); + return NULL; + } + + nbytes = (size_t)(n+1) * sizeof(*result); + if (nbytes / sizeof(*result) != (n+1)) + { + jnlib_set_errno (ENOMEM); + return NULL; + } + result = malloc (nbytes); + if (!result) + return NULL; + + n = MultiByteToWideChar (CP_UTF8, 0, string, -1, result, n); + if (n < 0) + { + free (result); + jnlib_set_errno (EINVAL); + result = NULL; + } + return result; +} +#endif /*HAVE_W32_SYSTEM*/ Modified: trunk/jnlib/utf8conv.h =================================================================== --- trunk/jnlib/utf8conv.h 2010-02-26 10:52:05 UTC (rev 5272) +++ trunk/jnlib/utf8conv.h 2010-02-26 18:44:36 UTC (rev 5273) @@ -36,6 +36,10 @@ char **outbuf, size_t *outbytesleft); int jnlib_iconv_close (jnlib_iconv_t cd); +#ifdef HAVE_W32_SYSTEM +char *wchar_to_utf8 (const wchar_t *string); +wchar_t *utf8_to_wchar (const char *string); +#endif /*HAVE_W32_SYSTEM*/ #endif /*LIBJNLIB_UTF8CONF_H*/ Modified: trunk/jnlib/w32-afunix.c =================================================================== --- trunk/jnlib/w32-afunix.c 2010-02-26 10:52:05 UTC (rev 5272) +++ trunk/jnlib/w32-afunix.c 2010-02-26 18:44:36 UTC (rev 5273) @@ -51,14 +51,15 @@ fclose (fp); if (!nread) { - errno = ENOFILE; +#warning remove this file + jnlib_set_errno (EIO); return -1; } buffer[nread] = 0; aval = atoi (buffer); if (aval < 1 || aval > 65535) { - errno = EINVAL; + jnlib_set_errno (EINVAL); return -1; } *port = (unsigned int)aval; @@ -66,7 +67,7 @@ ; if (*p != '\n' || nread != 17) { - errno = EINVAL; + jnlib_set_errno (EINVAL); return -1; } p++; nread--; @@ -126,7 +127,7 @@ ret = send (sockfd, nonce, 16, 0); if (ret >= 0 && ret != 16) { - errno = EIO; + jnlib_set_errno (EIO); ret = -1; } } Deleted: trunk/jnlib/w32-gettext.c Modified: trunk/jnlib/w32help.h =================================================================== --- trunk/jnlib/w32help.h 2010-02-26 10:52:05 UTC (rev 5272) +++ trunk/jnlib/w32help.h 2010-02-26 18:44:36 UTC (rev 5273) @@ -27,15 +27,6 @@ int write_w32_registry_string (const char *root, const char *dir, const char *name, const char *value); -#ifdef USE_SIMPLE_GETTEXT -char *bindtextdomain (const char *domainname, const char *dirname); -const char *gettext (const char *msgid ); -const char *ngettext (const char *msgid1, const char *msgid2, - unsigned long int n); -const char *gettext_localename (void); -void gettext_select_utf8 (int value); -#endif /*USE_SIMPLE_GETTEXT*/ - #endif /*HAVE_W32_SYSTEM*/ #endif /*LIBJNLIB_MISCHELP_H*/