Example #1
0
void
write_directory_file (void)
{
  FILE *fp = listed_incremental_stream;
  char buf[UINTMAX_STRSIZE_BOUND];
  char *s;

  if (! fp)
    return;

  if (fseeko (fp, 0L, SEEK_SET) != 0)
    seek_error (listed_incremental_option);
  if (sys_truncate (fileno (fp)) != 0)
    truncate_error (listed_incremental_option);

  fprintf (fp, "%s-%s-%d\n", PACKAGE_NAME, PACKAGE_VERSION,
	   TAR_INCREMENTAL_VERSION);

  s = (TYPE_SIGNED (time_t)
       ? imaxtostr (start_time.tv_sec, buf)
       : umaxtostr (start_time.tv_sec, buf));
  fwrite (s, strlen (s) + 1, 1, fp);
  s = umaxtostr (start_time.tv_nsec, buf);
  fwrite (s, strlen (s) + 1, 1, fp);

  if (! ferror (fp) && directory_table)
    hash_do_for_each (directory_table, write_directory_file_entry, fp);

  if (ferror (fp))
    write_error (listed_incremental_option);
  if (fclose (fp) != 0)
    close_error (listed_incremental_option);
}
Example #2
0
static void
out_of_range_header (char const *keyword, char const *value,
		     uintmax_t minus_minval, uintmax_t maxval)
{
  char minval_buf[UINTMAX_STRSIZE_BOUND + 1];
  char maxval_buf[UINTMAX_STRSIZE_BOUND];
  char *minval_string = umaxtostr (minus_minval, minval_buf + 1);
  char *maxval_string = umaxtostr (maxval, maxval_buf);
  if (minus_minval)
    *--minval_string = '-';

  /* TRANSLATORS: The first %s is the pax extended header keyword
     (atime, gid, etc.).  */
  ERROR ((0, 0, _("Extended header %s=%s is out of range %s..%s"),
	  keyword, value, minval_string, maxval_string));
}
Example #3
0
static void
xheader_print_n (struct xheader *xhdr, char const *keyword,
		 char const *value, size_t vsize)
{
  size_t p;
  size_t n = 0;
  char nbuf[UINTMAX_STRSIZE_BOUND];
  char const *np;
  size_t len, klen;

  keyword = xattr_encode_keyword (keyword);
  klen = strlen (keyword);
  len = klen + vsize + 3; /* ' ' + '=' + '\n' */

  do
    {
      p = n;
      np = umaxtostr (len + p, nbuf);
      n = nbuf + sizeof nbuf - 1 - np;
    }
  while (n != p);

  x_obstack_grow (xhdr, np, n);
  x_obstack_1grow (xhdr, ' ');
  x_obstack_grow (xhdr, keyword, klen);
  x_obstack_1grow (xhdr, '=');
  x_obstack_grow (xhdr, value, vsize);
  x_obstack_1grow (xhdr, '\n');
}
Example #4
0
extern char *
uid_to_name (uid_t uid)
{
    char buf[INT_BUFSIZE_BOUND (intmax_t)];
    struct passwd *pwd = getpwuid (uid);
    return xstrdup (pwd ? pwd->pw_name
                    : TYPE_SIGNED (uid_t) ? imaxtostr (uid, buf)
                    : umaxtostr (uid, buf));
}
Example #5
0
extern char *
gid_to_name (gid_t gid)
{
    char buf[INT_BUFSIZE_BOUND (intmax_t)];
    struct group *grp = getgrgid (gid);
    return xstrdup (grp ? grp->gr_name
                    : TYPE_SIGNED (gid_t) ? imaxtostr (gid, buf)
                    : umaxtostr (gid, buf));
}
Example #6
0
/* %o */
static char *
hdr_size (struct header_call_args *args, void *data)
{
  size_t m_size;
  char buf[UINTMAX_STRSIZE_BOUND];
  mu_message_size (args->msg, &m_size);
  
  return header_buf_string (args, umaxtostr (m_size, buf));
}
Example #7
0
/* Output incremental data for the directory ENTRY to the file DATA.
   Return nonzero if successful, preserving errno on write failure.  */
