keygen_set_std_prefs (const char *string,int personal)
{
    byte sym[MAX_PREFS], hash[MAX_PREFS], zip[MAX_PREFS];
    int nsym=0, nhash=0, nzip=0, val, rc=0;
    int mdc=1, modify=0; /* mdc defaults on, modify defaults off. */
    char dummy_string[20*4+1]; /* Enough for 20 items. */

    if (!string || !ascii_strcasecmp (string, "default"))
      {
	if (opt.def_preference_list)
	  string=opt.def_preference_list;
	else
	  {
            int any_compress = 0;
	    dummy_string[0]='\0';

            /* The rationale why we use the order AES256,192,128 is
               for compatibility reasons with PGP.  If gpg would
               define AES128 first, we would get the somewhat
               confusing situation:

                 gpg -r pgpkey -r gpgkey  ---gives--> AES256
                 gpg -r gpgkey -r pgpkey  ---gives--> AES

               Note that by using --personal-cipher-preferences it is
               possible to prefer AES128.
            */

	    /* Make sure we do not add more than 15 items here, as we
	       could overflow the size of dummy_string.  We currently
	       have at most 12. */
	    if ( !openpgp_cipher_test_algo (CIPHER_ALGO_AES256) )
	      strcat(dummy_string,"S9 ");
	    if ( !openpgp_cipher_test_algo (CIPHER_ALGO_AES192) )
	      strcat(dummy_string,"S8 ");
	    if ( !openpgp_cipher_test_algo (CIPHER_ALGO_AES) )
	      strcat(dummy_string,"S7 ");
	    strcat(dummy_string,"S2 "); /* 3DES */

            /* The default hash algo order is:
                 SHA-256, SHA-384, SHA-512, SHA-224, SHA-1.
             */
	    if (!openpgp_md_test_algo (DIGEST_ALGO_SHA256))
	      strcat (dummy_string, "H8 ");

	    if (!openpgp_md_test_algo (DIGEST_ALGO_SHA384))
	      strcat (dummy_string, "H9 ");

	    if (!openpgp_md_test_algo (DIGEST_ALGO_SHA512))
	      strcat (dummy_string, "H10 ");

	    if (!openpgp_md_test_algo (DIGEST_ALGO_SHA224))
	      strcat (dummy_string, "H11 ");

	    strcat (dummy_string, "H2 "); /* SHA-1 */

	    if(!check_compress_algo(COMPRESS_ALGO_ZLIB))
              {
                strcat(dummy_string,"Z2 ");
                any_compress = 1;
              }

	    if(!check_compress_algo(COMPRESS_ALGO_BZIP2))
              {
                strcat(dummy_string,"Z3 ");
                any_compress = 1;
              }

	    if(!check_compress_algo(COMPRESS_ALGO_ZIP))
              {
                strcat(dummy_string,"Z1 ");
                any_compress = 1;
              }

            /* In case we have no compress algo at all, declare that
               we prefer no compresssion.  */
            if (!any_compress)
              strcat(dummy_string,"Z0 ");

            /* Remove the trailing space.  */
            if (*dummy_string && dummy_string[strlen (dummy_string)-1] == ' ')
              dummy_string[strlen (dummy_string)-1] = 0;

	    string=dummy_string;
	  }
      }
    else if (!ascii_strcasecmp (string, "none"))
        string = "";

    if(strlen(string))
      {
	char *tok,*prefstring;

	prefstring=xstrdup(string); /* need a writable string! */

	while((tok=strsep(&prefstring," ,")))
	  {
	    if((val=string_to_cipher_algo (tok)))
	      {
		if(set_one_pref(val,1,tok,sym,&nsym))
		  rc=-1;
	      }
	    else if((val=string_to_digest_algo (tok)))
	      {
		if(set_one_pref(val,2,tok,hash,&nhash))
		  rc=-1;
	      }
	    else if((val=string_to_compress_algo(tok))>-1)
	      {
		if(set_one_pref(val,3,tok,zip,&nzip))
		  rc=-1;
	      }
	    else if (ascii_strcasecmp(tok,"mdc")==0)
	      mdc=1;
	    else if (ascii_strcasecmp(tok,"no-mdc")==0)
	      mdc=0;
	    else if (ascii_strcasecmp(tok,"ks-modify")==0)
	      modify=1;
	    else if (ascii_strcasecmp(tok,"no-ks-modify")==0)
	      modify=0;
	    else
	      {
		log_info (_("invalid item '%s' in preference string\n"),tok);
		rc=-1;
	      }
	  }

	xfree(prefstring);
      }

    if(!rc)
      {
	if(personal)
	  {
	    if(personal==PREFTYPE_SYM)
	      {
		xfree(opt.personal_cipher_prefs);

		if(nsym==0)
		  opt.personal_cipher_prefs=NULL;
		else
		  {
		    int i;

		    opt.personal_cipher_prefs=
		      xmalloc(sizeof(prefitem_t *)*(nsym+1));

		    for (i=0; i<nsym; i++)
		      {
			opt.personal_cipher_prefs[i].type = PREFTYPE_SYM;
			opt.personal_cipher_prefs[i].value = sym[i];
		      }

		    opt.personal_cipher_prefs[i].type = PREFTYPE_NONE;
		    opt.personal_cipher_prefs[i].value = 0;
		  }
	      }
	    else if(personal==PREFTYPE_HASH)
	      {
		xfree(opt.personal_digest_prefs);

		if(nhash==0)
		  opt.personal_digest_prefs=NULL;
		else
		  {
		    int i;

		    opt.personal_digest_prefs=
		      xmalloc(sizeof(prefitem_t *)*(nhash+1));

		    for (i=0; i<nhash; i++)
		      {
			opt.personal_digest_prefs[i].type = PREFTYPE_HASH;
			opt.personal_digest_prefs[i].value = hash[i];
		      }

		    opt.personal_digest_prefs[i].type = PREFTYPE_NONE;
		    opt.personal_digest_prefs[i].value = 0;
		  }
	      }
	    else if(personal==PREFTYPE_ZIP)
	      {
		xfree(opt.personal_compress_prefs);

		if(nzip==0)
		  opt.personal_compress_prefs=NULL;
		else
		  {
		    int i;

		    opt.personal_compress_prefs=
		      xmalloc(sizeof(prefitem_t *)*(nzip+1));

		    for (i=0; i<nzip; i++)
		      {
			opt.personal_compress_prefs[i].type = PREFTYPE_ZIP;
			opt.personal_compress_prefs[i].value = zip[i];
		      }

		    opt.personal_compress_prefs[i].type = PREFTYPE_NONE;
		    opt.personal_compress_prefs[i].value = 0;
		  }
	      }
	  }
	else
	  {
	    memcpy (sym_prefs,  sym,  (nsym_prefs=nsym));
	    memcpy (hash_prefs, hash, (nhash_prefs=nhash));
	    memcpy (zip_prefs,  zip,  (nzip_prefs=nzip));
	    mdc_available = mdc;
	    ks_modify = modify;
	    prefs_initialized = 1;
	  }
      }

    return rc;
}