version 1.43, 2006/04/14 02:45:35 |
version 1.44, 2006/05/27 03:30:30 |
|
|
|
|
#include "cvs.h" |
#include "cvs.h" |
#include "log.h" |
#include "log.h" |
#include "proto.h" |
|
|
|
extern char *cvs_rootstr; |
extern char *cvs_rootstr; |
|
|
/* |
|
* 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[] = { |
struct cvs_cmd *cvs_cdt[] = { |
|
&cvs_cmd_commit, |
|
&cvs_cmd_checkout, |
|
&cvs_cmd_diff, |
|
&cvs_cmd_update, |
|
&cvs_cmd_status, |
|
#if 0 |
&cvs_cmd_add, |
&cvs_cmd_add, |
&cvs_cmd_admin, |
&cvs_cmd_admin, |
&cvs_cmd_annotate, |
&cvs_cmd_annotate, |
&cvs_cmd_checkout, |
&cvs_cmd_checkout, |
&cvs_cmd_commit, |
|
&cvs_cmd_diff, |
|
&cvs_cmd_edit, |
&cvs_cmd_edit, |
&cvs_cmd_editors, |
&cvs_cmd_editors, |
&cvs_cmd_export, |
&cvs_cmd_export, |
&cvs_cmd_history, |
&cvs_cmd_history, |
&cvs_cmd_import, |
&cvs_cmd_import, |
&cvs_cmd_init, |
&cvs_cmd_init, |
#if defined(HAVE_KERBEROS) |
|
&cvs_cmd_kserver, |
|
#endif |
|
&cvs_cmd_log, |
|
#if 0 |
#if 0 |
&cvs_cmd_login, |
&cvs_cmd_login, |
&cvs_cmd_logout, |
&cvs_cmd_logout, |
|
|
&cvs_cmd_rlog, |
&cvs_cmd_rlog, |
&cvs_cmd_rtag, |
&cvs_cmd_rtag, |
&cvs_cmd_server, |
&cvs_cmd_server, |
&cvs_cmd_status, |
|
&cvs_cmd_tag, |
&cvs_cmd_tag, |
&cvs_cmd_unedit, |
&cvs_cmd_unedit, |
&cvs_cmd_update, |
&cvs_cmd_update, |
&cvs_cmd_version, |
&cvs_cmd_version, |
&cvs_cmd_watch, |
&cvs_cmd_watch, |
&cvs_cmd_watchers, |
&cvs_cmd_watchers, |
|
#endif |
NULL |
NULL |
}; |
}; |
|
|
#define MISSING_CVS_DIR 0x01 |
|
#define MISSING_CVS_ENTRIES 0x02 |
|
#define MISSING_CVS_REPO 0x04 |
|
|
|
/* |
|
* 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 * |
struct cvs_cmd * |
cvs_findcmd(const char *cmd) |
cvs_findcmd(const char *cmd) |
{ |
{ |
|
|
} |
} |
|
|
return (cmdp); |
return (cmdp); |
} |
|
|
|
|
|
/* |
|
* start the execution of a command. |
|
*/ |
|
int |
|
cvs_startcmd(struct cvs_cmd *cmd, int argc, char **argv) |
|
{ |
|
int i, ret, error; |
|
struct cvsroot *root; |
|
int (*ex_hdlr)(CVSFILE *, void *); |
|
CVSFILE *cf; |
|
struct stat st; |
|
|
|
/* 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) |
|
return cvs_server(argc, argv); |
|
|
|
if ((root = cvsroot_get(".")) == NULL) |
|
return (CVS_EX_BADROOT); |
|
|
|
i = 1; |
|
if (cmd->cmd_init != NULL) { |
|
if ((ret = (*cmd->cmd_init)(cmd, argc, argv, &i)) != 0) |
|
return (ret); |
|
} |
|
|
|
argc -= i; |
|
argv += i; |
|
|
|
/* |
|
* Check if we have the administrative files present, if we are |
|
* missing one, we will error out because we cannot continue. |
|
* |
|
* We are not checking for CVS/Root since we fetched the root |
|
* above via cvsroot_get(). |
|
* |
|
* checkout, export, import, init and release do not depend on |
|
* these files. |
|
*/ |
|
error = 0; |
|
if (cmd->cmd_op != CVS_OP_CHECKOUT && |
|
cmd->cmd_op != CVS_OP_EXPORT && |
|
cmd->cmd_op != CVS_OP_IMPORT && |
|
cmd->cmd_op != CVS_OP_INIT && |
|
cmd->cmd_op != CVS_OP_RELEASE && |
|
cmd->cmd_op != CVS_OP_VERSION) { |
|
/* check for the CVS directory */ |
|
ret = stat(CVS_PATH_CVSDIR, &st); |
|
if ((ret == -1 && errno == ENOENT) || |
|
(ret != -1 && !(S_ISDIR(st.st_mode)))) |
|
error |= MISSING_CVS_DIR; |
|
|
|
/* check if the CVS/Entries file exists */ |
|
ret = stat(CVS_PATH_ENTRIES, &st); |
|
if ((ret == -1 && errno == ENOENT) || |
|
(ret != -1 && !(S_ISREG(st.st_mode)))) |
|
error |= MISSING_CVS_ENTRIES; |
|
|
|
/* check if the CVS/Repository file exists */ |
|
ret = stat(CVS_PATH_REPOSITORY, &st); |
|
if ((ret == -1 && errno == ENOENT) || |
|
(ret != -1 && !(S_ISREG(st.st_mode)))) |
|
error |= MISSING_CVS_REPO; |
|
} |
|
|
|
if (error > 0) { |
|
if (error & MISSING_CVS_DIR) { |
|
cvs_log(LP_ABORT, "missing '%s' directory", |
|
CVS_PATH_CVSDIR); |
|
return (CVS_EX_FILE); |
|
} |
|
|
|
if (error & MISSING_CVS_ENTRIES) |
|
cvs_log(LP_ABORT, "missing '%s' file", |
|
CVS_PATH_ENTRIES); |
|
if (error & MISSING_CVS_REPO) |
|
cvs_log(LP_ABORT, "missing '%s' file", |
|
CVS_PATH_REPOSITORY); |
|
return (CVS_EX_FILE); |
|
} |
|
|
|
if (!(cmd->cmd_flags & CVS_CMD_ALLOWSPEC) && (argc > 0)) |
|
return (CVS_EX_USAGE); |
|
|
|
/* |
|
* This allows us to correctly fill in the repository |
|
* string for CVSFILE's fetched inside the repository itself. |
|
*/ |
|
if (cvs_cmdop == CVS_OP_SERVER) |
|
cvs_rootstr = xstrdup(root->cr_str); |
|
|
|
cvs_log(LP_TRACE, "cvs_startcmd() CVSROOT=%s", root->cr_str); |
|
|
|
if (root->cr_method != CVS_METHOD_LOCAL) |
|
cvs_connect(root); |
|
|
|
if (cmd->cmd_pre_exec != NULL) { |
|
if ((ret = cmd->cmd_pre_exec(root)) != 0) |
|
return (ret); |
|
} |
|
|
|
if (root->cr_method == CVS_METHOD_LOCAL) |
|
ex_hdlr = cmd->cmd_exec_local; |
|
else |
|
ex_hdlr = cmd->cmd_exec_remote; |
|
|
|
if (argc > 0) { |
|
ret = cvs_file_getspec(argv, argc, cmd->file_flags, |
|
ex_hdlr, NULL, NULL); |
|
} else { |
|
ret = cvs_file_get(".", cmd->file_flags, |
|
ex_hdlr, NULL, NULL); |
|
} |
|
|
|
if (ret != CVS_EX_OK) |
|
return (cvs_error); |
|
|
|
if (cmd->cmd_post_exec != NULL) { |
|
if ((ret = cmd->cmd_post_exec(root)) != 0) |
|
return (ret); |
|
} |
|
|
|
if (root->cr_method != CVS_METHOD_LOCAL) { |
|
/* |
|
* If we have to send the directory the command |
|
* has been issued in, obtain it. |
|
*/ |
|
if (cmd->cmd_flags & CVS_CMD_SENDDIR) { |
|
cf = cvs_file_loadinfo(".", CF_NOFILES, NULL, NULL, 1); |
|
if (cf == NULL) |
|
return (CVS_EX_DATA); |
|
cvs_senddir(root, cf); |
|
cvs_file_free(cf); |
|
} |
|
|
|
if (cmd->cmd_flags & CVS_CMD_SENDARGS2) { |
|
for (i = 0; i < argc; i++) |
|
cvs_sendarg(root, argv[i], 0); |
|
} |
|
|
|
if (cmd->cmd_req != CVS_REQ_NONE) { |
|
cvs_sendreq(root, cmd->cmd_req, |
|
(cmd->cmd_op == CVS_OP_INIT) ? root->cr_dir : NULL); |
|
} |
|
} |
|
|
|
if (cmd->cmd_cleanup != NULL) |
|
(*cmd->cmd_cleanup)(); |
|
|
|
#if 0 |
|
if (cvs_cmdop != CVS_OP_SERVER && cmd->cmd_flags & CVS_CMD_PRUNEDIRS) |
|
cvs_file_prune(fpath); |
|
#endif |
|
|
|
if (root->cr_method != CVS_METHOD_LOCAL) |
|
cvs_disconnect(root); |
|
|
|
return (0); |
|
} |
} |