/* * Copyright (C) 1986-2005 The Free Software Foundation, Inc. * * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , * 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 /* 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; 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 = xfopen (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 = xnmalloc (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"); optstart; optstart = strtok (NULL, "\t \n")) { new_argv [new_argc++] = xstrdup (optstart); if (new_argc >= max_new_argv) { max_new_argv += GROW; new_argv = xnrealloc (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 = xnrealloc (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; }