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

Annotation of src/usr.bin/cvs/commit.c, Revision 1.51

1.51    ! xsa         1: /*     $OpenBSD: commit.c,v 1.50 2005/12/30 02:03:28 joris Exp $       */
1.1       jfb         2: /*
                      3:  * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org>
1.9       tedu        4:  * All rights reserved.
1.1       jfb         5:  *
1.9       tedu        6:  * Redistribution and use in source and binary forms, with or without
                      7:  * modification, are permitted provided that the following conditions
                      8:  * are met:
1.1       jfb         9:  *
1.9       tedu       10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
1.1       jfb        12:  * 2. The name of the author may not be used to endorse or promote products
1.9       tedu       13:  *    derived from this software without specific prior written permission.
1.1       jfb        14:  *
                     15:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
                     16:  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
                     17:  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
                     18:  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
                     19:  * EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLUDING, BUT NOT LIMITED TO,
                     20:  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
                     21:  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
                     22:  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
                     23:  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
1.9       tedu       24:  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1.1       jfb        25:  */
                     26:
1.51    ! xsa        27: #include "includes.h"
1.1       jfb        28:
1.37      xsa        29: #include "buf.h"
1.1       jfb        30: #include "cvs.h"
                     31: #include "log.h"
1.2       jfb        32: #include "proto.h"
1.1       jfb        33:
                     34:
1.45      xsa        35: static int     cvs_commit_init(struct cvs_cmd *, int, char **, int *);
                     36: static int     cvs_commit_prepare(CVSFILE *, void *);
                     37: static int     cvs_commit_remote(CVSFILE *, void *);
                     38: static int     cvs_commit_local(CVSFILE *, void *);
                     39: static int     cvs_commit_pre_exec(struct cvsroot *);
1.34      jfb        40:
                     41: struct cvs_cmd cvs_cmd_commit = {
                     42:        CVS_OP_COMMIT, CVS_REQ_CI, "commit",
                     43:        { "ci",  "com" },
                     44:        "Check files into the repository",
                     45:        "[-flR] [-F logfile | -m msg] [-r rev] ...",
                     46:        "F:flm:Rr:",
1.18      joris      47:        NULL,
1.34      jfb        48:        CF_RECURSE | CF_IGNORE | CF_SORT,
                     49:        cvs_commit_init,
                     50:        cvs_commit_pre_exec,
1.39      xsa        51:        cvs_commit_remote,
                     52:        cvs_commit_local,
1.34      jfb        53:        NULL,
                     54:        NULL,
1.41      joris      55:        CVS_CMD_SENDDIR | CVS_CMD_ALLOWSPEC | CVS_CMD_SENDARGS2
1.18      joris      56: };
1.1       jfb        57:
1.18      joris      58: static char *mfile = NULL;
1.35      xsa        59: static char *rev = NULL;
1.32      joris      60: static char **commit_files = NULL;
                     61: static int commit_fcount = 0;
1.43      joris      62: static int wantedstatus = 0;
1.6       jfb        63:
1.34      jfb        64: static int
                     65: cvs_commit_init(struct cvs_cmd *cmd, int argc, char **argv, int *arg)
1.1       jfb        66: {
1.18      joris      67:        int ch;
1.3       krapht     68:
1.34      jfb        69:        while ((ch = getopt(argc, argv, cmd->cmd_opts)) != -1) {
1.1       jfb        70:                switch (ch) {
                     71:                case 'F':
                     72:                        mfile = optarg;
                     73:                        break;
                     74:                case 'f':
1.10      jfb        75:                        /* XXX half-implemented */
1.34      jfb        76:                        cmd->file_flags &= ~CF_RECURSE;
1.1       jfb        77:                        break;
                     78:                case 'l':
1.34      jfb        79:                        cmd->file_flags &= ~CF_RECURSE;
1.1       jfb        80:                        break;
                     81:                case 'm':
1.47      joris      82:                        cvs_msg = xstrdup(optarg);
1.1       jfb        83:                        break;
                     84:                case 'R':
1.34      jfb        85:                        cmd->file_flags |= CF_RECURSE;
1.1       jfb        86:                        break;
1.35      xsa        87:                case 'r':
                     88:                        rev = optarg;
                     89:                        break;
1.1       jfb        90:                default:
1.23      joris      91:                        return (CVS_EX_USAGE);
1.1       jfb        92:                }
                     93:        }
                     94:
1.14      jfb        95:        if ((cvs_msg != NULL) && (mfile != NULL)) {
1.1       jfb        96:                cvs_log(LP_ERR, "the -F and -m flags are mutually exclusive");
1.23      joris      97:                return (CVS_EX_USAGE);
1.1       jfb        98:        }
                     99:
1.48      xsa       100:        if (mfile != NULL)
                    101:                cvs_msg = cvs_logmsg_open(mfile);
1.1       jfb       102:
1.18      joris     103:        *arg = optind;
1.32      joris     104:
                    105:        commit_files = (argv + optind);
                    106:        commit_fcount = (argc - optind);
                    107:
1.18      joris     108:        return (0);
                    109: }