static bool
write_directory_file_entry (void *entry, void *data)
{
  struct directory const *directory = entry;
  FILE *fp = data;

  if (DIR_IS_FOUND (directory))
    {
      char buf[UINTMAX_STRSIZE_BOUND];
      char *s;

      s = DIR_IS_NFS (directory) ? "1" : "0";
      fwrite (s, 2, 1, fp);
      s = (TYPE_SIGNED (time_t)
	   ? imaxtostr (directory->mtime.tv_sec, buf)
	   : umaxtostr (directory->mtime.tv_sec, buf));
      fwrite (s, strlen (s) + 1, 1, fp);
      s = umaxtostr (directory->mtime.tv_nsec, buf);
      fwrite (s, strlen (s) + 1, 1, fp);
      s = umaxtostr (directory->device_number, buf);
      fwrite (s, strlen (s) + 1, 1, fp);
      s = umaxtostr (directory->inode_number, buf);
      fwrite (s, strlen (s) + 1, 1, fp);

      fwrite (directory->name, strlen (directory->name) + 1, 1, fp);
      if (directory->dump)
	{
	  const char *p;
	  dumpdir_iter_t itr;

	  for (p = dumpdir_first (directory->dump, 0, &itr);
	       p;
	       p = dumpdir_next (itr))
	    fwrite (p, strlen (p) + 1, 1, fp);
	  free (itr);
	}
      fwrite ("\0\0", 2, 1, fp);
    }

  return ! ferror (fp);
}
Example #8
0
char *
sysinttostr (uintmax_t value, intmax_t minval, uintmax_t maxval,
	     char buf[SYSINT_BUFSIZE])
{
  if (value <= maxval)
    return umaxtostr (value, buf);
  else
    {
      intmax_t i = value - minval;
      return imaxtostr (i + minval, buf);
    }
}
Example #9
0
bool
xheader_string_end (struct xheader *xhdr, char const *keyword)
{
  uintmax_t len;
  uintmax_t p;
  uintmax_t n = 0;
  size_t size;
  char nbuf[UINTMAX_STRSIZE_BOUND];
  char const *np;
  char *cp;

  if (xhdr->buffer)
    return false;
  xheader_init (xhdr);

  len = strlen (keyword) + xhdr->string_length + 3; /* ' ' + '=' + '\n' */

  do
    {
      p = n;
      np = umaxtostr (len + p, nbuf);
      n = nbuf + sizeof nbuf - 1 - np;
    }
  while (n != p);

  p = strlen (keyword) + n + 2;
  size = p;
  if (size != p)
    {
      ERROR ((0, 0,
        _("Generated keyword/value pair is too long (keyword=%s, length=%s)"),
	      keyword, nbuf));
      obstack_free (xhdr->stk, obstack_finish (xhdr->stk));
      return false;
    }
  x_obstack_blank (xhdr, p);
  x_obstack_1grow (xhdr, '\n');
  cp = obstack_next_free (xhdr->stk) - xhdr->string_length - p - 1;
  memmove (cp + p, cp, xhdr->string_length);
  cp = stpcpy (cp, np);
  *cp++ = ' ';
  cp = stpcpy (cp, keyword);
  *cp++ = '=';
  return true;
}
Example #10
0
char const *
code_timespec (struct timespec t, char sbuf[TIMESPEC_STRSIZE_BOUND])
{
  time_t s = t.tv_sec;
  int ns = t.tv_nsec;
  char *np;
  bool negative = s < 0;

  /* ignore invalid values of ns */
  if (BILLION <= ns || ns < 0)
    ns = 0;

  if (negative && ns != 0)
    {
      s++;
      ns = BILLION - ns;
    }

  np = umaxtostr (negative ? - (uintmax_t) s : (uintmax_t) s, sbuf + 1);
  if (negative)
    *--np = '-';
  code_ns_fraction (ns, sbuf + UINTMAX_STRSIZE_BOUND);
  return np;
}
Example #11
0
/* %m */
static char *
hdr_number (struct header_call_args *args, void *data)
{
  char buf[UINTMAX_STRSIZE_BOUND];
  return header_buf_string (args, umaxtostr (args->mspec->msg_part[0], buf));
}
Example #12
0
static int
build_algparm (pskc_key_t * kp, xmlNodePtr keyp)
{
  const char *suite = pskc_get_key_algparm_suite (kp);
  int chall_encoding_p;
  pskc_valueformat chall_encoding = pskc_get_key_algparm_chall_encoding
    (kp, &chall_encoding_p);
  int chall_min_p;
  uint32_t chall_min = pskc_get_key_algparm_chall_min (kp, &chall_min_p);
  int chall_max_p;
  uint32_t chall_max = pskc_get_key_algparm_chall_max (kp, &chall_max_p);
  int chall_checkdigits_p;
  int chall_checkdigits = pskc_get_key_algparm_chall_checkdigits
    (kp, &chall_checkdigits_p);
  int resp_encoding_p;
  pskc_valueformat resp_encoding = pskc_get_key_algparm_resp_encoding
    (kp, &resp_encoding_p);
  int resp_length_p;
  uint32_t resp_length =
    pskc_get_key_algparm_resp_length (kp, &resp_length_p);
  int resp_checkdigits_p;
  int resp_checkdigits = pskc_get_key_algparm_resp_checkdigits
    (kp, &resp_checkdigits_p);
  xmlNodePtr algparm;

  if (!suite && !chall_encoding_p && !chall_min_p && !chall_max_p
      && !chall_checkdigits_p && !resp_encoding_p && !resp_length_p
      && !resp_checkdigits_p)
    return PSKC_OK;

  algparm = xmlNewChild (keyp, NULL, BAD_CAST "AlgorithmParameters", NULL);

  if (suite)
    xmlNewTextChild (algparm, NULL, BAD_CAST "Suite", BAD_CAST suite);

  if (chall_encoding_p || chall_min_p || chall_max_p || resp_checkdigits_p)
    {
      xmlNodePtr chall;

      chall = xmlNewChild (algparm, NULL, BAD_CAST "ChallengeFormat", NULL);

      if (chall_encoding_p)
	xmlNewProp (chall, BAD_CAST "Encoding",
		    BAD_CAST pskc_valueformat2str (chall_encoding));


      if (chall_min_p)
	{
	  char buf[INT_BUFSIZE_BOUND (uintmax_t)];
	  char *p = umaxtostr (chall_min, buf);
	  xmlNewProp (chall, BAD_CAST "Min", BAD_CAST p);
	}

      if (chall_max_p)
	{
	  char buf[INT_BUFSIZE_BOUND (uintmax_t)];
	  char *p = umaxtostr (chall_max, buf);
	  xmlNewProp (chall, BAD_CAST "Max", BAD_CAST p);
	}

      if (chall_checkdigits_p && chall_checkdigits)
	xmlNewProp (chall, BAD_CAST "CheckDigits", BAD_CAST "true");
    }

  if (resp_encoding_p || resp_length_p || resp_checkdigits_p)
    {
      xmlNodePtr resp;

      resp = xmlNewChild (algparm, NULL, BAD_CAST "ResponseFormat", NULL);

      if (resp_encoding_p)
	xmlNewProp (resp, BAD_CAST "Encoding",
		    BAD_CAST pskc_valueformat2str (resp_encoding));

      if (resp_length_p)
	{
	  char buf[INT_BUFSIZE_BOUND (uintmax_t)];
	  char *p = umaxtostr (resp_length, buf);
	  xmlNewProp (resp, BAD_CAST "Length", BAD_CAST p);
	}

      if (resp_checkdigits_p && resp_checkdigits)
	xmlNewProp (resp, BAD_CAST "CheckDigits", BAD_CAST "true");
    }

  return PSKC_OK;
}
Example #13
0
File: userspec.c Project: 8l/csolve
static char const *
parse_with_separator (char const *spec, char const *separator,
                      uid_t *uid, gid_t *gid,
                      char **username, char **groupname)
{
  static const char *E_invalid_user = N_("invalid user");
  static const char *E_invalid_group = N_("invalid group");
  static const char *E_bad_spec = N_("invalid spec");

  const char *error_msg;
  struct passwd *pwd;
  struct group *grp;
  char *u;
  char const *g;
  char *gname = NULL;
  uid_t unum = *uid;
  gid_t gnum = *gid;

  error_msg = NULL;
  *username = *groupname = NULL;

  /* Set U and G to nonzero length strings corresponding to user and
     group specifiers or to NULL.  If U is not NULL, it is a newly
     allocated string.  */

  u = NULL;
  if (separator == NULL)
    {
      if (*spec)
        u = xstrdup (spec);
    }
  else
    {
      size_t ulen = separator - spec;
      if (ulen != 0)
        {
          u = xmemdup (spec, ulen + 1);
          u[ulen] = '\0';
        }
    }

  g = (separator == NULL || *(separator + 1) == '\0'
       ? NULL
       : separator + 1);

#ifdef __DJGPP__
  /* Pretend that we are the user U whose group is G.  This makes
     pwd and grp functions ``know'' about the UID and GID of these.  */
  if (u && !is_number (u))
    setenv ("USER", u, 1);
  if (g && !is_number (g))
    setenv ("GROUP", g, 1);
#endif

  if (u != NULL)
    {
      /* If it starts with "+", skip the look-up.  */
      pwd = (*u == '+' ? NULL : getpwnam (u));
      if (pwd == NULL)
        {
          bool use_login_group = (separator != NULL && g == NULL);
          if (use_login_group)
            {
              /* If there is no group,
                 then there may not be a trailing ":", either.  */
              error_msg = E_bad_spec;
            }
          else
            {
              unsigned long int tmp;
              if (xstrtoul (u, NULL, 10, &tmp, "") == LONGINT_OK
                  && tmp <= MAXUID && (uid_t) tmp != (uid_t) -1)
                unum = tmp;
              else
                error_msg = E_invalid_user;
            }
        }
      else
        {
          unum = pwd->pw_uid;
          if (g == NULL && separator != NULL)
            {
              /* A separator was given, but a group was not specified,
                 so get the login group.  */
              char buf[INT_BUFSIZE_BOUND (uintmax_t)];
              gnum = pwd->pw_gid;
              grp = getgrgid (gnum);
              gname = xstrdup (grp ? grp->gr_name : umaxtostr (gnum, buf));
              endgrent ();
            }
        }
      endpwent ();
    }

  if (g != NULL && error_msg == NULL)
    {
      /* Explicit group.  */
      /* If it starts with "+", skip the look-up.  */
      grp = (*g == '+' ? NULL : getgrnam (g));
      if (grp == NULL)
        {
          unsigned long int tmp;
          if (xstrtoul (g, NULL, 10, &tmp, "") == LONGINT_OK
              && tmp <= MAXGID && (gid_t) tmp != (gid_t) -1)
            gnum = tmp;
          else
            error_msg = E_invalid_group;
        }
      else
        gnum = grp->gr_gid;
      endgrent ();              /* Save a file descriptor.  */
      gname = xstrdup (g);
    }

  if (error_msg == NULL)
    {
      *uid = unum;
      *gid = gnum;
      *username = u;
      *groupname = gname;
      u = NULL;
    }
  else
    free (gname);

  free (u);
  return _(error_msg);
}
Example #14
0
/* Convert a gid_t to string.  Do not use this function directly.
   Instead, use it via the gidtostr macro.
   Beware that it returns a pointer to static storage.  */
