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