xref: /openbsd/gnu/usr.bin/cvs/src/cvsrc.c (revision f9bbbf45)
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