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

Annotation of src/usr.bin/cvs/tag.c, Revision 1.43

1.43    ! deraadt     1: /*     $OpenBSD: tag.c,v 1.42 2006/04/12 14:09:11 xsa Exp $    */
1.1       jfb         2: /*
                      3:  * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org>
1.5       joris       4:  * Copyright (c) 2004 Joris Vink <joris@openbsd.org>
1.40      xsa         5:  * Copyright (c) 2005, 2006 Xavier Santolaria <xsa@openbsd.org>
1.1       jfb         6:  * All rights reserved.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  *
                     12:  * 1. Redistributions of source code must retain the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer.
                     14:  * 2. The name of the author may not be used to endorse or promote products
                     15:  *    derived from this software without specific prior written permission.
                     16:  *
                     17:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
                     18:  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
                     19:  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
                     20:  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
                     21:  * EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLUDING, BUT NOT LIMITED TO,
                     22:  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
                     23:  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
                     24:  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
                     25:  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
                     26:  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     27:  */
                     28:
1.36      xsa        29: #include "includes.h"
1.1       jfb        30:
                     31: #include "cvs.h"
                     32: #include "log.h"
                     33: #include "proto.h"
                     34:
1.40      xsa        35: #define TAG_BRANCH     (1<<0)
                     36: #define TAG_DELETE     (1<<1)
                     37: #define TAG_FORCE_HEAD (1<<2)
                     38: #define TAG_FORCE_RM   (1<<3)
                     39: #define UPTODATE       (1<<4)
1.1       jfb        40:
1.28      xsa        41: static int     cvs_tag_init(struct cvs_cmd *, int, char **, int *);
                     42: static int     cvs_tag_local(CVSFILE *, void *);
                     43: static int     cvs_tag_remote(CVSFILE *, void *);
                     44: static int     cvs_tag_pre_exec(struct cvsroot *);
1.14      jfb        45:
1.40      xsa        46: static int runflags = 0;
1.14      jfb        47: static char *tag_name = NULL;
                     48: static char *tag_date = NULL;
                     49: static char *tag_oldname = NULL;
1.7       joris      50:
1.17      jfb        51: struct cvs_cmd cvs_cmd_tag = {
                     52:        CVS_OP_TAG, CVS_REQ_TAG, "tag",
                     53:        { "ta", "freeze" },
                     54:        "Add a symbolic tag to checked out version of files",
1.40      xsa        55:        "[-bcdFflR] [-D date | -r rev] tag [file ...]",
1.17      jfb        56:        "bcD:dFflRr:",
                     57:        NULL,
1.7       joris      58:        CF_SORT | CF_IGNORE | CF_RECURSE,
1.17      jfb        59:        cvs_tag_init,
                     60:        cvs_tag_pre_exec,
                     61:        cvs_tag_remote,
                     62:        cvs_tag_local,
                     63:        NULL,
                     64:        NULL,
                     65:        CVS_CMD_ALLOWSPEC | CVS_CMD_SENDDIR
                     66: };
                     67:
                     68:
                     69: struct cvs_cmd cvs_cmd_rtag = {
                     70:        CVS_OP_RTAG, CVS_REQ_TAG, "rtag",
1.30      xsa        71:        { "rt", "rfreeze" },
1.17      jfb        72:        "Add a symbolic tag to a module",
1.40      xsa        73:        "[-abdFflnR] [-D date | -r rev] tag modules ...",
1.21      xsa        74:        "abD:fFflnRr:",
1.17      jfb        75:        NULL,
                     76:        CF_SORT | CF_IGNORE | CF_RECURSE,
                     77:        cvs_tag_init,
                     78:        cvs_tag_pre_exec,
                     79:        cvs_tag_remote,
                     80:        cvs_tag_local,
                     81:        NULL,
                     82:        NULL,
1.14      jfb        83:        CVS_CMD_ALLOWSPEC | CVS_CMD_SENDDIR
1.7       joris      84: };
1.1       jfb        85:
1.14      jfb        86: static int
1.17      jfb        87: cvs_tag_init(struct cvs_cmd *cmd, int argc, char **argv, int *arg)
1.1       jfb        88: {
1.7       joris      89:        int ch;
1.1       jfb        90:
1.14      jfb        91:        tag_date = tag_oldname = NULL;
1.1       jfb        92:
1.17      jfb        93:        while ((ch = getopt(argc, argv, cmd->cmd_opts)) != -1) {
1.1       jfb        94:                switch (ch) {
                     95:                case 'b':
1.40      xsa        96:                        runflags |= TAG_BRANCH;
                     97:                        break;
                     98:                case 'c':
                     99:                        runflags |= UPTODATE;
1.1       jfb       100:                        break;
                    101:                case 'd':
1.40      xsa       102:                        runflags |= TAG_DELETE;
1.14      jfb       103:                        break;
1.21      xsa       104:                case 'F':
1.40      xsa       105:                        runflags |= TAG_FORCE_RM;
1.21      xsa       106:                        break;
1.14      jfb       107:                case 'f':
1.40      xsa       108:                        runflags |= TAG_FORCE_HEAD;
1.1       jfb       109:                        break;
1.3       jfb       110:                case 'D':
1.14      jfb       111:                        tag_date = optarg;
1.3       jfb       112:                        break;
1.1       jfb       113:                case 'l':
1.17      jfb       114:                        cmd->file_flags &= ~CF_RECURSE;
                    115:                        break;
                    116:                case 'R':
                    117:                        cmd->file_flags |= CF_RECURSE;
1.1       jfb       118:                        break;
                    119:                case 'r':
1.14      jfb       120:                        tag_oldname = optarg;
1.1       jfb       121:                        break;
                    122:                default:
1.11      joris     123:                        return (CVS_EX_USAGE);
1.1       jfb       124:                }
                    125:        }
                    126:
1.7       joris     127:        *arg = optind;
1.1       jfb       128:        argc -= optind;
                    129:        argv += optind;
                    130:
1.40      xsa       131:        if (argc == 0)
1.11      joris     132:                return (CVS_EX_USAGE);
1.40      xsa       133:        else {
1.14      jfb       134:                tag_name = argv[0];
1.1       jfb       135:                argc--;
                    136:                argv++;
1.7       joris     137:                *arg += 1;
1.15      jfb       138:        }
                    139:
1.38      xsa       140:        if (!rcs_sym_check(tag_name))
                    141:                fatal("tag `%s' must not contain the characters `%s'",
1.15      jfb       142:                    tag_name, RCS_SYM_INVALCHAR);
1.1       jfb       143:
1.40      xsa       144:        if ((runflags & TAG_BRANCH) && (runflags & TAG_DELETE)) {
1.1       jfb       145:                cvs_log(LP_WARN, "ignoring -b with -d options");
1.41      deraadt   146:                runflags &= ~TAG_BRANCH;
1.1       jfb       147:        }
                    148:
1.43    ! deraadt   149:        if ((runflags & TAG_DELETE) && tag_oldname != NULL)
1.14      jfb       150:                tag_oldname = NULL;
1.1       jfb       151:
1.43    ! deraadt   152:        if ((runflags & TAG_DELETE) && tag_date != NULL)
1.14      jfb       153:                tag_date = NULL;
1.3       jfb       154:
1.43    ! deraadt   155:        if ((tag_oldname != NULL) && tag_date != NULL) {
1.20      xsa       156:                cvs_log(LP_ERR, "the -D and -r options are mutually exclusive");
1.11      joris     157:                return (CVS_EX_USAGE);
1.3       jfb       158:        }
                    159:
1.7       joris     160:        return (0);
                    161: }
                    162:
