11e72d8d2Sderaadt /*
21e72d8d2Sderaadt * Copyright (c) 1993 david d zuhn
31e72d8d2Sderaadt *
42286d8edStholo * Written by david d `zoo' zuhn while at Cygnus Support
51e72d8d2Sderaadt *
62286d8edStholo * You may distribute under the terms of the GNU General Public License as
72286d8edStholo * specified in the README file that comes with the CVS source distribution.
81e72d8d2Sderaadt *
91e72d8d2Sderaadt */
101e72d8d2Sderaadt
111e72d8d2Sderaadt
121e72d8d2Sderaadt #include "cvs.h"
1313571821Stholo #include "getline.h"
141e72d8d2Sderaadt
151e72d8d2Sderaadt /* this file is to be found in the user's home directory */
161e72d8d2Sderaadt
171e72d8d2Sderaadt #ifndef CVSRC_FILENAME
181e72d8d2Sderaadt #define CVSRC_FILENAME ".cvsrc"
191e72d8d2Sderaadt #endif
201e72d8d2Sderaadt char cvsrc[] = CVSRC_FILENAME;
211e72d8d2Sderaadt
221e72d8d2Sderaadt #define GROW 10
231e72d8d2Sderaadt
241e72d8d2Sderaadt extern char *strtok ();
251e72d8d2Sderaadt
26c2c61682Stholo /* Read cvsrc, processing options matching CMDNAME ("cvs" for global
27c2c61682Stholo options, and update *ARGC and *ARGV accordingly. */
28c2c61682Stholo
291e72d8d2Sderaadt void
read_cvsrc(argc,argv,cmdname)30c2c61682Stholo read_cvsrc (argc, argv, cmdname)
311e72d8d2Sderaadt int *argc;
321e72d8d2Sderaadt char ***argv;
33c2c61682Stholo char *cmdname;
341e72d8d2Sderaadt {
351e72d8d2Sderaadt char *homedir;
361e72d8d2Sderaadt char *homeinit;
371e72d8d2Sderaadt FILE *cvsrcfile;
381e72d8d2Sderaadt
3913571821Stholo char *line;
4013571821Stholo int line_length;
4113571821Stholo size_t line_chars_allocated;
421e72d8d2Sderaadt
431e72d8d2Sderaadt char *optstart;
441e72d8d2Sderaadt
4513571821Stholo int command_len;
461e72d8d2Sderaadt int found = 0;
471e72d8d2Sderaadt
481e72d8d2Sderaadt int i;
491e72d8d2Sderaadt
501e72d8d2Sderaadt int new_argc;
511e72d8d2Sderaadt int max_new_argv;
521e72d8d2Sderaadt char **new_argv;
531e72d8d2Sderaadt
542770ece5Stholo /* old_argc and old_argv hold the values returned from the
552770ece5Stholo previous invocation of read_cvsrc and are used to free the
562770ece5Stholo allocated memory. The first invocation of read_cvsrc gets argv
572770ece5Stholo from the system, this memory must not be free'd. */
582770ece5Stholo static int old_argc = 0;
592770ece5Stholo static char **old_argv = NULL;
602770ece5Stholo
611e72d8d2Sderaadt /* don't do anything if argc is -1, since that implies "help" mode */
621e72d8d2Sderaadt if (*argc == -1)
631e72d8d2Sderaadt return;
641e72d8d2Sderaadt
651e72d8d2Sderaadt /* determine filename for ~/.cvsrc */
661e72d8d2Sderaadt
67c26070a5Stholo homedir = get_homedir ();
68c71bc7e2Stholo /* If we can't find a home directory, ignore ~/.cvsrc. This may
69c71bc7e2Stholo make tracking down problems a bit of a pain, but on the other
70c71bc7e2Stholo hand it might be obnoxious to complain when CVS will function
71c71bc7e2Stholo just fine without .cvsrc (and many users won't even know what
72c71bc7e2Stholo .cvsrc is). */
731e72d8d2Sderaadt if (!homedir)
741e72d8d2Sderaadt return;
751e72d8d2Sderaadt
761e72d8d2Sderaadt homeinit = (char *) xmalloc (strlen (homedir) + strlen (cvsrc) + 10);
771e72d8d2Sderaadt strcpy (homeinit, homedir);
781e72d8d2Sderaadt strcat (homeinit, "/");
791e72d8d2Sderaadt strcat (homeinit, cvsrc);
801e72d8d2Sderaadt
811e72d8d2Sderaadt /* if it can't be read, there's no point to continuing */
821e72d8d2Sderaadt
8313571821Stholo if (!isreadable (homeinit))
841e72d8d2Sderaadt {
851e72d8d2Sderaadt free (homeinit);
861e72d8d2Sderaadt return;
871e72d8d2Sderaadt }
881e72d8d2Sderaadt
891e72d8d2Sderaadt /* now scan the file until we find the line for the command in question */
901e72d8d2Sderaadt
9113571821Stholo line = NULL;
9213571821Stholo line_chars_allocated = 0;
93c2c61682Stholo command_len = strlen (cmdname);
941e72d8d2Sderaadt cvsrcfile = open_file (homeinit, "r");
95*f9bbbf45Sfgsch while ((line_length = get_line (&line, &line_chars_allocated, cvsrcfile))
9613571821Stholo >= 0)
971e72d8d2Sderaadt {
981e72d8d2Sderaadt /* skip over comment lines */
9913571821Stholo if (line[0] == '#')
1001e72d8d2Sderaadt continue;
1011e72d8d2Sderaadt
1021e72d8d2Sderaadt /* stop if we match the current command */
103c2c61682Stholo if (!strncmp (line, cmdname, command_len)
104c71bc7e2Stholo && isspace ((unsigned char) *(line + command_len)))
1051e72d8d2Sderaadt {
1061e72d8d2Sderaadt found = 1;
1071e72d8d2Sderaadt break;
1081e72d8d2Sderaadt }
1091e72d8d2Sderaadt }
1101e72d8d2Sderaadt
1112286d8edStholo if (line_length < 0 && !feof (cvsrcfile))
1122286d8edStholo error (0, errno, "cannot read %s", homeinit);
1132286d8edStholo
1141e72d8d2Sderaadt fclose (cvsrcfile);
1151e72d8d2Sderaadt
1162770ece5Stholo /* setup the new options list */
1172770ece5Stholo
1182770ece5Stholo new_argc = 1;
1192770ece5Stholo max_new_argv = (*argc) + GROW;
1202770ece5Stholo new_argv = (char **) xmalloc (max_new_argv * sizeof (char*));
1212770ece5Stholo new_argv[0] = xstrdup ((*argv)[0]);
1222770ece5Stholo
1231e72d8d2Sderaadt if (found)
1241e72d8d2Sderaadt {
1251e72d8d2Sderaadt /* skip over command in the options line */
1262770ece5Stholo for (optstart = strtok (line + command_len, "\t \n");
1272770ece5Stholo optstart;
1282770ece5Stholo optstart = strtok (NULL, "\t \n"))
1291e72d8d2Sderaadt {
1302770ece5Stholo new_argv [new_argc++] = xstrdup (optstart);
1311e72d8d2Sderaadt
1321e72d8d2Sderaadt if (new_argc >= max_new_argv)
1331e72d8d2Sderaadt {
1341e72d8d2Sderaadt max_new_argv += GROW;
1352770ece5Stholo new_argv = (char **) xrealloc (new_argv, max_new_argv * sizeof (char*));
1361e72d8d2Sderaadt }
1371e72d8d2Sderaadt }
1381e72d8d2Sderaadt }
1391e72d8d2Sderaadt
14013571821Stholo if (line != NULL)
14113571821Stholo free (line);
14213571821Stholo
1431e72d8d2Sderaadt /* now copy the remaining arguments */
1441e72d8d2Sderaadt
1452770ece5Stholo if (new_argc + *argc > max_new_argv)
1462770ece5Stholo {
1472770ece5Stholo max_new_argv = new_argc + *argc;
1482770ece5Stholo new_argv = (char **) xrealloc (new_argv, max_new_argv * sizeof (char*));
1492770ece5Stholo }
1501e72d8d2Sderaadt for (i=1; i < *argc; i++)
1511e72d8d2Sderaadt {
1522770ece5Stholo new_argv [new_argc++] = xstrdup ((*argv)[i]);
1531e72d8d2Sderaadt }
1541e72d8d2Sderaadt
1552770ece5Stholo if (old_argv != NULL)
1562770ece5Stholo {
1572770ece5Stholo /* Free the memory which was allocated in the previous
1582770ece5Stholo read_cvsrc call. */
1592770ece5Stholo free_names (&old_argc, old_argv);
1602770ece5Stholo }
1612770ece5Stholo
1622770ece5Stholo old_argc = *argc = new_argc;
1632770ece5Stholo old_argv = *argv = new_argv;
1641e72d8d2Sderaadt
1651e72d8d2Sderaadt free (homeinit);
1661e72d8d2Sderaadt return;
1671e72d8d2Sderaadt }
168