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