[BACK]Return to checkout.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / cvs

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: }