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

Annotation of src/usr.bin/cvs/init.c, Revision 1.21

1.21    ! xsa         1: /*     $OpenBSD: init.c,v 1.20 2006/01/02 08:11:56 xsa Exp $   */
1.1       jfb         2: /*
                      3:  * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org>
1.8       tedu        4:  * All rights reserved.
1.1       jfb         5:  *
1.8       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.8       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.8       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.8       tedu       24:  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1.1       jfb        25:  */
                     26:
1.20      xsa        27: #include "includes.h"
1.1       jfb        28:
                     29: #include "cvs.h"
                     30: #include "log.h"
1.6       jfb        31: #include "proto.h"
1.1       jfb        32:
                     33:
1.19      xsa        34: #define CFT_FILE       1
                     35: #define CFT_DIR                2
1.1       jfb        36:
                     37:
                     38: struct cvsroot_file {
1.19      xsa        39:        char    *cf_path;       /* path relative to CVS root directory */
                     40:        u_int    cf_type;
                     41:        mode_t   cf_mode;
1.1       jfb        42: } cvsroot_files[] = {
                     43:        { CVS_PATH_ROOT,   CFT_DIR, (S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) },
1.18      xsa        44:        { CVS_PATH_EMPTYDIR, CFT_DIR, (S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) },
1.1       jfb        45:        { CVS_PATH_COMMITINFO,  CFT_FILE, (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) },
                     46:        { CVS_PATH_CONFIG,      CFT_FILE, (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) },
                     47:        { CVS_PATH_CVSIGNORE,   CFT_FILE, (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) },
                     48:        { CVS_PATH_CVSWRAPPERS, CFT_FILE, (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) },
                     49:        { CVS_PATH_EDITINFO,    CFT_FILE, (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) },
                     50:        { CVS_PATH_HISTORY,     CFT_FILE, (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) },
                     51:        { CVS_PATH_LOGINFO,     CFT_FILE, (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) },
                     52:        { CVS_PATH_MODULES,     CFT_FILE, (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) },
                     53:        { CVS_PATH_NOTIFY,      CFT_FILE, (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) },
                     54:        { CVS_PATH_RCSINFO,     CFT_FILE, (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) },
                     55:        { CVS_PATH_TAGINFO,     CFT_FILE, (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) },
                     56:        { CVS_PATH_VERIFYMSG,   CFT_FILE, (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) },
                     57: };
                     58:
1.19      xsa        59: static int     cvs_init_pre_exec(struct cvsroot *);
1.21    ! xsa        60: static void    cvs_init_create_files(struct cvsroot *);
1.12      joris      61:
1.16      jfb        62: struct cvs_cmd cvs_cmd_init = {
                     63:        CVS_OP_INIT, CVS_REQ_INIT, "init",
                     64:        { },
                     65:        "Create a CVS repository if it doesn't exist",
                     66:        "",
                     67:        "",
1.12      joris      68:        NULL,
                     69:        0,
1.16      jfb        70:        NULL,
1.18      xsa        71:        cvs_init_pre_exec,
1.16      jfb        72:        NULL,
                     73:        NULL,
                     74:        NULL,
                     75:        NULL,
1.12      joris      76:        0
                     77: };
1.1       jfb        78:
1.2       jfb        79: /*
1.18      xsa        80:  * cvs_init_pre_exec()
                     81:  *
                     82:  * Local/remote handler for the "cvs init" command.
                     83:  * Returns 0 on success, -1 on failure.
                     84:  */
                     85: static int
                     86: cvs_init_pre_exec(struct cvsroot *root)
                     87: {
1.21    ! xsa        88:        if (root->cr_method == CVS_METHOD_LOCAL)
        !            89:                cvs_init_create_files(root);
1.18      xsa        90:
                     91:        return (0);
                     92: }
                     93:
                     94: /*
                     95:  * cvs_init_create_files
1.2       jfb        96:  *
1.18      xsa        97:  * Create all required files for the "cvs init" command.
                     98:  * Used by the local handlers.
1.13      xsa        99:  * Returns 0 on success, -1 on failure.
1.18      xsa       100:  *
1.2       jfb       101:  */
1.21    ! xsa       102: static void
1.18      xsa       103: cvs_init_create_files(struct cvsroot *root)
1.1       jfb       104: {
1.18      xsa       105:        size_t len;
                    106:        int fd;
1.1       jfb       107:        u_int i;
                    108:        char path[MAXPATHLEN];
                    109:        RCSFILE *rfp;
1.18      xsa       110:        struct stat st;
1.4       jfb       111:
1.18      xsa       112:        /* Create repository root directory if it does not already exist */
                    113:        if (mkdir(root->cr_dir, 0777) == -1) {
                    114:                if (!(errno == EEXIST || (errno == EACCES &&
                    115:                    (stat(root->cr_dir, &st) == 0) && S_ISDIR(st.st_mode)))) {
1.21    ! xsa       116:                        fatal("cvs_init_create_files: mkdir: %s: %s",
        !           117:                            root->cr_dir, strerror(errno));
1.18      xsa       118:                }
                    119:        }
                    120:
                    121:        /* Create the repository administrative files */
1.1       jfb       122:        for (i = 0; i < sizeof(cvsroot_files)/sizeof(cvsroot_files[i]); i++) {
1.18      xsa       123:                len = cvs_path_cat(root->cr_dir, cvsroot_files[i].cf_path,
                    124:                    path, sizeof(path));
                    125:                if (len >= sizeof(path))
1.21    ! xsa       126:                        fatal("cvs_init_create_files: path truncation");
1.1       jfb       127:
                    128:                if (cvsroot_files[i].cf_type == CFT_DIR) {
                    129:                        if (mkdir(path, cvsroot_files[i].cf_mode) == -1) {
1.18      xsa       130:                                if (!(errno == EEXIST || (errno == EACCES &&
                    131:                                    (stat(path, &st) == 0) &&
                    132:                                    S_ISDIR(st.st_mode)))) {
1.21    ! xsa       133:                                        fatal("cvs_init_create_files: mkdir: "
        !           134:                                            "%s: %s", path, strerror(errno));
1.18      xsa       135:                                }
1.1       jfb       136:                        }
1.7       deraadt   137:                } else if (cvsroot_files[i].cf_type == CFT_FILE) {
1.1       jfb       138:                        fd = open(path, O_WRONLY|O_CREAT|O_EXCL,
                    139:                            cvsroot_files[i].cf_mode);
1.21    ! xsa       140:                        if (fd == -1)
        !           141:                                fatal("cvs_init_create_file: open failed: %s",
        !           142:                                    strerror(errno));
1.1       jfb       143:
                    144:                        (void)close(fd);
                    145:
                    146:                        strlcat(path, RCS_FILE_EXT, sizeof(path));
1.11      jfb       147:                        rfp = rcs_open(path, RCS_WRITE|RCS_CREATE, 0640);
1.21    ! xsa       148:                        if (rfp == NULL)
        !           149:                                return;
1.1       jfb       150:
                    151:                        rcs_close(rfp);
                    152:                }
                    153:        }
                    154: }