xref: /openbsd/usr.bin/cvs/history.c (revision ac41f80c)
1 /*	$OpenBSD: history.c,v 1.25 2006/01/02 08:11:56 xsa Exp $	*/
2 /*
3  * Copyright (c) 2004 Jean-Francois Brousseau <jfb@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 "includes.h"
28 
29 #include "cvs.h"
30 #include "log.h"
31 #include "proto.h"
32 
33 #define CVS_HISTORY_MAXMOD	16
34 
35 /* history flags */
36 #define CVS_HF_A	0x01
37 #define CVS_HF_C	0x02
38 #define CVS_HF_E	0x04
39 #define CVS_HF_L	0x08
40 #define CVS_HF_M	0x10
41 #define CVS_HF_O	0x20
42 #define CVS_HF_T	0x40
43 #define CVS_HF_W	0x80
44 
45 #define CVS_HF_EXCL	(CVS_HF_C|CVS_HF_E|CVS_HF_M|CVS_HF_O|CVS_HF_T|CVS_HF_X)
46 
47 static int	cvs_history_init(struct cvs_cmd *, int, char **, int *);
48 #if 0
49 static void	cvs_history_print(struct cvs_hent *);
50 #endif
51 static int	cvs_history_pre_exec(struct cvsroot *);
52 
53 extern char *__progname;
54 
55 struct cvs_cmd cvs_cmd_history = {
56 	CVS_OP_HISTORY, CVS_REQ_HISTORY, "history",
57 	{ "hi", "his" },
58 	"Show repository access history",
59 	"[-aceloTw] [-b str] [-D date] [-f file] [-m module] [-n module] "
60 	"[-p path] [-r rev] [-t tag] [-u user] [-x ACEFGMORTUW] [-z tz]",
61 	"ab:cD:ef:lm:n:op:r:Tt:u:wx:z:",
62 	NULL,
63 	0,
64 	cvs_history_init,
65 	cvs_history_pre_exec,
66 	NULL,
67 	NULL,
68 	NULL,
69 	NULL,
70 	CVS_CMD_SENDDIR
71 };
72 
73 static int flags = 0;
74 static char *date, *rev, *user, *tag;
75 static char *zone = "+0000";
76 static u_int nbmod = 0;
77 static u_int rep = 0;
78 static char *modules[CVS_HISTORY_MAXMOD];
79 
80 static int
81 cvs_history_init(struct cvs_cmd *cmd, int argc, char **argv, int *arg)
82 {
83 	int ch;
84 
85 	date = rev = user = tag = NULL;
86 
87 	while ((ch = getopt(argc, argv, cmd->cmd_opts)) != -1) {
88 		switch (ch) {
89 		case 'a':
90 			flags |= CVS_HF_A;
91 			break;
92 		case 'b':
93 			break;
94 		case 'c':
95 			rep++;
96 			flags |= CVS_HF_C;
97 			break;
98 		case 'D':
99 			break;
100 		case 'e':
101 			rep++;
102 			flags |= CVS_HF_E;
103 			break;
104 		case 'f':
105 			break;
106 		case 'l':
107 			flags |= CVS_HF_L;
108 			break;
109 		case 'm':
110 			rep++;
111 			flags |= CVS_HF_M;
112 			if (nbmod == CVS_HISTORY_MAXMOD) {
113 				cvs_log(LP_ERR, "too many `-m' options");
114 				return (CVS_EX_USAGE);
115 			}
116 			modules[nbmod++] = optarg;
117 			break;
118 		case 'n':
119 			break;
120 		case 'o':
121 			rep++;
122 			flags |= CVS_HF_O;
123 			break;
124 		case 'r':
125 			rev = optarg;
126 			break;
127 		case 'T':
128 			rep++;
129 			flags |= CVS_HF_T;
130 			break;
131 		case 't':
132 			tag = optarg;
133 			break;
134 		case 'u':
135 			user = optarg;
136 			break;
137 		case 'w':
138 			flags |= CVS_HF_W;
139 			break;
140 		case 'x':
141 			rep++;
142 			break;
143 		case 'z':
144 			zone = optarg;
145 			break;
146 		default:
147 			return (CVS_EX_USAGE);
148 		}
149 	}
150 
151 	if (rep > 1) {
152 		cvs_log(LP_ERR,
153 		    "Only one report type allowed from: \"-Tcomxe\"");
154 		return (CVS_EX_USAGE);
155 	} else if (rep == 0)
156 		flags |= CVS_HF_O;    /* use -o as default */
157 
158 	*arg = optind;
159 	return (0);
160 }
161 
162 static int
163 cvs_history_pre_exec(struct cvsroot *root)
164 {
165 	if (root->cr_method != CVS_METHOD_LOCAL) {
166 		if (flags & CVS_HF_A)
167 			cvs_sendarg(root, "-a", 0);
168 
169 		if (flags & CVS_HF_C)
170 			cvs_sendarg(root, "-c", 0);
171 
172 		if (flags & CVS_HF_O)
173 			cvs_sendarg(root, "-o", 0);
174 
175 		if (date != NULL) {
176 			cvs_sendarg(root, "-D", 0);
177 			cvs_sendarg(root, date, 0);
178 		}
179 
180 		if (rev != NULL) {
181 			cvs_sendarg(root, "-r", 0);
182 			cvs_sendarg(root, rev, 0);
183 		}
184 
185 		if (tag != NULL) {
186 			cvs_sendarg(root, "-t", 0);
187 			cvs_sendarg(root, tag, 0);
188 		}
189 
190 		/* if no user is specified, get login name of command issuer */
191 		if (!(flags & CVS_HF_A) && (user == NULL)) {
192 			if ((user = getlogin()) == NULL)
193 				fatal("cannot get login name");
194 		}
195 
196 		if (!(flags & CVS_HF_A)) {
197 			cvs_sendarg(root, "-u", 0);
198 			cvs_sendarg(root, user, 0);
199 		}
200 
201 		cvs_sendarg(root, "-z", 0);
202 		cvs_sendarg(root, zone, 0);
203 	}
204 
205 	return (0);
206 }
207 
208 
209 #if 0
210 static void
211 cvs_history_print(struct cvs_hent *hent)
212 {
213 	struct tm etime;
214 
215 	if (localtime_r(&(hent->ch_date), &etime) == NULL) {
216 		cvs_log(LP_ERR, "failed to convert timestamp to structure");
217 		return;
218 	}
219 
220 	printf("%c %4d-%02d-%02d %02d:%02d +%04d %-16s %-16s\n",
221 	    hent->ch_event, etime.tm_year + 1900, etime.tm_mon + 1,
222 	    etime.tm_mday, etime.tm_hour, etime.tm_min,
223 	    0, hent->ch_user, hent->ch_repo);
224 }
225 #endif
226