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

1.36    ! xsa         1: /*     $OpenBSD: tag.c,v 1.35 2005/12/30 02:03:28 joris 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:
                    134:        if (!rcs_sym_check(tag_name)) {
                    135:                cvs_log(LP_ABORT,
                    136:                    "tag `%s' must not contain the characters `%s'",
                    137:                    tag_name, RCS_SYM_INVALCHAR);
                    138:                return (CVS_EX_BADTAG);
1.1       jfb       139:        }
                    140:
1.31      xsa       141:        if ((tag_branch == 1) && (tag_delete == 1)) {
1.1       jfb       142:                cvs_log(LP_WARN, "ignoring -b with -d options");
1.14      jfb       143:                tag_branch = 0;
1.1       jfb       144:        }
                    145:
1.31      xsa       146:        if ((tag_delete == 1) && (tag_oldname != NULL))
1.14      jfb       147:                tag_oldname = NULL;
1.1       jfb       148:
1.31      xsa       149:        if ((tag_delete == 1) && (tag_date != NULL))
1.14      jfb       150:                tag_date = NULL;
1.3       jfb       151:
1.31      xsa       152:        if ((tag_oldname != NULL) && (tag_date != NULL)) {
1.20      xsa       153:                cvs_log(LP_ERR, "the -D and -r options are mutually exclusive");
1.11      joris     154:                return (CVS_EX_USAGE);
1.3       jfb       155:        }
                    156:
1.7       joris     157:        return (0);
                    158: }
                    159:
1.14      jfb       160: static int
1.17      jfb       161: cvs_tag_pre_exec(struct cvsroot *root)
1.7       joris     162: {
1.17      jfb       163:        if (root->cr_method != CVS_METHOD_LOCAL) {
1.35      joris     164:                if (tag_branch == 1)
                    165:                        cvs_sendarg(root, "-b", 0);
1.17      jfb       166:
1.35      joris     167:                if (tag_delete == 1)
                    168:                        cvs_sendarg(root, "-d", 0);
1.7       joris     169:
1.35      joris     170:                if (tag_forcemove == 1)
                    171:                        cvs_sendarg(root, "-F", 0);
1.21      xsa       172:
1.35      joris     173:                if (tag_forcehead == 1)
                    174:                        cvs_sendarg(root, "-f", 0);
1.21      xsa       175:
1.35      joris     176:                if (tag_oldname != NULL) {
                    177:                        cvs_sendarg(root, "-r", 0);
                    178:                        cvs_sendarg(root, tag_oldname, 0);
                    179:                }
1.1       jfb       180:
1.35      joris     181:                if (tag_date != NULL) {
                    182:                        cvs_sendarg(root, "-D", 0);
                    183:                        cvs_sendarg(root, tag_date, 0);
                    184:                }
1.1       jfb       185:
1.35      joris     186:                cvs_sendarg(root, tag_name, 0);
1.1       jfb       187:        }
1.7       joris     188:
1.1       jfb       189:        return (0);
                    190: }
                    191:
                    192:
                    193: /*
1.14      jfb       194:  * cvs_tag_remote()
1.1       jfb       195:  *
                    196:  * Get the status of a single file.
                    197:  */
1.14      jfb       198: static int
                    199: cvs_tag_remote(CVSFILE *cfp, void *arg)
