Annotation of src/usr.bin/rcs/rlog.c, Revision 1.14
1.14 ! xsa 1: /* $OpenBSD: rlog.c,v 1.13 2005/11/17 18:03:51 xsa Exp $ */
1.1 joris 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"
1.3 niallo 38: #include "diff.h"
1.1 joris 39: #include "rcsprog.h"
40:
41: static int rlog_file(const char *, const char *, RCSFILE *);
42:
43: #define REVSEP "----------------------------"
44: #define REVEND \
1.6 xsa 45: "============================================================================="
1.1 joris 46:
47: static int hflag;
1.11 xsa 48: static int Lflag;
1.1 joris 49: static int tflag;
50: static int Nflag;
51:
52: int
53: rlog_main(int argc, char **argv)
54: {
55: int Rflag;
56: int i, ch;
57: char fpath[MAXPATHLEN];
58: RCSFILE *file;
59:
60: hflag = Rflag = 0;
1.14 ! xsa 61: while ((ch = rcs_getopt(argc, argv, "hLNqRTtVx:")) != -1) {
1.1 joris 62: switch (ch) {
63: case 'h':
64: hflag = 1;
65: break;
1.11 xsa 66: case 'L':
67: Lflag = 1;
68: break;
1.1 joris 69: case 'N':
70: Nflag = 1;
71: break;
72: case 'q':
73: verbose = 0;
74: break;
75: case 'R':
76: Rflag = 1;
77: break;
1.8 xsa 78: case 'T':
79: /*
80: * kept for compatibility
81: */
82: break;
1.1 joris 83: case 't':
84: tflag = 1;
85: break;
86: case 'V':
87: printf("%s\n", rcs_version);
88: exit(0);
1.14 ! xsa 89: case 'x':
! 90: rcs_suffixes = rcs_optarg;
! 91: break;
1.1 joris 92: default:
93: break;
94: }
95: }
96:
1.5 joris 97: argc -= rcs_optind;
98: argv += rcs_optind;
1.1 joris 99:
100: if (argc == 0) {
101: cvs_log(LP_ERR, "no input file");
102: (usage)();
103: exit(1);
104: }
105:
1.7 xsa 106: if ((hflag == 1) && (tflag == 1)) {
1.6 xsa 107: cvs_log(LP_WARN, "warning: -t overrides -h.");
1.7 xsa 108: hflag = 0;
109: }
1.6 xsa 110:
1.1 joris 111: for (i = 0; i < argc; i++) {
112: if (rcs_statfile(argv[i], fpath, sizeof(fpath)) < 0)
113: continue;
114:
1.11 xsa 115: if ((file = rcs_open(fpath, RCS_READ)) == NULL)
116: continue;
117:
118: if ((Lflag == 1) && (TAILQ_EMPTY(&(file->rf_locks)))) {
119: rcs_close(file);
120: continue;
121: }
122:
1.9 xsa 123: if (Rflag == 1) {
124: printf("%s\n", fpath);
1.11 xsa 125: rcs_close(file);
1.9 xsa 126: continue;
127: }
128:
129: rlog_file(argv[i], fpath, file);
130:
1.1 joris 131: rcs_close(file);
132: }
133:
134: return (0);
135: }
136:
137: void
138: rlog_usage(void)
139: {
1.4 deraadt 140: fprintf(stderr,
1.11 xsa 141: "usage: rlog [-hLNqRTtV] file ...\n");
1.1 joris 142: }
143:
144: static int
145: rlog_file(const char *fname, const char *fpath, RCSFILE *file)
146: {
147: char numb[64];
148: struct rcs_sym *sym;
149: struct rcs_delta *rdp;
150: struct rcs_access *acp;
1.10 xsa 151: struct rcs_lock *lkp;
1.1 joris 152:
1.12 xsa 153: printf("\nRCS file: %s", fpath);
1.6 xsa 154: printf("\nWorking file: %s", fname);
1.1 joris 155: printf("\nhead:");
156: if (file->rf_head != NULL)
157: printf(" %s", rcsnum_tostr(file->rf_head, numb, sizeof(numb)));
158:
159: printf("\nbranch:");
160: if (rcs_branch_get(file) != NULL) {
161: printf(" %s", rcsnum_tostr(rcs_branch_get(file),
162: numb, sizeof(numb)));
163: }
164:
165: printf("\nlocks: %s", (file->rf_flags & RCS_SLOCK) ? "strict" : "");
1.10 xsa 166: TAILQ_FOREACH(lkp, &(file->rf_locks), rl_list)
167: printf("\n\t%s: %s", lkp->rl_name,
168: rcsnum_tostr(lkp->rl_num, numb, sizeof(numb)));
1.1 joris 169: printf("\naccess list:\n");
170: TAILQ_FOREACH(acp, &(file->rf_access), ra_list)
171: printf("\t%s\n", acp->ra_name);
172:
173: if (Nflag == 0) {
174: printf("symbolic names:\n");
175: TAILQ_FOREACH(sym, &(file->rf_symbols), rs_list) {
176: printf("\t%s: %s\n", sym->rs_name,
177: rcsnum_tostr(sym->rs_num, numb, sizeof(numb)));
178: }
179: }
180:
181: printf("keyword substitution: %s\n",
182: file->rf_expand == NULL ? "kv" : file->rf_expand);
183:
184: printf("total revisions: %u\n", file->rf_ndelta);
185:
186: if ((hflag == 0) || (tflag == 1))
1.13 xsa 187: printf("description:\n%s", file->rf_desc);
1.1 joris 188:
189: if ((hflag == 0) && (tflag == 0)) {
190: TAILQ_FOREACH(rdp, &(file->rf_delta), rd_list) {
191: rcsnum_tostr(rdp->rd_num, numb, sizeof(numb));
192: printf("%s\nrevision %s\n", REVSEP, numb);
193: printf("date: %d/%02d/%02d %02d:%02d:%02d;"
194: " author: %s; state: %s;\n",
195: rdp->rd_date.tm_year + 1900,
196: rdp->rd_date.tm_mon + 1,
197: rdp->rd_date.tm_mday, rdp->rd_date.tm_hour,
198: rdp->rd_date.tm_min, rdp->rd_date.tm_sec,
199: rdp->rd_author, rdp->rd_state);
200: printf("%s", rdp->rd_log);
201: }
202: }
203:
204: printf("%s\n", REVEND);
205: return (0);
206: }