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

1.20    ! xsa         1: /*     $OpenBSD: commit.c,v 1.19 2005/03/31 15:10:51 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:
                     27: #include <sys/types.h>
1.6       jfb        28: #include <sys/queue.h>
1.1       jfb        29: #include <sys/stat.h>
                     30:
                     31: #include <errno.h>
                     32: #include <stdio.h>
                     33: #include <fcntl.h>
                     34: #include <stdlib.h>
                     35: #include <unistd.h>
                     36: #include <string.h>
                     37: #include <sysexits.h>
                     38:
                     39: #include "cvs.h"
                     40: #include "log.h"
1.5       krapht     41: #include "buf.h"
1.2       jfb        42: #include "proto.h"
1.1       jfb        43:
                     44:
1.19      joris      45: int cvs_commit_prepare(CVSFILE *, void *);
1.18      joris      46: int cvs_commit_file(CVSFILE *, void *);
                     47: int cvs_commit_options(char *, int, char **, int *);
                     48: int cvs_commit_helper(void);
                     49:
                     50: struct cvs_cmd_info cvs_commit = {
                     51:        cvs_commit_options,
                     52:        NULL,
                     53:        cvs_commit_file,
                     54:        NULL,
                     55:        cvs_commit_helper,
                     56:        CF_RECURSE | CF_IGNORE | CF_SORT,
                     57:        CVS_REQ_CI,
                     58:        CVS_CMD_NEEDLOG | CVS_CMD_SENDDIR | CVS_CMD_SENDARGS2
                     59: };
1.1       jfb        60:
1.18      joris      61: static char *mfile = NULL;
1.6       jfb        62:
1.1       jfb        63: int
1.18      joris      64: cvs_commit_options(char *opt, int argc, char **argv, int *arg)
1.1       jfb        65: {
1.18      joris      66:        int ch;
1.3       krapht     67:
1.18      joris      68:        while ((ch = getopt(argc, argv, opt)) != -1) {
1.1       jfb        69:                switch (ch) {
                     70:                case 'F':
                     71:                        mfile = optarg;
                     72:                        break;
                     73:                case 'f':
1.10      jfb        74:                        /* XXX half-implemented */
1.18      joris      75:                        cvs_commit.file_flags &= ~CF_RECURSE;
1.1       jfb        76:                        break;
                     77:                case 'l':
1.18      joris      78:                        cvs_commit.file_flags &= ~CF_RECURSE;
1.1       jfb        79:                        break;
                     80:                case 'm':
1.14      jfb        81:                        cvs_msg = strdup(optarg);
                     82:                        if (cvs_msg == NULL) {
                     83:                                cvs_log(LP_ERRNO, "failed to copy message");
1.20    ! xsa        84:                                return (-1);
1.14      jfb        85:                        }
1.1       jfb        86:                        break;
                     87:                case 'R':
1.18      joris      88:                        cvs_commit.file_flags |= CF_RECURSE;
1.1       jfb        89:                        break;
                     90:                default:
                     91:                        return (EX_USAGE);
                     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");
                     97:                return (EX_USAGE);
                     98:        }
                     99:
1.14      jfb       100:        if ((mfile != NULL) && (cvs_msg = cvs_logmsg_open(mfile)) == NULL)
1.20    ! xsa       101:                return (-1);
1.1       jfb       102:
1.18      joris     103:        *arg = optind;
                    104:        return (0);
                    105: }
