=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/cvs/getlog.c,v retrieving revision 1.56 retrieving revision 1.57 diff -c -r1.56 -r1.57 *** src/usr.bin/cvs/getlog.c 2006/04/14 22:33:15 1.56 --- src/usr.bin/cvs/getlog.c 2006/05/28 21:11:12 1.57 *************** *** 1,51 **** ! /* $OpenBSD: getlog.c,v 1.56 2006/04/14 22:33:15 niallo Exp $ */ /* ! * Copyright (c) 2004 Jean-Francois Brousseau ! * Copyright (c) 2005, 2006 Xavier Santolaria ! * All rights reserved. * ! * Redistribution and use in source and binary forms, with or without ! * modification, are permitted provided that the following conditions ! * are met: * ! * 1. Redistributions of source code must retain the above copyright ! * notice, this list of conditions and the following disclaimer. ! * 2. The name of the author may not be used to endorse or promote products ! * derived from this software without specific prior written permission. ! * ! * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, ! * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY ! * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ! * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, ! * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, ! * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; ! * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, ! * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR ! * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ! * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" #include "cvs.h" #include "log.h" #include "proto.h" ! #define CVS_GETLOG_REVSEP "----------------------------" ! #define CVS_GETLOG_REVEND \ "=============================================================================" ! #define GLOG_BRANCH (1<<0) ! #define GLOG_HEADER (1<<1) ! #define GLOG_HEADER_DESCR (1<<2) ! #define GLOG_NAME (1<<3) ! #define GLOG_NOTAGS (1<<4) ! static int cvs_getlog_init(struct cvs_cmd *, int, char **, int *); ! static int cvs_getlog_remote(CVSFILE *, void *); ! static int cvs_getlog_local(CVSFILE *, void *); ! static int cvs_getlog_pre_exec(struct cvsroot *); struct cvs_cmd cvs_cmd_log = { CVS_OP_LOG, CVS_REQ_LOG, "log", --- 1,37 ---- ! /* $OpenBSD: getlog.c,v 1.57 2006/05/28 21:11:12 joris Exp $ */ /* ! * Copyright (c) 2006 Joris Vink * ! * Permission to use, copy, modify, and distribute this software for any ! * purpose with or without fee is hereby granted, provided that the above ! * copyright notice and this permission notice appear in all copies. * ! * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ! * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ! * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ! * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ! * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ! * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ! * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "includes.h" #include "cvs.h" + #include "diff.h" #include "log.h" #include "proto.h" + #define LOG_REVSEP \ + "----------------------------" ! #define LOG_REVEND \ "=============================================================================" ! int cvs_getlog(int, char **); ! void cvs_log_local(struct cvs_file *); ! char *logrev = NULL; struct cvs_cmd cvs_cmd_log = { CVS_OP_LOG, CVS_REQ_LOG, "log", *************** *** 54,296 **** "[-bhlNRt] [-d dates] [-r revisions] [-s states] [-w logins]", "bd:hlNRr:s:tw:", NULL, ! CF_NOSYMS | CF_IGNORE | CF_SORT | CF_RECURSE, ! cvs_getlog_init, ! cvs_getlog_pre_exec, ! cvs_getlog_remote, ! cvs_getlog_local, ! NULL, ! NULL, ! CVS_CMD_SENDDIR | CVS_CMD_ALLOWSPEC | CVS_CMD_SENDARGS2 }; ! ! struct cvs_cmd cvs_cmd_rlog = { ! CVS_OP_LOG, CVS_REQ_LOG, "log", ! { "lo" }, ! "Print out history information for files", ! "[-bhlNRt] [-d dates] [-r revisions] [-s states] [-w logins]", ! "d:hlRr:", ! NULL, ! CF_NOSYMS | CF_IGNORE | CF_SORT | CF_RECURSE, ! cvs_getlog_init, ! cvs_getlog_pre_exec, ! cvs_getlog_remote, ! cvs_getlog_local, ! NULL, ! NULL, ! CVS_CMD_SENDDIR | CVS_CMD_ALLOWSPEC | CVS_CMD_SENDARGS2 ! }; ! ! static int runflags = 0; ! ! static int ! cvs_getlog_init(struct cvs_cmd *cmd, int argc, char **argv, int *arg) { int ch; ! while ((ch = getopt(argc, argv, cmd->cmd_opts)) != -1) { switch (ch) { - case 'b': - runflags |= GLOG_BRANCH; - break; - case 'd': - break; - case 'h': - runflags |= GLOG_HEADER; - break; case 'l': ! cmd->file_flags &= ~CF_RECURSE; break; - case 'N': - runflags |= GLOG_NOTAGS; - break; - case 'R': - runflags |= GLOG_NAME; - break; case 'r': break; - case 's': - break; - case 't': - runflags |= GLOG_HEADER_DESCR; - break; - case 'w': - break; default: ! return (CVS_EX_USAGE); } } ! *arg = optind; ! rcsnum_flags |= RCSNUM_NO_MAGIC; ! return (0); ! } ! static int ! cvs_getlog_pre_exec(struct cvsroot *root) ! { ! if (root->cr_method != CVS_METHOD_LOCAL) { ! if (runflags & GLOG_BRANCH) ! cvs_sendarg(root, "-b", 0); ! if (runflags & GLOG_HEADER) ! cvs_sendarg(root, "-h", 0); - if (runflags & GLOG_NOTAGS) - cvs_sendarg(root, "-N", 0); - - if (runflags & GLOG_NAME) - cvs_sendarg(root, "-R", 0); - - if (runflags & GLOG_HEADER_DESCR) - cvs_sendarg(root, "-t", 0); - } return (0); } ! /* ! * cvs_getlog_remote() ! * ! */ ! static int ! cvs_getlog_remote(CVSFILE *cf, void *arg) { ! char fpath[MAXPATHLEN]; ! struct cvsroot *root; ! ! root = CVS_DIR_ROOT(cf); ! ! if (cf->cf_type == DT_DIR) { ! if (cf->cf_cvstat == CVS_FST_UNKNOWN) ! cvs_sendreq(root, CVS_REQ_QUESTIONABLE, cf->cf_name); ! else ! cvs_senddir(root, cf); ! return (0); ! } ! ! cvs_file_getpath(cf, fpath, sizeof(fpath)); ! ! cvs_sendentry(root, cf); ! ! switch (cf->cf_cvstat) { ! case CVS_FST_UNKNOWN: ! cvs_sendreq(root, CVS_REQ_QUESTIONABLE, cf->cf_name); ! break; ! case CVS_FST_UPTODATE: ! cvs_sendreq(root, CVS_REQ_UNCHANGED, cf->cf_name); ! break; ! case CVS_FST_ADDED: ! case CVS_FST_MODIFIED: ! cvs_sendreq(root, CVS_REQ_ISMODIFIED, cf->cf_name); ! break; ! default: ! break; ! } ! ! return (0); ! } ! ! ! ! static int ! cvs_getlog_local(CVSFILE *cf, void *arg) ! { ! int nrev; ! char rcspath[MAXPATHLEN], numbuf[64]; ! RCSFILE *rf; struct rcs_sym *sym; struct rcs_delta *rdp; struct rcs_access *acp; ! nrev = 0; ! if (cf->cf_cvstat == CVS_FST_ADDED) { if (verbosity > 0) ! cvs_log(LP_WARN, "%s has been added, but not committed", ! cf->cf_name); ! return (0); ! } ! ! if (cf->cf_cvstat == CVS_FST_UNKNOWN) { if (verbosity > 0) ! cvs_log(LP_WARN, "nothing known about %s", cf->cf_name); ! return (0); } ! if (cf->cf_type == DT_DIR) { ! if (verbosity > 1) ! cvs_log(LP_NOTICE, "Logging %s", cf->cf_name); ! return (0); ! } ! cvs_rcs_getpath(cf, rcspath, sizeof(rcspath)); ! ! if (runflags & GLOG_NAME) { ! cvs_printf("%s\n", rcspath); ! return (0); } ! if ((rf = rcs_open(rcspath, RCS_READ|RCS_PARSE_FULLY)) == NULL) ! fatal("cvs_getlog_local: rcs_open `%s': %s", rcspath, ! rcs_errstr(rcs_errno)); ! cvs_printf("\nRCS file: %s", rcspath); ! cvs_printf("\nWorking file: %s", cf->cf_name); ! cvs_printf("\nhead:"); ! if (rcs_head_get(rf) != NULL) { ! cvs_printf(" %s", ! rcsnum_tostr(rcs_head_get(rf), numbuf, sizeof(numbuf))); ! } ! cvs_printf("\nbranch:"); ! if (rcs_branch_get(rf) != NULL) { ! cvs_printf(" %s", ! rcsnum_tostr(rcs_branch_get(rf), numbuf, sizeof(numbuf))); ! } ! cvs_printf("\nlocks:%s", (rf->rf_flags & RCS_SLOCK) ? " strict" : ""); ! cvs_printf("\naccess list:\n"); ! TAILQ_FOREACH(acp, &(rf->rf_access), ra_list) ! cvs_printf("\t%s\n", acp->ra_name); ! ! if (!(runflags & GLOG_NOTAGS)) { ! cvs_printf("symbolic names:\n"); ! TAILQ_FOREACH(sym, &(rf->rf_symbols), rs_list) ! cvs_printf("\t%s: %s\n", sym->rs_name, ! rcsnum_tostr(sym->rs_num, numbuf, sizeof(numbuf))); } ! cvs_printf("keyword substitution: %s\n", ! rf->rf_expand == NULL ? "kv" : rf->rf_expand); ! cvs_printf("total revisions: %u", rf->rf_ndelta); ! if (!(runflags & GLOG_HEADER) && !(runflags & GLOG_HEADER_DESCR)) ! cvs_printf(";\tselected revisions: %u", nrev); ! cvs_printf("\n"); ! if (!(runflags & GLOG_HEADER) || (runflags & GLOG_HEADER_DESCR)) ! cvs_printf("description:\n%s", rf->rf_desc); ! if (!(runflags & GLOG_HEADER) && !(runflags & GLOG_HEADER_DESCR)) { ! TAILQ_FOREACH(rdp, &(rf->rf_delta), rd_list) { ! rcsnum_tostr(rdp->rd_num, numbuf, sizeof(numbuf)); ! cvs_printf(CVS_GETLOG_REVSEP "\nrevision %s\n", numbuf); ! cvs_printf("date: %d/%02d/%02d %02d:%02d:%02d;" ! " author: %s; state: %s;\n", ! rdp->rd_date.tm_year + 1900, ! rdp->rd_date.tm_mon + 1, ! rdp->rd_date.tm_mday, rdp->rd_date.tm_hour, ! rdp->rd_date.tm_min, rdp->rd_date.tm_sec, ! rdp->rd_author, rdp->rd_state); ! cvs_printf("%s", rdp->rd_log); ! } ! } ! cvs_printf(CVS_GETLOG_REVEND "\n"); ! rcs_close(rf); ! return (0); } --- 40,173 ---- "[-bhlNRt] [-d dates] [-r revisions] [-s states] [-w logins]", "bd:hlNRr:s:tw:", NULL, ! cvs_getlog }; ! int ! cvs_getlog(int argc, char **argv) { int ch; + int flags; + char *arg = "."; + struct cvs_recursion cr; ! rcsnum_flags |= RCSNUM_NO_MAGIC; ! flags = CR_RECURSE_DIRS; ! ! while ((ch = getopt(argc, argv, cvs_cmd_log.cmd_opts)) != -1) { switch (ch) { case 'l': ! flags &= ~CR_RECURSE_DIRS; break; case 'r': + logrev = optarg; break; default: ! fatal("%s", cvs_cmd_log.cmd_synopsis); } } ! argc -= optind; ! argv += optind; ! cr.enterdir = NULL; ! cr.leavedir = NULL; ! cr.remote = NULL; ! cr.local = cvs_log_local; ! cr.flags = flags; ! if (argc > 0) ! cvs_file_run(argc, argv, &cr); ! else ! cvs_file_run(1, &arg, &cr); return (0); } ! void ! cvs_log_local(struct cvs_file *cf) { ! u_int nrev; struct rcs_sym *sym; + struct rcs_lock *lkp; struct rcs_delta *rdp; struct rcs_access *acp; + char numb[32], timeb[32]; ! cvs_file_classify(cf, 0); ! if (cf->file_status == FILE_UNKNOWN) { if (verbosity > 0) ! cvs_log(LP_ERR, "nothing known about %s", ! cf->file_path); ! return; ! } else if (cf->file_status == FILE_ADDED) { if (verbosity > 0) ! cvs_log(LP_ERR, "%s has been added, but not commited", ! cf->file_path); ! return; } ! printf("\nRCS file: %s", cf->file_rpath); ! printf("\nWorking file: %s", cf->file_path); ! printf("\nhead:"); ! if (cf->file_rcs->rf_head != NULL) ! printf(" %s", rcsnum_tostr(cf->file_rcs->rf_head, ! numb, sizeof(numb))); ! printf("\nbranch:"); ! if (rcs_branch_get(cf->file_rcs) != NULL) { ! printf(" %s", rcsnum_tostr(rcs_branch_get(cf->file_rcs), ! numb, sizeof(numb))); } ! printf("\nlocks: %s", (cf->file_rcs->rf_flags & RCS_SLOCK) ! ? "strict" : ""); ! TAILQ_FOREACH(lkp, &(cf->file_rcs->rf_locks), rl_list) ! printf("\n\t%s: %s", lkp->rl_name, ! rcsnum_tostr(lkp->rl_num, numb, sizeof(numb))); ! printf("\naccess list:\n"); ! TAILQ_FOREACH(acp, &(cf->file_rcs->rf_access), ra_list) ! printf("\t%s\n", acp->ra_name); ! printf("symbolic names:\n"); ! TAILQ_FOREACH(sym, &(cf->file_rcs->rf_symbols), rs_list) { ! printf("\t%s: %s\n", sym->rs_name, ! rcsnum_tostr(sym->rs_num, numb, sizeof(numb))); } ! printf("keyword substitution: %s\n", ! cf->file_rcs->rf_expand == NULL ? "kv" : cf->file_rcs->rf_expand); ! printf("total revisions: %u", cf->file_rcs->rf_ndelta); ! if (logrev != NULL) ! nrev = 1; ! else ! nrev = cf->file_rcs->rf_ndelta; ! printf(";\tselected revisions: %u", nrev); ! printf("\n"); ! printf("description:\n%s", cf->file_rcs->rf_desc); ! TAILQ_FOREACH(rdp, &(cf->file_rcs->rf_delta), rd_list) { ! rcsnum_tostr(rdp->rd_num, numb, sizeof(numb)); ! if (logrev != NULL && ! strcmp(logrev, numb)) ! continue; ! printf("%s\n", LOG_REVSEP); ! printf("revision %s", numb); ! strftime(timeb, sizeof(timeb), "%Y/%m/%d %H:%M:%S", ! &rdp->rd_date); ! printf("\ndate: %s; author: %s; state: %s;\n", timeb, ! rdp->rd_author, rdp->rd_state); ! printf("%s", rdp->rd_log); ! } ! ! printf("%s\n", LOG_REVEND); }