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