1.1       jfb       106:
1.18      joris     107: int
                    108: cvs_commit_helper(void)
                    109: {
                    110:        struct cvs_flist cl;
                    111:        CVSFILE *cfp;
1.1       jfb       112:
1.18      joris     113:        TAILQ_INIT(&cl);
1.7       jfb       114:        cvs_file_examine(cvs_files, cvs_commit_prepare, &cl);
1.11      jfb       115:        if (TAILQ_EMPTY(&cl))
                    116:                return (0);
1.7       jfb       117:
1.17      joris     118:        if (cvs_msg == NULL)
1.14      jfb       119:                cvs_msg = cvs_logmsg_get(CVS_FILE_NAME(cvs_files),
                    120:                    NULL, &cl, NULL);
1.17      joris     121:
                    122:        while (!TAILQ_EMPTY(&cl)) {
                    123:                cfp = TAILQ_FIRST(&cl);
                    124:                TAILQ_REMOVE(&cl, cfp, cf_list);
                    125:                cvs_file_free(cfp);
1.7       jfb       126:        }
1.17      joris     127:
                    128:        if (cvs_msg == NULL)
1.20    ! xsa       129:                return (-1);
1.7       jfb       130:
                    131:        return (0);
                    132: }
                    133:
                    134: /*
                    135:  * cvs_commit_prepare()
                    136:  *
                    137:  * Examine the file <cf> to see if it will be part of the commit, in which
                    138:  * case it gets added to the list passed as second argument.
                    139:  */
                    140: int
                    141: cvs_commit_prepare(CVSFILE *cf, void *arg)
                    142: {
                    143:        CVSFILE *copy;
                    144:        struct cvs_flist *clp = (struct cvs_flist *)arg;
                    145:
                    146:        if ((cf->cf_type == DT_REG) && (cf->cf_cvstat == CVS_FST_MODIFIED)) {
                    147:                copy = cvs_file_copy(cf);
                    148:                if (copy == NULL)
                    149:                        return (-1);
                    150:
                    151:                TAILQ_INSERT_TAIL(clp, copy, cf_list);
                    152:        }
1.3       krapht    153:
1.6       jfb       154:        return (0);
1.3       krapht    155: }
                    156:
                    157:
                    158: /*
1.6       jfb       159:  * cvs_commit_file()
1.3       krapht    160:  *
1.6       jfb       161:  * Commit a single file.
1.3       krapht    162:  */
1.6       jfb       163: int
                    164: cvs_commit_file(CVSFILE *cf, void *arg)
1.3       krapht    165: {
1.13      jfb       166:        int ret;
1.6       jfb       167:        char *repo, rcspath[MAXPATHLEN], fpath[MAXPATHLEN];
                    168:        RCSFILE *rf;
                    169:        struct cvsroot *root;
                    170:        struct cvs_ent *entp;
                    171:
1.13      jfb       172:        ret = 0;
1.7       jfb       173:        rf = NULL;
                    174:        repo = NULL;
1.12      jfb       175:        root = CVS_DIR_ROOT(cf);
1.6       jfb       176:
                    177:        if (cf->cf_type == DT_DIR) {
1.13      jfb       178:                if (root->cr_method != CVS_METHOD_LOCAL) {
                    179:                        if (cf->cf_cvstat != CVS_FST_UNKNOWN)
                    180:                                ret = cvs_senddir(root, cf);
1.6       jfb       181:                }
1.3       krapht    182:
1.13      jfb       183:                return (ret);
1.3       krapht    184:        }
                    185:
1.7       jfb       186:        cvs_file_getpath(cf, fpath, sizeof(fpath));
                    187:
                    188:        if (cf->cf_parent != NULL)
1.6       jfb       189:                repo = cf->cf_parent->cf_ddat->cd_repo;
1.5       krapht    190:
1.6       jfb       191:        entp = cvs_ent_getent(fpath);
                    192:        if (entp == NULL)
                    193:                return (-1);
1.3       krapht    194:
1.6       jfb       195:        if ((cf->cf_cvstat == CVS_FST_ADDED) ||
                    196:            (cf->cf_cvstat == CVS_FST_MODIFIED)) {
1.16      joris     197:                if (root->cr_method != CVS_METHOD_LOCAL) {
                    198:                        if (cvs_sendentry(root, entp) < 0) {
                    199:                                cvs_ent_free(entp);
                    200:                                return (-1);
                    201:                        }
                    202:
                    203:                        if (cvs_sendreq(root, CVS_REQ_MODIFIED,
                    204:                            CVS_FILE_NAME(cf)) < 0) {
                    205:                                cvs_ent_free(entp);
                    206:                                return (-1);
                    207:                        }
                    208:
                    209:                        if (cvs_sendfile(root, fpath) < 0) {
                    210:                                cvs_ent_free(entp);
                    211:                                return (-1);
                    212:                        }
1.5       krapht    213:                }
                    214:        }
1.3       krapht    215:
1.6       jfb       216:        snprintf(rcspath, sizeof(rcspath), "%s/%s/%s%s",
                    217:            root->cr_dir, repo, fpath, RCS_FILE_EXT);
1.3       krapht    218:
1.6       jfb       219:        cvs_ent_free(entp);
1.3       krapht    220:
1.6       jfb       221:        return (0);
1.1       jfb       222: }