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