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