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

Annotation of src/usr.bin/cvs/root.c, Revision 1.47

1.47    ! nicm        1: /*     $OpenBSD: root.c,v 1.46 2009/02/21 12:52:47 joris Exp $ */
1.1       jfb         2: /*
                      3:  * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org>
1.13      tedu        4:  * All rights reserved.
1.1       jfb         5:  *
1.13      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.13      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.13      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.13      tedu       24:  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1.1       jfb        25:  */
                     26:
1.36      otto       27: #include <errno.h>
                     28: #include <stdlib.h>
                     29: #include <string.h>
1.1       jfb        30:
                     31: #include "cvs.h"
                     32:
                     33: extern char *cvs_rootstr;
                     34:
                     35: /* keep these ordered with the defines */
                     36: const char *cvs_methods[] = {
                     37:        "",
                     38:        "local",
                     39:        "ssh",
                     40:        "pserver",
                     41:        "kserver",
                     42:        "gserver",
                     43:        "ext",
                     44:        "fork",
                     45: };
                     46:
1.20      xsa        47: #define CVS_NBMETHODS  (sizeof(cvs_methods)/sizeof(cvs_methods[0]))
1.6       jfb        48:
                     49: /*
1.1       jfb        50:  * cvsroot_parse()
                     51:  *
                     52:  * Parse a CVS root string (as found in CVS/Root files or the CVSROOT
                     53:  * environment variable) and store the fields in a dynamically
                     54:  * allocated cvs_root structure.  The format of the string is as follows:
1.39      xsa        55:  *     [:method:][[user[:pass]@]host[:port]:]path
1.1       jfb        56:  * Returns a pointer to the allocated information on success, or NULL
                     57:  * on failure.
                     58:  */
1.40      joris      59: static struct cvsroot *
1.1       jfb        60: cvsroot_parse(const char *str)
                     61: {
                     62:        u_int i;
                     63:        char *cp, *sp, *pp;
1.37      xsa        64:        const char *errstr;
1.40      joris      65:        static struct cvsroot *root = NULL;
1.1       jfb        66:
1.40      joris      67:        if (root != NULL)
                     68:                return (root);
1.6       jfb        69:
1.31      ray        70:        root = xcalloc(1, sizeof(*root));
1.1       jfb        71:        root->cr_method = CVS_METHOD_NONE;
1.26      joris      72:        root->cr_str = xstrdup(str);
                     73:        root->cr_buf = xstrdup(str);
1.1       jfb        74:
                     75:        sp = root->cr_buf;
                     76:        cp = root->cr_buf;
                     77:        if (*sp == ':') {
                     78:                sp++;
1.27      xsa        79:                if ((cp = strchr(sp, ':')) == NULL)
                     80:                        fatal("failed to parse CVSROOT: unterminated method");
                     81:
1.1       jfb        82:                *(cp++) = '\0';
                     83:
                     84:                for (i = 0; i < CVS_NBMETHODS; i++) {
                     85:                        if (strcmp(sp, cvs_methods[i]) == 0) {
                     86:                                root->cr_method = i;
                     87:                                break;
                     88:                        }
1.14      jfb        89:                }
1.27      xsa        90:                if (i == CVS_NBMETHODS)
                     91:                        fatal("cvsroot_parse: unknown method `%s'", sp);
1.1       jfb        92:        }
                     93:
                     94:        /* find the start of the actual path */
1.27      xsa        95:        if ((sp = strchr(cp, '/')) == NULL)
                     96:                fatal("no path specification in CVSROOT");
1.1       jfb        97:
                     98:        root->cr_dir = sp;
1.32      joris      99:        STRIP_SLASH(root->cr_dir);
1.1       jfb       100:        if (sp == cp) {
                    101:                if (root->cr_method == CVS_METHOD_NONE)
                    102:                        root->cr_method = CVS_METHOD_LOCAL;
                    103:                /* stop here, it's just a path */
                    104:                return (root);
                    105:        }
                    106:
1.27      xsa       107:        if (*(sp - 1) != ':')
                    108:                fatal("missing host/path delimiter in CVSROOT");
                    109:
1.1       jfb       110:        *(sp - 1) = '\0';
                    111:
                    112:        /*
                    113:         * looks like we have more than just a directory path, so
                    114:         * attempt to split it into user and host parts
                    115:         */
                    116:        sp = strchr(cp, '@');
                    117:        if (sp != NULL) {
                    118:                *(sp++) = '\0';
                    119:
                    120:                /* password ? */
                    121:                pp = strchr(cp, ':');
                    122:                if (pp != NULL) {
                    123:                        *(pp++) = '\0';
                    124:                        root->cr_pass = pp;
                    125:                }
                    126:
                    127:                root->cr_user = cp;
1.12      deraadt   128:        } else
1.11      jfb       129:                sp = cp;
1.1       jfb       130:
                    131:        pp = strchr(sp, ':');
                    132:        if (pp != NULL) {
                    133:                *(pp++) = '\0';
1.43      joris     134:                root->cr_port = strtonum(pp, 1, 65535, &errstr);
1.37      xsa       135:                if (errstr != NULL)
                    136:                        fatal("port specification in CVSROOT is %s", errstr);
1.1       jfb       137:
                    138:        }
                    139:
                    140:        root->cr_host = sp;
                    141:
                    142:        if (root->cr_method == CVS_METHOD_NONE) {
                    143:                /* no method found from start of CVSROOT, guess */
                    144:                if (root->cr_host != NULL)
                    145:                        root->cr_method = CVS_METHOD_SERVER;
                    146:                else
                    147:                        root->cr_method = CVS_METHOD_LOCAL;
                    148:        }
                    149:
                    150:        return (root);
1.25      joris     151: }
1.1       jfb       152:
                    153: /*
                    154:  * cvsroot_get()
                    155:  *
                    156:  * Get the CVSROOT information for a specific directory <dir>.  The
                    157:  * value is taken from one of 3 possible sources (in order of precedence):
                    158:  *
                    159:  * 1) the `-d' command-line option
                    160:  * 2) the CVS/Root file found in checked-out trees
                    161:  * 3) the CVSROOT environment variable
                    162:  */
