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