rlog.c revision 1.4
1/*	$OpenBSD: rlog.c,v 1.4 2005/10/12 17:13:30 deraadt Exp $	*/
2/*
3 * Copyright (c) 2005 Joris Vink <joris@openbsd.org>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. The name of the author may not be used to endorse or promote products
13 *    derived from this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
16 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
17 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
18 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include <sys/param.h>
28#include <sys/stat.h>
29
30#include <dirent.h>
31#include <stdio.h>
32#include <stdlib.h>
33#include <string.h>
34#include <unistd.h>
35
36#include "log.h"
37#include "rcs.h"
38#include "diff.h"
39#include "rcsprog.h"
40
41static int rlog_file(const char *, const char *, RCSFILE *);
42
43#define REVSEP		"----------------------------"
44#define REVEND \
45 "============================================================================"
46
47static int hflag;
48static int tflag;
49static int Nflag;
50
51int
52rlog_main(int argc, char **argv)
53{
54	int Rflag;
55	int i, ch;
56	char fpath[MAXPATHLEN];
57	RCSFILE *file;
58
59	hflag = Rflag = 0;
60	while ((ch = getopt(argc, argv, "hNqRtV")) != -1) {
61		switch (ch) {
62		case 'h':
63			hflag = 1;
64			break;
65		case 'N':
66			Nflag = 1;
67			break;
68		case 'q':
69			verbose = 0;
70			break;
71		case 'R':
72			Rflag = 1;
73			break;
74		case 't':
75			tflag = 1;
76			break;
77		case 'V':
78			printf("%s\n", rcs_version);
79			exit(0);
80		default:
81			break;
82		}
83	}
84
85	argc -= optind;
86	argv += optind;
87
88	if (argc == 0) {
89		cvs_log(LP_ERR, "no input file");
90		(usage)();
91		exit(1);
92	}
93
94	for (i = 0; i < argc; i++) {
95		if (rcs_statfile(argv[i], fpath, sizeof(fpath)) < 0)
96			continue;
97
98		if ((file = rcs_open(fpath, RCS_READ)) == NULL)
99			continue;
100
101		if (Rflag == 0)
102			rlog_file(argv[i], fpath, file);
103		rcs_close(file);
104	}
105
106	return (0);
107}
108
109void
110rlog_usage(void)
111{
112	fprintf(stderr,
113	    "usage: rlog [-hNqRtV] file ...\n");
114}
115
116static int
117rlog_file(const char *fname, const char *fpath, RCSFILE *file)
118{
119	char numb[64];
120	struct rcs_sym *sym;
121	struct rcs_delta *rdp;
122	struct rcs_access *acp;
123
124	printf("Working file: %s", fname);
125	printf("\nhead:");
126	if (file->rf_head != NULL)
127		printf(" %s", rcsnum_tostr(file->rf_head, numb, sizeof(numb)));
128
129	printf("\nbranch:");
130	if (rcs_branch_get(file) != NULL) {
131		printf(" %s", rcsnum_tostr(rcs_branch_get(file),
132		    numb, sizeof(numb)));
133	}
134
135	printf("\nlocks: %s", (file->rf_flags & RCS_SLOCK) ? "strict" : "");
136	printf("\naccess list:\n");
137	TAILQ_FOREACH(acp, &(file->rf_access), ra_list)
138		printf("\t%s\n", acp->ra_name);
139
140	if (Nflag == 0) {
141		printf("symbolic names:\n");
142		TAILQ_FOREACH(sym, &(file->rf_symbols), rs_list) {
143			printf("\t%s: %s\n", sym->rs_name,
144			    rcsnum_tostr(sym->rs_num, numb, sizeof(numb)));
145		}
146	}
147
148	printf("keyword substitution: %s\n",
149	    file->rf_expand == NULL ? "kv" : file->rf_expand);
150
151	printf("total revisions: %u\n", file->rf_ndelta);
152
153	if ((hflag == 0) || (tflag == 1))
154	printf("description: %s\n", file->rf_desc);
155
156	if ((hflag == 0) && (tflag == 0)) {
157		TAILQ_FOREACH(rdp, &(file->rf_delta), rd_list) {
158			rcsnum_tostr(rdp->rd_num, numb, sizeof(numb));
159			printf("%s\nrevision %s\n", REVSEP, numb);
160			printf("date: %d/%02d/%02d %02d:%02d:%02d;"
161			    "  author: %s;  state: %s;\n",
162			    rdp->rd_date.tm_year + 1900,
163			    rdp->rd_date.tm_mon + 1,
164			    rdp->rd_date.tm_mday, rdp->rd_date.tm_hour,
165			    rdp->rd_date.tm_min, rdp->rd_date.tm_sec,
166			    rdp->rd_author, rdp->rd_state);
167			printf("%s", rdp->rd_log);
168		}
169	}
170
171	printf("%s\n", REVEND);
172	return (0);
173}
174