version 1.16, 2004/12/06 21:58:31 |
version 1.17, 2004/12/07 06:33:10 |
|
|
|
|
/* compression level used with zlib, 0 meaning no compression taking place */ |
/* compression level used with zlib, 0 meaning no compression taking place */ |
int cvs_compress = 0; |
int cvs_compress = 0; |
|
int cvs_readrc = 1; /* read .cvsrc on startup */ |
int cvs_trace = 0; |
int cvs_trace = 0; |
int cvs_nolog = 0; |
int cvs_nolog = 0; |
int cvs_readonly = 0; |
int cvs_readonly = 0; |
int cvs_nocase = 0; /* set to 1 to disable case sensitivity on filenames */ |
int cvs_nocase = 0; /* set to 1 to disable filename case sensitivity */ |
|
|
/* name of the command we are running */ |
char *cvs_defargs; /* default global arguments from .cvsrc */ |
char *cvs_command; |
char *cvs_command; /* name of the command we are running */ |
int cvs_cmdop; |
int cvs_cmdop; |
char *cvs_rootstr; |
char *cvs_rootstr; |
char *cvs_rsh = CVS_RSH_DEFAULT; |
char *cvs_rsh = CVS_RSH_DEFAULT; |
|
|
char *cmd_synopsis; |
char *cmd_synopsis; |
char *cmd_opts; |
char *cmd_opts; |
char cmd_descr[CVS_CMD_MAXDESCRLEN]; |
char cmd_descr[CVS_CMD_MAXDESCRLEN]; |
|
char *cmd_defargs; |
} cvs_cdt[] = { |
} cvs_cdt[] = { |
{ |
{ |
CVS_OP_ADD, "add", { "ad", "new" }, cvs_add, |
CVS_OP_ADD, "add", { "ad", "new" }, cvs_add, |
"[-m msg] file ...", |
"[-m msg] file ...", |
"", |
"", |
"Add a new file/directory to the repository", |
"Add a new file/directory to the repository", |
|
NULL, |
}, |
}, |
{ |
{ |
-1, "admin", { "adm", "rcs" }, NULL, |
-1, "admin", { "adm", "rcs" }, NULL, |
"", |
"", |
"", |
"", |
"Administration front end for rcs", |
"Administration front end for rcs", |
|
NULL, |
}, |
}, |
{ |
{ |
CVS_OP_ANNOTATE, "annotate", { "ann" }, NULL, |
CVS_OP_ANNOTATE, "annotate", { "ann" }, NULL, |
"", |
"", |
"", |
"", |
"Show last revision where each line was modified", |
"Show last revision where each line was modified", |
|
NULL, |
}, |
}, |
{ |
{ |
CVS_OP_CHECKOUT, "checkout", { "co", "get" }, cvs_checkout, |
CVS_OP_CHECKOUT, "checkout", { "co", "get" }, cvs_checkout, |
"", |
"", |
"", |
"", |
"Checkout sources for editing", |
"Checkout sources for editing", |
|
NULL, |
}, |
}, |
{ |
{ |
CVS_OP_COMMIT, "commit", { "ci", "com" }, cvs_commit, |
CVS_OP_COMMIT, "commit", { "ci", "com" }, cvs_commit, |
"[-flR] [-F logfile | -m msg] [-r rev] ...", |
"[-flR] [-F logfile | -m msg] [-r rev] ...", |
"F:flm:Rr:", |
"F:flm:Rr:", |
"Check files into the repository", |
"Check files into the repository", |
|
NULL, |
}, |
}, |
{ |
{ |
CVS_OP_DIFF, "diff", { "di", "dif" }, cvs_diff, |
CVS_OP_DIFF, "diff", { "di", "dif" }, cvs_diff, |
"[-cilu] [-D date] [-r rev] ...", |
"[-cilu] [-D date] [-r rev] ...", |
"cD:ilur:", |
"cD:ilur:", |
"Show differences between revisions", |
"Show differences between revisions", |
|
NULL, |
}, |
}, |
{ |
{ |
-1, "edit", { }, NULL, |
-1, "edit", { }, NULL, |
"", |
"", |
"", |
"", |
"Get ready to edit a watched file", |
"Get ready to edit a watched file", |
|
NULL, |
}, |
}, |
{ |
{ |
-1, "editors", { }, NULL, |
-1, "editors", { }, NULL, |
"", |
"", |
"", |
"", |
"See who is editing a watched file", |
"See who is editing a watched file", |
|
NULL, |
}, |
}, |
{ |
{ |
-1, "export", { "ex", "exp" }, NULL, |
-1, "export", { "ex", "exp" }, NULL, |
"", |
"", |
"", |
"", |
"Export sources from CVS, similar to checkout", |
"Export sources from CVS, similar to checkout", |
|
NULL, |
}, |
}, |
{ |
{ |
CVS_OP_HISTORY, "history", { "hi", "his" }, cvs_history, |
CVS_OP_HISTORY, "history", { "hi", "his" }, cvs_history, |
"", |
"", |
"", |
"", |
"Show repository access history", |
"Show repository access history", |
|
NULL, |
}, |
}, |
{ |
{ |
CVS_OP_IMPORT, "import", { "im", "imp" }, NULL, |
CVS_OP_IMPORT, "import", { "im", "imp" }, NULL, |
|
|
"repository vendor-tag release-tags ...", |
"repository vendor-tag release-tags ...", |
"b:dI:k:m:", |
"b:dI:k:m:", |
"Import sources into CVS, using vendor branches", |
"Import sources into CVS, using vendor branches", |
|
NULL, |
}, |
}, |
{ |
{ |
CVS_OP_INIT, "init", { }, cvs_init, |
CVS_OP_INIT, "init", { }, cvs_init, |
"", |
"", |
"", |
"", |
"Create a CVS repository if it doesn't exist", |
"Create a CVS repository if it doesn't exist", |
|
NULL, |
}, |
}, |
#if defined(HAVE_KERBEROS) |
#if defined(HAVE_KERBEROS) |
{ |
{ |
|
|
"", |
"", |
"", |
"", |
"Start a Kerberos authentication CVS server", |
"Start a Kerberos authentication CVS server", |
|
NULL, |
}, |
}, |
#endif |
#endif |
{ |
{ |
|
|
"", |
"", |
"", |
"", |
"Print out history information for files", |
"Print out history information for files", |
|
NULL, |
}, |
}, |
{ |
{ |
-1, "login", {}, NULL, |
-1, "login", {}, NULL, |
"", |
"", |
"", |
"", |
"Prompt for password for authenticating server", |
"Prompt for password for authenticating server", |
|
NULL, |
}, |
}, |
{ |
{ |
-1, "logout", {}, NULL, |
-1, "logout", {}, NULL, |
"", |
"", |
"", |
"", |
"Removes entry in .cvspass for remote repository", |
"Removes entry in .cvspass for remote repository", |
|
NULL, |
}, |
}, |
{ |
{ |
-1, "rdiff", {}, NULL, |
-1, "rdiff", {}, NULL, |
"", |
"", |
"", |
"", |
"Create 'patch' format diffs between releases", |
"Create 'patch' format diffs between releases", |
|
NULL, |
}, |
}, |
{ |
{ |
-1, "release", {}, NULL, |
-1, "release", {}, NULL, |
"", |
"", |
"", |
"", |
"Indicate that a Module is no longer in use", |
"Indicate that a Module is no longer in use", |
|
NULL, |
}, |
}, |
{ |
{ |
CVS_OP_REMOVE, "remove", {}, NULL, |
CVS_OP_REMOVE, "remove", {}, NULL, |
"", |
"", |
"", |
"", |
"Remove an entry from the repository", |
"Remove an entry from the repository", |
|
NULL, |
}, |
}, |
{ |
{ |
-1, "rlog", {}, NULL, |
-1, "rlog", {}, NULL, |
"", |
"", |
"", |
"", |
"Print out history information for a module", |
"Print out history information for a module", |
|
NULL, |
}, |
}, |
{ |
{ |
-1, "rtag", {}, NULL, |
-1, "rtag", {}, NULL, |
"", |
"", |
"", |
"", |
"Add a symbolic tag to a module", |
"Add a symbolic tag to a module", |
|
NULL, |
}, |
}, |
{ |
{ |
CVS_OP_SERVER, "server", {}, cvs_server, |
CVS_OP_SERVER, "server", {}, cvs_server, |
"", |
"", |
"", |
"", |
"Server mode", |
"Server mode", |
|
NULL, |
}, |
}, |
{ |
{ |
CVS_OP_STATUS, "status", { "st", "stat" }, cvs_status, |
CVS_OP_STATUS, "status", { "st", "stat" }, cvs_status, |
"", |
"", |
"", |
"", |
"Display status information on checked out files", |
"Display status information on checked out files", |
|
NULL, |
}, |
}, |
{ |
{ |
CVS_OP_TAG, "tag", { "ta", "freeze" }, NULL, |
CVS_OP_TAG, "tag", { "ta", "freeze" }, NULL, |
"", |
"", |
"", |
"", |
"Add a symbolic tag to checked out version of files", |
"Add a symbolic tag to checked out version of files", |
|
NULL, |
}, |
}, |
{ |
{ |
-1, "unedit", {}, NULL, |
-1, "unedit", {}, NULL, |
"", |
"", |
"", |
"", |
"Undo an edit command", |
"Undo an edit command", |
|
NULL, |
}, |
}, |
{ |
{ |
CVS_OP_UPDATE, "update", { "up", "upd" }, cvs_update, |
CVS_OP_UPDATE, "update", { "up", "upd" }, cvs_update, |
"", |
"", |
"", |
"", |
"Bring work tree in sync with repository", |
"Bring work tree in sync with repository", |
|
NULL, |
}, |
}, |
{ |
{ |
CVS_OP_VERSION, "version", { "ve", "ver" }, cvs_version, |
CVS_OP_VERSION, "version", { "ve", "ver" }, cvs_version, |
"", "", |
"", "", |
"Show current CVS version(s)", |
"Show current CVS version(s)", |
|
NULL, |
}, |
}, |
{ |
{ |
-1, "watch", {}, NULL, |
-1, "watch", {}, NULL, |
"", |
"", |
"", |
"", |
"Set watches", |
"Set watches", |
|
NULL, |
}, |
}, |
{ |
{ |
-1, "watchers", {}, NULL, |
-1, "watchers", {}, NULL, |
"", |
"", |
"", |
"", |
"See who is watching a file", |
"See who is watching a file", |
|
NULL, |
}, |
}, |
}; |
}; |
|
|
|
|
|
|
void usage (void); |
void usage (void); |
void sigchld_hdlr (int); |
void sigchld_hdlr (int); |
void cvs_readrc (void); |
void cvs_read_rcfile (void); |
struct cvs_cmd* cvs_findcmd (const char *); |
struct cvs_cmd* cvs_findcmd (const char *); |
|
int cvs_getopt (int, char **); |
|
|
|
|
/* |
/* |
|
|
int |
int |
main(int argc, char **argv) |
main(int argc, char **argv) |
{ |
{ |
char *envstr, *ep; |
char *envstr, *cmd_argv[CVS_CMD_MAXARG], **targv; |
int ret; |
int i, ret, cmd_argc; |
u_int i, readrc; |
|
struct cvs_cmd *cmdp; |
struct cvs_cmd *cmdp; |
|
|
readrc = 1; |
|
|
|
if (cvs_log_init(LD_STD, 0) < 0) |
if (cvs_log_init(LD_STD, 0) < 0) |
err(1, "failed to initialize logging"); |
err(1, "failed to initialize logging"); |
|
|
|
|
((envstr = getenv("EDITOR")) != NULL)) |
((envstr = getenv("EDITOR")) != NULL)) |
cvs_editor = envstr; |
cvs_editor = envstr; |
|
|
|
ret = cvs_getopt(argc, argv); |
|
|
|
argc -= ret; |
|
argv += ret; |
|
if (argc == 0) { |
|
usage(); |
|
exit(EX_USAGE); |
|
} |
|
cvs_command = argv[0]; |
|
|
|
if (cvs_readrc) { |
|
cvs_read_rcfile(); |
|
|
|
if (cvs_defargs != NULL) { |
|
targv = cvs_makeargv(cvs_defargs, &i); |
|
if (targv == NULL) { |
|
cvs_log(LP_ERR, |
|
"failed to load default arguments to %s", |
|
__progname); |
|
exit(EX_OSERR); |
|
} |
|
|
|
cvs_getopt(i, targv); |
|
cvs_freeargv(targv, i); |
|
free(targv); |
|
} |
|
} |
|
|
|
/* setup signal handlers */ |
|
signal(SIGPIPE, SIG_IGN); |
|
|
|
cvs_file_init(); |
|
|
|
ret = -1; |
|
|
|
cmdp = cvs_findcmd(cvs_command); |
|
if (cmdp == NULL) { |
|
fprintf(stderr, "Unknown command: `%s'\n\n", cvs_command); |
|
fprintf(stderr, "CVS commands are:\n"); |
|
for (i = 0; i < (int)CVS_NBCMD; i++) |
|
fprintf(stderr, "\t%-16s%s\n", |
|
cvs_cdt[i].cmd_name, cvs_cdt[i].cmd_descr); |
|
exit(EX_USAGE); |
|
} |
|
|
|
if (cmdp->cmd_hdlr == NULL) { |
|
cvs_log(LP_ERR, "command `%s' not implemented", cvs_command); |
|
exit(1); |
|
} |
|
|
|
cvs_cmdop = cmdp->cmd_op; |
|
|
|
cmd_argc = 0; |
|
memset(cmd_argv, 0, sizeof(cmd_argv)); |
|
|
|
cmd_argv[cmd_argc++] = argv[0]; |
|
if (cmdp->cmd_defargs != NULL) { |
|
/* transform into a new argument vector */ |
|
ret = cvs_getargv(cmdp->cmd_defargs, cmd_argv + 1, |
|
CVS_CMD_MAXARG - 1); |
|
if (ret < 0) { |
|
cvs_log(LP_ERRNO, "failed to generate argument vector " |
|
"from default arguments"); |
|
exit(EX_DATAERR); |
|
} |
|
cmd_argc += ret; |
|
} |
|
for (ret = 1; ret < argc; ret++) |
|
cmd_argv[cmd_argc++] = argv[ret]; |
|
|
|
ret = (*cmdp->cmd_hdlr)(cmd_argc, cmd_argv); |
|
if (ret == EX_USAGE) { |
|
fprintf(stderr, "Usage: %s %s %s\n", __progname, cvs_command, |
|
cmdp->cmd_synopsis); |
|
} |
|
|
|
if (cvs_files != NULL) |
|
cvs_file_free(cvs_files); |
|
|
|
return (ret); |
|
} |
|
|
|
|
|
int |
|
cvs_getopt(int argc, char **argv) |
|
{ |
|
int ret; |
|
char *ep; |
|
|
while ((ret = getopt(argc, argv, "b:d:e:fHlnQqrtvz:")) != -1) { |
while ((ret = getopt(argc, argv, "b:d:e:fHlnQqrtvz:")) != -1) { |
switch (ret) { |
switch (ret) { |
case 'b': |
case 'b': |
|
|
cvs_editor = optarg; |
cvs_editor = optarg; |
break; |
break; |
case 'f': |
case 'f': |
readrc = 0; |
cvs_readrc = 0; |
break; |
break; |
case 'l': |
case 'l': |
cvs_nolog = 1; |
cvs_nolog = 1; |
|
|
} |
} |
} |
} |
|
|
argc -= optind; |
ret = optind; |
argv += optind; |
|
|
|
/* reset getopt() for use by commands */ |
|
optind = 1; |
optind = 1; |
optreset = 1; |
optreset = 1; /* for next call */ |
|
|
if (argc == 0) { |
|
usage(); |
|
exit(EX_USAGE); |
|
} |
|
|
|
/* setup signal handlers */ |
|
signal(SIGPIPE, SIG_IGN); |
|
|
|
cvs_file_init(); |
|
|
|
if (readrc) |
|
cvs_readrc(); |
|
|
|
cvs_command = argv[0]; |
|
ret = -1; |
|
|
|
cmdp = cvs_findcmd(cvs_command); |
|
if (cmdp == NULL) { |
|
fprintf(stderr, "Unknown command: `%s'\n\n", cvs_command); |
|
fprintf(stderr, "CVS commands are:\n"); |
|
for (i = 0; i < CVS_NBCMD; i++) |
|
fprintf(stderr, "\t%-16s%s\n", |
|
cvs_cdt[i].cmd_name, cvs_cdt[i].cmd_descr); |
|
exit(EX_USAGE); |
|
} |
|
|
|
if (cmdp->cmd_hdlr == NULL) { |
|
cvs_log(LP_ERR, "command `%s' not implemented", cvs_command); |
|
exit(1); |
|
} |
|
|
|
cvs_cmdop = cmdp->cmd_op; |
|
|
|
ret = (*cmdp->cmd_hdlr)(argc, argv); |
|
if (ret == EX_USAGE) { |
|
fprintf(stderr, "Usage: %s %s %s\n", __progname, cvs_command, |
|
cmdp->cmd_synopsis); |
|
} |
|
|
|
if (cvs_files != NULL) |
|
cvs_file_free(cvs_files); |
|
|
|
return (ret); |
return (ret); |
} |
} |
|
|
|
|
|
|
|
|
/* |
/* |
* cvs_readrc() |
* cvs_read_rcfile() |
* |
* |
* Read the CVS `.cvsrc' file in the user's home directory. If the file |
* Read the CVS `.cvsrc' file in the user's home directory. If the file |
* exists, it should contain a list of arguments that should always be given |
* exists, it should contain a list of arguments that should always be given |
|
|
*/ |
*/ |
|
|
void |
void |
cvs_readrc(void) |
cvs_read_rcfile(void) |
{ |
{ |
char rcpath[MAXPATHLEN], linebuf[128], *lp; |
char rcpath[MAXPATHLEN], linebuf[128], *lp; |
|
size_t len; |
struct cvs_cmd *cmdp; |
struct cvs_cmd *cmdp; |
struct passwd *pw; |
struct passwd *pw; |
FILE *fp; |
FILE *fp; |
|
|
} |
} |
|
|
while (fgets(linebuf, sizeof(linebuf), fp) != NULL) { |
while (fgets(linebuf, sizeof(linebuf), fp) != NULL) { |
lp = strchr(linebuf, ' '); |
if ((len = strlen(linebuf)) == 0) |
|
|
/* ignore lines with no arguments */ |
|
if (lp == NULL) |
|
continue; |
continue; |
|
if (linebuf[len - 1] != '\n') { |
|
cvs_log(LP_WARN, ".cvsrc line too long"); |
|
break; |
|
} |
|
linebuf[--len] = '\0'; |
|
|
*(lp++) = '\0'; |
lp = strchr(linebuf, ' '); |
|
if (lp == NULL) |
|
continue; /* ignore lines with no arguments */ |
|
*lp = '\0'; |
if (strcmp(linebuf, "cvs") == 0) { |
if (strcmp(linebuf, "cvs") == 0) { |
/* global options */ |
/* |
|
* Global default options. In the case of cvs only, |
|
* we keep the 'cvs' string as first argument because |
|
* getopt() does not like starting at index 0 for |
|
* argument processing. |
|
*/ |
|
*lp = ' '; |
|
cvs_defargs = strdup(linebuf); |
|
if (cvs_defargs == NULL) |
|
cvs_log(LP_ERRNO, |
|
"failed to copy global arguments"); |
} else { |
} else { |
|
lp++; |
cmdp = cvs_findcmd(linebuf); |
cmdp = cvs_findcmd(linebuf); |
if (cmdp == NULL) { |
if (cmdp == NULL) { |
cvs_log(LP_NOTICE, |
cvs_log(LP_NOTICE, |
|
|
linebuf); |
linebuf); |
continue; |
continue; |
} |
} |
|
|
|
cmdp->cmd_defargs = strdup(lp); |
|
if (cmdp->cmd_defargs == NULL) |
|
cvs_log(LP_ERRNO, |
|
"failed to copy default arguments for %s", |
|
cmdp->cmd_name); |
} |
} |
} |
} |
if (ferror(fp)) { |
if (ferror(fp)) { |