1.21      xsa       163: struct cvsroot *
1.1       jfb       164: cvsroot_get(const char *dir)
                    165: {
1.5       jfb       166:        char rootpath[MAXPATHLEN], *rootstr, line[128];
1.1       jfb       167:        FILE *fp;
                    168:
                    169:        if (cvs_rootstr != NULL)
                    170:                return cvsroot_parse(cvs_rootstr);
1.41      tobias    171:
                    172:        if (cvs_server_active == 1)
                    173:                return cvsroot_parse(dir);
1.45      tobias    174:
1.47    ! nicm      175:        if (cvs_cmdop == CVS_OP_IMPORT) {
        !           176:                if ((rootstr = getenv("CVSROOT")) != NULL)
        !           177:                        return (cvsroot_parse(rootstr));
        !           178:                return (NULL);
        !           179:        }
1.1       jfb       180:
1.35      xsa       181:        (void)xsnprintf(rootpath, MAXPATHLEN, "%s/%s", dir, CVS_PATH_ROOTSPEC);
1.16      xsa       182:
1.27      xsa       183:        if ((fp = fopen(rootpath, "r")) == NULL) {
1.1       jfb       184:                if (errno == ENOENT) {
                    185:                        /* try env as a last resort */
                    186:                        if ((rootstr = getenv("CVSROOT")) != NULL)
                    187:                                return cvsroot_parse(rootstr);
                    188:                        else
1.32      joris     189:                                return (NULL);
1.12      deraadt   190:                } else {
1.27      xsa       191:                        fatal("cvsroot_get: fopen: `%s': %s",
                    192:                            CVS_PATH_ROOTSPEC, strerror(errno));
1.1       jfb       193:                }
                    194:        }
                    195:
1.27      xsa       196:        if (fgets(line, (int)sizeof(line), fp) == NULL)
                    197:                fatal("cvsroot_get: fgets: `%s'", CVS_PATH_ROOTSPEC);
                    198:
1.5       jfb       199:        (void)fclose(fp);
1.1       jfb       200:
1.44      gilles    201:        line[strcspn(line, "\n")] = '\0';
                    202:        if (line[0] == '\0')
1.32      joris     203:                cvs_log(LP_ERR, "empty %s file", CVS_PATH_ROOTSPEC);
1.1       jfb       204:
1.5       jfb       205:        return cvsroot_parse(line);
1.1       jfb       206: }