co.c revision 1.6
1/* $OpenBSD: co.c,v 1.6 2005/10/05 11:52:16 joris Exp $ */ 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 <stdio.h> 31#include <stdlib.h> 32#include <string.h> 33#include <unistd.h> 34 35#include "log.h" 36#include "rcs.h" 37#include "rcsprog.h" 38 39extern char *__progname; 40 41#define LOCK_LOCK 1 42#define LOCK_UNLOCK 2 43 44int 45checkout_main(int argc, char **argv) 46{ 47 int i, ch; 48 int lock; 49 RCSNUM *frev, *rev; 50 RCSFILE *file; 51 BUF *bp; 52 char buf[16]; 53 char fpath[MAXPATHLEN]; 54 char *username; 55 56 lock = 0; 57 rev = RCS_HEAD_REV; 58 frev = NULL; 59 60 if ((username = getlogin()) == NULL) { 61 cvs_log(LP_ERR, "failed to get username"); 62 exit (1); 63 } 64 65 while ((ch = getopt(argc, argv, "l:qr:u:")) != -1) { 66 switch (ch) { 67 case 'l': 68 if (rev != RCS_HEAD_REV) 69 cvs_log(LP_WARN, 70 "redefinition of revision number"); 71 72 if ((rev = rcsnum_parse(optarg)) == NULL) { 73 cvs_log(LP_ERR, "bad revision number"); 74 exit (1); 75 } 76 77 lock = LOCK_LOCK; 78 break; 79 case 'q': 80 verbose = 0; 81 break; 82 case 'r': 83 if (rev != RCS_HEAD_REV) 84 cvs_log(LP_WARN, 85 "redefinition of revision number"); 86 87 if ((rev = rcsnum_parse(optarg)) == NULL) { 88 cvs_log(LP_ERR, "bad revision number"); 89 exit(1); 90 } 91 92 break; 93 case 'u': 94 lock = LOCK_UNLOCK; 95 if (rev != RCS_HEAD_REV) 96 cvs_log(LP_WARN, 97 "redefinition of revision number"); 98 99 if ((rev = rcsnum_parse(optarg)) == NULL) { 100 cvs_log(LP_ERR, "bad revision number"); 101 exit (1); 102 } 103 104 break; 105 default: 106 (usage)(); 107 exit(1); 108 } 109 } 110 111 argc -= optind; 112 argv += optind; 113 114 if (argc == 0) { 115 cvs_log(LP_ERR, "no input file"); 116 (usage)(); 117 exit (1); 118 } 119 120 for (i = 0; i < argc; i++) { 121 if (rcs_statfile(argv[i], fpath, sizeof(fpath)) < 0) 122 continue; 123 124 if ((file = rcs_open(fpath, RCS_RDWR)) == NULL) 125 continue; 126 127 if (rev == RCS_HEAD_REV) 128 frev = file->rf_head; 129 else 130 frev = rev; 131 132 rcsnum_tostr(frev, buf, sizeof(buf)); 133 134 if ((bp = rcs_getrev(file, frev)) == NULL) { 135 cvs_log(LP_ERR, "cannot find '%s' in %s", buf, fpath); 136 rcs_close(file); 137 continue; 138 } 139 140 if (cvs_buf_write(bp, argv[i], 0644) < 0) { 141 cvs_log(LP_ERR, "failed to write revision to file"); 142 cvs_buf_free(bp); 143 rcs_close(file); 144 continue; 145 } 146 147 cvs_buf_free(bp); 148 149 if (lock == LOCK_LOCK) { 150 if (rcs_lock_add(file, username, frev) < 0) { 151 if (rcs_errno != RCS_ERR_DUPENT) 152 cvs_log(LP_ERR, "failed to lock '%s'", buf); 153 else 154 cvs_log(LP_WARN, "you already have a lock"); 155 } 156 } else if (lock == LOCK_UNLOCK) { 157 if (rcs_lock_remove(file, frev) < 0) { 158 if (rcs_errno != RCS_ERR_NOENT) 159 cvs_log(LP_ERR, 160 "failed to remove lock '%s'", buf); 161 } 162 } 163 164 rcs_close(file); 165 if (verbose) { 166 printf("revision %s ", buf); 167 if (lock == LOCK_LOCK) 168 printf("(locked)"); 169 else if (lock == LOCK_UNLOCK) 170 printf("(unlocked)"); 171 printf("\n"); 172 printf("done\n"); 173 } 174 } 175 176 if (rev != RCS_HEAD_REV) 177 rcsnum_free(frev); 178 179 return (0); 180} 181 182void 183checkout_usage(void) 184{ 185 fprintf(stderr, "usage %s [-r rev] file ...\n", __progname); 186} 187