1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* crypto/engine/eng_ctrl.c */
2656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* ====================================================================
3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Redistribution and use in source and binary forms, with or without
6656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * modification, are permitted provided that the following conditions
7656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * are met:
8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 1. Redistributions of source code must retain the above copyright
10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer.
11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer in
14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    the documentation and/or other materials provided with the
15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    distribution.
16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
17656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 3. All advertising materials mentioning features or use of this
18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    software must display the following acknowledgment:
19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software developed by the OpenSSL Project
20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    endorse or promote products derived from this software without
24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    prior written permission. For written permission, please contact
25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    licensing@OpenSSL.org.
26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 5. Products derived from this software may not be called "OpenSSL"
28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    nor may "OpenSSL" appear in their names without prior written
29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    permission of the OpenSSL Project.
30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 6. Redistributions of any form whatsoever must retain the following
32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    acknowledgment:
33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software developed by the OpenSSL Project
34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OF THE POSSIBILITY OF SUCH DAMAGE.
48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ====================================================================
49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This product includes cryptographic software written by Eric Young
51656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * (eay@cryptsoft.com).  This product includes software written by Tim
52656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Hudson (tjh@cryptsoft.com).
53656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
54656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
55656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "eng_int.h"
57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
58656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* When querying a ENGINE-specific control command's 'description', this string
59656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * is used if the ENGINE_CMD_DEFN has cmd_desc set to NULL. */
60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic const char *int_no_description = "";
61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
62656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* These internal functions handle 'CMD'-related control commands when the
63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ENGINE in question has asked us to take care of it (ie. the ENGINE did not
64656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * set the ENGINE_FLAGS_MANUAL_CMD_CTRL flag. */
65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
66656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int int_ctrl_cmd_is_null(const ENGINE_CMD_DEFN *defn)
67656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
68656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if((defn->cmd_num == 0) || (defn->cmd_name == NULL))
69656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 1;
70656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 0;
71656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
72656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
73656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int int_ctrl_cmd_by_name(const ENGINE_CMD_DEFN *defn, const char *s)
74656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
75656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int idx = 0;
76656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	while(!int_ctrl_cmd_is_null(defn) && (strcmp(defn->cmd_name, s) != 0))
77656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
78656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		idx++;
79656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		defn++;
80656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
81656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(int_ctrl_cmd_is_null(defn))
82656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* The given name wasn't found */
83656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return -1;
84656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return idx;
85656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
86656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
87656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int int_ctrl_cmd_by_num(const ENGINE_CMD_DEFN *defn, unsigned int num)
88656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
89656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int idx = 0;
90656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* NB: It is stipulated that 'cmd_defn' lists are ordered by cmd_num. So
91656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * our searches don't need to take any longer than necessary. */
92656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	while(!int_ctrl_cmd_is_null(defn) && (defn->cmd_num < num))
93656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
94656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		idx++;
95656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		defn++;
96656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
97656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(defn->cmd_num == num)
98656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return idx;
99656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* The given cmd_num wasn't found */
100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return -1;
101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int int_ctrl_helper(ENGINE *e, int cmd, long i, void *p,
104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			   void (*f)(void))
105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
106656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int idx;
107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	char *s = (char *)p;
108656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Take care of the easy one first (eg. it requires no searches) */
109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(cmd == ENGINE_CTRL_GET_FIRST_CMD_TYPE)
110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
111656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if((e->cmd_defns == NULL) || int_ctrl_cmd_is_null(e->cmd_defns))
112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return 0;
113656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return e->cmd_defns->cmd_num;
114656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
115656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* One or two commands require that "p" be a valid string buffer */
116656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if((cmd == ENGINE_CTRL_GET_CMD_FROM_NAME) ||
117656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			(cmd == ENGINE_CTRL_GET_NAME_FROM_CMD) ||
118656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			(cmd == ENGINE_CTRL_GET_DESC_FROM_CMD))
119656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
120656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(s == NULL)
121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
122656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ENGINEerr(ENGINE_F_INT_CTRL_HELPER,
123656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ERR_R_PASSED_NULL_PARAMETER);
124656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return -1;
125656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
126656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
127656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Now handle cmd_name -> cmd_num conversion */
128656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(cmd == ENGINE_CTRL_GET_CMD_FROM_NAME)
129656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
130656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if((e->cmd_defns == NULL) || ((idx = int_ctrl_cmd_by_name(
131656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project						e->cmd_defns, s)) < 0))
132656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
133656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ENGINEerr(ENGINE_F_INT_CTRL_HELPER,
134656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ENGINE_R_INVALID_CMD_NAME);
135656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return -1;
136656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
137656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return e->cmd_defns[idx].cmd_num;
138656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
139656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* For the rest of the commands, the 'long' argument must specify a
140656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * valie command number - so we need to conduct a search. */
141656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if((e->cmd_defns == NULL) || ((idx = int_ctrl_cmd_by_num(e->cmd_defns,
142656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					(unsigned int)i)) < 0))
143656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
144656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ENGINEerr(ENGINE_F_INT_CTRL_HELPER,
145656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ENGINE_R_INVALID_CMD_NUMBER);
146656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return -1;
147656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
148656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Now the logic splits depending on command type */
149656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	switch(cmd)
150656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
151656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case ENGINE_CTRL_GET_NEXT_CMD_TYPE:
152656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		idx++;
153656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(int_ctrl_cmd_is_null(e->cmd_defns + idx))
154656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* end-of-list */
155656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return 0;
156656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else
157656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return e->cmd_defns[idx].cmd_num;
158656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case ENGINE_CTRL_GET_NAME_LEN_FROM_CMD:
159656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return strlen(e->cmd_defns[idx].cmd_name);
160656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case ENGINE_CTRL_GET_NAME_FROM_CMD:
161656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return BIO_snprintf(s,strlen(e->cmd_defns[idx].cmd_name) + 1,
162656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				    "%s", e->cmd_defns[idx].cmd_name);
163656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case ENGINE_CTRL_GET_DESC_LEN_FROM_CMD:
164656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(e->cmd_defns[idx].cmd_desc)
165656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return strlen(e->cmd_defns[idx].cmd_desc);
166656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return strlen(int_no_description);
167656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case ENGINE_CTRL_GET_DESC_FROM_CMD:
168656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(e->cmd_defns[idx].cmd_desc)
169656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return BIO_snprintf(s,
170656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					    strlen(e->cmd_defns[idx].cmd_desc) + 1,
171656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					    "%s", e->cmd_defns[idx].cmd_desc);
172656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return BIO_snprintf(s, strlen(int_no_description) + 1,"%s",
173656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				    int_no_description);
174656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case ENGINE_CTRL_GET_CMD_FLAGS:
175656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return e->cmd_defns[idx].cmd_flags;
176656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
177656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Shouldn't really be here ... */
178656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ENGINEerr(ENGINE_F_INT_CTRL_HELPER,ENGINE_R_INTERNAL_LIST_ERROR);
179656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return -1;
180656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
181656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
182656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
183656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
184656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int ctrl_exists, ref_exists;
185656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(e == NULL)
186656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
187656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ENGINEerr(ENGINE_F_ENGINE_CTRL,ERR_R_PASSED_NULL_PARAMETER);
188656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
189656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
190656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
191656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ref_exists = ((e->struct_ref > 0) ? 1 : 0);
192656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
193656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctrl_exists = ((e->ctrl == NULL) ? 0 : 1);
194656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!ref_exists)
195656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
196656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ENGINEerr(ENGINE_F_ENGINE_CTRL,ENGINE_R_NO_REFERENCE);
197656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
198656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
199656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Intercept any "root-level" commands before trying to hand them on to
200656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * ctrl() handlers. */
201656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	switch(cmd)
202656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
203656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case ENGINE_CTRL_HAS_CTRL_FUNCTION:
204656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return ctrl_exists;
205656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case ENGINE_CTRL_GET_FIRST_CMD_TYPE:
206656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case ENGINE_CTRL_GET_NEXT_CMD_TYPE:
207656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case ENGINE_CTRL_GET_CMD_FROM_NAME:
208656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case ENGINE_CTRL_GET_NAME_LEN_FROM_CMD:
209656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case ENGINE_CTRL_GET_NAME_FROM_CMD:
210656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case ENGINE_CTRL_GET_DESC_LEN_FROM_CMD:
211656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case ENGINE_CTRL_GET_DESC_FROM_CMD:
212656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case ENGINE_CTRL_GET_CMD_FLAGS:
213656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(ctrl_exists && !(e->flags & ENGINE_FLAGS_MANUAL_CMD_CTRL))
214656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return int_ctrl_helper(e,cmd,i,p,f);
215656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(!ctrl_exists)
216656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
217656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ENGINEerr(ENGINE_F_ENGINE_CTRL,ENGINE_R_NO_CONTROL_FUNCTION);
218656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* For these cmd-related functions, failure is indicated
219656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			 * by a -1 return value (because 0 is used as a valid
220656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			 * return in some places). */
221656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return -1;
222656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
223656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	default:
224656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
225656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
226656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Anything else requires a ctrl() handler to exist. */
227656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!ctrl_exists)
228656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
229656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ENGINEerr(ENGINE_F_ENGINE_CTRL,ENGINE_R_NO_CONTROL_FUNCTION);
230656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
231656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
232656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return e->ctrl(e, cmd, i, p, f);
233656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
234656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
235656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint ENGINE_cmd_is_executable(ENGINE *e, int cmd)
236656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
237656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int flags;
238656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if((flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, cmd, NULL, NULL)) < 0)
239656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
240656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ENGINEerr(ENGINE_F_ENGINE_CMD_IS_EXECUTABLE,
241656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ENGINE_R_INVALID_CMD_NUMBER);
242656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
243656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
244656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!(flags & ENGINE_CMD_FLAG_NO_INPUT) &&
245656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			!(flags & ENGINE_CMD_FLAG_NUMERIC) &&
246656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			!(flags & ENGINE_CMD_FLAG_STRING))
247656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
248656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
249656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
250656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
251656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name,
252656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        long i, void *p, void (*f)(void), int cmd_optional)
253656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        {
254656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int num;
255656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
256656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if((e == NULL) || (cmd_name == NULL))
257656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
258656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD,
259656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ERR_R_PASSED_NULL_PARAMETER);
260656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
261656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
262656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if((e->ctrl == NULL) || ((num = ENGINE_ctrl(e,
263656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					ENGINE_CTRL_GET_CMD_FROM_NAME,
264656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					0, (void *)cmd_name, NULL)) <= 0))
265656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
266656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* If the command didn't *have* to be supported, we fake
267656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * success. This allows certain settings to be specified for
268656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * multiple ENGINEs and only require a change of ENGINE id
269656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * (without having to selectively apply settings). Eg. changing
270656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * from a hardware device back to the regular software ENGINE
271656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * without editing the config file, etc. */
272656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(cmd_optional)
273656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
274656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ERR_clear_error();
275656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return 1;
276656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
277656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD,
278656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ENGINE_R_INVALID_CMD_NAME);
279656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
280656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
281656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Force the result of the control command to 0 or 1, for the reasons
282656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * mentioned before. */
28398d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom        if (ENGINE_ctrl(e, num, i, p, f) > 0)
284656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                return 1;
285656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        return 0;
286656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        }
287656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
288656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg,
289656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				int cmd_optional)
290656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
291656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int num, flags;
292656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	long l;
293656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	char *ptr;
294656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if((e == NULL) || (cmd_name == NULL))
295656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
296656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
297656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ERR_R_PASSED_NULL_PARAMETER);
298656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
299656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
300656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if((e->ctrl == NULL) || ((num = ENGINE_ctrl(e,
301656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					ENGINE_CTRL_GET_CMD_FROM_NAME,
302656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					0, (void *)cmd_name, NULL)) <= 0))
303656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
304656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* If the command didn't *have* to be supported, we fake
305656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * success. This allows certain settings to be specified for
306656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * multiple ENGINEs and only require a change of ENGINE id
307656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * (without having to selectively apply settings). Eg. changing
308656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * from a hardware device back to the regular software ENGINE
309656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * without editing the config file, etc. */
310656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(cmd_optional)
311656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
312656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ERR_clear_error();
313656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return 1;
314656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
315656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
316656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ENGINE_R_INVALID_CMD_NAME);
317656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
318656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
319656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!ENGINE_cmd_is_executable(e, num))
320656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
321656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
322656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ENGINE_R_CMD_NOT_EXECUTABLE);
323656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
324656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
325656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if((flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, num, NULL, NULL)) < 0)
326656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
327656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Shouldn't happen, given that ENGINE_cmd_is_executable()
328656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * returned success. */
329656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
330656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ENGINE_R_INTERNAL_LIST_ERROR);
331656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
332656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
333656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* If the command takes no input, there must be no input. And vice
334656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * versa. */
335656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(flags & ENGINE_CMD_FLAG_NO_INPUT)
336656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
337656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(arg != NULL)
338656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
339656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
340656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ENGINE_R_COMMAND_TAKES_NO_INPUT);
341656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return 0;
342656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
343656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* We deliberately force the result of ENGINE_ctrl() to 0 or 1
344656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * rather than returning it as "return data". This is to ensure
345656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * usage of these commands is consistent across applications and
346656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * that certain applications don't understand it one way, and
347656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * others another. */
34898d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom		if(ENGINE_ctrl(e, num, 0, (void *)arg, NULL) > 0)
349656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return 1;
350656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
351656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
352656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* So, we require input */
353656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(arg == NULL)
354656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
355656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
356656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ENGINE_R_COMMAND_TAKES_INPUT);
357656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
358656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
359656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* If it takes string input, that's easy */
360656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(flags & ENGINE_CMD_FLAG_STRING)
361656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
362656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Same explanation as above */
36398d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom		if(ENGINE_ctrl(e, num, 0, (void *)arg, NULL) > 0)
364656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return 1;
365656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
366656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
367656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* If it doesn't take numeric either, then it is unsupported for use in
368656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * a config-setting situation, which is what this function is for. This
369656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * should never happen though, because ENGINE_cmd_is_executable() was
370656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * used. */
371656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!(flags & ENGINE_CMD_FLAG_NUMERIC))
372656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
373656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
374656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ENGINE_R_INTERNAL_LIST_ERROR);
375656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
376656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
377656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	l = strtol(arg, &ptr, 10);
378656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if((arg == ptr) || (*ptr != '\0'))
379656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
380656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
381656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER);
382656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
383656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
384656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Force the result of the control command to 0 or 1, for the reasons
385656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * mentioned before. */
38698d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom	if(ENGINE_ctrl(e, num, l, NULL, NULL) > 0)
387656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 1;
388656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 0;
389656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
390