1.1       jfb       110:
1.18      joris     111: int
1.34      jfb       112: cvs_commit_pre_exec(struct cvsroot *root)
1.18      joris     113: {
                    114:        CVSFILE *cfp;
1.32      joris     115:        CVSFILE *tmp;
1.44      joris     116:        int ret, i, flags = CF_RECURSE | CF_IGNORE | CF_SORT;
1.43      joris     117:        struct cvs_flist added, modified, removed, *cl[3];
                    118:        int stattype[] = { CVS_FST_ADDED, CVS_FST_MODIFIED, CVS_FST_REMOVED };
                    119:
                    120:        SIMPLEQ_INIT(&added);
                    121:        SIMPLEQ_INIT(&modified);
                    122:        SIMPLEQ_INIT(&removed);
                    123:
                    124:        cl[0] = &added;
                    125:        cl[1] = &modified;
                    126:        cl[2] = &removed;
                    127:
1.44      joris     128:        if ((tmp = cvs_file_loadinfo(".", CF_NOFILES, NULL, NULL, 1)) == NULL)
                    129:                return (CVS_EX_DATA);
                    130:
1.43      joris     131:        /*
                    132:         * Obtain the file lists for the logmessage.
                    133:         */
                    134:        for (i = 0; i < 3; i++) {
                    135:                wantedstatus = stattype[i];
                    136:                if (commit_fcount != 0) {
1.44      joris     137:                        ret = cvs_file_getspec(commit_files, commit_fcount,
                    138:                            flags, cvs_commit_prepare, cl[i], NULL);
1.43      joris     139:                } else {
1.44      joris     140:                        ret = cvs_file_get(".", flags, cvs_commit_prepare,
                    141:                            cl[i], NULL);
1.43      joris     142:                }
1.32      joris     143:
1.44      joris     144:                if (ret != CVS_EX_OK) {
                    145:                        cvs_file_free(tmp);
1.43      joris     146:                        return (CVS_EX_DATA);
1.44      joris     147:                }
1.32      joris     148:        }
1.1       jfb       149:
1.43      joris     150:        /*
                    151:         * If we didn't catch any file, don't call the editor.
                    152:         */
                    153:        if (SIMPLEQ_EMPTY(&added) && SIMPLEQ_EMPTY(&modified) &&
                    154:            SIMPLEQ_EMPTY(&removed)) {
1.32      joris     155:                cvs_file_free(tmp);
1.11      jfb       156:                return (0);
1.32      joris     157:        }
1.7       jfb       158:
1.43      joris     159:        /*
                    160:         * Fetch the log message for real, with all the files.
                    161:         */
1.17      joris     162:        if (cvs_msg == NULL)
1.43      joris     163:                cvs_msg = cvs_logmsg_get(tmp->cf_name, &added, &modified,
                    164:                    &removed);
1.32      joris     165:
                    166:        cvs_file_free(tmp);
1.17      joris     167:
1.43      joris     168:        /* free the file lists */
                    169:        for (i = 0; i < 3; i++) {
                    170:                while (!SIMPLEQ_EMPTY(cl[i])) {
                    171:                        cfp = SIMPLEQ_FIRST(cl[i]);
                    172:                        SIMPLEQ_REMOVE_HEAD(cl[i], cf_list);
                    173:                        cvs_file_free(cfp);
                    174:                }
1.7       jfb       175:        }
1.17      joris     176:
                    177:        if (cvs_msg == NULL)
1.23      joris     178:                return (CVS_EX_DATA);
1.35      xsa       179:
                    180:        if (root->cr_method != CVS_METHOD_LOCAL) {
1.50      joris     181:                cvs_logmsg_send(root, cvs_msg);
1.36      joris     182:
1.35      xsa       183:                if (rev != NULL) {
1.50      joris     184:                        cvs_sendarg(root, "-r", 0);
                    185:                        cvs_sendarg(root, rev, 0);
1.35      xsa       186:                }
                    187:        }
1.7       jfb       188:
                    189:        return (0);
                    190: }
                    191:
                    192: /*
                    193:  * cvs_commit_prepare()
                    194:  *
                    195:  * Examine the file <cf> to see if it will be part of the commit, in which
                    196:  * case it gets added to the list passed as second argument.
                    197:  */
                    198: int
                    199: cvs_commit_prepare(CVSFILE *cf, void *arg)
                    200: {
                    201:        CVSFILE *copy;
                    202:        struct cvs_flist *clp = (struct cvs_flist *)arg;
                    203:
1.43      joris     204:        if ((cf->cf_type == DT_REG) && (cf->cf_cvstat == wantedstatus)) {
1.7       jfb       205:                copy = cvs_file_copy(cf);
                    206:                if (copy == NULL)
1.23      joris     207:                        return (CVS_EX_DATA);
1.7       jfb       208:
1.26      jfb       209:                SIMPLEQ_INSERT_TAIL(clp, copy, cf_list);
1.7       jfb       210:        }
1.3       krapht    211:
1.6       jfb       212:        return (0);
1.3       krapht    213: }
                    214:
                    215:
                    216: /*
1.39      xsa       217:  * cvs_commit_remote()
1.3       krapht    218:  *
1.6       jfb       219:  * Commit a single file.
1.3       krapht    220:  */
1.6       jfb       221: int
1.39      xsa       222: cvs_commit_remote(CVSFILE *cf, void *arg)
1.3       krapht    223: {
1.39      xsa       224:        int ret;
                    225:        char *repo, fpath[MAXPATHLEN];
1.6       jfb       226:        RCSFILE *rf;
                    227:        struct cvsroot *root;
                    228:
1.13      jfb       229:        ret = 0;
1.7       jfb       230:        rf = NULL;
                    231:        repo = NULL;
1.12      jfb       232:        root = CVS_DIR_ROOT(cf);
1.6       jfb       233:
                    234:        if (cf->cf_type == DT_DIR) {
1.50      joris     235:                if (cf->cf_cvstat != CVS_FST_UNKNOWN)
                    236:                        cvs_senddir(root, cf);
1.33      joris     237:                return (0);
1.3       krapht    238:        }
                    239:
1.7       jfb       240:        cvs_file_getpath(cf, fpath, sizeof(fpath));
                    241:
                    242:        if (cf->cf_parent != NULL)
1.26      jfb       243:                repo = cf->cf_parent->cf_repo;
1.3       krapht    244:
1.6       jfb       245:        if ((cf->cf_cvstat == CVS_FST_ADDED) ||
1.29      jfb       246:            (cf->cf_cvstat == CVS_FST_MODIFIED) ||
                    247:            (cf->cf_cvstat == CVS_FST_REMOVED)) {
1.50      joris     248:                cvs_sendentry(root, cf);
1.31      joris     249:
1.39      xsa       250:                /* if it's removed, don't bother sending a
                    251:                 * Modified request together with the file its
                    252:                 * contents.
                    253:                 */
                    254:                if (cf->cf_cvstat == CVS_FST_REMOVED)
                    255:                        return (0);
1.16      joris     256:
1.50      joris     257:                cvs_sendreq(root, CVS_REQ_MODIFIED, cf->cf_name);
                    258:                cvs_sendfile(root, fpath);
1.5       krapht    259:        }
1.3       krapht    260:
1.39      xsa       261:        return (0);
                    262: }
                    263:
                    264: static int
                    265: cvs_commit_local(CVSFILE *cf, void *arg)
                    266: {
                    267:        char fpath[MAXPATHLEN], rcspath[MAXPATHLEN];
                    268:
                    269:        if (cf->cf_type == DT_DIR) {
                    270:                if (verbosity > 1)
1.46      xsa       271:                        cvs_log(LP_NOTICE, "Examining %s", cf->cf_name);
1.39      xsa       272:                return (0);
                    273:        }
                    274:
                    275:        cvs_file_getpath(cf, fpath, sizeof(fpath));
1.49      xsa       276:        cvs_rcs_getpath(cf, rcspath, sizeof(rcspath));
1.3       krapht    277:
1.6       jfb       278:        return (0);
1.1       jfb       279: }