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