mirror of
git://git.gnupg.org/gnupg.git
synced 2024-07-02 02:48:57 +02:00
254 lines
6.2 KiB
C
254 lines
6.2 KiB
C
|
/* assuan-handler.c - dispatch commands
|
|||
|
* Copyright (C) 2001 Free Software Foundation, Inc.
|
|||
|
*
|
|||
|
* This file is part of GnuPG.
|
|||
|
*
|
|||
|
* GnuPG is free software; you can redistribute it and/or modify
|
|||
|
* it under the terms of the GNU General Public License as published by
|
|||
|
* the Free Software Foundation; either version 2 of the License, or
|
|||
|
* (at your option) any later version.
|
|||
|
*
|
|||
|
* GnuPG 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 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
|
|||
|
*/
|
|||
|
|
|||
|
#include <config.h>
|
|||
|
#include <stdlib.h>
|
|||
|
#include <stdio.h>
|
|||
|
#include <string.h>
|
|||
|
|
|||
|
#include "assuan-defs.h"
|
|||
|
|
|||
|
#define digitp(a) ((a) >= '0' && (a) <= '9')
|
|||
|
|
|||
|
|
|||
|
static int
|
|||
|
dummy_handler (ASSUAN_CONTEXT ctx, char *line)
|
|||
|
{
|
|||
|
fprintf (stderr, "DBG-assuan: dummy handler called\n");
|
|||
|
return set_error (ctx, Server_Fault, "no handler registered");
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
static int
|
|||
|
std_handler_nop (ASSUAN_CONTEXT ctx, char *line)
|
|||
|
{
|
|||
|
fprintf (stderr, "DBG-assuan: processing a NOP `%s'\n", line);
|
|||
|
return 0; /* okay */
|
|||
|
}
|
|||
|
|
|||
|
static int
|
|||
|
std_handler_cancel (ASSUAN_CONTEXT ctx, char *line)
|
|||
|
{
|
|||
|
fprintf (stderr, "DBG-assuan: processing a CANCEL `%s'\n", line);
|
|||
|
return set_error (ctx, Not_Implemented, NULL);
|
|||
|
}
|
|||
|
|
|||
|
static int
|
|||
|
std_handler_bye (ASSUAN_CONTEXT ctx, char *line)
|
|||
|
{
|
|||
|
fprintf (stderr, "DBG-assuan: processing a BYE `%s'\n", line);
|
|||
|
return set_error (ctx, Not_Implemented, NULL);
|
|||
|
}
|
|||
|
|
|||
|
static int
|
|||
|
std_handler_auth (ASSUAN_CONTEXT ctx, char *line)
|
|||
|
{
|
|||
|
fprintf (stderr, "DBG-assuan: processing a AUTH `%s'\n", line);
|
|||
|
return set_error (ctx, Not_Implemented, NULL);
|
|||
|
}
|
|||
|
|
|||
|
static int
|
|||
|
std_handler_reset (ASSUAN_CONTEXT ctx, char *line)
|
|||
|
{
|
|||
|
fprintf (stderr, "DBG-assuan: processing a RESET `%s'\n", line);
|
|||
|
return set_error (ctx, Not_Implemented, NULL);
|
|||
|
}
|
|||
|
|
|||
|
static int
|
|||
|
std_handler_end (ASSUAN_CONTEXT ctx, char *line)
|
|||
|
{
|
|||
|
fprintf (stderr, "DBG-assuan: processing a END `%s'\n", line);
|
|||
|
return set_error (ctx, Not_Implemented, NULL);
|
|||
|
}
|
|||
|
|
|||
|
static int
|
|||
|
parse_cmd_input_output (ASSUAN_CONTEXT ctx, char *line, int *rfd)
|
|||
|
{
|
|||
|
char *endp;
|
|||
|
|
|||
|
if (strncmp (line, "FD=", 3))
|
|||
|
return set_error (ctx, Syntax_Error, "FD=<n> expected");
|
|||
|
line += 3;
|
|||
|
if (!digitp (*line))
|
|||
|
return set_error (ctx, Syntax_Error, "number required");
|
|||
|
*rfd = strtoul (line, &endp, 10);
|
|||
|
if (*endp)
|
|||
|
return set_error (ctx, Syntax_Error, "garbage found");
|
|||
|
if (*rfd == ctx->inbound.fd)
|
|||
|
return set_error (ctx, Parameter_Conflict, "fd same as inbound fd");
|
|||
|
if (*rfd == ctx->outbound.fd)
|
|||
|
return set_error (ctx, Parameter_Conflict, "fd same as outbound fd");
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
/* Format is INPUT FD=<n> */
|
|||
|
static int
|
|||
|
std_handler_input (ASSUAN_CONTEXT ctx, char *line)
|
|||
|
{
|
|||
|
int rc, fd;
|
|||
|
|
|||
|
fprintf (stderr, "DBG-assuan: processing a INPUT `%s'\n", line);
|
|||
|
|
|||
|
rc = parse_cmd_input_output (ctx, line, &fd);
|
|||
|
if (rc)
|
|||
|
return rc;
|
|||
|
ctx->input_fd = fd;
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
/* Format is OUTPUT FD=<n> */
|
|||
|
static int
|
|||
|
std_handler_output (ASSUAN_CONTEXT ctx, char *line)
|
|||
|
{
|
|||
|
int rc, fd;
|
|||
|
|
|||
|
rc = parse_cmd_input_output (ctx, line, &fd);
|
|||
|
if (rc)
|
|||
|
return rc;
|
|||
|
ctx->output_fd = fd;
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/* This is a table with the standard commands and handler for them.
|
|||
|
The table is used to initialize a new context and assuciate strings
|
|||
|
and handlers with cmd_ids */
|
|||
|
static struct {
|
|||
|
const char *name;
|
|||
|
int cmd_id;
|
|||
|
int (*handler)(ASSUAN_CONTEXT, char *line);
|
|||
|
int always; /* always initializethis command */
|
|||
|
} std_cmd_table[] = {
|
|||
|
{ "NOP", ASSUAN_CMD_NOP, std_handler_nop, 1 },
|
|||
|
{ "CANCEL", ASSUAN_CMD_CANCEL, std_handler_cancel, 1 },
|
|||
|
{ "BYE", ASSUAN_CMD_BYE, std_handler_bye, 1 },
|
|||
|
{ "AUTH", ASSUAN_CMD_AUTH, std_handler_auth, 1 },
|
|||
|
{ "RESET", ASSUAN_CMD_RESET, std_handler_reset, 1 },
|
|||
|
{ "END", ASSUAN_CMD_END, std_handler_end, 1 },
|
|||
|
|
|||
|
{ "INPUT", ASSUAN_CMD_INPUT, std_handler_input },
|
|||
|
{ "OUTPUT", ASSUAN_CMD_OUTPUT, std_handler_output },
|
|||
|
{ NULL }
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
|
|||
|
static const char *
|
|||
|
std_cmd_name (int cmd_id)
|
|||
|
{
|
|||
|
int i;
|
|||
|
|
|||
|
for (i=0; std_cmd_table[i].name; i++)
|
|||
|
if (std_cmd_table[i].cmd_id == cmd_id)
|
|||
|
return std_cmd_table[i].name;
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/**
|
|||
|
* assuan_register_command:
|
|||
|
* @ctx: the server context
|
|||
|
* @cmd_id: An ID value for the command
|
|||
|
* @cmd_name: A string with the command name
|
|||
|
* @handler: The handler function to be called
|
|||
|
*
|
|||
|
* Register a handler to be used for a given command.
|
|||
|
*
|
|||
|
* The @cmd_name must be %NULL for all @cmd_ids below
|
|||
|
* %ASSUAN_CMD_USER becuase predefined values are used.
|
|||
|
*
|
|||
|
* Return value:
|
|||
|
**/
|
|||
|
int
|
|||
|
assuan_register_command (ASSUAN_CONTEXT ctx,
|
|||
|
int cmd_id, const char *cmd_name,
|
|||
|
int (*handler)(ASSUAN_CONTEXT, char *))
|
|||
|
{
|
|||
|
if (cmd_name && cmd_id < ASSUAN_CMD_USER)
|
|||
|
return ASSUAN_Invalid_Value;
|
|||
|
|
|||
|
if (!cmd_name)
|
|||
|
cmd_name = std_cmd_name (cmd_id);
|
|||
|
|
|||
|
if (!cmd_name)
|
|||
|
return ASSUAN_Invalid_Value;
|
|||
|
|
|||
|
fprintf (stderr, "DBG-assuan: registering %d as `%s'\n", cmd_id, cmd_name);
|
|||
|
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
/* Helper to register the standards commands */
|
|||
|
int
|
|||
|
_assuan_register_std_commands (ASSUAN_CONTEXT ctx)
|
|||
|
{
|
|||
|
int i, rc;
|
|||
|
|
|||
|
for (i=0; std_cmd_table[i].name; i++)
|
|||
|
{
|
|||
|
if (std_cmd_table[i].always)
|
|||
|
{
|
|||
|
rc = assuan_register_command (ctx, std_cmd_table[i].cmd_id, NULL,
|
|||
|
std_cmd_table[i].handler);
|
|||
|
if (rc)
|
|||
|
return rc;
|
|||
|
}
|
|||
|
}
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/* Process the special data lines. The "D " has already been removed
|
|||
|
from the line. As all handlers this function may modify the line. */
|
|||
|
static int
|
|||
|
handle_data_line (ASSUAN_CONTEXT ctx, char *line)
|
|||
|
{
|
|||
|
return set_error (ctx, Not_Implemented, NULL);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/* Parse the line, break out the command, find it in the command
|
|||
|
table, remove leading and white spaces from the arguments, all the
|
|||
|
handler with the argument line and return the error */
|
|||
|
static int
|
|||
|
dispatch_command (ASSUAN_CONTEXT ctx, char *line)
|
|||
|
{
|
|||
|
if (*line == 'D' && line[1] == ' ') /* divert to special handler */
|
|||
|
return handle_data_line (ctx, line+2);
|
|||
|
|
|||
|
|
|||
|
return set_error (ctx, Not_Implemented, NULL);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|