1.14      jfb       163: static int
1.17      jfb       164: cvs_tag_pre_exec(struct cvsroot *root)
1.7       joris     165: {
1.17      jfb       166:        if (root->cr_method != CVS_METHOD_LOCAL) {
1.40      xsa       167:                if (runflags & TAG_BRANCH)
1.35      joris     168:                        cvs_sendarg(root, "-b", 0);
1.17      jfb       169:
1.40      xsa       170:                if (runflags & UPTODATE)
                    171:                        cvs_sendarg(root, "-c", 0);
                    172:
                    173:                if (runflags & TAG_DELETE)
1.35      joris     174:                        cvs_sendarg(root, "-d", 0);
1.7       joris     175:
1.40      xsa       176:                if (runflags & TAG_FORCE_RM)
1.35      joris     177:                        cvs_sendarg(root, "-F", 0);
1.21      xsa       178:
1.40      xsa       179:                if (runflags & TAG_FORCE_HEAD)
1.35      joris     180:                        cvs_sendarg(root, "-f", 0);
1.21      xsa       181:
1.35      joris     182:                if (tag_oldname != NULL) {
                    183:                        cvs_sendarg(root, "-r", 0);
                    184:                        cvs_sendarg(root, tag_oldname, 0);
                    185:                }
1.1       jfb       186:
1.35      joris     187:                if (tag_date != NULL) {
                    188:                        cvs_sendarg(root, "-D", 0);
                    189:                        cvs_sendarg(root, tag_date, 0);
                    190:                }
1.1       jfb       191:
1.35      joris     192:                cvs_sendarg(root, tag_name, 0);
1.1       jfb       193:        }
                    194:        return (0);
                    195: }
                    196:
                    197:
                    198: /*
1.14      jfb       199:  * cvs_tag_remote()
1.1       jfb       200:  *
                    201:  * Get the status of a single file.
                    202:  */
1.14      jfb       203: static int
                    204: cvs_tag_remote(CVSFILE *cfp, void *arg)