static char *
gidtostr_ptr (gid_t const *gid)
{
  static char buf[INT_BUFSIZE_BOUND (uintmax_t)];
  return umaxtostr (*gid, buf);
}
Example #15
0
char *
xheader_format_name (struct tar_stat_info *st, const char *fmt, size_t n)
{
  char *buf;
  size_t len = strlen (fmt);
  char *q;
  const char *p;
  char *dirp = NULL;
  char *dir = NULL;
  char *base = NULL;
  char pidbuf[UINTMAX_STRSIZE_BOUND];
  char const *pptr = NULL;
  char nbuf[UINTMAX_STRSIZE_BOUND];
  char const *nptr = NULL;

  for (p = fmt; *p && (p = strchr (p, '%')); )
    {
      switch (p[1])
	{
	case '%':
	  len--;
	  break;

	case 'd':
	  if (st)
	    {
	      if (!dirp)
		dirp = dir_name (st->orig_file_name);
	      dir = safer_name_suffix (dirp, false, absolute_names_option);
	      len += strlen (dir) - 2;
	    }
	  break;

	case 'f':
	  if (st)
	    {
	      base = last_component (st->orig_file_name);
	      len += strlen (base) - 2;
	    }
	  break;

	case 'p':
	  pptr = umaxtostr (getpid (), pidbuf);
	  len += pidbuf + sizeof pidbuf - 1 - pptr - 2;
	  break;

	case 'n':
	  nptr = umaxtostr (n, nbuf);
	  len += nbuf + sizeof nbuf - 1 - nptr - 2;
	  break;
	}
      p++;
    }

  buf = xmalloc (len + 1);
  for (q = buf, p = fmt; *p; )
    {
      if (*p == '%')
	{
	  switch (p[1])
	    {
	    case '%':
	      *q++ = *p++;
	      p++;
	      break;

	    case 'd':
	      if (dir)
		q = stpcpy (q, dir);
	      p += 2;
	      break;

	    case 'f':
	      if (base)
		q = stpcpy (q, base);
	      p += 2;
	      break;

	    case 'p':
	      q = stpcpy (q, pptr);
	      p += 2;
	      break;

	    case 'n':
	      q = stpcpy (q, nptr);
	      p += 2;
	      break;


	    default:
	      *q++ = *p++;
	      if (*p)
		*q++ = *p++;
	    }
	}
      else
	*q++ = *p++;
    }

  free (dirp);

  /* Do not allow it to end in a slash */
  while (q > buf && ISSLASH (q[-1]))
    q--;
  *q = 0;
  return buf;
}
Example #16
0
static bool
read_num (FILE *fp, char const *fieldname,
	  intmax_t min_val, uintmax_t max_val, intmax_t *pval)
{
  int i;
  char buf[INT_BUFSIZE_BOUND (intmax_t)];
  char offbuf[INT_BUFSIZE_BOUND (off_t)];
  char minbuf[INT_BUFSIZE_BOUND (intmax_t)];
  char maxbuf[INT_BUFSIZE_BOUND (intmax_t)];
  int conversion_errno;
  int c = getc (fp);
  bool negative = c == '-';

  for (i = 0; (i == 0 && negative) || ISDIGIT (c); i++)
    {
      buf[i] = c;
      if (i == sizeof buf - 1)
	FATAL_ERROR ((0, 0,
		      _("%s: byte %s: %s %.*s... too long"),
		      quotearg_colon (listed_incremental_option),
		      offtostr (ftello (fp), offbuf),
		      fieldname, i + 1, buf));
      c = getc (fp);
    }

  buf[i] = 0;

  if (c < 0)
    {
      if (ferror (fp))
	read_fatal (listed_incremental_option);
      if (i != 0)
	FATAL_ERROR ((0, 0, "%s: %s",
		      quotearg_colon (listed_incremental_option),
		      _("Unexpected EOF in snapshot file")));
      return false;
    }

  if (c)
    {
      unsigned uc = c;
      FATAL_ERROR ((0, 0,
		    _("%s: byte %s: %s %s followed by invalid byte 0x%02x"),
		    quotearg_colon (listed_incremental_option),
		    offtostr (ftello (fp), offbuf),
		    fieldname, buf, uc));
    }

  *pval = strtosysint (buf, NULL, min_val, max_val);
  conversion_errno = errno;

  switch (conversion_errno)
    {
    case ERANGE:
      FATAL_ERROR ((0, conversion_errno,
		    _("%s: byte %s: (valid range %s..%s)\n\t%s %s"),
		    quotearg_colon (listed_incremental_option),
		    offtostr (ftello (fp), offbuf),
		    imaxtostr (min_val, minbuf),
		    umaxtostr (max_val, maxbuf), fieldname, buf));
    default:
      FATAL_ERROR ((0, conversion_errno,
		    _("%s: byte %s: %s %s"),
		    quotearg_colon (listed_incremental_option),
		    offtostr (ftello (fp), offbuf), fieldname, buf));
    case 0:
      break;
    }

  return true;
}
Example #17
0
static int
build_data (pskc_key_t * kp, xmlNodePtr keyp)
{
  const char *b64secret = pskc_get_key_data_b64secret (kp);
  int counter_p;
  uint64_t counter = pskc_get_key_data_counter (kp, &counter_p);
  int t_p;
  uint32_t t = pskc_get_key_data_time (kp, &t_p);
  int tinterval_p;
  uint32_t tinterval = pskc_get_key_data_timeinterval (kp, &tinterval_p);
  int tdrift_p;
  uint32_t tdrift = pskc_get_key_data_timedrift (kp, &tdrift_p);
  xmlNodePtr data, sub;

  if (!b64secret && !counter_p && !t_p && !tinterval_p && !tdrift_p)
    return PSKC_OK;

  data = xmlNewChild (keyp, NULL, BAD_CAST "Data", NULL);

  if (b64secret)
    {
      sub = xmlNewChild (data, NULL, BAD_CAST "Secret", NULL);
      xmlNewTextChild (sub, NULL, BAD_CAST "PlainValue", BAD_CAST b64secret);
    }

  if (counter_p)
    {
      char buf[INT_BUFSIZE_BOUND (uintmax_t)];
      char *p = umaxtostr (counter, buf);

      sub = xmlNewChild (data, NULL, BAD_CAST "Counter", NULL);
      xmlNewTextChild (sub, NULL, BAD_CAST "PlainValue", BAD_CAST p);
    }

  if (t_p)
    {
      char buf[INT_BUFSIZE_BOUND (uintmax_t)];
      char *p = umaxtostr (t, buf);

      sub = xmlNewChild (data, NULL, BAD_CAST "Time", NULL);
      xmlNewTextChild (sub, NULL, BAD_CAST "PlainValue", BAD_CAST p);
    }

  if (tinterval_p)
    {
      char buf[INT_BUFSIZE_BOUND (uintmax_t)];
      char *p = umaxtostr (tinterval, buf);

      sub = xmlNewChild (data, NULL, BAD_CAST "TimeInterval", NULL);
      xmlNewTextChild (sub, NULL, BAD_CAST "PlainValue", BAD_CAST p);
    }

  if (tdrift_p)
    {
      char buf[INT_BUFSIZE_BOUND (uintmax_t)];
      char *p = umaxtostr (tdrift, buf);

      sub = xmlNewChild (data, NULL, BAD_CAST "TimeDrift", NULL);
      xmlNewTextChild (sub, NULL, BAD_CAST "PlainValue", BAD_CAST p);
    }

  return PSKC_OK;
}
Example #18
0
static void
code_num (uintmax_t value, char const *keyword, struct xheader *xhdr)
{
  char sbuf[UINTMAX_STRSIZE_BOUND];
  xheader_print (xhdr, keyword, umaxtostr (value, sbuf));
}
Example #19
0
static int
build_policy (pskc_key_t * kp, xmlNodePtr keyp)
{
  int keyusage_p;
  int keyusages = pskc_get_key_policy_keyusages (kp, &keyusage_p);
  const struct tm *startdate = pskc_get_key_policy_startdate (kp);
  const struct tm *expirydate = pskc_get_key_policy_expirydate (kp);
  const char *pinkeyid = pskc_get_key_policy_pinkeyid (kp);
  int pinusagemode_p;
  pskc_pinusagemode pinusagemode =
    pskc_get_key_policy_pinusagemode (kp, &pinusagemode_p);
  int attempts_p;
  uint32_t attempts =
    pskc_get_key_policy_pinmaxfailedattempts (kp, &attempts_p);
  int pinmin_p;
  uint32_t pinmin = pskc_get_key_policy_pinminlength (kp, &pinmin_p);
  int pinmax_p;
  uint32_t pinmax = pskc_get_key_policy_pinmaxlength (kp, &pinmax_p);
  int pinencoding_p;
  pskc_valueformat pinencoding =
    pskc_get_key_policy_pinencoding (kp, &pinencoding_p);
  int numberoftransactions_p;
  uint64_t numberoftransactions = pskc_get_key_policy_numberoftransactions
    (kp, &numberoftransactions_p);
  xmlNodePtr policy, pinpolicy;

  if (!keyusage_p && !startdate && !expirydate && !pinkeyid && !pinusagemode_p
      && !attempts_p && !pinmin_p && !pinmax_p && !pinencoding_p)
    return PSKC_OK;

  policy = xmlNewChild (keyp, NULL, BAD_CAST "Policy", NULL);

  if (startdate)
    {
      char t[100];
      strftime (t, sizeof (t), "%Y-%m-%dT%H:%M:%SZ", startdate);
      xmlNewTextChild (policy, NULL, BAD_CAST "StartDate", BAD_CAST t);
    }

  if (expirydate)
    {
      char t[100];
      strftime (t, sizeof (t), "%Y-%m-%dT%H:%M:%SZ", expirydate);
      xmlNewTextChild (policy, NULL, BAD_CAST "ExpiryDate", BAD_CAST t);
    }

  if (pinkeyid || pinusagemode_p || attempts_p
      || pinmin_p || pinmax_p || pinencoding_p)
    {
      pinpolicy = xmlNewChild (policy, NULL, BAD_CAST "PINPolicy", NULL);

      if (pinkeyid)
	xmlNewProp (pinpolicy, BAD_CAST "PINKeyId", BAD_CAST pinkeyid);

      if (pinusagemode_p)
	xmlNewProp (pinpolicy, BAD_CAST "PINUsageMode",
		    BAD_CAST pskc_pinusagemode2str (pinusagemode));

      if (attempts_p)
	{
	  char buf[INT_BUFSIZE_BOUND (uintmax_t)];
	  char *p = umaxtostr (attempts, buf);
	  xmlNewProp (pinpolicy, BAD_CAST "MaxFailedAttempts", BAD_CAST p);
	}

      if (pinmin_p)
	{
	  char buf[INT_BUFSIZE_BOUND (uintmax_t)];
	  char *p = umaxtostr (pinmin, buf);
	  xmlNewProp (pinpolicy, BAD_CAST "MinLength", BAD_CAST p);
	}

      if (pinmax_p)
	{
	  char buf[INT_BUFSIZE_BOUND (uintmax_t)];
	  char *p = umaxtostr (pinmax, buf);
	  xmlNewProp (pinpolicy, BAD_CAST "MaxLength", BAD_CAST p);
	}

      if (pinencoding_p)
	xmlNewProp (pinpolicy, BAD_CAST "PINEncoding",
		    BAD_CAST pskc_valueformat2str (pinencoding));
    }

  if (keyusage_p)
    {
      int i;
      for (i = 1; i <= PSKC_KEYUSAGE_LAST; i = i << 1)
	{
	  const char *keyusage_str = pskc_keyusage2str (i);

	  if (keyusages & i)
	    xmlNewTextChild (policy, NULL, BAD_CAST "KeyUsage",
			     BAD_CAST keyusage_str);
	}
    }

  if (numberoftransactions_p)
    {
      char buf[INT_BUFSIZE_BOUND (uintmax_t)];
      char *p = umaxtostr (numberoftransactions, buf);
      xmlNewTextChild (policy, NULL, BAD_CAST "NumberOfTransactions",
		       BAD_CAST p);
    }

  return PSKC_OK;
}