| File: | src/usr.bin/cvs/getlog.c |
| Warning: | line 321, column 2 Value stored to 'i' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* $OpenBSD: getlog.c,v 1.101 2017/06/01 08:08:24 joris Exp $ */ |
| 2 | /* |
| 3 | * Copyright (c) 2005, 2006 Xavier Santolaria <xsa@openbsd.org> |
| 4 | * Copyright (c) 2006 Joris Vink <joris@openbsd.org> |
| 5 | * |
| 6 | * Permission to use, copy, modify, and distribute this software for any |
| 7 | * purpose with or without fee is hereby granted, provided that the above |
| 8 | * copyright notice and this permission notice appear in all copies. |
| 9 | * |
| 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
| 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
| 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
| 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
| 14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
| 15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
| 16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
| 17 | */ |
| 18 | |
| 19 | #include <unistd.h> |
| 20 | #include <stdlib.h> |
| 21 | #include <string.h> |
| 22 | #include <errno(*__errno()).h> |
| 23 | #include <ctype.h> |
| 24 | |
| 25 | #include "cvs.h" |
| 26 | #include "remote.h" |
| 27 | |
| 28 | #define L_HEAD0x01 0x01 |
| 29 | #define L_HEAD_DESCR0x02 0x02 |
| 30 | #define L_NAME0x04 0x04 |
| 31 | #define L_NOTAGS0x08 0x08 |
| 32 | #define L_LOGINS0x10 0x10 |
| 33 | #define L_STATES0x20 0x20 |
| 34 | |
| 35 | #define LDATE_LATER0x01 0x01 |
| 36 | #define LDATE_EARLIER0x02 0x02 |
| 37 | #define LDATE_SINGLE0x04 0x04 |
| 38 | #define LDATE_RANGE0x08 0x08 |
| 39 | #define LDATE_INCLUSIVE0x10 0x10 |
| 40 | |
| 41 | void cvs_log_local(struct cvs_file *); |
| 42 | static void log_rev_print(struct rcs_delta *); |
| 43 | static char *push_date(char *dest, const char *); |
| 44 | static u_int date_select(RCSFILE *, char *); |
| 45 | |
| 46 | int runflags = 0; |
| 47 | char *logrev = NULL((void *)0); |
| 48 | char *logdate = NULL((void *)0); |
| 49 | char *slist = NULL((void *)0); |
| 50 | char *wlist = NULL((void *)0); |
| 51 | |
| 52 | struct cvs_cmd cvs_cmd_log = { |
| 53 | CVS_OP_LOG13, CVS_USE_WDIR0x01, "log", |
| 54 | { "lo" }, |
| 55 | "Print out history information for files", |
| 56 | "[-bhlNRt] [-d dates] [-r revisions] [-s states] [-w logins]", |
| 57 | "bd:hlNRr:s:tw:", |
| 58 | NULL((void *)0), |
| 59 | cvs_getlog |
| 60 | }; |
| 61 | |
| 62 | struct cvs_cmd cvs_cmd_rlog = { |
| 63 | CVS_OP_RLOG18, 0, "rlog", |
| 64 | { "rlo" }, |
| 65 | "Print out history information for files", |
| 66 | "[-bhlNRt] [-d dates] [-r revisions] [-s states] [-w logins]", |
| 67 | "bd:hlNRr:s:tw:", |
| 68 | NULL((void *)0), |
| 69 | cvs_getlog |
| 70 | }; |
| 71 | |
| 72 | int |
| 73 | cvs_getlog(int argc, char **argv) |
| 74 | { |
| 75 | int ch, flags, i; |
| 76 | char *arg = "."; |
| 77 | struct cvs_recursion cr; |
| 78 | |
| 79 | flags = CR_RECURSE_DIRS0x01; |
| 80 | |
| 81 | while ((ch = getopt(argc, argv, cvs_cmdop == CVS_OP_LOG13 ? |
| 82 | cvs_cmd_log.cmd_opts : cvs_cmd_rlog.cmd_opts)) != -1) { |
| 83 | switch (ch) { |
| 84 | case 'd': |
| 85 | logdate = push_date(logdate, optarg); |
| 86 | break; |
| 87 | case 'h': |
| 88 | runflags |= L_HEAD0x01; |
| 89 | break; |
| 90 | case 'l': |
| 91 | flags &= ~CR_RECURSE_DIRS0x01; |
| 92 | break; |
| 93 | case 'N': |
| 94 | runflags |= L_NOTAGS0x08; |
| 95 | break; |
| 96 | case 'R': |
| 97 | runflags |= L_NAME0x04; |
| 98 | break; |
| 99 | case 'r': |
| 100 | logrev = optarg; |
| 101 | break; |
| 102 | case 's': |
| 103 | runflags |= L_STATES0x20; |
| 104 | slist = optarg; |
| 105 | break; |
| 106 | case 't': |
| 107 | runflags |= L_HEAD_DESCR0x02; |
| 108 | break; |
| 109 | case 'w': |
| 110 | runflags |= L_LOGINS0x10; |
| 111 | wlist = optarg; |
| 112 | break; |
| 113 | default: |
| 114 | fatal("%s", cvs_cmdop == CVS_OP_LOG13 ? |
| 115 | cvs_cmd_log.cmd_synopsis : |
| 116 | cvs_cmd_rlog.cmd_synopsis); |
| 117 | } |
| 118 | } |
| 119 | |
| 120 | argc -= optind; |
| 121 | argv += optind; |
| 122 | |
| 123 | if (cvs_cmdop == CVS_OP_RLOG18) { |
| 124 | flags |= CR_REPO0x04; |
| 125 | |
| 126 | if (argc == 0) |
| 127 | return 0; |
| 128 | |
| 129 | for (i = 0; i < argc; i++) |
| 130 | if (argv[i][0] == '/') |
| 131 | fatal("Absolute path name is invalid: %s", |
| 132 | argv[i]); |
| 133 | } |
| 134 | |
| 135 | cr.enterdir = NULL((void *)0); |
| 136 | cr.leavedir = NULL((void *)0); |
| 137 | |
| 138 | if (cvsroot_is_remote()) { |
| 139 | cvs_client_connect_to_server(); |
| 140 | cr.fileproc = cvs_client_sendfile; |
| 141 | |
| 142 | if (logdate != NULL((void *)0)) |
| 143 | cvs_client_send_request("Argument -d%s", logdate); |
| 144 | |
| 145 | if (runflags & L_HEAD0x01) |
| 146 | cvs_client_send_request("Argument -h"); |
| 147 | |
| 148 | if (!(flags & CR_RECURSE_DIRS0x01)) |
| 149 | cvs_client_send_request("Argument -l"); |
| 150 | |
| 151 | if (runflags & L_NOTAGS0x08) |
| 152 | cvs_client_send_request("Argument -N"); |
| 153 | |
| 154 | if (runflags & L_NAME0x04) |
| 155 | cvs_client_send_request("Argument -R"); |
| 156 | |
| 157 | if (logrev != NULL((void *)0)) |
| 158 | cvs_client_send_request("Argument -r%s", logrev); |
| 159 | |
| 160 | if (runflags & L_STATES0x20) |
| 161 | cvs_client_send_request("Argument -s%s", slist); |
| 162 | |
| 163 | if (runflags & L_HEAD_DESCR0x02) |
| 164 | cvs_client_send_request("Argument -t"); |
| 165 | |
| 166 | if (runflags & L_LOGINS0x10) |
| 167 | cvs_client_send_request("Argument -w%s", wlist); |
| 168 | } else { |
| 169 | if (cvs_cmdop == CVS_OP_RLOG18 && |
| 170 | chdir(current_cvsroot->cr_dir) == -1) |
| 171 | fatal("cvs_getlog: %s", strerror(errno(*__errno()))); |
| 172 | |
| 173 | cr.fileproc = cvs_log_local; |
| 174 | } |
| 175 | |
| 176 | cr.flags = flags; |
| 177 | |
| 178 | if (cvs_cmdop == CVS_OP_LOG13 || cvsroot_is_local()) { |
| 179 | if (argc > 0) |
| 180 | cvs_file_run(argc, argv, &cr); |
| 181 | else |
| 182 | cvs_file_run(1, &arg, &cr); |
| 183 | } |
| 184 | |
| 185 | if (cvsroot_is_remote()) { |
| 186 | cvs_client_send_files(argv, argc); |
| 187 | cvs_client_senddir("."); |
| 188 | |
| 189 | cvs_client_send_request((cvs_cmdop == CVS_OP_RLOG18) ? |
| 190 | "rlog" : "log"); |
| 191 | |
| 192 | cvs_client_get_responses(); |
| 193 | } |
| 194 | |
| 195 | return (0); |
| 196 | } |
| 197 | |
| 198 | void |
| 199 | cvs_log_local(struct cvs_file *cf) |
| 200 | { |
| 201 | u_int nrev; |
| 202 | RCSNUM *rev; |
| 203 | struct rcs_sym *sym; |
| 204 | struct rcs_lock *lkp; |
| 205 | struct rcs_delta *rdp; |
| 206 | struct rcs_access *acp; |
| 207 | char numb[CVS_REV_BUFSZ32]; |
| 208 | |
| 209 | cvs_log(LP_TRACE4, "cvs_log_local(%s)", cf->file_path); |
| 210 | |
| 211 | cvs_file_classify(cf, cvs_directory_tag); |
| 212 | |
| 213 | if (cf->file_type == CVS_DIR1) { |
| 214 | if (verbosity > 1) |
| 215 | cvs_log(LP_ERR1, "Logging %s", cf->file_path); |
| 216 | return; |
| 217 | } |
| 218 | |
| 219 | if (cf->file_rcs == NULL((void *)0)) { |
| 220 | return; |
| 221 | } else if (cf->file_status == FILE_ADDED1) { |
| 222 | if (verbosity > 0) |
| 223 | cvs_log(LP_ERR1, "%s has been added, but not committed", |
| 224 | cf->file_path); |
| 225 | return; |
| 226 | } |
| 227 | |
| 228 | if (runflags & L_NAME0x04) { |
| 229 | cvs_printf("%s\n", cf->file_rpath); |
| 230 | return; |
| 231 | } |
| 232 | |
| 233 | if (logrev != NULL((void *)0)) |
| 234 | nrev = cvs_revision_select(cf->file_rcs, logrev); |
| 235 | else if (logdate != NULL((void *)0)) { |
| 236 | if ((nrev = date_select(cf->file_rcs, logdate)) == (u_int)-1) { |
| 237 | cvs_log(LP_ERR1, "invalid date: %s", logdate); |
| 238 | return; |
| 239 | } |
| 240 | } else |
| 241 | nrev = cf->file_rcs->rf_ndelta; |
| 242 | |
| 243 | cvs_printf("\nRCS file: %s", cf->file_rpath); |
| 244 | |
| 245 | if (cvs_cmdop != CVS_OP_RLOG18) |
| 246 | cvs_printf("\nWorking file: %s", cf->file_path); |
| 247 | |
| 248 | cvs_printf("\nhead:"); |
| 249 | if (cf->file_rcs->rf_head != NULL((void *)0)) |
| 250 | cvs_printf(" %s", rcsnum_tostr(cf->file_rcs->rf_head, |
| 251 | numb, sizeof(numb))); |
| 252 | |
| 253 | cvs_printf("\nbranch:"); |
| 254 | if (rcs_branch_get(cf->file_rcs) != NULL((void *)0)) { |
| 255 | cvs_printf(" %s", rcsnum_tostr(rcs_branch_get(cf->file_rcs), |
| 256 | numb, sizeof(numb))); |
| 257 | } |
| 258 | |
| 259 | cvs_printf("\nlocks: %s", (cf->file_rcs->rf_flags & RCS_SLOCK(1<<6)) |
| 260 | ? "strict" : ""); |
| 261 | TAILQ_FOREACH(lkp, &(cf->file_rcs->rf_locks), rl_list)for((lkp) = ((&(cf->file_rcs->rf_locks))->tqh_first ); (lkp) != ((void *)0); (lkp) = ((lkp)->rl_list.tqe_next) ) |
| 262 | cvs_printf("\n\t%s: %s", lkp->rl_name, |
| 263 | rcsnum_tostr(lkp->rl_num, numb, sizeof(numb))); |
| 264 | |
| 265 | cvs_printf("\naccess list:\n"); |
| 266 | TAILQ_FOREACH(acp, &(cf->file_rcs->rf_access), ra_list)for((acp) = ((&(cf->file_rcs->rf_access))->tqh_first ); (acp) != ((void *)0); (acp) = ((acp)->ra_list.tqe_next) ) |
| 267 | cvs_printf("\t%s\n", acp->ra_name); |
| 268 | |
| 269 | if (!(runflags & L_NOTAGS0x08)) { |
| 270 | cvs_printf("symbolic names:\n"); |
| 271 | TAILQ_FOREACH(sym, &(cf->file_rcs->rf_symbols), rs_list)for((sym) = ((&(cf->file_rcs->rf_symbols))->tqh_first ); (sym) != ((void *)0); (sym) = ((sym)->rs_list.tqe_next) ) { |
| 272 | rev = rcsnum_alloc(); |
| 273 | rcsnum_cpy(sym->rs_num, rev, 0); |
| 274 | if (RCSNUM_ISBRANCH(sym->rs_num)((sym->rs_num)->rn_len % 2)) |
| 275 | rcsnum_addmagic(rev); |
| 276 | |
| 277 | cvs_printf("\t%s: %s\n", sym->rs_name, |
| 278 | rcsnum_tostr(rev, numb, sizeof(numb))); |
| 279 | free(rev); |
| 280 | } |
| 281 | } |
| 282 | |
| 283 | cvs_printf("keyword substitution: %s\n", |
| 284 | cf->file_rcs->rf_expand == NULL((void *)0) ? "kv" : cf->file_rcs->rf_expand); |
| 285 | |
| 286 | cvs_printf("total revisions: %u", cf->file_rcs->rf_ndelta); |
| 287 | |
| 288 | if (cf->file_rcs->rf_head != NULL((void *)0) && |
| 289 | !(runflags & L_HEAD0x01) && !(runflags & L_HEAD_DESCR0x02)) |
| 290 | cvs_printf(";\tselected revisions: %u", nrev); |
| 291 | |
| 292 | cvs_printf("\n"); |
| 293 | |
| 294 | if (!(runflags & L_HEAD0x01) || (runflags & L_HEAD_DESCR0x02)) |
| 295 | cvs_printf("description:\n%s", cf->file_rcs->rf_desc); |
| 296 | |
| 297 | if (!(runflags & L_HEAD0x01) && !(runflags & L_HEAD_DESCR0x02)) { |
| 298 | TAILQ_FOREACH(rdp, &(cf->file_rcs->rf_delta), rd_list)for((rdp) = ((&(cf->file_rcs->rf_delta))->tqh_first ); (rdp) != ((void *)0); (rdp) = ((rdp)->rd_list.tqe_next) ) { |
| 299 | /* |
| 300 | * if selections are enabled verify that entry is |
| 301 | * selected. |
| 302 | */ |
| 303 | if ((logrev == NULL((void *)0) && logdate == NULL((void *)0)) || |
| 304 | (rdp->rd_flags & RCS_RD_SELECT0x02)) |
| 305 | log_rev_print(rdp); |
| 306 | } |
| 307 | } |
| 308 | |
| 309 | cvs_printf("%s\n", LOG_REVEND"============================================================================="); |
| 310 | } |
| 311 | |
| 312 | static void |
| 313 | log_rev_print(struct rcs_delta *rdp) |
| 314 | { |
| 315 | int i, found; |
| 316 | char numb[CVS_REV_BUFSZ32], timeb[CVS_TIME_BUFSZ64]; |
| 317 | struct cvs_argvector *sargv, *wargv; |
| 318 | struct rcs_branch *rb; |
| 319 | struct rcs_delta *nrdp; |
| 320 | |
| 321 | i = found = 0; |
Value stored to 'i' is never read | |
| 322 | |
| 323 | /* -s states */ |
| 324 | if (runflags & L_STATES0x20) { |
| 325 | sargv = cvs_strsplit(slist, ","); |
| 326 | for (i = 0; sargv->argv[i] != NULL((void *)0); i++) { |
| 327 | if (strcmp(rdp->rd_state, sargv->argv[i]) == 0) { |
| 328 | found++; |
| 329 | break; |
| 330 | } |
| 331 | found = 0; |
| 332 | } |
| 333 | cvs_argv_destroy(sargv); |
| 334 | } |
| 335 | |
| 336 | /* -w[logins] */ |
| 337 | if (runflags & L_LOGINS0x10) { |
| 338 | wargv = cvs_strsplit(wlist, ","); |
| 339 | for (i = 0; wargv->argv[i] != NULL((void *)0); i++) { |
| 340 | if (strcmp(rdp->rd_author, wargv->argv[i]) == 0) { |
| 341 | found++; |
| 342 | break; |
| 343 | } |
| 344 | found = 0; |
| 345 | } |
| 346 | cvs_argv_destroy(wargv); |
| 347 | } |
| 348 | |
| 349 | if ((runflags & (L_STATES0x20|L_LOGINS0x10)) && found == 0) |
| 350 | return; |
| 351 | |
| 352 | cvs_printf("%s\n", LOG_REVSEP"----------------------------"); |
| 353 | |
| 354 | rcsnum_tostr(rdp->rd_num, numb, sizeof(numb)); |
| 355 | cvs_printf("revision %s", numb); |
| 356 | |
| 357 | strftime(timeb, sizeof(timeb), "%Y/%m/%d %H:%M:%S", &rdp->rd_date); |
| 358 | cvs_printf("\ndate: %s; author: %s; state: %s;", |
| 359 | timeb, rdp->rd_author, rdp->rd_state); |
| 360 | |
| 361 | /* |
| 362 | * If we are a branch revision, the diff of this revision is stored |
| 363 | * in place. |
| 364 | * Otherwise, it is stored in the previous revision as a reversed diff. |
| 365 | */ |
| 366 | if (RCSNUM_ISBRANCHREV(rdp->rd_num)(!((rdp->rd_num)->rn_len % 2) && ((rdp->rd_num )->rn_len >= 4))) |
| 367 | nrdp = rdp; |
| 368 | else |
| 369 | nrdp = TAILQ_NEXT(rdp, rd_list)((rdp)->rd_list.tqe_next); |
| 370 | |
| 371 | /* |
| 372 | * We do not write diff stats for the first revision of the default |
| 373 | * branch, since it was not a diff but a full text. |
| 374 | */ |
| 375 | if (nrdp != NULL((void *)0) && rdp->rd_num->rn_len == nrdp->rd_num->rn_len) { |
| 376 | int added, removed; |
| 377 | rcs_delta_stats(nrdp, &added, &removed); |
| 378 | if (RCSNUM_ISBRANCHREV(rdp->rd_num)(!((rdp->rd_num)->rn_len % 2) && ((rdp->rd_num )->rn_len >= 4))) |
| 379 | cvs_printf(" lines: +%d -%d;", added, removed); |
| 380 | else |
| 381 | cvs_printf(" lines: +%d -%d;", removed, added); |
| 382 | } |
| 383 | |
| 384 | if (rdp->rd_commitid != NULL((void *)0)) |
| 385 | printf(" commitid: %s;", rdp->rd_commitid); |
| 386 | |
| 387 | cvs_printf("\n"); |
| 388 | |
| 389 | if (!TAILQ_EMPTY(&(rdp->rd_branches))(((&(rdp->rd_branches))->tqh_first) == ((void *)0))) { |
| 390 | cvs_printf("branches:"); |
| 391 | TAILQ_FOREACH(rb, &(rdp->rd_branches), rb_list)for((rb) = ((&(rdp->rd_branches))->tqh_first); (rb) != ((void *)0); (rb) = ((rb)->rb_list.tqe_next)) { |
| 392 | RCSNUM *branch; |
| 393 | branch = rcsnum_revtobr(rb->rb_num); |
| 394 | rcsnum_tostr(branch, numb, sizeof(numb)); |
| 395 | cvs_printf(" %s;", numb); |
| 396 | free(branch); |
| 397 | } |
| 398 | cvs_printf("\n"); |
| 399 | } |
| 400 | |
| 401 | cvs_printf("%s", rdp->rd_log); |
| 402 | } |
| 403 | |
| 404 | static char * |
| 405 | push_date(char *dest, const char *src) |
| 406 | { |
| 407 | size_t len; |
| 408 | |
| 409 | if (dest == NULL((void *)0)) |
| 410 | return (xstrdup(src)); |
| 411 | |
| 412 | /* 2 = ; and '\0' */ |
| 413 | len = strlen(dest) + strlen(src) + 2; |
| 414 | |
| 415 | dest[strlen(dest)] = ';'; |
| 416 | dest = xreallocarray(dest, len, 1); |
| 417 | strlcat(dest, src, len); |
| 418 | return (dest); |
| 419 | } |
| 420 | |
| 421 | static u_int |
| 422 | date_select(RCSFILE *file, char *date) |
| 423 | { |
| 424 | int i, nrev, flags; |
| 425 | struct rcs_delta *rdp; |
| 426 | struct cvs_argvector *args; |
| 427 | char *first, *last, delim; |
| 428 | time_t firstdate, lastdate, rcsdate; |
| 429 | |
| 430 | nrev = 0; |
| 431 | args = cvs_strsplit(date, ";"); |
| 432 | |
| 433 | for (i = 0; args->argv[i] != NULL((void *)0); i++) { |
| 434 | flags = 0; |
| 435 | firstdate = lastdate = -1; |
| 436 | |
| 437 | first = args->argv[i]; |
| 438 | last = strchr(args->argv[i], '<'); |
| 439 | if (last != NULL((void *)0)) { |
| 440 | delim = *last; |
| 441 | *last++ = '\0'; |
| 442 | |
| 443 | if (*last == '=') { |
| 444 | last++; |
| 445 | flags |= LDATE_INCLUSIVE0x10; |
| 446 | } |
| 447 | } else { |
| 448 | last = strchr(args->argv[i], '>'); |
| 449 | if (last != NULL((void *)0)) { |
| 450 | delim = *last; |
| 451 | *last++ = '\0'; |
| 452 | |
| 453 | if (*last == '=') { |
| 454 | last++; |
| 455 | flags |= LDATE_INCLUSIVE0x10; |
| 456 | } |
| 457 | } |
| 458 | } |
| 459 | |
| 460 | if (last == NULL((void *)0)) { |
| 461 | flags |= LDATE_SINGLE0x04; |
| 462 | if ((firstdate = date_parse(first)) == -1) |
| 463 | return -1; |
| 464 | delim = '\0'; |
| 465 | last = "\0"; |
| 466 | } else { |
| 467 | while (*last && isspace((unsigned char)*last)) |
| 468 | last++; |
| 469 | } |
| 470 | |
| 471 | if (delim == '>' && *last == '\0') { |
| 472 | flags |= LDATE_EARLIER0x02; |
| 473 | if ((firstdate = date_parse(first)) == -1) |
| 474 | return -1; |
| 475 | } |
| 476 | |
| 477 | if (delim == '>' && *first == '\0' && *last != '\0') { |
| 478 | flags |= LDATE_LATER0x01; |
| 479 | if ((firstdate = date_parse(last)) == -1) |
| 480 | return -1; |
| 481 | } |
| 482 | |
| 483 | if (delim == '<' && *last == '\0') { |
| 484 | flags |= LDATE_LATER0x01; |
| 485 | if ((firstdate = date_parse(first)) == -1) |
| 486 | return -1; |
| 487 | } |
| 488 | |
| 489 | if (delim == '<' && *first == '\0' && *last != '\0') { |
| 490 | flags |= LDATE_EARLIER0x02; |
| 491 | if ((firstdate = date_parse(last)) == -1) |
| 492 | return -1; |
| 493 | } |
| 494 | |
| 495 | if (*first != '\0' && *last != '\0') { |
| 496 | flags |= LDATE_RANGE0x08; |
| 497 | |
| 498 | if (delim == '<') { |
| 499 | firstdate = date_parse(first); |
| 500 | lastdate = date_parse(last); |
| 501 | } else { |
| 502 | firstdate = date_parse(last); |
| 503 | lastdate = date_parse(first); |
| 504 | } |
| 505 | if (firstdate == -1 || lastdate == -1) |
| 506 | return -1; |
| 507 | } |
| 508 | |
| 509 | TAILQ_FOREACH(rdp, &(file->rf_delta), rd_list)for((rdp) = ((&(file->rf_delta))->tqh_first); (rdp) != ((void *)0); (rdp) = ((rdp)->rd_list.tqe_next)) { |
| 510 | rcsdate = mktime(&(rdp->rd_date)); |
| 511 | |
| 512 | if (flags & LDATE_SINGLE0x04) { |
| 513 | if (rcsdate <= firstdate) { |
| 514 | rdp->rd_flags |= RCS_RD_SELECT0x02; |
| 515 | nrev++; |
| 516 | break; |
| 517 | } |
| 518 | } |
| 519 | |
| 520 | if (flags & LDATE_EARLIER0x02) { |
| 521 | if (rcsdate < firstdate) { |
| 522 | rdp->rd_flags |= RCS_RD_SELECT0x02; |
| 523 | nrev++; |
| 524 | continue; |
| 525 | } |
| 526 | |
| 527 | if (flags & LDATE_INCLUSIVE0x10 && |
| 528 | (rcsdate <= firstdate)) { |
| 529 | rdp->rd_flags |= RCS_RD_SELECT0x02; |
| 530 | nrev++; |
| 531 | continue; |
| 532 | } |
| 533 | } |
| 534 | |
| 535 | if (flags & LDATE_LATER0x01) { |
| 536 | if (rcsdate > firstdate) { |
| 537 | rdp->rd_flags |= RCS_RD_SELECT0x02; |
| 538 | nrev++; |
| 539 | continue; |
| 540 | } |
| 541 | |
| 542 | if (flags & LDATE_INCLUSIVE0x10 && |
| 543 | (rcsdate >= firstdate)) { |
| 544 | rdp->rd_flags |= RCS_RD_SELECT0x02; |
| 545 | nrev++; |
| 546 | continue; |
| 547 | } |
| 548 | } |
| 549 | |
| 550 | if (flags & LDATE_RANGE0x08) { |
| 551 | if ((rcsdate > firstdate) && |
| 552 | (rcsdate < lastdate)) { |
| 553 | rdp->rd_flags |= RCS_RD_SELECT0x02; |
| 554 | nrev++; |
| 555 | continue; |
| 556 | } |
| 557 | |
| 558 | if (flags & LDATE_INCLUSIVE0x10 && |
| 559 | ((rcsdate >= firstdate) && |
| 560 | (rcsdate <= lastdate))) { |
| 561 | rdp->rd_flags |= RCS_RD_SELECT0x02; |
| 562 | nrev++; |
| 563 | continue; |
| 564 | } |
| 565 | } |
| 566 | } |
| 567 | } |
| 568 | |
| 569 | cvs_argv_destroy(args); |
| 570 | |
| 571 | return (nrev); |
| 572 | } |