/*
* 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
#ifndef _WIN32
extern char *strtok (char *, const char *);
#endif
/* 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 freed. */
static int old_argc = 0;
static char **old_argv = NULL;
/* Read cvsrc, processing options matching CMDNAME ("cvs" for global
options, and update *ARGC and *ARGV accordingly. */
void read_cvsrc (int *argc, char ***argv, const char *cmdname)
{
char *homedir;
char *homeinit;
FILE *cvsrcfile;
char *line = NULL, *server_line = NULL;
int line_length;
size_t line_chars_allocated;
char *optstart;
int command_len;
int found = 0, server_found = 0;
int i;
int new_argc;
int max_new_argv;
char **new_argv;
int len;
char *buffer = NULL, *ptr;
/* don't do anything if argc is -1, since that implies "help" mode */
if (*argc == -1)
return;
command_len = strlen (cmdname);
#ifdef SERVER_SUPPORT
/* Attempt to read server cvsrc */
if (server_started)
{
if(supported_request("read-cvsrc2")) /* Sensible version */
{
TRACE(1,"Requesting server cvsrc (read-cvsrc2)");
send_to_server ("read-cvsrc2\n", 0);
read_line(&server_line);
if(server_line[0]=='E' && server_line[1]==' ')
{
fprintf (stderr, "%s\n", server_line + 2);
error_exit();
}
len = atoi(server_line);
buffer = (char*)xmalloc(len+1);
ptr = buffer;
while (len > 0)
{
size_t n;
n = try_read_from_server (ptr, len);
len -= n;
ptr += n;
}
*ptr = '\0';
}
else if(supported_request("read-cvsrc")) /* Version done after one too many beers */
{
TRACE(1,"Requesting server cvsrc (read-cvsrc)");
send_to_server ("read-cvsrc\n", 0);
buffer = (char*)xmalloc(1);
len = 0;
do
{
read_line(&server_line);
if(server_line[0]=='E' && server_line[1]==' ')
{
fprintf (stderr, "%s\n", server_line + 2);
error_exit();
}
if(!strcmp(server_line,"end-cvsrc"))
break;
buffer = (char*)xrealloc(buffer, len+strlen(server_line)+2);
strcpy(buffer+len,server_line);
len+=strlen(server_line);
buffer[len++]='\n';
} while(1);
buffer[len]='\0';
}
}
else
#endif
if(current_parsed_root && (server_active || !current_parsed_root->hostname))
{
homeinit = (char *) xmalloc (strlen (current_parsed_root->directory) + sizeof(CVSROOTADM) + sizeof(CVSROOTADM_CVSRC) + 10);
strcpy (homeinit, current_parsed_root->directory);
strcat (homeinit, "/");
strcat (homeinit, CVSROOTADM);
strcat (homeinit, "/");
strcat (homeinit, CVSROOTADM_CVSRC);
TRACE(1,"Reading global cvsrc");
/* if it can't be read, there's no point to continuing */
if (isreadable (homeinit))
{
cvsrcfile = open_file (homeinit, "r");
fseek(cvsrcfile,0,SEEK_END);
len = ftell(cvsrcfile);
fseek(cvsrcfile,0,SEEK_SET);
buffer = (char*)xmalloc(len+1);
len = fread(buffer,1,len,cvsrcfile);
buffer[len]='\0';
fclose(cvsrcfile);
}
xfree(homeinit);
}
if(buffer)
{
/* now scan the file until we find the line for the command in question */
TRACE(3,"Parsing global cvsrc started");
ptr = strtok(buffer, "\n");
while(ptr && *ptr && !server_found)
{
TRACE(3,"%s",PATCH_NULL(ptr));
/* skip over comment lines */
if (ptr[0] == '#')
{
ptr = strtok(NULL,"\n");
continue;
}
/* stop if we match the current command */
if (!strncmp (ptr, cmdname, command_len)
&& isspace ((unsigned char) *(ptr + command_len)))
{
server_found = 1;
server_line = xstrdup(ptr);
break;
}
ptr = strtok(NULL,"\n");
}
xfree(buffer);
TRACE(3,"Parsing global cvsrc finished");
}
/* 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)
{
homeinit = (char *) xmalloc (strlen (homedir) + strlen (cvsrc) + 10);
strcpy (homeinit, homedir);
strcat (homeinit, "/");
strcat (homeinit, cvsrc);
/* if it can't be read, there's no point to continuing */
if (isreadable (homeinit))
{
/* now scan the file until we find the line for the command in question */
line = NULL;
line_chars_allocated = 0;
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);
}
xfree (homeinit);
}
/* 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 (server_found)
{
/* skip over command in the options line */
for (optstart = strtok (server_line + command_len, "\t \n");
optstart;
optstart = strtok (NULL, "\t \n"))
{
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 (found)
{
/* skip over command in the options line */
for (optstart = strtok (line + command_len, "\t \n");
optstart;
optstart = strtok (NULL, "\t \n"))
{
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)
xfree (line);
if (server_line != NULL)
xfree (server_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;
return;
}
int close_cvsrc()
{
if(old_argv != NULL)
free_names(&old_argc, old_argv);
old_argv = NULL;
return 0;
}
void reset_saved_cvsrc()
{
old_argc = 0;
old_argv = NULL;
}
syntax highlighted by Code2HTML, v. 0.9.1