1*40440ce1Sjoris /* $OpenBSD: getlog.c,v 1.58 2006/05/28 21:35:58 joris Exp $ */ 26c121f58Sjfb /* 3e8c16debSjoris * Copyright (c) 2006 Joris Vink <joris@openbsd.org> 46c121f58Sjfb * 5e8c16debSjoris * Permission to use, copy, modify, and distribute this software for any 6e8c16debSjoris * purpose with or without fee is hereby granted, provided that the above 7e8c16debSjoris * copyright notice and this permission notice appear in all copies. 86c121f58Sjfb * 9e8c16debSjoris * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10e8c16debSjoris * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11e8c16debSjoris * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12e8c16debSjoris * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13e8c16debSjoris * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14e8c16debSjoris * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15e8c16debSjoris * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 166c121f58Sjfb */ 176c121f58Sjfb 18ac41f80cSxsa #include "includes.h" 196c121f58Sjfb 206c121f58Sjfb #include "cvs.h" 21e8c16debSjoris #include "diff.h" 226c121f58Sjfb #include "log.h" 23dc6a6879Sjfb #include "proto.h" 246c121f58Sjfb 25e8c16debSjoris #define LOG_REVSEP \ 26e8c16debSjoris "----------------------------" 276c121f58Sjfb 28e8c16debSjoris #define LOG_REVEND \ 296c121f58Sjfb "=============================================================================" 306c121f58Sjfb 31e8c16debSjoris int cvs_getlog(int, char **); 32e8c16debSjoris void cvs_log_local(struct cvs_file *); 3369d26cb1Sxsa 34e8c16debSjoris char *logrev = NULL; 356c121f58Sjfb 36e4276007Sjfb struct cvs_cmd cvs_cmd_log = { 37e4276007Sjfb CVS_OP_LOG, CVS_REQ_LOG, "log", 38e4276007Sjfb { "lo" }, 39e4276007Sjfb "Print out history information for files", 40e4276007Sjfb "[-bhlNRt] [-d dates] [-r revisions] [-s states] [-w logins]", 417e93b57dSxsa "bd:hlNRr:s:tw:", 42e4276007Sjfb NULL, 43e8c16debSjoris cvs_getlog 44e4276007Sjfb }; 45e4276007Sjfb 46e8c16debSjoris int 47e8c16debSjoris cvs_getlog(int argc, char **argv) 486c121f58Sjfb { 4916cfc147Sjoris int ch; 50e8c16debSjoris int flags; 51e8c16debSjoris char *arg = "."; 52e8c16debSjoris struct cvs_recursion cr; 536c121f58Sjfb 54e8c16debSjoris rcsnum_flags |= RCSNUM_NO_MAGIC; 55e8c16debSjoris flags = CR_RECURSE_DIRS; 56e8c16debSjoris 57e8c16debSjoris while ((ch = getopt(argc, argv, cvs_cmd_log.cmd_opts)) != -1) { 5816cfc147Sjoris switch (ch) { 596c121f58Sjfb case 'l': 60e8c16debSjoris flags &= ~CR_RECURSE_DIRS; 616c121f58Sjfb break; 626c121f58Sjfb case 'r': 63e8c16debSjoris logrev = optarg; 6484c3cb67Sxsa break; 656c121f58Sjfb default: 66e8c16debSjoris fatal("%s", cvs_cmd_log.cmd_synopsis); 676c121f58Sjfb } 686c121f58Sjfb } 696c121f58Sjfb 70e8c16debSjoris argc -= optind; 71e8c16debSjoris argv += optind; 726c121f58Sjfb 73e8c16debSjoris cr.enterdir = NULL; 74e8c16debSjoris cr.leavedir = NULL; 75e8c16debSjoris cr.remote = NULL; 76e8c16debSjoris cr.local = cvs_log_local; 77e8c16debSjoris cr.flags = flags; 7869d26cb1Sxsa 79e8c16debSjoris if (argc > 0) 80e8c16debSjoris cvs_file_run(argc, argv, &cr); 8125c4314aSjfb else 82e8c16debSjoris cvs_file_run(1, &arg, &cr); 8325c4314aSjfb 847e393898Sjoris return (0); 85a96bf98bSjfb } 86df745765Sjfb 87e8c16debSjoris void 88e8c16debSjoris cvs_log_local(struct cvs_file *cf) 899931af54Sjfb { 90e8c16debSjoris u_int nrev; 919931af54Sjfb struct rcs_sym *sym; 92e8c16debSjoris struct rcs_lock *lkp; 939931af54Sjfb struct rcs_delta *rdp; 94874e0b9fSjfb struct rcs_access *acp; 95e8c16debSjoris char numb[32], timeb[32]; 969931af54Sjfb 97e8c16debSjoris cvs_file_classify(cf, 0); 985bf4e3f1Sxsa 99e8c16debSjoris if (cf->file_status == FILE_UNKNOWN) { 1005bf4e3f1Sxsa if (verbosity > 0) 101e8c16debSjoris cvs_log(LP_ERR, "nothing known about %s", 102e8c16debSjoris cf->file_path); 103e8c16debSjoris return; 104e8c16debSjoris } else if (cf->file_status == FILE_ADDED) { 105ef407d49Sxsa if (verbosity > 0) 106e8c16debSjoris cvs_log(LP_ERR, "%s has been added, but not commited", 107e8c16debSjoris cf->file_path); 108e8c16debSjoris return; 1099931af54Sjfb } 1109931af54Sjfb 111e8c16debSjoris printf("\nRCS file: %s", cf->file_rpath); 112e8c16debSjoris printf("\nWorking file: %s", cf->file_path); 113e8c16debSjoris printf("\nhead:"); 114e8c16debSjoris if (cf->file_rcs->rf_head != NULL) 115e8c16debSjoris printf(" %s", rcsnum_tostr(cf->file_rcs->rf_head, 116e8c16debSjoris numb, sizeof(numb))); 117e8c16debSjoris 118e8c16debSjoris printf("\nbranch:"); 119e8c16debSjoris if (rcs_branch_get(cf->file_rcs) != NULL) { 120e8c16debSjoris printf(" %s", rcsnum_tostr(rcs_branch_get(cf->file_rcs), 121e8c16debSjoris numb, sizeof(numb))); 122874e0b9fSjfb } 1239931af54Sjfb 124e8c16debSjoris printf("\nlocks: %s", (cf->file_rcs->rf_flags & RCS_SLOCK) 125e8c16debSjoris ? "strict" : ""); 126e8c16debSjoris TAILQ_FOREACH(lkp, &(cf->file_rcs->rf_locks), rl_list) 127e8c16debSjoris printf("\n\t%s: %s", lkp->rl_name, 128e8c16debSjoris rcsnum_tostr(lkp->rl_num, numb, sizeof(numb))); 1299931af54Sjfb 130e8c16debSjoris printf("\naccess list:\n"); 131e8c16debSjoris TAILQ_FOREACH(acp, &(cf->file_rcs->rf_access), ra_list) 132e8c16debSjoris printf("\t%s\n", acp->ra_name); 133e8c16debSjoris 134e8c16debSjoris printf("symbolic names:\n"); 135e8c16debSjoris TAILQ_FOREACH(sym, &(cf->file_rcs->rf_symbols), rs_list) { 136e8c16debSjoris printf("\t%s: %s\n", sym->rs_name, 137e8c16debSjoris rcsnum_tostr(sym->rs_num, numb, sizeof(numb))); 138874e0b9fSjfb } 139874e0b9fSjfb 140e8c16debSjoris printf("keyword substitution: %s\n", 141e8c16debSjoris cf->file_rcs->rf_expand == NULL ? "kv" : cf->file_rcs->rf_expand); 1429931af54Sjfb 143e8c16debSjoris printf("total revisions: %u", cf->file_rcs->rf_ndelta); 1449931af54Sjfb 145e8c16debSjoris if (logrev != NULL) 146*40440ce1Sjoris nrev = cvs_revision_select(cf->file_rcs, logrev); 147e8c16debSjoris else 148e8c16debSjoris nrev = cf->file_rcs->rf_ndelta; 149874e0b9fSjfb 150e8c16debSjoris printf(";\tselected revisions: %u", nrev); 151e8c16debSjoris printf("\n"); 152e8c16debSjoris printf("description:\n%s", cf->file_rcs->rf_desc); 153874e0b9fSjfb 154e8c16debSjoris TAILQ_FOREACH(rdp, &(cf->file_rcs->rf_delta), rd_list) { 155e8c16debSjoris if (logrev != NULL && 156*40440ce1Sjoris !(rdp->rd_flags & RCS_RD_SELECT)) 157e8c16debSjoris continue; 1583fe70097Sxsa 159e8c16debSjoris printf("%s\n", LOG_REVSEP); 160daf00afbSxsa 161*40440ce1Sjoris rcsnum_tostr(rdp->rd_num, numb, sizeof(numb)); 162e8c16debSjoris printf("revision %s", numb); 163daf00afbSxsa 164e8c16debSjoris strftime(timeb, sizeof(timeb), "%Y/%m/%d %H:%M:%S", 165e8c16debSjoris &rdp->rd_date); 166e8c16debSjoris printf("\ndate: %s; author: %s; state: %s;\n", timeb, 1676c121f58Sjfb rdp->rd_author, rdp->rd_state); 168e8c16debSjoris printf("%s", rdp->rd_log); 169874e0b9fSjfb } 1706c121f58Sjfb 171e8c16debSjoris printf("%s\n", LOG_REVEND); 1726c121f58Sjfb } 173