=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/cvs/cvs.c,v retrieving revision 1.97 retrieving revision 1.98 diff -u -r1.97 -r1.98 --- src/usr.bin/cvs/cvs.c 2006/04/14 02:45:35 1.97 +++ src/usr.bin/cvs/cvs.c 2006/05/27 03:30:30 1.98 @@ -1,5 +1,6 @@ -/* $OpenBSD: cvs.c,v 1.97 2006/04/14 02:45:35 deraadt Exp $ */ +/* $OpenBSD: cvs.c,v 1.98 2006/05/27 03:30:30 joris Exp $ */ /* + * Copyright (c) 2006 Joris Vink * Copyright (c) 2004 Jean-Francois Brousseau * All rights reserved. * @@ -30,49 +31,72 @@ #include "log.h" #include "file.h" - extern char *__progname; - /* verbosity level: 0 = really quiet, 1 = quiet, 2 = verbose */ int verbosity = 2; /* compression level used with zlib, 0 meaning no compression taking place */ -int cvs_compress = 0; -int cvs_readrc = 1; /* read .cvsrc on startup */ -int cvs_trace = 0; -int cvs_nolog = 0; -int cvs_readonly = 0; -int cvs_nocase = 0; /* set to 1 to disable filename case sensitivity */ -int cvs_noexec = 0; /* set to 1 to disable disk operations (-n option) */ -int cvs_error = -1; /* set to the correct error code on failure */ -char *cvs_defargs; /* default global arguments from .cvsrc */ -char *cvs_command; /* name of the command we are running */ -int cvs_cmdop; -char *cvs_rootstr; -char *cvs_rsh = CVS_RSH_DEFAULT; -char *cvs_editor = CVS_EDITOR_DEFAULT; -char *cvs_homedir = NULL; -char *cvs_msg = NULL; -char *cvs_repo_base = NULL; -char *cvs_tmpdir = CVS_TMPDIR_DEFAULT; +int cvs_compress = 0; +int cvs_readrc = 1; /* read .cvsrc on startup */ +int cvs_trace = 0; +int cvs_nolog = 0; +int cvs_readonly = 0; +int cvs_nocase = 0; /* set to 1 to disable filename case sensitivity */ +int cvs_noexec = 0; /* set to 1 to disable disk operations (-n option) */ +int cvs_error = -1; /* set to the correct error code on failure */ +int cvs_cmdop; -/* hierarchy of all the files affected by the command */ -CVSFILE *cvs_files; +char *cvs_defargs; /* default global arguments from .cvsrc */ +char *cvs_command; /* name of the command we are running */ +char *cvs_rootstr; +char *cvs_rsh = CVS_RSH_DEFAULT; +char *cvs_editor = CVS_EDITOR_DEFAULT; +char *cvs_homedir = NULL; +char *cvs_msg = NULL; +char *cvs_repo_base = NULL; +char *cvs_tmpdir = CVS_TMPDIR_DEFAULT; +struct cvsroot *current_cvsroot = NULL; + static TAILQ_HEAD(, cvs_var) cvs_variables; - +int cvs_getopt(int, char **); void usage(void); static void cvs_read_rcfile(void); -int cvs_getopt(int, char **); -/* - * usage() - * - * Display usage information. - */ +struct cvs_wklhead temp_files; + +void sighandler(int); +volatile sig_atomic_t cvs_quit = 0; +volatile sig_atomic_t sig_received = 0; + void +sighandler(int sig) +{ + sig_received = sig; + + switch (sig) { + case SIGINT: + case SIGTERM: + cvs_quit = 1; + break; + default: + break; + } +} + +void +cvs_cleanup(void) +{ + cvs_log(LP_TRACE, "cvs_cleanup: removing locks"); + cvs_worklist_run(&repo_locks, cvs_worklist_unlink); + + cvs_log(LP_TRACE, "cvs_cleanup: removing temp files"); + cvs_worklist_run(&temp_files, cvs_worklist_unlink); +} + +void usage(void) { fprintf(stderr, @@ -80,7 +104,6 @@ "[-T tmpdir] [-z level] command [...]\n", __progname); } - int main(int argc, char **argv) { @@ -93,16 +116,9 @@ tzset(); TAILQ_INIT(&cvs_variables); + SLIST_INIT(&repo_locks); + SLIST_INIT(&temp_files); - cvs_log_init(LD_STD, 0); - - /* by default, be very verbose */ - (void)cvs_log_filter(LP_FILTER_UNSET, LP_INFO); - -#ifdef DEBUG - (void)cvs_log_filter(LP_FILTER_UNSET, LP_DEBUG); -#endif - /* check environment so command-line options override it */ if ((envstr = getenv("CVS_RSH")) != NULL) cvs_rsh = envstr; @@ -130,7 +146,7 @@ argv += ret; if (argc == 0) { usage(); - exit(CVS_EX_USAGE); + exit(1); } cvs_command = argv[0]; @@ -160,13 +176,13 @@ } /* setup signal handlers */ - signal(SIGPIPE, SIG_IGN); + signal(SIGTERM, sighandler); + signal(SIGINT, sighandler); + signal(SIGHUP, sighandler); + signal(SIGABRT, sighandler); + signal(SIGALRM, sighandler); + signal(SIGPIPE, sighandler); - if (cvs_file_init() < 0) - fatal("failed to initialize file support"); - - ret = -1; - cmdp = cvs_findcmd(cvs_command); if (cmdp == NULL) { fprintf(stderr, "Unknown command: `%s'\n\n", cvs_command); @@ -174,7 +190,7 @@ for (i = 0; cvs_cdt[i] != NULL; i++) fprintf(stderr, "\t%-16s%s\n", cvs_cdt[i]->cmd_name, cvs_cdt[i]->cmd_descr); - exit(CVS_EX_USAGE); + exit(1); } cvs_cmdop = cmdp->cmd_op; @@ -192,47 +208,27 @@ cmd_argc += ret; } + for (ret = 1; ret < argc; ret++) cmd_argv[cmd_argc++] = argv[ret]; - ret = cvs_startcmd(cmdp, cmd_argc, cmd_argv); - switch (ret) { - case CVS_EX_USAGE: - fprintf(stderr, "Usage: %s %s %s\n", __progname, - cmdp->cmd_name, cmdp->cmd_synopsis); - break; - case CVS_EX_DATA: - cvs_log(LP_ABORT, "internal data error"); - break; - case CVS_EX_PROTO: - cvs_log(LP_ABORT, "protocol error"); - break; - case CVS_EX_FILE: - cvs_log(LP_ABORT, "an operation on a file or directory failed"); - break; - case CVS_EX_BADROOT: - /* match GNU CVS output, thus the LP_ERR and LP_ABORT codes. */ + cvs_file_init(); + + if ((current_cvsroot = cvsroot_get(".")) == NULL) { cvs_log(LP_ERR, - "No CVSROOT specified! Please use the `-d' option"); - cvs_log(LP_ABORT, - "or set the CVSROOT enviroment variable."); - break; - case CVS_EX_ERR: - cvs_log(LP_ABORT, "yeah, we failed, and we don't know why"); - break; - default: - break; + "No CVSROOT specified! Please use the '-d' option"); + fatal("or set the CVSROOT enviroment variable."); } - if (cvs_files != NULL) - cvs_file_free(cvs_files); - if (cvs_msg != NULL) - xfree(cvs_msg); + if (current_cvsroot->cr_method != CVS_METHOD_LOCAL) + fatal("remote setups are not supported yet"); - return (ret); + cmdp->cmd(cmd_argc, cmd_argv); + cvs_cleanup(); + + return (0); } - int cvs_getopt(int argc, char **argv) { @@ -279,17 +275,16 @@ ep = strchr(optarg, '='); if (ep == NULL) { cvs_log(LP_ERR, "no = in variable assignment"); - exit(CVS_EX_USAGE); + exit(1); } *(ep++) = '\0'; if (cvs_var_set(optarg, ep) < 0) - exit(CVS_EX_USAGE); + exit(1); break; case 'T': cvs_tmpdir = optarg; break; case 't': - (void)cvs_log_filter(LP_FILTER_UNSET, LP_TRACE); cvs_trace = 1; break; case 'v': @@ -315,7 +310,7 @@ break; default: usage(); - exit(CVS_EX_USAGE); + exit(1); } } @@ -326,7 +321,6 @@ return (ret); } - /* * cvs_read_rcfile() * @@ -347,7 +341,7 @@ strlcat(rcpath, "/", sizeof(rcpath)) >= sizeof(rcpath) || strlcat(rcpath, CVS_PATH_RC, sizeof(rcpath)) >= sizeof(rcpath)) { errno = ENAMETOOLONG; - cvs_log(LP_ERRNO, "%s", rcpath); + cvs_log(LP_ERR, "%s", rcpath); return; } @@ -364,7 +358,7 @@ if ((len = strlen(linebuf)) == 0) continue; if (linebuf[len - 1] != '\n') { - cvs_log(LP_WARN, "line too long in `%s:%d'", rcpath, + cvs_log(LP_ERR, "line too long in `%s:%d'", rcpath, linenum); break; } @@ -405,6 +399,7 @@ cmdp->cmd_defargs = xstrdup(lp); } } + if (ferror(fp)) { cvs_log(LP_NOTICE, "failed to read line from `%s'", rcpath); } @@ -412,7 +407,6 @@ (void)fclose(fp); } - /* * cvs_var_set() * @@ -460,7 +454,6 @@ return (0); } - /* * cvs_var_set() * @@ -482,9 +475,7 @@ } return (-1); - } - /* * cvs_var_get()