Annotation of src/usr.bin/cvs/checkout.c, Revision 1.57
1.57 ! joris 1: /* $OpenBSD: checkout.c,v 1.56 2006/05/27 15:14:27 joris Exp $ */
1.1 jfb 2: /*
1.53 joris 3: * Copyright (c) 2006 Joris Vink <joris@openbsd.org>
1.1 jfb 4: *
1.53 joris 5: * Permission to use, copy, modify, and distribute this software for any
6: * purpose with or without fee is hereby granted, provided that the above
7: * copyright notice and this permission notice appear in all copies.
1.1 jfb 8: *
1.53 joris 9: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1.1 jfb 16: */
17:
1.44 xsa 18: #include "includes.h"
1.1 jfb 19:
20: #include "cvs.h"
21: #include "log.h"
1.53 joris 22: #include "diff.h"
1.5 jfb 23: #include "proto.h"
1.1 jfb 24:
1.53 joris 25: int cvs_checkout(int, char **);
26: static void checkout_repository(const char *, const char *);
1.14 joris 27:
1.54 joris 28: extern int prune_dirs;
1.57 ! joris 29: extern int build_dirs;
1.54 joris 30:
1.22 jfb 31: struct cvs_cmd cvs_cmd_checkout = {
32: CVS_OP_CHECKOUT, CVS_REQ_CO, "checkout",
33: { "co", "get" },
1.53 joris 34: "Checkout a working copy of a repository",
1.33 xsa 35: "[-AcflNnPpRs] [-D date | -r tag] [-d dir] [-j rev] [-k mode] "
1.22 jfb 36: "[-t id] module ...",
37: "AcD:d:fj:k:lNnPRr:st:",
38: NULL,
1.53 joris 39: cvs_checkout
1.33 xsa 40: };
41:
1.53 joris 42: int
43: cvs_checkout(int argc, char **argv)
1.1 jfb 44: {
1.53 joris 45: int i, ch, l;
46: struct stat st;
47: char repo[MAXPATHLEN];
1.13 jfb 48:
1.53 joris 49: while ((ch = getopt(argc, argv, cvs_cmd_checkout.cmd_opts)) != -1) {
1.1 jfb 50: switch (ch) {
1.54 joris 51: case 'P':
52: prune_dirs = 1;
53: break;
1.1 jfb 54: default:
1.53 joris 55: fatal("%s", cvs_cmd_checkout.cmd_synopsis);
1.1 jfb 56: }
57: }
58:
59: argc -= optind;
60: argv += optind;
61:
1.53 joris 62: if (argc == 0)
63: fatal("%s", cvs_cmd_checkout.cmd_synopsis);
1.22 jfb 64:
1.53 joris 65: for (i = 0; i < argc; i++) {
66: cvs_mkpath(argv[i]);
1.1 jfb 67:
1.53 joris 68: l = snprintf(repo, sizeof(repo), "%s/%s",
69: current_cvsroot->cr_dir, argv[i]);
70: if (l == -1 || l >= (int)sizeof(repo))
71: fatal("cvs_checkout: overflow");
1.13 jfb 72:
1.53 joris 73: if (stat(repo, &st) == -1) {
74: cvs_log(LP_ERR, "cannot find repository %s - ignored",
75: argv[i]);
76: continue;
77: }
78:
79: checkout_repository(repo, argv[i]);
1.33 xsa 80: }
81:
1.14 joris 82: return (0);
83: }
1.9 jfb 84:
1.53 joris 85: static void
86: checkout_repository(const char *repobase, const char *wdbase)
1.14 joris 87: {
1.53 joris 88: struct cvs_flisthead fl, dl;
89: struct cvs_recursion cr;
90:
91: TAILQ_INIT(&fl);
92: TAILQ_INIT(&dl);
1.41 joris 93:
1.57 ! joris 94: build_dirs = 1;
1.53 joris 95: cr.enterdir = cvs_update_enterdir;
1.54 joris 96: cr.leavedir = cvs_update_leavedir;
1.53 joris 97: cr.local = cvs_update_local;
98: cr.remote = NULL;
1.56 joris 99: cr.flags = CR_REPO | CR_RECURSE_DIRS;
1.41 joris 100:
1.53 joris 101: cvs_repository_lock(repobase);
1.56 joris 102: cvs_repository_getdir(repobase, wdbase, &fl, &dl, 1);
1.1 jfb 103:
1.53 joris 104: cvs_file_walklist(&fl, &cr);
105: cvs_file_freelist(&fl);
1.23 joris 106:
1.53 joris 107: cvs_repository_unlock(repobase);
1.23 joris 108:
1.53 joris 109: cvs_file_walklist(&dl, &cr);
110: cvs_file_freelist(&dl);
111: }
1.23 joris 112:
1.53 joris 113: int
114: cvs_checkout_file(struct cvs_file *cf, RCSNUM *rnum, int flags)
115: {
116: BUF *bp;
117: int l, oflags, exists;
118: time_t rcstime;
119: CVSENTRIES *ent;
120: struct timeval tv[2];
121: char *entry, rev[16], timebuf[32];
1.22 jfb 122:
1.53 joris 123: rcsnum_tostr(rnum, rev, sizeof(rev));
1.41 joris 124:
1.53 joris 125: cvs_log(LP_TRACE, "cvs_checkout_file(%s, %s, %d)",
126: cf->file_path, rev, flags);
1.42 joris 127:
1.53 joris 128: if ((bp = rcs_getrev(cf->file_rcs, rnum)) == NULL) {
129: cvs_log(LP_ERR, "%s: cannot find revision %s",
130: cf->file_path, rev);
131: return (0);
132: }
1.55 joris 133:
134: bp = rcs_kwexp_buf(bp, cf->file_rcs, rnum);
1.42 joris 135:
1.53 joris 136: oflags = O_WRONLY | O_TRUNC;
137: if (cf->fd != -1) {
138: exists = 1;
139: (void)close(cf->fd);
140: } else {
141: exists = 0;
142: oflags |= O_CREAT;
143: }
1.22 jfb 144:
1.53 joris 145: cf->fd = open(cf->file_path, oflags);
146: if (cf->fd == -1)
147: fatal("cvs_checkout_file: open: %s", strerror(errno));
1.22 jfb 148:
1.53 joris 149: if (cvs_buf_write_fd(bp, cf->fd) == -1)
150: fatal("cvs_checkout_file: %s", strerror(errno));
1.42 joris 151:
1.53 joris 152: cvs_buf_free(bp);
1.42 joris 153:
1.53 joris 154: if (fchmod(cf->fd, 0644) == -1)
155: fatal("cvs_checkout_file: fchmod: %s", strerror(errno));
1.41 joris 156:
1.53 joris 157: if (exists == 0) {
158: rcstime = rcs_rev_getdate(cf->file_rcs, rnum);
159: if ((rcstime = cvs_hack_time(rcstime, 0)) == 0)
160: fatal("cvs_checkout_file: time conversion failed");
161: } else {
162: time(&rcstime);
1.41 joris 163: }
164:
1.53 joris 165: tv[0].tv_sec = rcstime;
166: tv[0].tv_usec = 0;
167: tv[1] = tv[0];
168: if (futimes(cf->fd, tv) == -1)
169: fatal("cvs_checkout_file: futimes: %s", strerror(errno));
1.45 xsa 170:
1.53 joris 171: if ((rcstime = cvs_hack_time(rcstime, 1)) == 0)
172: fatal("cvs_checkout_file: to gmt failed");
1.41 joris 173:
1.53 joris 174: ctime_r(&rcstime, timebuf);
175: if (timebuf[strlen(timebuf) - 1] == '\n')
176: timebuf[strlen(timebuf) - 1] = '\0';
1.41 joris 177:
1.53 joris 178: entry = xmalloc(CVS_ENT_MAXLINELEN);
179: l = snprintf(entry, CVS_ENT_MAXLINELEN, "/%s/%s/%s//", cf->file_name,
180: rev, timebuf);
1.41 joris 181:
1.53 joris 182: ent = cvs_ent_open(cf->file_wd);
183: cvs_ent_add(ent, entry);
184: cvs_ent_close(ent, ENT_SYNC);
1.41 joris 185:
1.53 joris 186: xfree(entry);
1.41 joris 187:
1.53 joris 188: return (1);
1.1 jfb 189: }