[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.62

1.62    ! joris       1: /*     $OpenBSD: checkout.c,v 1.61 2006/06/06 06:58:46 xsa 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 **);
1.61      xsa        26: int    cvs_export(int, char **);
                     27: static void checkout_check_repository(int, char **);
1.53      joris      28: static void checkout_repository(const char *, const char *);
1.14      joris      29:
1.54      joris      30: extern int prune_dirs;
1.57      joris      31: extern int build_dirs;
1.54      joris      32:
1.22      jfb        33: struct cvs_cmd cvs_cmd_checkout = {
                     34:        CVS_OP_CHECKOUT, CVS_REQ_CO, "checkout",
                     35:        { "co", "get" },
1.53      joris      36:        "Checkout a working copy of a repository",
1.33      xsa        37:        "[-AcflNnPpRs] [-D date | -r tag] [-d dir] [-j rev] [-k mode] "
1.22      jfb        38:        "[-t id] module ...",
                     39:        "AcD:d:fj:k:lNnPRr:st:",
1.59      joris      40:        NULL,
                     41:        cvs_checkout
                     42: };
                     43:
                     44: struct cvs_cmd cvs_cmd_export = {
                     45:        CVS_OP_EXPORT, CVS_REQ_EXPORT, "export",
                     46:        { "exp", "ex" },
                     47:        "Export sources from CVS, similar to checkout",
1.61      xsa        48:        "[-flNnR] [-d dir] [-k mode] -D date | -r rev module ...",
                     49:        "D:d:k:flNnRr:",
1.22      jfb        50:        NULL,
1.61      xsa        51:        cvs_export
1.33      xsa        52: };
                     53:
1.53      joris      54: int
                     55: cvs_checkout(int argc, char **argv)
1.1       jfb        56: {
1.61      xsa        57:        int ch;
1.13      jfb        58:
1.53      joris      59:        while ((ch = getopt(argc, argv, cvs_cmd_checkout.cmd_opts)) != -1) {
1.1       jfb        60:                switch (ch) {
1.54      joris      61:                case 'P':
                     62:                        prune_dirs = 1;
                     63:                        break;
1.1       jfb        64:                default:
1.53      joris      65:                        fatal("%s", cvs_cmd_checkout.cmd_synopsis);
1.1       jfb        66:                }
                     67:        }
                     68:
                     69:        argc -= optind;
                     70:        argv += optind;
                     71:
1.53      joris      72:        if (argc == 0)
                     73:                fatal("%s", cvs_cmd_checkout.cmd_synopsis);
1.22      jfb        74:
1.61      xsa        75:        checkout_check_repository(argc, argv);
                     76:
                     77:        return (0);
                     78: }
                     79:
                     80: int
                     81: cvs_export(int argc, char **argv)
                     82: {
                     83:        int ch, flags;
                     84:
                     85:        prune_dirs = 1;
                     86:        flags = CR_RECURSE_DIRS;
                     87:
                     88:        while ((ch = getopt(argc, argv, cvs_cmd_export.cmd_opts)) != -1) {
                     89:                switch (ch) {
                     90:                case 'l':
                     91:                        flags &= ~CR_RECURSE_DIRS;
                     92:                        break;
                     93:                case 'R':
                     94:                        break;
                     95:                default:
                     96:                        fatal("%s", cvs_cmd_export.cmd_synopsis);
                     97:                }
                     98:        }
                     99:
                    100:        argc -= optind;
                    101:        argv += optind;
                    102:
                    103:        if (argc == 0)
                    104:                fatal("%s", cvs_cmd_export.cmd_synopsis);
                    105:
                    106:        checkout_check_repository(argc, argv);
                    107:
                    108:        return (0);
                    109: }
                    110:
                    111: static void
                    112: checkout_check_repository(int argc, char **argv)
                    113: {
                    114:        int i, l;
                    115:        char repo[MAXPATHLEN];
                    116:        struct stat st;
                    117:
1.53      joris     118:        for (i = 0; i < argc; i++) {
                    119:                cvs_mkpath(argv[i]);
1.1       jfb       120:
1.53      joris     121:                l = snprintf(repo, sizeof(repo), "%s/%s",
                    122:                    current_cvsroot->cr_dir, argv[i]);
                    123:                if (l == -1 || l >= (int)sizeof(repo))
1.61      xsa       124:                        fatal("checkout_check_repository: overflow");
1.13      jfb       125:
1.53      joris     126:                if (stat(repo, &st) == -1) {
                    127:                        cvs_log(LP_ERR, "cannot find repository %s - ignored",
                    128:                            argv[i]);
                    129:                        continue;
                    130:                }
                    131:
                    132:                checkout_repository(repo, argv[i]);
1.33      xsa       133:        }
1.14      joris     134: }
1.9       jfb       135:
1.53      joris     136: static void
                    137: checkout_repository(const char *repobase, const char *wdbase)
1.14      joris     138: {
1.53      joris     139:        struct cvs_flisthead fl, dl;
                    140:        struct cvs_recursion cr;
                    141:
                    142:        TAILQ_INIT(&fl);
                    143:        TAILQ_INIT(&dl);
1.41      joris     144:
1.57      joris     145:        build_dirs = 1;
1.53      joris     146:        cr.enterdir = cvs_update_enterdir;
1.54      joris     147:        cr.leavedir = cvs_update_leavedir;
1.53      joris     148:        cr.local = cvs_update_local;
                    149:        cr.remote = NULL;
1.56      joris     150:        cr.flags = CR_REPO | CR_RECURSE_DIRS;
1.41      joris     151:
1.53      joris     152:        cvs_repository_lock(repobase);
1.56      joris     153:        cvs_repository_getdir(repobase, wdbase, &fl, &dl, 1);
1.1       jfb       154:
1.53      joris     155:        cvs_file_walklist(&fl, &cr);
                    156:        cvs_file_freelist(&fl);
1.23      joris     157:
1.53      joris     158:        cvs_repository_unlock(repobase);
1.23      joris     159:
1.53      joris     160:        cvs_file_walklist(&dl, &cr);
                    161:        cvs_file_freelist(&dl);
                    162: }
1.23      joris     163:
1.58      joris     164: void
                    165: cvs_checkout_file(struct cvs_file *cf, RCSNUM *rnum, BUF *bp, int flags)
1.53      joris     166: {
1.58      joris     167:        BUF *nbp;
1.53      joris     168:        int l, oflags, exists;
                    169:        time_t rcstime;
                    170:        CVSENTRIES *ent;
                    171:        struct timeval tv[2];
1.60      joris     172:        char *entry, rev[16], timebuf[64], tbuf[32], stickytag[32];
1.22      jfb       173:
1.53      joris     174:        rcsnum_tostr(rnum, rev, sizeof(rev));
1.41      joris     175:
1.53      joris     176:        cvs_log(LP_TRACE, "cvs_checkout_file(%s, %s, %d)",
                    177:            cf->file_path, rev, flags);
1.42      joris     178:
1.58      joris     179:        nbp = rcs_kwexp_buf(bp, cf->file_rcs, rnum);
1.42      joris     180:
1.53      joris     181:        oflags = O_WRONLY | O_TRUNC;
                    182:        if (cf->fd != -1) {
                    183:                exists = 1;
                    184:                (void)close(cf->fd);
                    185:        } else  {
                    186:                exists = 0;
                    187:                oflags |= O_CREAT;
                    188:        }
1.22      jfb       189:
1.53      joris     190:        cf->fd = open(cf->file_path, oflags);
                    191:        if (cf->fd == -1)
                    192:                fatal("cvs_checkout_file: open: %s", strerror(errno));
1.22      jfb       193:
1.58      joris     194:        if (cvs_buf_write_fd(nbp, cf->fd) == -1)
1.53      joris     195:                fatal("cvs_checkout_file: %s", strerror(errno));
1.42      joris     196:
1.58      joris     197:        cvs_buf_free(nbp);
1.42      joris     198:
1.53      joris     199:        if (fchmod(cf->fd, 0644) == -1)
                    200:                fatal("cvs_checkout_file: fchmod: %s", strerror(errno));
1.41      joris     201:
1.53      joris     202:        if (exists == 0) {
                    203:                rcstime = rcs_rev_getdate(cf->file_rcs, rnum);
1.62    ! joris     204:                rcstime = cvs_hack_time(rcstime, 0);
1.53      joris     205:        } else {
                    206:                time(&rcstime);
1.41      joris     207:        }
                    208:
1.53      joris     209:        tv[0].tv_sec = rcstime;
                    210:        tv[0].tv_usec = 0;
                    211:        tv[1] = tv[0];
                    212:        if (futimes(cf->fd, tv) == -1)
                    213:                fatal("cvs_checkout_file: futimes: %s", strerror(errno));
1.45      xsa       214:
1.62    ! joris     215:        rcstime = cvs_hack_time(rcstime, 1);
1.41      joris     216:
1.58      joris     217:        ctime_r(&rcstime, tbuf);
                    218:        if (tbuf[strlen(tbuf) - 1] == '\n')
                    219:                tbuf[strlen(tbuf) - 1] = '\0';
                    220:
                    221:        if (flags & CO_MERGE) {
                    222:                l = snprintf(timebuf, sizeof(timebuf), "Result of merge+%s",
                    223:                    tbuf);
                    224:                if (l == -1 || l >= (int)sizeof(timebuf))
                    225:                        fatal("cvs_checkout_file: overflow");
                    226:        } else {
                    227:                strlcpy(timebuf, tbuf, sizeof(timebuf));
                    228:        }
1.41      joris     229:
1.60      joris     230:        if (flags & CO_SETSTICKY) {
                    231:                l = snprintf(stickytag, sizeof(stickytag), "T%s", rev);
                    232:                if (l == -1 || l >= (int)sizeof(stickytag))
                    233:                        fatal("cvs_checkout_file: overflow");
                    234:        } else {
                    235:                stickytag[0] = '\0';
                    236:        }
                    237:
1.53      joris     238:        entry = xmalloc(CVS_ENT_MAXLINELEN);
1.60      joris     239:        l = snprintf(entry, CVS_ENT_MAXLINELEN, "/%s/%s/%s//%s", cf->file_name,
                    240:            rev, timebuf, stickytag);
1.41      joris     241:
1.53      joris     242:        ent = cvs_ent_open(cf->file_wd);
                    243:        cvs_ent_add(ent, entry);
                    244:        cvs_ent_close(ent, ENT_SYNC);
1.41      joris     245:
1.53      joris     246:        xfree(entry);
1.1       jfb       247: }