summaryrefslogtreecommitdiff
path: root/usr.bin/cvs/cmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/cvs/cmd.c')
-rw-r--r--usr.bin/cvs/cmd.c186
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);
}