print_token_info (CK_FUNCTION_LIST_PTR module, CK_SLOT_ID slot_id)
{
	CK_TOKEN_INFO info;
	char *value;
	CK_RV rv;

	rv = (module->C_GetTokenInfo) (slot_id, &info);
	if (rv != CKR_OK) {
		p11_message ("couldn't load module info: %s", p11_kit_strerror (rv));
		return;
	}

	value = p11_kit_space_strdup (info.label, sizeof (info.label));
	printf ("    token: %s\n", value);
	free (value);

	value = p11_kit_space_strdup (info.manufacturerID, sizeof (info.manufacturerID));
	printf ("        manufacturer: %s\n", value);
	free (value);

	value = p11_kit_space_strdup (info.model, sizeof (info.model));
	printf ("        model: %s\n", value);
	free (value);

	if (is_ascii_string (info.serialNumber, sizeof (info.serialNumber)))
		value = p11_kit_space_strdup (info.serialNumber, sizeof (info.serialNumber));
	else
		value = hex_encode (info.serialNumber, sizeof (info.serialNumber));
	printf ("        serial-number: %s\n", value);
	free (value);

	if (info.hardwareVersion.major || info.hardwareVersion.minor)
		printf ("        hardware-version: %d.%d\n",
		        info.hardwareVersion.major,
		        info.hardwareVersion.minor);

	if (info.firmwareVersion.major || info.firmwareVersion.minor)
		printf ("        firmware-version: %d.%d\n",
		        info.firmwareVersion.major,
		        info.firmwareVersion.minor);

	printf ("        flags:\n");
	#define X(x, y)   if (info.flags & (x)) printf ("               %s\n", (y))
	X(CKF_RNG, "rng");
	X(CKF_WRITE_PROTECTED, "write-protected");
	X(CKF_LOGIN_REQUIRED, "login-required");
	X(CKF_USER_PIN_INITIALIZED, "user-pin-initialized");
	X(CKF_RESTORE_KEY_NOT_NEEDED, "restore-key-not-needed");
	X(CKF_CLOCK_ON_TOKEN, "clock-on-token");
	X(CKF_PROTECTED_AUTHENTICATION_PATH, "protected-authentication-path");
	X(CKF_DUAL_CRYPTO_OPERATIONS, "dual-crypto-operations");
	X(CKF_TOKEN_INITIALIZED, "token-initialized");
	X(CKF_SECONDARY_AUTHENTICATION, "secondary-authentication");
	X(CKF_USER_PIN_COUNT_LOW, "user-pin-count-low");
	X(CKF_USER_PIN_FINAL_TRY, "user-pin-final-try");
	X(CKF_USER_PIN_LOCKED, "user-pin-locked");
	X(CKF_USER_PIN_TO_BE_CHANGED, "user-pin-to-be-changed");
	X(CKF_SO_PIN_COUNT_LOW, "so-pin-count-low");
	X(CKF_SO_PIN_FINAL_TRY, "so-pin-final-try");
	X(CKF_SO_PIN_LOCKED, "so-pin-locked");
	X(CKF_SO_PIN_TO_BE_CHANGED, "so-pin-to-be-changed");
	#undef X
}
print_token_info (CK_FUNCTION_LIST_PTR module, CK_SLOT_ID slot_id)
{
	CK_TOKEN_INFO info;
	char *value;
	CK_RV rv;

	rv = (module->C_GetTokenInfo) (slot_id, &info);
	if (rv != CKR_OK) {
		p11_message ("couldn't load module info: %s", p11_kit_strerror (rv));
		return;
	}

	value = p11_kit_space_strdup (info.label, sizeof (info.label));
	printf ("    token: %s\n", value);
	free (value);

	value = p11_kit_space_strdup (info.manufacturerID, sizeof (info.manufacturerID));
	printf ("        manufacturer: %s\n", value);
	free (value);

	value = p11_kit_space_strdup (info.model, sizeof (info.model));
	printf ("        model: %s\n", value);
	free (value);

	if (is_ascii_string (info.serialNumber, sizeof (info.serialNumber)))
		value = p11_kit_space_strdup (info.serialNumber, sizeof (info.serialNumber));
	else
		value = hex_encode (info.serialNumber, sizeof (info.serialNumber));
	printf ("        serial-number: %s\n", value);
	free (value);

	if (info.hardwareVersion.major || info.hardwareVersion.minor)
		printf ("        hardware-version: %d.%d\n",
		        info.hardwareVersion.major,
		        info.hardwareVersion.minor);

	if (info.firmwareVersion.major || info.firmwareVersion.minor)
		printf ("        firmware-version: %d.%d\n",
		        info.firmwareVersion.major,
		        info.firmwareVersion.minor);

	printf ("        flags:\n");
	#define X(x, y)   if (info.flags & (x)) printf ("               %s\n", (y))
	X(CKF_RNG, "rng");
	X(CKF_WRITE_PROTECTED, "write-protected");
	X(CKF_LOGIN_REQUIRED, "login-required");
	X(CKF_USER_PIN_INITIALIZED, "user-pin-initialized");
	X(CKF_RESTORE_KEY_NOT_NEEDED, "restore-key-not-needed");
	X(CKF_CLOCK_ON_TOKEN, "clock-on-token");
	X(CKF_PROTECTED_AUTHENTICATION_PATH, "protected-authentication-path");
	X(CKF_DUAL_CRYPTO_OPERATIONS, "dual-crypto-operations");
	X(CKF_TOKEN_INITIALIZED, "token-initialized");
	X(CKF_SECONDARY_AUTHENTICATION, "secondary-authentication");
	X(CKF_USER_PIN_COUNT_LOW, "user-pin-count-low");
	X(CKF_USER_PIN_FINAL_TRY, "user-pin-final-try");
	X(CKF_USER_PIN_LOCKED, "user-pin-locked");
	X(CKF_USER_PIN_TO_BE_CHANGED, "user-pin-to-be-changed");
	X(CKF_SO_PIN_COUNT_LOW, "so-pin-count-low");
	X(CKF_SO_PIN_FINAL_TRY, "so-pin-final-try");
	X(CKF_SO_PIN_LOCKED, "so-pin-locked");
	X(CKF_SO_PIN_TO_BE_CHANGED, "so-pin-to-be-changed");
	#undef X
}