summaryrefslogtreecommitdiffstats
path: root/contrib/cvs/src/cvsrc.c
blob: 60de909b588624f0405d29906ac6e197051981fe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/*
 * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
 *
 * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
 *                                  and others.
 *
 * Portions Copyright (C) 1993 david d zuhn
 * 
 * Written by david d `zoo' zuhn while at Cygnus Support
 * 
 * You may distribute under the terms of the GNU General Public License as
 * specified in the README file that comes with the CVS source distribution.
 *
 */


#include "cvs.h"
#include "getline.h"

/* this file is to be found in the user's home directory */

#ifndef	CVSRC_FILENAME
#define	CVSRC_FILENAME	".cvsrc"
#endif
char cvsrc[] = CVSRC_FILENAME;

#define	GROW	10

extern char *strtok ();

/* Read cvsrc, processing options matching CMDNAME ("cvs" for global
   options, and update *ARGC and *ARGV accordingly.  */

void
read_cvsrc (argc, argv, cmdname)
    int *argc;
    char ***argv;
    const char *cmdname;
{
    char *homedir;
    char *homeinit;
    FILE *cvsrcfile;

    char *line;
    int line_length;
    size_t line_chars_allocated;

    char *optstart;

    int command_len;
    int found = 0;

    int i;

    int new_argc;
    int max_new_argv;
    char **new_argv;

    /* old_argc and old_argv hold the values returned from the
       previous invocation of read_cvsrc and are used to free the
       allocated memory.  The first invocation of read_cvsrc gets argv
       from the system, this memory must not be free'd.  */
    static int old_argc = 0;
    static char **old_argv = NULL;

    /* don't do anything if argc is -1, since that implies "help" mode */
    if (*argc == -1)
	return;

    /* determine filename for ~/.cvsrc */

    homedir = get_homedir ();
    /* If we can't find a home directory, ignore ~/.cvsrc.  This may
       make tracking down problems a bit of a pain, but on the other
       hand it might be obnoxious to complain when CVS will function
       just fine without .cvsrc (and many users won't even know what
       .cvsrc is).  */
    if (!homedir)
	return;

    homeinit = strcat_filename_onto_homedir (homedir, cvsrc);

    /* if it can't be read, there's no point to continuing */

    if (!isreadable (homeinit))
    {
	free (homeinit);
	return;
    }

    /* now scan the file until we find the line for the command in question */

    line = NULL;
    line_chars_allocated = 0;
    command_len = strlen (cmdname);
    cvsrcfile = open_file (homeinit, "r");
    while ((line_length = getline (&line, &line_chars_allocated, cvsrcfile))
	   >= 0)
    {
	/* skip over comment lines */
	if (line[0] == '#')
	    continue;

	/* stop if we match the current command */
	if (!strncmp (line, cmdname, command_len)
	    && isspace ((unsigned char) *(line + command_len)))
	{
	    found = 1;
	    break;
	}
    }

    if (line_length < 0 && !feof (cvsrcfile))
	error (0, errno, "cannot read %s", homeinit);

    fclose (cvsrcfile);

    /* setup the new options list */

    new_argc = 1;
    max_new_argv = (*argc) + GROW;
    new_argv = (char **) xmalloc (max_new_argv * sizeof (char*));
    new_argv[0] = xstrdup ((*argv)[0]);

    if (found)
    {
	/* skip over command in the options line */
	for (optstart = strtok (line + command_len, "\t \n\r");
	     optstart;
	     optstart = strtok (NULL, "\t \n\r"))
	{
	    new_argv [new_argc++] = xstrdup (optstart);
	  
	    if (new_argc >= max_new_argv)
	    {
		max_new_argv += GROW;
		new_argv = (char **) xrealloc (new_argv, max_new_argv * sizeof (char*));
	    }
	}
    }

    if (line != NULL)
	free (line);

    /* now copy the remaining arguments */
  
    if (new_argc + *argc > max_new_argv)
    {
	max_new_argv = new_argc + *argc;
	new_argv = (char **) xrealloc (new_argv, max_new_argv * sizeof (char*));
    }
    for (i=1; i < *argc; i++)
    {
	new_argv [new_argc++] = xstrdup ((*argv)[i]);
    }

    if (old_argv != NULL)
    {
	/* Free the memory which was allocated in the previous
           read_cvsrc call.  */
	free_names (&old_argc, old_argv);
    }

    old_argc = *argc = new_argc;
    old_argv = *argv = new_argv;

    free (homeinit);
    return;
}
OpenPOWER on IntegriCloud