1.1       jfb       200: {
1.14      jfb       201:        char fpath[MAXPATHLEN];
1.1       jfb       202:        struct cvsroot *root;
                    203:
                    204:        root = CVS_DIR_ROOT(cfp);
                    205:
1.14      jfb       206:        if (cfp->cf_type == DT_DIR) {
1.35      joris     207:                cvs_senddir(root, cfp);
                    208:                return (0);
1.1       jfb       209:        }
                    210:
1.35      joris     211:        cvs_sendentry(root, cfp);
1.1       jfb       212:        cvs_file_getpath(cfp, fpath, sizeof(fpath));
                    213:
1.14      jfb       214:        switch (cfp->cf_cvstat) {
                    215:        case CVS_FST_UNKNOWN:
1.35      joris     216:                cvs_sendreq(root, CVS_REQ_QUESTIONABLE, cfp->cf_name);
1.14      jfb       217:                break;
                    218:        case CVS_FST_UPTODATE:
1.35      joris     219:                cvs_sendreq(root, CVS_REQ_UNCHANGED, cfp->cf_name);
1.14      jfb       220:                break;
                    221:        case CVS_FST_MODIFIED:
1.35      joris     222:                cvs_sendreq(root, CVS_REQ_ISMODIFIED, cfp->cf_name);
1.14      jfb       223:        default:
                    224:                break;
                    225:        }
                    226:
1.35      joris     227:        return (0);
1.14      jfb       228: }
                    229:
                    230:
                    231: static int
                    232: cvs_tag_local(CVSFILE *cf, void *arg)
                    233: {
1.25      xsa       234:        char fpath[MAXPATHLEN], rcspath[MAXPATHLEN];
1.14      jfb       235:        RCSFILE *rf;
                    236:        RCSNUM *tag_rev;
                    237:
                    238:        cvs_file_getpath(cf, fpath, sizeof(fpath));
                    239:
1.17      jfb       240:        if (cf->cf_type == DT_DIR) {
1.23      xsa       241:                if (verbosity > 1)
1.29      xsa       242:                        cvs_log(LP_NOTICE, "%s %s",
1.23      xsa       243:                            tag_delete ? "Untagging" : "Tagging", fpath);
1.17      jfb       244:                return (CVS_EX_OK);
                    245:        }
                    246:
1.14      jfb       247:        if (cf->cf_cvstat == CVS_FST_UNKNOWN) {
1.26      xsa       248:                if (verbosity > 1)
                    249:                        cvs_log(LP_WARN, "nothing known about %s", fpath);
1.33      xsa       250:                return (0);
                    251:        } else if (cf->cf_cvstat == CVS_FST_ADDED) {
                    252:                if (verbosity > 1)
                    253:                        cvs_log(LP_WARN,
                    254:                            "couldn't tag added but un-commited file `%s'",
                    255:                            fpath);
                    256:                return (0);
                    257:        } else if (cf->cf_cvstat == CVS_FST_REMOVED) {
                    258:                if (verbosity > 1)
                    259:                        cvs_log(LP_WARN,
                    260:                            "skipping removed but un-commited file `%s'",
                    261:                            fpath);
1.14      jfb       262:                return (0);
                    263:        }
1.1       jfb       264:
1.17      jfb       265:        tag_rev = cf->cf_lrev;
1.1       jfb       266:
1.34      xsa       267:        cvs_rcs_getpath(cf, rcspath, sizeof(rcspath));
1.1       jfb       268:
1.14      jfb       269:        rf = rcs_open(rcspath, RCS_READ|RCS_WRITE);
                    270:        if (rf == NULL) {
                    271:                cvs_log(LP_ERR, "failed to open %s: %s", rcspath,
                    272:                    rcs_errstr(rcs_errno));
1.16      joris     273:                return (CVS_EX_DATA);
1.32      xsa       274:        }
                    275:
                    276:        if (tag_delete == 1) {
                    277:                /* XXX */
                    278:                if (verbosity > 0)
                    279:                        cvs_printf("D %s\n", fpath);
                    280:
                    281:                return (0);
1.14      jfb       282:        }
1.1       jfb       283:
1.27      xsa       284:        if (cvs_noexec == 0) {
1.18      xsa       285:                if (rcs_sym_add(rf, tag_name, tag_rev) < 0) {
                    286:                        cvs_log(LP_ERR, "failed to tag %s: %s", rcspath,
                    287:                            rcs_errstr(rcs_errno));
                    288:                }
1.1       jfb       289:        }
1.17      jfb       290:
1.24      xsa       291:        if (verbosity > 0)
                    292:                cvs_printf("T %s\n", fpath);
1.1       jfb       293:
1.14      jfb       294:        rcs_close(rf);
                    295:        return (0);
1.1       jfb       296: }