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

Annotation of src/usr.bin/cvs/admin.c, Revision 1.31

1.31    ! ray         1: /*     $OpenBSD: admin.c,v 1.30 2006/03/16 09:06:19 xsa Exp $  */
1.1       joris       2: /*
                      3:  * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org>
                      4:  * Copyright (c) 2005 Joris Vink <joris@openbsd.org>
                      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.26      xsa        28: #include "includes.h"
1.1       joris      29:
                     30: #include "cvs.h"
                     31: #include "log.h"
                     32: #include "proto.h"
                     33:
                     34:
                     35: #define LOCK_SET       0x01
                     36: #define LOCK_REMOVE    0x02
                     37:
                     38: #define FLAG_BRANCH            0x01
                     39: #define FLAG_DELUSER           0x02
                     40: #define FLAG_INTERACTIVE       0x04
                     41: #define FLAG_QUIET             0x08
                     42:
1.22      xsa        43: static int     cvs_admin_init(struct cvs_cmd *, int, char **, int *);
                     44: static int     cvs_admin_pre_exec(struct cvsroot *);
                     45: static int     cvs_admin_remote(CVSFILE *, void *);
                     46: static int     cvs_admin_local(CVSFILE *, void *);
1.15      jfb        47:
                     48: struct cvs_cmd cvs_cmd_admin = {
                     49:        CVS_OP_ADMIN, CVS_REQ_ADMIN, "admin",
                     50:        { "adm", "rcs" },
                     51:        "Administrative front-end for RCS",
                     52:        "",
                     53:        "a:A:b::c:e::Ik:l::Lm:n:N:o:qs:t:u::U",
                     54:        NULL,
                     55:        CF_SORT | CF_IGNORE | CF_RECURSE,
                     56:        cvs_admin_init,
                     57:        cvs_admin_pre_exec,
1.16      jfb        58:        cvs_admin_remote,
                     59:        cvs_admin_local,
1.15      jfb        60:        NULL,
                     61:        NULL,
1.7       joris      62:        CVS_CMD_ALLOWSPEC | CVS_CMD_SENDDIR | CVS_CMD_SENDARGS2
                     63: };
                     64:
                     65: static char *q, *Ntag, *ntag, *comment, *replace_msg;
                     66: static char *alist, *subst, *lockrev_arg, *unlockrev_arg;
                     67: static char *state, *userfile, *branch_arg, *elist, *range;
1.16      jfb        68: static int runflags, kflag, lockrev, lkmode;
                     69:
                     70: /* flag as invalid */
                     71: static int kflag = RCS_KWEXP_ERR;
                     72: static int lkmode = RCS_LOCK_INVAL;
1.7       joris      73:
1.15      jfb        74: static int
                     75: cvs_admin_init(struct cvs_cmd *cmd, int argc, char **argv, int *arg)
