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