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

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