/contrib/cvs/src/cvsrc.c

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