xref: /dflybsd-src/contrib/cvs-1.12/src/cvsrc.c (revision 86d7f5d305c6adaa56ff4582ece9859d73106103)
1*86d7f5d3SJohn Marino /*
2*86d7f5d3SJohn Marino  * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
3*86d7f5d3SJohn Marino  *
4*86d7f5d3SJohn Marino  * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
5*86d7f5d3SJohn Marino  *                                  and others.
6*86d7f5d3SJohn Marino  *
7*86d7f5d3SJohn Marino  * Portions Copyright (C) 1993 david d zuhn
8*86d7f5d3SJohn Marino  *
9*86d7f5d3SJohn Marino  * Written by david d `zoo' zuhn while at Cygnus Support
10*86d7f5d3SJohn Marino  *
11*86d7f5d3SJohn Marino  * You may distribute under the terms of the GNU General Public License as
12*86d7f5d3SJohn Marino  * specified in the README file that comes with the CVS source distribution.
13*86d7f5d3SJohn Marino  *
14*86d7f5d3SJohn Marino  */
15*86d7f5d3SJohn Marino 
16*86d7f5d3SJohn Marino 
17*86d7f5d3SJohn Marino #include "cvs.h"
18*86d7f5d3SJohn Marino #include "getline.h"
19*86d7f5d3SJohn Marino 
20*86d7f5d3SJohn Marino /* this file is to be found in the user's home directory */
21*86d7f5d3SJohn Marino 
22*86d7f5d3SJohn Marino #ifndef	CVSRC_FILENAME
23*86d7f5d3SJohn Marino #define	CVSRC_FILENAME	".cvsrc"
24*86d7f5d3SJohn Marino #endif
25*86d7f5d3SJohn Marino char cvsrc[] = CVSRC_FILENAME;
26*86d7f5d3SJohn Marino 
27*86d7f5d3SJohn Marino #define	GROW	10
28*86d7f5d3SJohn Marino 
29*86d7f5d3SJohn Marino /* Read cvsrc, processing options matching CMDNAME ("cvs" for global
30*86d7f5d3SJohn Marino    options, and update *ARGC and *ARGV accordingly.  */
31*86d7f5d3SJohn Marino 
32*86d7f5d3SJohn Marino void
read_cvsrc(int * argc,char *** argv,const char * cmdname)33*86d7f5d3SJohn Marino read_cvsrc (int *argc, char ***argv, const char *cmdname)
34*86d7f5d3SJohn Marino {
35*86d7f5d3SJohn Marino     char *homedir;
36*86d7f5d3SJohn Marino     char *homeinit;
37*86d7f5d3SJohn Marino     FILE *cvsrcfile;
38*86d7f5d3SJohn Marino 
39*86d7f5d3SJohn Marino     char *line;
40*86d7f5d3SJohn Marino     int line_length;
41*86d7f5d3SJohn Marino     size_t line_chars_allocated;
42*86d7f5d3SJohn Marino 
43*86d7f5d3SJohn Marino     char *optstart;
44*86d7f5d3SJohn Marino 
45*86d7f5d3SJohn Marino     int command_len;
46*86d7f5d3SJohn Marino     int found = 0;
47*86d7f5d3SJohn Marino 
48*86d7f5d3SJohn Marino     int i;
49*86d7f5d3SJohn Marino 
50*86d7f5d3SJohn Marino     int new_argc;
51*86d7f5d3SJohn Marino     int max_new_argv;
52*86d7f5d3SJohn Marino     char **new_argv;
53*86d7f5d3SJohn Marino 
54*86d7f5d3SJohn Marino     /* old_argc and old_argv hold the values returned from the
55*86d7f5d3SJohn Marino        previous invocation of read_cvsrc and are used to free the
56*86d7f5d3SJohn Marino        allocated memory.  The first invocation of read_cvsrc gets argv
57*86d7f5d3SJohn Marino        from the system, this memory must not be free'd.  */
58*86d7f5d3SJohn Marino     static int old_argc = 0;
59*86d7f5d3SJohn Marino     static char **old_argv = NULL;
60*86d7f5d3SJohn Marino 
61*86d7f5d3SJohn Marino     /* don't do anything if argc is -1, since that implies "help" mode */
62*86d7f5d3SJohn Marino     if (*argc == -1)
63*86d7f5d3SJohn Marino 	return;
64*86d7f5d3SJohn Marino 
65*86d7f5d3SJohn Marino     /* determine filename for ~/.cvsrc */
66*86d7f5d3SJohn Marino 
67*86d7f5d3SJohn Marino     homedir = get_homedir ();
68*86d7f5d3SJohn Marino     /* If we can't find a home directory, ignore ~/.cvsrc.  This may
69*86d7f5d3SJohn Marino        make tracking down problems a bit of a pain, but on the other
70*86d7f5d3SJohn Marino        hand it might be obnoxious to complain when CVS will function
71*86d7f5d3SJohn Marino        just fine without .cvsrc (and many users won't even know what
72*86d7f5d3SJohn Marino        .cvsrc is).  */
73*86d7f5d3SJohn Marino     if (!homedir)
74*86d7f5d3SJohn Marino 	return;
75*86d7f5d3SJohn Marino 
76*86d7f5d3SJohn Marino     homeinit = strcat_filename_onto_homedir (homedir, cvsrc);
77*86d7f5d3SJohn Marino 
78*86d7f5d3SJohn Marino     /* if it can't be read, there's no point to continuing */
79*86d7f5d3SJohn Marino 
80*86d7f5d3SJohn Marino     if (!isreadable (homeinit))
81*86d7f5d3SJohn Marino     {
82*86d7f5d3SJohn Marino 	free (homeinit);
83*86d7f5d3SJohn Marino 	return;
84*86d7f5d3SJohn Marino     }
85*86d7f5d3SJohn Marino 
86*86d7f5d3SJohn Marino     /* now scan the file until we find the line for the command in question */
87*86d7f5d3SJohn Marino 
88*86d7f5d3SJohn Marino     line = NULL;
89*86d7f5d3SJohn Marino     line_chars_allocated = 0;
90*86d7f5d3SJohn Marino     command_len = strlen (cmdname);
91*86d7f5d3SJohn Marino     cvsrcfile = xfopen (homeinit, "r");
92*86d7f5d3SJohn Marino     while ((line_length = getline (&line, &line_chars_allocated, cvsrcfile))
93*86d7f5d3SJohn Marino 	   >= 0)
94*86d7f5d3SJohn Marino     {
95*86d7f5d3SJohn Marino 	/* skip over comment lines */
96*86d7f5d3SJohn Marino 	if (line[0] == '#')
97*86d7f5d3SJohn Marino 	    continue;
98*86d7f5d3SJohn Marino 
99*86d7f5d3SJohn Marino 	/* stop if we match the current command */
100*86d7f5d3SJohn Marino 	if (!strncmp (line, cmdname, command_len)
101*86d7f5d3SJohn Marino 	    && isspace ((unsigned char) *(line + command_len)))
102*86d7f5d3SJohn Marino 	{
103*86d7f5d3SJohn Marino 	    found = 1;
104*86d7f5d3SJohn Marino 	    break;
105*86d7f5d3SJohn Marino 	}
106*86d7f5d3SJohn Marino     }
107*86d7f5d3SJohn Marino 
108*86d7f5d3SJohn Marino     if (line_length < 0 && !feof (cvsrcfile))
109*86d7f5d3SJohn Marino 	error (0, errno, "cannot read %s", homeinit);
110*86d7f5d3SJohn Marino 
111*86d7f5d3SJohn Marino     fclose (cvsrcfile);
112*86d7f5d3SJohn Marino 
113*86d7f5d3SJohn Marino     /* setup the new options list */
114*86d7f5d3SJohn Marino 
115*86d7f5d3SJohn Marino     new_argc = 1;
116*86d7f5d3SJohn Marino     max_new_argv = (*argc) + GROW;
117*86d7f5d3SJohn Marino     new_argv = xnmalloc (max_new_argv, sizeof (char *));
118*86d7f5d3SJohn Marino     new_argv[0] = xstrdup ((*argv)[0]);
119*86d7f5d3SJohn Marino 
120*86d7f5d3SJohn Marino     if (found)
121*86d7f5d3SJohn Marino     {
122*86d7f5d3SJohn Marino 	/* skip over command in the options line */
123*86d7f5d3SJohn Marino 	for (optstart = strtok (line + command_len, "\t \n");
124*86d7f5d3SJohn Marino 	     optstart;
125*86d7f5d3SJohn Marino 	     optstart = strtok (NULL, "\t \n"))
126*86d7f5d3SJohn Marino 	{
127*86d7f5d3SJohn Marino 	    new_argv [new_argc++] = xstrdup (optstart);
128*86d7f5d3SJohn Marino 
129*86d7f5d3SJohn Marino 	    if (new_argc >= max_new_argv)
130*86d7f5d3SJohn Marino 	    {
131*86d7f5d3SJohn Marino 		max_new_argv += GROW;
132*86d7f5d3SJohn Marino 		new_argv = xnrealloc (new_argv, max_new_argv, sizeof (char *));
133*86d7f5d3SJohn Marino 	    }
134*86d7f5d3SJohn Marino 	}
135*86d7f5d3SJohn Marino     }
136*86d7f5d3SJohn Marino 
137*86d7f5d3SJohn Marino     if (line != NULL)
138*86d7f5d3SJohn Marino 	free (line);
139*86d7f5d3SJohn Marino 
140*86d7f5d3SJohn Marino     /* now copy the remaining arguments */
141*86d7f5d3SJohn Marino 
142*86d7f5d3SJohn Marino     if (new_argc + *argc > max_new_argv)
143*86d7f5d3SJohn Marino     {
144*86d7f5d3SJohn Marino 	max_new_argv = new_argc + *argc;
145*86d7f5d3SJohn Marino 	new_argv = xnrealloc (new_argv, max_new_argv, sizeof (char *));
146*86d7f5d3SJohn Marino     }
147*86d7f5d3SJohn Marino     for (i = 1; i < *argc; i++)
148*86d7f5d3SJohn Marino 	new_argv [new_argc++] = xstrdup ((*argv)[i]);
149*86d7f5d3SJohn Marino 
150*86d7f5d3SJohn Marino     if (old_argv != NULL)
151*86d7f5d3SJohn Marino     {
152*86d7f5d3SJohn Marino 	/* Free the memory which was allocated in the previous
153*86d7f5d3SJohn Marino            read_cvsrc call.  */
154*86d7f5d3SJohn Marino 	free_names (&old_argc, old_argv);
155*86d7f5d3SJohn Marino     }
156*86d7f5d3SJohn Marino 
157*86d7f5d3SJohn Marino     old_argc = *argc = new_argc;
158*86d7f5d3SJohn Marino     old_argv = *argv = new_argv;
159*86d7f5d3SJohn Marino 
160*86d7f5d3SJohn Marino     free (homeinit);
161*86d7f5d3SJohn Marino     return;
162*86d7f5d3SJohn Marino }
163