root.c revision 17721
1/*
2 * Copyright (c) 1992, Mark D. Baushke
3 *
4 * You may distribute under the terms of the GNU General Public License as
5 * specified in the README file that comes with the CVS 1.4 kit.
6 *
7 * Name of Root
8 *
9 * Determine the path to the CVSROOT and set "Root" accordingly.
10 * If this looks like of modified clone of Name_Repository() in
11 * repos.c, it is...
12 */
13
14#include "cvs.h"
15
16char *
17Name_Root(dir, update_dir)
18     char *dir;
19     char *update_dir;
20{
21    FILE *fpin;
22    char *ret, *xupdate_dir;
23    char root[PATH_MAX];
24    char tmp[PATH_MAX];
25    char cvsadm[PATH_MAX];
26    char *cp;
27
28    if (update_dir && *update_dir)
29	xupdate_dir = update_dir;
30    else
31	xupdate_dir = ".";
32
33    if (dir != NULL)
34    {
35	(void) sprintf (cvsadm, "%s/%s", dir, CVSADM);
36	(void) sprintf (tmp, "%s/%s", dir, CVSADM_ROOT);
37    }
38    else
39    {
40	(void) strcpy (cvsadm, CVSADM);
41	(void) strcpy (tmp, CVSADM_ROOT);
42    }
43
44    /*
45     * Do not bother looking for a readable file if there is no cvsadm
46     * directory present.
47     *
48     * It is possible that not all repositories will have a CVS/Root
49     * file. This is ok, but the user will need to specify -d
50     * /path/name or have the environment variable CVSROOT set in
51     * order to continue.
52     */
53    if ((!isdir (cvsadm)) || (!isreadable (tmp)))
54    {
55	if (CVSroot == NULL)
56	{
57	    error (0, 0, "in directory %s:", xupdate_dir);
58	    error (0, 0, "must set the CVSROOT environment variable");
59	    error (0, 0, "or specify the '-d' option to %s.", program_name);
60	}
61	return (NULL);
62    }
63
64    /*
65     * The assumption here is that the CVS Root is always contained in the
66     * first line of the "Root" file.
67     */
68    fpin = open_file (tmp, "r");
69
70    if (fgets (root, PATH_MAX, fpin) == NULL)
71    {
72	error (0, 0, "in directory %s:", xupdate_dir);
73	error (0, errno, "cannot read %s", CVSADM_ROOT);
74	error (0, 0, "please correct this problem");
75	return (NULL);
76    }
77    (void) fclose (fpin);
78    if ((cp = strrchr (root, '\n')) != NULL)
79	*cp = '\0';			/* strip the newline */
80
81    /*
82     * root now contains a candidate for CVSroot. It must be an
83     * absolute pathname
84     */
85
86#ifdef CLIENT_SUPPORT
87    /* It must specify a server via remote CVS or be an absolute pathname.  */
88    if ((strchr (root, ':') == NULL)
89    	&& ! isabsolute (root))
90#else /* ! CLIENT_SUPPORT */
91    if (root[0] != '/')
92#endif /* CLIENT_SUPPORT */
93    {
94	error (0, 0, "in directory %s:", xupdate_dir);
95	error (0, 0,
96	       "ignoring %s because it does not contain an absolute pathname.",
97	       CVSADM_ROOT);
98	return (NULL);
99    }
100
101#ifdef CLIENT_SUPPORT
102    if ((strchr (root, ':') == NULL) && !isdir (root))
103#else /* ! CLIENT_SUPPORT */
104    if (!isdir (root))
105#endif /* CLIENT_SUPPORT */
106    {
107	error (0, 0, "in directory %s:", xupdate_dir);
108	error (0, 0,
109	       "ignoring %s because it specifies a non-existent repository %s",
110	       CVSADM_ROOT, root);
111	return (NULL);
112    }
113
114    /* allocate space to return and fill it in */
115    strip_path (root);
116    ret = xstrdup (root);
117    return (ret);
118}
119
120/*
121 * Returns non-zero if the two directories have the same stat values
122 * which indicates that they are really the same directories.
123 */
124int
125same_directories (dir1, dir2)
126     char *dir1;
127     char *dir2;
128{
129    struct stat sb1;
130    struct stat sb2;
131    int ret;
132
133    if (stat (dir1, &sb1) < 0)
134        return (0);
135    if (stat (dir2, &sb2) < 0)
136        return (0);
137
138    ret = 0;
139    if ( (memcmp( &sb1.st_dev, &sb2.st_dev, sizeof(dev_t) ) == 0) &&
140	 (memcmp( &sb1.st_ino, &sb2.st_ino, sizeof(ino_t) ) == 0))
141        ret = 1;
142
143    return (ret);
144}
145
146
147/*
148 * Write the CVS/Root file so that the environment variable CVSROOT
149 * and/or the -d option to cvs will be validated or not necessary for
150 * future work.
151 */
152void
153Create_Root (dir, rootdir)
154     char *dir;
155     char *rootdir;
156{
157    FILE *fout;
158    char tmp[PATH_MAX];
159
160    if (noexec)
161	return;
162
163    /* record the current cvs root */
164
165    if (rootdir != NULL)
166    {
167        if (dir != NULL)
168	    (void) sprintf (tmp, "%s/%s", dir, CVSADM_ROOT);
169        else
170	    (void) strcpy (tmp, CVSADM_ROOT);
171        fout = open_file (tmp, "w+");
172        if (fprintf (fout, "%s\n", rootdir) < 0)
173	    error (1, errno, "write to %s failed", tmp);
174        if (fclose (fout) == EOF)
175	    error (1, errno, "cannot close %s", tmp);
176    }
177}
178