1.1       joris      76: {
1.7       joris      77:        int ch;
1.1       joris      78:        RCSNUM *rcs;
                     79:
1.16      jfb        80:        runflags = lockrev = 0;
1.5       joris      81:        Ntag = ntag = comment = replace_msg = NULL;
                     82:        state = alist = subst = elist = lockrev_arg = NULL;
                     83:        range = userfile = branch_arg = unlockrev_arg = NULL;
1.1       joris      84:
                     85:        /* option-o-rama ! */
1.15      jfb        86:        while ((ch = getopt(argc, argv, cmd->cmd_opts)) != -1) {
1.1       joris      87:                switch (ch) {
                     88:                case 'a':
                     89:                        alist = optarg;
                     90:                        break;
                     91:                case 'A':
                     92:                        userfile = optarg;
                     93:                        break;
                     94:                case 'b':
                     95:                        runflags |= FLAG_BRANCH;
                     96:                        if (optarg)
                     97:                                branch_arg = optarg;
                     98:                        break;
                     99:                case 'c':
                    100:                        comment = optarg;
                    101:                        break;
                    102:                case 'e':
                    103:                        runflags |= FLAG_DELUSER;
                    104:                        if (optarg)
                    105:                                elist = optarg;
                    106:                        break;
                    107:                case 'I':
                    108:                        runflags |= FLAG_INTERACTIVE;
                    109:                        break;
                    110:                case 'k':
                    111:                        subst = optarg;
1.3       joris     112:                        kflag = rcs_kflag_get(subst);
                    113:                        if (RCS_KWEXP_INVAL(kflag)) {
                    114:                                cvs_log(LP_ERR,
                    115:                                    "invalid RCS keyword expansion mode");
                    116:                                rcs_kflag_usage();
1.11      joris     117:                                return (CVS_EX_USAGE);
1.3       joris     118:                        }
1.1       joris     119:                        break;
                    120:                case 'l':
                    121:                        lockrev |= LOCK_SET;
                    122:                        if (optarg)
                    123:                                lockrev_arg = optarg;
                    124:                        break;
                    125:                case 'L':
1.16      jfb       126:                        lkmode = RCS_LOCK_STRICT;
1.1       joris     127:                        break;
                    128:                case 'm':
                    129:                        replace_msg = optarg;
                    130:                        break;
                    131:                case 'n':
1.5       joris     132:                        ntag = optarg;
1.1       joris     133:                        break;
                    134:                case 'N':
1.5       joris     135:                        Ntag = optarg;
1.1       joris     136:                        break;
                    137:                case 'o':
1.5       joris     138:                        range = optarg;
1.1       joris     139:                        break;
                    140:                case 'q':
                    141:                        runflags |= FLAG_QUIET;
                    142:                        break;
                    143:                case 's':
1.5       joris     144:                        state = optarg;
1.1       joris     145:                        break;
                    146:                case 't':
                    147:                        break;
                    148:                case 'u':
                    149:                        lockrev |= LOCK_REMOVE;
                    150:                        if (optarg)
                    151:                                unlockrev_arg = optarg;
                    152:                        break;
                    153:                case 'U':
1.16      jfb       154:                        if (lkmode != RCS_LOCK_INVAL) {
                    155:                                cvs_log(LP_ERR, "-L and -U are incompatible");
                    156:                                return (CVS_EX_USAGE);
                    157:                        }
                    158:                        lkmode = RCS_LOCK_LOOSE;
1.1       joris     159:                        break;
                    160:                default:
1.11      joris     161:                        return (CVS_EX_USAGE);
1.1       joris     162:                }
                    163:        }
                    164:
                    165:        argc -= optind;
                    166:        argv += optind;
                    167:
                    168:        if (lockrev_arg != NULL) {
                    169:                if ((rcs = rcsnum_parse(lockrev_arg)) == NULL) {
                    170:                        cvs_log(LP_ERR, "%s is not a numeric branch",
                    171:                            lockrev_arg);
1.11      joris     172:                        return (CVS_EX_USAGE);
1.1       joris     173:                }
                    174:                rcsnum_free(rcs);
                    175:        }
                    176:
                    177:        if (unlockrev_arg != NULL) {
                    178:                if ((rcs = rcsnum_parse(unlockrev_arg)) == NULL) {
                    179:                        cvs_log(LP_ERR, "%s is not a numeric branch",
                    180:                            unlockrev_arg);
1.11      joris     181:                        return (CVS_EX_USAGE);
1.1       joris     182:                }
                    183:                rcsnum_free(rcs);
                    184:        }
                    185:
                    186:        if (replace_msg != NULL) {
                    187:                if ((q = strchr(replace_msg, ':')) == NULL) {
                    188:                        cvs_log(LP_ERR, "invalid option for -m");
1.11      joris     189:                        return (CVS_EX_USAGE);
1.1       joris     190:                }
                    191:                *q = '\0';
                    192:                if ((rcs = rcsnum_parse(replace_msg)) == NULL) {
                    193:                        cvs_log(LP_ERR, "%s is not a numeric revision",
                    194:                            replace_msg);
1.11      joris     195:                        return (CVS_EX_USAGE);
1.1       joris     196:                }
1.2       joris     197:                rcsnum_free(rcs);
1.1       joris     198:                *q = ':';
                    199:        }
                    200:
1.7       joris     201:        *arg = optind;
                    202:        return (0);
                    203: }