1.1       jfb       205: {
1.14      jfb       206:        char fpath[MAXPATHLEN];
1.1       jfb       207:        struct cvsroot *root;
                    208:
                    209:        root = CVS_DIR_ROOT(cfp);
                    210:
1.14      jfb       211:        if (cfp->cf_type == DT_DIR) {
1.35      joris     212:                cvs_senddir(root, cfp);
                    213:                return (0);
1.1       jfb       214:        }
                    215:
1.35      joris     216:        cvs_sendentry(root, cfp);
1.1       jfb       217:        cvs_file_getpath(cfp, fpath, sizeof(fpath));
                    218:
1.14      jfb       219:        switch (cfp->cf_cvstat) {
                    220:        case CVS_FST_UNKNOWN:
1.35      joris     221:                cvs_sendreq(root, CVS_REQ_QUESTIONABLE, cfp->cf_name);
1.14      jfb       222:                break;
                    223:        case CVS_FST_UPTODATE:
1.35      joris     224:                cvs_sendreq(root, CVS_REQ_UNCHANGED, cfp->cf_name);
1.14      jfb       225:                break;
                    226:        case CVS_FST_MODIFIED:
1.35      joris     227:                cvs_sendreq(root, CVS_REQ_ISMODIFIED, cfp->cf_name);
1.42      xsa       228:                break;
1.14      jfb       229:        default:
                    230:                break;
                    231:        }
                    232:
1.35      joris     233:        return (0);
1.14      jfb       234: }
                    235:
                    236:
                    237: static int
                    238: cvs_tag_local(CVSFILE *cf, void *arg)
                    239: {
1.39      xsa       240:        char fpath[MAXPATHLEN], numbuf[64], rcspath[MAXPATHLEN];
1.14      jfb       241:        RCSFILE *rf;
                    242:        RCSNUM *tag_rev;
                    243:
                    244:        cvs_file_getpath(cf, fpath, sizeof(fpath));
                    245:
1.17      jfb       246:        if (cf->cf_type == DT_DIR) {
1.23      xsa       247:                if (verbosity > 1)
1.29      xsa       248:                        cvs_log(LP_NOTICE, "%s %s",
1.40      xsa       249:                            (runflags & TAG_DELETE) ? "Untagging" : "Tagging",
                    250:                            fpath);
1.17      jfb       251:                return (CVS_EX_OK);
                    252:        }
                    253:
1.14      jfb       254:        if (cf->cf_cvstat == CVS_FST_UNKNOWN) {
1.26      xsa       255:                if (verbosity > 1)
                    256:                        cvs_log(LP_WARN, "nothing known about %s", fpath);
1.33      xsa       257:                return (0);
                    258:        } else if (cf->cf_cvstat == CVS_FST_ADDED) {
                    259:                if (verbosity > 1)
                    260:                        cvs_log(LP_WARN,
                    261:                            "couldn't tag added but un-commited file `%s'",
                    262:                            fpath);
                    263:                return (0);
                    264:        } else if (cf->cf_cvstat == CVS_FST_REMOVED) {
                    265:                if (verbosity > 1)
                    266:                        cvs_log(LP_WARN,
                    267:                            "skipping removed but un-commited file `%s'",
                    268:                            fpath);
1.14      jfb       269:                return (0);
                    270:        }
1.1       jfb       271:
1.17      jfb       272:        tag_rev = cf->cf_lrev;
1.1       jfb       273:
1.34      xsa       274:        cvs_rcs_getpath(cf, rcspath, sizeof(rcspath));
1.1       jfb       275:
1.37      xsa       276:        if ((rf = rcs_open(rcspath, RCS_READ|RCS_WRITE)) == NULL)
                    277:                fatal("cvs_tag_local: rcs_open: %s: %s", rcspath,
1.14      jfb       278:                    rcs_errstr(rcs_errno));
1.32      xsa       279:
1.40      xsa       280:        if (runflags & TAG_DELETE) {
1.39      xsa       281:                if (cvs_noexec == 0) {
                    282:                        if (rcs_sym_remove(rf, tag_name) < 0)
                    283:                                fatal("failed to remove tag %s from %s",
                    284:                                    tag_name, rcspath);
                    285:                }
                    286:
1.32      xsa       287:                if (verbosity > 0)
                    288:                        cvs_printf("D %s\n", fpath);
                    289:
1.39      xsa       290:                rcs_close(rf);
1.32      xsa       291:                return (0);
1.14      jfb       292:        }
1.1       jfb       293:
1.27      xsa       294:        if (cvs_noexec == 0) {
1.39      xsa       295:                if (rcs_sym_add(rf, tag_name, tag_rev) < 0) {
                    296:                        rcsnum_tostr(tag_rev, numbuf, sizeof(numbuf));
                    297:                        fatal("failed to set tag %s to revision %s in %s",
                    298:                            tag_name, numbuf, rcspath);
                    299:                }
1.1       jfb       300:        }
1.17      jfb       301:
1.24      xsa       302:        if (verbosity > 0)
                    303:                cvs_printf("T %s\n", fpath);
1.1       jfb       304:
1.14      jfb       305:        rcs_close(rf);
                    306:        return (0);
1.1       jfb       307: }