diff options
Diffstat (limited to 'usr.bin/cvs/cmd.c')
-rw-r--r-- | usr.bin/cvs/cmd.c | 186 |
1 files changed, 143 insertions, 43 deletions
diff --git a/usr.bin/cvs/cmd.c b/usr.bin/cvs/cmd.c index 24d406957fd..88a1a672d81 100644 --- a/usr.bin/cvs/cmd.c +++ b/usr.bin/cvs/cmd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd.c,v 1.18 2005/05/23 17:43:54 xsa Exp $ */ +/* $OpenBSD: cmd.c,v 1.19 2005/05/24 04:12:25 jfb Exp $ */ /* * Copyright (c) 2005 Joris Vink <joris@openbsd.org> * All rights reserved. @@ -39,6 +39,113 @@ #include "rcs.h" #include "proto.h" + +/* + * Command dispatch table + * ---------------------- + * + * The synopsis field should only contain the list of arguments that the + * command supports, without the actual command's name. + * + * Command handlers are expected to return 0 if no error occurred, or one of + * the CVS_EX_* error codes in case of an error. In case the error + * returned is 1, the command's usage string is printed to standard + * error before returning. + */ +struct cvs_cmd *cvs_cdt[] = { + &cvs_cmd_add, + &cvs_cmd_admin, + &cvs_cmd_annotate, + &cvs_cmd_checkout, + &cvs_cmd_commit, + &cvs_cmd_diff, +#if 0 + &cvs_cmd_edit, + &cvs_cmd_editors, + &cvs_cmd_export, +#endif + &cvs_cmd_history, + &cvs_cmd_import, + &cvs_cmd_init, +#if defined(HAVE_KERBEROS) + &cvs_cmd_kserver, +#endif + &cvs_cmd_log, +#if 0 + &cvs_cmd_login, + &cvs_cmd_logout, +#endif + &cvs_cmd_rdiff, + &cvs_cmd_release, + &cvs_cmd_remove, + &cvs_cmd_rlog, + &cvs_cmd_rtag, + &cvs_cmd_server, + &cvs_cmd_status, + &cvs_cmd_tag, +#if 0 + &cvs_cmd_unedit, +#endif + &cvs_cmd_update, + &cvs_cmd_version, +#if 0 + &cvs_cmd_watch, + &cvs_cmd_watchers, +#endif + NULL +}; + + + +/* + * cvs_findcmd() + * + * Find the entry in the command dispatch table whose name or one of its + * aliases matches <cmd>. + * Returns a pointer to the command entry on success, NULL on failure. + */ +struct cvs_cmd* +cvs_findcmd(const char *cmd) +{ + int i, j; + struct cvs_cmd *cmdp; + + cmdp = NULL; + + for (i = 0; (cvs_cdt[i] != NULL) && (cmdp == NULL); i++) { + if (strcmp(cmd, cvs_cdt[i]->cmd_name) == 0) + cmdp = cvs_cdt[i]; + else { + for (j = 0; j < CVS_CMD_MAXALIAS; j++) { + if (strcmp(cmd, + cvs_cdt[i]->cmd_alias[j]) == 0) { + cmdp = cvs_cdt[i]; + break; + } + } + } + } + + return (cmdp); +} + +struct cvs_cmd* +cvs_findcmdbyreq(int reqid) +{ + int i; + struct cvs_cmd *cmdp; + + cmdp = NULL; + for (i = 0; cvs_cdt[i] != NULL; i++) + if (cvs_cdt[i]->cmd_req == reqid) { + cmdp = cvs_cdt[i]; + break; + } + + return (cmdp); +} + + /* * start the execution of a command. */ @@ -48,89 +155,82 @@ cvs_startcmd(struct cvs_cmd *cmd, int argc, char **argv) int i; int ret; struct cvsroot *root; - struct cvs_cmd_info *c = cmd->cmd_info; + int (*ex_hdlr)(CVSFILE *, void *); /* if the command requested is the server one, just call the * cvs_server() function to handle it, and return after it. */ - if (cmd->cmd_op == CVS_OP_SERVER) { - ret = cvs_server(argc, argv); - return (ret); - } + if (cmd->cmd_op == CVS_OP_SERVER) + return cvs_server(argc, argv); - if (c->cmd_options != NULL) { - if ((ret = c->cmd_options(cmd->cmd_opts, argc, argv, &i)) != 0) + if (cmd->cmd_init != NULL) { + printf("[init]\n"); + if ((ret = (*cmd->cmd_init)(cmd, argc, argv, &i)) != 0) return (ret); argc -= i; argv += i; } - if ((c->cmd_helper != NULL) && ((ret = c->cmd_helper()) != 0)) - return (ret); + if (!(cmd->cmd_flags & CVS_CMD_ALLOWSPEC) && (argc > 0)) + return (CVS_EX_USAGE); if ((root = cvsroot_get(".")) == NULL) return (CVS_EX_BADROOT); + if ((root->cr_method != CVS_METHOD_LOCAL) && (cvs_connect(root) < 0)) + return (CVS_EX_PROTO); if (cvs_trace) cvs_log(LP_TRACE, "cvs_startcmd() CVSROOT=%s", root->cr_str); - if (root->cr_method != CVS_METHOD_LOCAL) { - if (cvs_connect(root) < 0) - return (CVS_EX_PROTO); - - if (c->cmd_flags & CVS_CMD_SENDARGS1) { - for (i = 0; i < argc; i++) { - if (cvs_sendarg(root, argv[i], 0) < 0) - return (CVS_EX_PROTO); - } - } - - if (c->cmd_sendflags != NULL) { - if ((ret = c->cmd_sendflags(root)) != 0) - return (ret); - } - - if (c->cmd_flags & CVS_CMD_NEEDLOG) { - if (cvs_logmsg_send(root, cvs_msg) < 0) - return (CVS_EX_PROTO); - } + if (cmd->cmd_pre_exec != NULL) { + printf("[pre-exec]\n"); + if ((ret = cmd->cmd_pre_exec(root)) != 0) + return (ret); } - /* if we are the version command, don't bother going - * any further now, we did everything we had to. - */ - if (cmd->cmd_op == CVS_OP_VERSION) - return (0); + if (root->cr_method == CVS_METHOD_LOCAL) + ex_hdlr = cmd->cmd_exec_local; + else + ex_hdlr = cmd->cmd_exec_remote; - if ((c->cmd_flags & CVS_CMD_ALLOWSPEC) && argc != 0) { - cvs_files = cvs_file_getspec(argv, argc, c->file_flags, - c->cmd_examine, NULL); + if (argc > 0) { + cvs_files = cvs_file_getspec(argv, argc, cmd->file_flags, + ex_hdlr, NULL); } else { - cvs_files = cvs_file_get(".", c->file_flags, - c->cmd_examine, NULL); + cvs_files = cvs_file_get(".", cmd->file_flags, + ex_hdlr, NULL); } if (cvs_files == NULL) return (CVS_EX_DATA); + if (cmd->cmd_post_exec != NULL) { + printf("[post-exec]\n"); + if ((ret = cmd->cmd_post_exec(root)) != 0) + return (ret); + } + if (root->cr_method != CVS_METHOD_LOCAL) { - if (c->cmd_flags & CVS_CMD_SENDDIR) { + if (cmd->cmd_flags & CVS_CMD_SENDDIR) { if (cvs_senddir(root, cvs_files) < 0) return (CVS_EX_PROTO); } - if (c->cmd_flags & CVS_CMD_SENDARGS2) { + if (cmd->cmd_flags & CVS_CMD_SENDARGS2) { for (i = 0; i < argc; i++) { if (cvs_sendarg(root, argv[i], 0) < 0) return (CVS_EX_PROTO); } } - if (cvs_sendreq(root, c->cmd_req, + if (cmd->cmd_req != CVS_REQ_NONE && cvs_sendreq(root, cmd->cmd_req, (cmd->cmd_op == CVS_OP_INIT) ? root->cr_dir : NULL) < 0) return (CVS_EX_PROTO); } + if (cmd->cmd_cleanup != NULL) + (*cmd->cmd_cleanup)(); + return (0); } |