1.1       joris     204:
1.15      jfb       205: static int
                    206: cvs_admin_pre_exec(struct cvsroot *root)
1.7       joris     207: {
1.16      jfb       208:        if (root->cr_method == CVS_METHOD_LOCAL)
                    209:                return (0);
                    210:
1.25      joris     211:        if (alist != NULL) {
                    212:                cvs_sendarg(root, "-a", 0);
                    213:                cvs_sendarg(root, alist, 0);
                    214:        }
                    215:
                    216:        if (userfile != NULL) {
                    217:                cvs_sendarg(root, "-A", 0);
                    218:                cvs_sendarg(root, userfile, 0);
                    219:        }
1.1       joris     220:
1.7       joris     221:        if (runflags & FLAG_BRANCH) {
1.25      joris     222:                cvs_sendarg(root, "-b", 0);
                    223:                if (branch_arg != NULL)
                    224:                        cvs_sendarg(root, branch_arg, 0);
1.7       joris     225:        }
1.1       joris     226:
1.25      joris     227:        if (comment != NULL) {
                    228:                cvs_sendarg(root, "-c", 0);
                    229:                cvs_sendarg(root, comment, 0);
                    230:        }
1.1       joris     231:
1.7       joris     232:        if (runflags & FLAG_DELUSER)  {
1.25      joris     233:                cvs_sendarg(root, "-e", 0);
                    234:                if (elist != NULL)
                    235:                        cvs_sendarg(root, elist, 0);
                    236:        }
                    237:
                    238:        if (runflags & FLAG_INTERACTIVE)
                    239:                cvs_sendarg(root, "-I", 0);
                    240:
                    241:        if (subst != NULL) {
                    242:                cvs_sendarg(root, "-k", 0);
                    243:                cvs_sendarg(root, subst, 0);
1.7       joris     244:        }
1.1       joris     245:
1.25      joris     246:        if (lockrev & LOCK_SET) {
                    247:                cvs_sendarg(root, "-l", 0);
                    248:                if (lockrev_arg != NULL)
                    249:                        cvs_sendarg(root, lockrev_arg, 0);
1.7       joris     250:        }
1.1       joris     251:
1.25      joris     252:        if (lkmode == RCS_LOCK_STRICT)
                    253:                cvs_sendarg(root, "-L", 0);
                    254:        else if (lkmode == RCS_LOCK_LOOSE)
                    255:                cvs_sendarg(root, "-U", 0);
                    256:
                    257:        if (replace_msg != NULL) {
                    258:                cvs_sendarg(root, "-m", 0);
                    259:                cvs_sendarg(root, replace_msg, 0);
                    260:        }
1.5       joris     261:
1.25      joris     262:        if (ntag != NULL) {
                    263:                cvs_sendarg(root, "-n", 0);
                    264:                cvs_sendarg(root, ntag, 0);
                    265:        }
                    266:
                    267:        if (Ntag != NULL) {
                    268:                cvs_sendarg(root, "-N", 0);
                    269:                cvs_sendarg(root, Ntag, 0);
                    270:        }
                    271:
                    272:        if (range != NULL) {
                    273:                cvs_sendarg(root, "-o", 0);
                    274:                cvs_sendarg(root, range, 0);
                    275:        }
                    276:
                    277:        if (state != NULL) {
                    278:                cvs_sendarg(root, "-s", 0);
                    279:                cvs_sendarg(root, state, 0);
                    280:        }
1.1       joris     281:
1.7       joris     282:        if (lockrev & LOCK_REMOVE) {
1.25      joris     283:                cvs_sendarg(root, "-u", 0);
                    284:                if (unlockrev_arg != NULL)
                    285:                        cvs_sendarg(root, unlockrev_arg, 0);
1.1       joris     286:        }
                    287:
                    288:        return (0);
                    289: }
                    290:
                    291: /*
1.16      jfb       292:  * cvs_admin_remote()
1.1       joris     293:  *
                    294:  * Perform admin commands on each file.
                    295:  */
