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