1.15      jfb       296: static int
1.16      jfb       297: cvs_admin_remote(CVSFILE *cf, void *arg)
1.1       joris     298: {
1.30      xsa       299:        char fpath[MAXPATHLEN];
1.1       joris     300:        struct cvsroot *root;
                    301:
1.16      jfb       302:        root = CVS_DIR_ROOT(cf);
1.14      joris     303:
1.16      jfb       304:        if (cf->cf_type == DT_DIR) {
                    305:                if (cf->cf_cvstat == CVS_FST_UNKNOWN)
1.25      joris     306:                        cvs_sendreq(root, CVS_REQ_QUESTIONABLE, cf->cf_name);
1.16      jfb       307:                else
1.25      joris     308:                        cvs_senddir(root, cf);
                    309:                return (0);
1.1       joris     310:        }
                    311:
1.16      jfb       312:        cvs_file_getpath(cf, fpath, sizeof(fpath));
1.25      joris     313:        cvs_sendentry(root, cf);
1.16      jfb       314:
                    315:        switch (cf->cf_cvstat) {
                    316:        case CVS_FST_UNKNOWN:
1.25      joris     317:                cvs_sendreq(root, CVS_REQ_QUESTIONABLE, cf->cf_name);
1.16      jfb       318:                break;
                    319:        case CVS_FST_UPTODATE:
1.25      joris     320:                cvs_sendreq(root, CVS_REQ_UNCHANGED, cf->cf_name);
1.16      jfb       321:                break;
                    322:        case CVS_FST_MODIFIED:
1.25      joris     323:                cvs_sendreq(root, CVS_REQ_MODIFIED, cf->cf_name);
                    324:                cvs_sendfile(root, fpath);
1.31    ! ray       325:                break;
1.16      jfb       326:        default:
                    327:                break;
                    328:        }
1.1       joris     329:
1.25      joris     330:        return (0);
1.16      jfb       331: }
1.14      joris     332:
1.16      jfb       333: /*
                    334:  * cvs_admin_local()
                    335:  *
                    336:  * Perform administrative operations on a local RCS file.
                    337:  */
                    338: static int
                    339: cvs_admin_local(CVSFILE *cf, void *arg)
                    340: {
1.20      xsa       341:        int ret;
                    342:        char fpath[MAXPATHLEN], rcspath[MAXPATHLEN];
1.16      jfb       343:        RCSFILE *rf;
1.19      xsa       344:
                    345:        if (cf->cf_type == DT_DIR) {
                    346:                if (verbosity > 1)
1.23      xsa       347:                        cvs_log(LP_NOTICE, "Administrating %s", cf->cf_name);
1.19      xsa       348:                return (0);
                    349:        }
1.1       joris     350:
1.29      xsa       351:        if (cf->cf_cvstat == CVS_FST_UNKNOWN)
                    352:                return (0);
                    353:        else if (cf->cf_cvstat == CVS_FST_ADDED) {
                    354:                cvs_log(LP_WARN, "cannot admin newly added file `%s'",
                    355:                    cf->cf_name);
1.16      jfb       356:                return (0);
                    357:        }
1.1       joris     358:
1.16      jfb       359:        cvs_file_getpath(cf, fpath, sizeof(fpath));
1.24      xsa       360:        cvs_rcs_getpath(cf, rcspath, sizeof(rcspath));
1.1       joris     361:
1.27      xsa       362:        if ((rf = rcs_open(rcspath, RCS_RDWR)) == NULL)
                    363:                fatal("cvs_admin_local: rcs_open `%s': %s", rcspath,
1.28      xsa       364:                    rcs_errstr(rcs_errno));
1.16      jfb       365:
1.29      xsa       366:        if (!(runflags & FLAG_QUIET))
                    367:                cvs_printf("RCS file: %s\n", rcspath);
                    368:
1.16      jfb       369:        if (!RCS_KWEXP_INVAL(kflag))
                    370:                ret = rcs_kwexp_set(rf, kflag);
                    371:        if (lkmode != RCS_LOCK_INVAL)
                    372:                ret = rcs_lock_setmode(rf, lkmode);
                    373:
                    374:        rcs_close(rf);
1.29      xsa       375:
                    376:        if (!(runflags & FLAG_QUIET))
                    377:                cvs_printf("done\n");
1.16      jfb       378:
                    379:        return (0);
1.1       joris     380: }